Repository navigation
Releases: EdgeMetric/mammothsdk
Release list
mammoth-io 0.8.52
Added (mammoth-io 0.8.52)
- SDK: conditional reads. A GET whose response had an
ETagis sent again withIf-None-Match, and a304 Not Modifiedreturns the kept body, so an unchanged resource is not downloaded twice. This covers every route the API tags (workspaces, users, projects, folders, browse, datasets, views, project resources) without a per-route list. The server changes a tag on every change event (a pipeline's status and row count included), and any write the client sends empties the kept bodies first.MammothClient.etag_cacheis the store. By default it'sMemoryETagCache, bounded by entry count and bytes;MemoryETagCache.scoped(name)gives one caller their own share of a cache that many callers use. Pass anymammoth.etag.ETagCacheto keep the bodies elsewhere, orNoneto turn this off. With atoken_provider, the kept bodies are keyed by the token sent too, so a client serving many users never offers one user's body to another. - SDK: writes are safe to retry. Every write except a file upload carries a fresh
Idempotency-Key(a caller's own key is kept). Once a response from the server echoes the key, the server is known to run a keyed write only once. From then on, a write whose connection dropped after it was sent, that got a 502/503/504, or that is still running from the first attempt (4094GENR038) is sent again with the same key, at most twice, and runs once. A server that has never echoed a key gets no replays, as before.mammoth.client.honours_idempotency_keys(base_url)andmark_idempotency_keys_honoured(base_url)read and set what a process knows. If the write is still running after the retries (4094GENR038), the error saysoperation_stateoutcome_unknown, notfailed: it may still finish, so it must not be sent again.
mammoth-io 0.8.51
Added (mammoth-io 0.8.51)
- SDK
mammoth.client.server_health(base_url, timeout=10)GETs the public API v2/healthroute and returnsstatus_codeandlatency_ms(plusversion/commitwhen the backend sends them). A non-2xx status is returned; a timeout or unreachable server raisesMammothAPIError(#304).
Changed (mammoth-io 0.8.51)
- SDK: waiting on a job polls every 0.5 s by default (
DEFAULT_JOB_POLL_SECONDSwas 2), so a short job returns sooner.
mammoth-cli 2.3.1
Fixed (mammoth-cli 2.3.1)
- CLI:
how/schema findrecipe matching: wrong matches, tied parts reported as unresolved, results no longer depend on the hash seed.
mammoth-cli 2.3.0
Added (mammoth-cli 2.3.0)
- CLI: typed output schemas (#315). Every command (346 reads and 505 writes) declares the shape of its
dataasoutput_schemain the manifest, andschema get --fullreturns it as a self-contained JSON Schema 2020-12. A command declaresopenapi(itsdatais the API's own200body), a named schema fromspec/manifests/output-schemas.yaml({ref: NAME}, shared between commands), or an inline schema. Writes shareWriteResult: theverifyblock every API-backed write returns, thestateread-back where the command has one, and the API's own fields. Transforms, exports, bulk deletes, agent turns and runs, and skill writes build on it (TransformResult,ExportResult,DatabaseExportResult,BulkDeleteResult,AgentTurnResult,AgentRunResult,SkillWriteResultand others); a delete with no response body isnull(WriteResultOrNull).output_schemais always the real run'sdata.--dry-runof an API-backed write returns a report instead, andschema get --fullreturns its schema asdry_run_output_schema(nullfor a read). A contract test checks that each of the 851 commands declares one and that it resolves, and a fixture test runs each command's example (and each write's--dry-run) through the real handler and validates the result. It found two wrong read schemas, fixed here:view data comparereturnsdata, notrows, and a folder'screated_bycan be text. - CLI: ETag'd bodies are kept on disk between commands, so repeated
project list,dataset listorview getcalls download only what changed. There is one owner-only directory per credential, profile, server and workspace, under the user cache dir. A write through that credential empties it, andauth login/auth logoutremove all of them.MAMMOTH_CLI_ETAG_CACHE=0keeps the bodies for one command only. Embedded calls (embed.invoke(runtime=...)) never touch the disk. The host'sEmbedRuntimekeeps one in-memory cache, capped at 4096 bodies and 128 MB, and each caller uses only their own scope of it, named by a digest of their credential. Two users therefore never share a body, even when the server gives them the same tag for differently filtered lists. - CLI: every API request names the command that sent it in its
User-Agent, which the server's request log already stores:mammoth-cli/<version> (cmd=view.data.get; inv=3f9c2a1b7d4e; surface=run; agent=claude-code) mammoth-io/<version>.invis one id per command invocation, shared by all its requests and equal to the local run log'srun_id.surfaceisterminal,run(amammoth runline) orembed.agentis set fromMAMMOTH_AGENT, or from the variable a coding agent sets (CLAUDECODE,CURSOR_AGENT,GEMINI_CLI,CODEX_SANDBOX), and never for an embedded call. Only identifiers are sent: no argument values, paths or data. - CLI: steps in
mammoth run. A line with"name"keeps its envelope, and a later line reads it inargs,inputorflagsas"{{steps.<name>.data...}}"."when"skips a line on a JSON condition (eq,in,not,all,any,present), and"for_each"runs a line once per item of a list, with{{item}}and{{index}}. A reference that does not resolve fails the line withunresolved_reference(exit 2); under--dry-runthe line is planned instead. It is plain JSON: no code runs. A$-key other than a value operator ($schema,$ref) in a line is data. Awhenthat is a bare string (no braces) is refused, as it would always be true. Under--dry-run, only a reference into the result of an earlier line plans the line; a malformed expression or a step no line makes fails it. Afor_eachover an empty list prints a skipped envelope withdata: [], and with--continueit runs the items after a failed one. - CLI:
mammoth history list,history show IDandhistory undo ID. Every write is journaled on this machine (owner-only, under the log directory, rotated at 10 MB) with themammoth runlines that reverse it: a trash is undone by a restore, an object a write made goes to the trash, and a pipeline edit returns the view to the pipeline version it had before.history undotakes one write'sinvor a wholemammoth run'sgroup, runs the lines newest first through the normal command path, stops at the first failure (outcome: partial, exit 3) and needs a prompt or--yes;--dry-runpreviews them. A permanent delete, or a write with an effect outside Mammoth, is listed with the reason it cannot be undone.MAMMOTH_CLI_JOURNAL=0turns the journal off; embedded calls are never journaled. An append (file uploadwithappend_to_ds_id) or an export into an existing dataset is nevercreated, so its undo does not trash the dataset (rows cannot be taken out again, and the undo says so). Undo records only the--profilethat was typed, not the default, so an env-token write is not undone as another account. An undo of a pipeline edit refuses when the view's pipeline changed since the edit (--input '{"force": true}'overrides), a stopped undo goes on from the line that failed, and two undos of one write cannot run together. The journal takes a file lock for each append, writes each record in one write, and keeps a run's plan in its own file (pruned after 60 days) so a rotation never drops it. Plans and named results are stored with credential-looking values replaced.history list --input '{"limit": 0}'is refused. An undo runs as the account the write used: a write made under a stored profile is undone under that profile even afterprofile usechanged, and one made withMAMMOTH_API_TOKENis refused withundo_needs_tokenwhen no token is set. The fingerprint that detects a changed pipeline redacts like the CLI output. When another process holds a write's undo, the writes already undone stay in the result (exit 3,not_undonelists the rest), and an undo's lock file is removed when it ends. A journal that cannot be written warns once on stderr. - CLI: every write command declares how
history undoreverses it in its manifest, asundo:{strategy: inverse, command}(run the named command with the write's own arguments, e.g.agent run pauseandresume,dataset file-settings updateandundo),pipeline_version(apply the view's version from before the edit),trash_created(trash what the write made),manual(a command reverses it but needs an id the write made, so it is named, not run) orirreversiblewith a specific reason (a permanent delete, an export to a named system, an email, a refund).journal.compensationreads the declaration instead of working it out frommutation_class.scripts/build_manifests.pyderives the default;spec/manifests/commands/<group>.yamloverrides it, and a contract test fails a write with noundo. #311 Aninverseundo line carries the--confirmtarget and the--sessionthe original write named, so a high-impact reversal runs; an inverse that needs input the write lacks (support partner client cancel-detach) ismanual. Amanualentry says why it is not run, including for pairs that take the same arguments (addon,project user,dashboard filter).file upload-folderanddataset create-from-pdfare undone by trashing what they made;view variants createlists every view it made; a repeateddashboard live-chart createis not journaled as created. - CLI: every success envelope carries
meta.run_id, the invocation id: the same id as the run log'srun_id(log tail), the journal'sinv(history show) and theinvin the request's User-Agent.embed.invoke(..., schema_version=1)pins the envelope version a host was written against;mammoth-cli/docs/envelope-compatibility.mdsays what may change in a minor release and what needs a newschema_version(still 1: nothing in 2.3 breaks it). - CLI: the servers that honour
Idempotency-Keyare remembered between commands (one owner-only file of API base URLs in the user cache dir), so a command's first write can be replayed safely too. Embedded calls never write it. - CLI:
mammoth recipe listandmammoth recipe run ID --input '{"inputs": {...}}'run a common task as one command. All 32 recipes indiscovery/recipes.jsonare executable: append-rows, upload-dashboard, export-csv (takesview_idanddataset_id), share-dashboard, refresh-daily, blend-by-key, stuck-upload, export-powerbi, clean-data, cleanup-mine, upload-clean, join-files, lookup-column, add-calculated-column, extract-date-part, split-column, find-replace, fill-blanks-with-value, rename-columns, remove-duplicates, pivot-summary, top-n, filter-export-csv, export-xlsx, export-to-s3, email-view, dashboard-from-view, summarize-by, compare-views, refresh-now, undo-last-change and revert-view-version. The tasks that would replace a view's rows (pivot-summary, top-n, filter-export-csv) work on a copy. A recipe input can be a string, an integer, an array, an object orany. A recipe's steps run through themammoth runpath in one process, printing one envelope per step and a summary (recipe,inputs,partial_lines). A recipe that writes asks once (prompt or--yes), and--dry-runpreviews every step.mammoth howreturns the recipe'srun_command;schema findlists matching recipes (recipes), andschema listandcapability findlisttasks, before single commands.scripts/eval_task_calls.pycounts the calls: 32 with recipes against 113 step by step for the 32 tasks (mammoth-cli/docs/task-call-eval.md). New error codes:recipe_not_found,recipe_input_invalid.cleanup-minemoves things to the trash (nothing is deleted for good), after a name check and a dependents dry run. A recipe never confirms a destructive line for the caller: it needs an explicit--yes, and the one prompt names those lines. Ananyinput takes a list or a boolean.upload-clean,upload-dashboardandjoin-filesskip the lines that need the upload's view...
mammoth-cli 2.2.100
Added (mammoth-cli 2.2.100)
- CLI
mammoth doctorhas aservercheck: a GET of<api>/health(public, so it needs no login or project) that reportsstatus_codeandlatency_ms(healthy in 84 ms), andversion/commitwhen the backend returns them. It fails (and doctor exits non-zero) on a non-2xx answer, a timeout or an unreachable server, and still runs when auth fails, so an expired login and a down server read differently (#304).
Changed (mammoth-cli 2.2.100)
- CLI:
schema findreturns a compact result (the keysfull_schema_command,known_restrictionsandmatched_onare left out;schema gethas them).schema find --fullreturns the whole result, as before. - CLI:
dashboard canvas getleaves out null fields.
mammoth-io 0.8.50
Added (mammoth-io 0.8.50, mammoth-cli 2.2.98)
- SDK
WorkspaceAPI.list(fields=...)asksGET /workspacesfor the given fields (default"id,name", as before), e.g."id,name,download_file_types";mammoth workspace list --input '{"fields": "..."}'passes it (#272). - CLI
workspace user list --project IDlists that project's members with their roles;schema findreaches it for "project members" and "my role". The project was dropped before (#256). - CLI
--revealondashboard embed secret rotateanddashboard embed preview-token createprints the new signing secret or preview token, which the API shows only once. Without it they stay masked as before (#278).
Changed (mammoth-cli 2.2.98)
- CLI: a plan or AI-quota refusal (
4SUBS101–4SUBS106, e.g.AI_QUOTA_EXHAUSTED,FEATURE_NOT_AVAILABLE_ON_PLAN) is the new error codeplan_limit(exit 4), with the backend's message and a hint about the plan and quota, instead ofauthorization_requiredwith "check the ids" (#254). - CLI:
dashboard live-chart createwaits for the chart's bake job (bounded by--job-timeout) and reads the chart back; the result keepsdashboard_idandjob_id. Before, it returned the queued job with no wait or readback (#281). - CLI:
dashboard live-chart create,dashboard template applyanddashboard v3 generatesend an explicit--projectas the new board'sproject_id; without it the server still uses the source view's project (#280). - CLI:
view export rest-fillrefuseswaitandtimeoutin--inputinstead of ignoring them; it always waits, for at most--job-timeoutseconds (#279).
Fixed (mammoth-io 0.8.50, mammoth-cli 2.2.98)
- SDK
DashboardsAPI.embed_lifetime_setrefuses atoken_ttlthat is not an integer (a bool, a string) as well as one outside 60–3600. CLIdashboard embed lifetime set --dry-runapplies the same check, and its example now uses900instead of the invalid1(#283).
Fixed (mammoth-cli 2.2.98)
- CLI: a backend
PERMISSION_ERROR(4PERM002) sent as an HTTP 400 isauthorization_required(exit 4) with the backend's message, not a genericapi_errortelling the caller to correct the request (#277). - CLI:
dashboard embed config getshowshas_signing_secretastrue/false; key redaction never masks a boolean (#278). - CLI:
--helpandschema getlist the values of aLiteralfield:view export downloadshowsfile_type (csv | xlsx | json | ndjson | xml | yaml | parquet)andschema getreports itsenum. A long type in--helpis cut at a word with..., never inside a value (it showed'par). The command's docstring and example namefile_type(#282). - CLI:
schema get view.summaryreportsdataset_idas optional, as its positional is, andschema findsends column-statistics searches toview data profilerather thanview summary(#284). - CLI:
file uploadof a file that made no dataset (a PDF waiting for table extraction) reportsstatus: no_datasetwith a message andverify.needs_user, notready(#255).
mammoth-io 0.8.49
mammoth-io 0.8.49: MammothClient(default_headers=...) and add_default_headers() keep per-user headers on each request, so clients can share one http_client safely. The generated dashboard models are regenerated from the 2026-10-22 production spec. See CHANGELOG.
mammoth-io 0.8.48
mammoth-io 0.8.48 (with mammoth-cli 2.2.95): connector drafts sub-client, dashboard figure rows/drill/recipe and chart types, automation file routing, 45 support admin methods, agent access, one pipeline read per transform, dead SDK routes removed. See CHANGELOG.md, section "mammoth-io 0.8.48, mammoth-cli 2.2.95".
mammoth-io 0.8.47
mammoth-io 0.8.47 (with mammoth-cli 2.2.94). See CHANGELOG.md, section "mammoth-io 0.8.47, mammoth-cli 2.2.94, mammoth-mcp-server 0.2.7".
mammoth-mcp-server 0.2.8
mammoth-mcp-server 0.2.8 requires mammoth-io >=0.8.47. 0.2.7 next to an older SDK failed on its first request with a TypeError on http_client. The image now refreshes its CA certificates on every build, which drops the distrusted eMudhra CA. See CHANGELOG.