@martini-film/cli 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,7 +7,7 @@ in. One HTTPS request per call, a static key, no MCP session.
7
7
 
8
8
  ```bash
9
9
  npx @martini-film/cli --help # or: pnpm add -g @martini-film/cli → martini
10
- martini login # pair this device through the browser (90-day key)
10
+ martini login # pair this device through the browser (90-day key); --no-wait to return at once, rerun to collect
11
11
  martini get_board_overview --project <id> # any MCP tool, flags from its arguments
12
12
  martini get_asset --asset-id <id> --fields asset.status,asset.imageUrl
13
13
  martini upload ./ref.png ./take.mp4 --canvas <id>
@@ -19,16 +19,21 @@ martini probe <path|asset-id>… # duration, resolution, fps, c
19
19
 
20
20
  ## How commands are generated
21
21
 
22
- `martini <tool>` exists for every entry of the tool manifest (`src/generated/manifest.json`), which the backend
23
- exports from its MCP registry (`pnpm --dir backend run export:tool-manifest`) and drift-tests against the live
24
- registry. Flags are derived from each tool's JSON Schema: `assetId` becomes `--asset-id`, arrays repeat the flag
25
- (or take a JSON list), objects take JSON, and `--json '{…}'` / `--json @args.json` passes the whole arguments
26
- object — so a plan a script computed is submitted without retyping it. `martini <tool> --help` prints the tool's
27
- own description, every flag with its type and whether it is required, and one example.
22
+ `martini <tool>` exists for every entry of the tool manifest the build carries — the same list the Martini
23
+ MCP server publishes; `martini tools` says when the server has a newer one. Flags are derived from each tool's JSON Schema: `assetId` becomes `--asset-id`, arrays take the values
24
+ after the flag (`--node-ids a b`), a repeated flag, or a JSON list, objects take JSON, a `string | null` argument takes the literal `null` to clear it, a
25
+ `"start" | "end" | {…}` union takes the bare word, and `--args '{…}'` / `--args @args.json` passes the whole
26
+ arguments object (`--json` is an alias, except on a tool whose own argument is named `json`) — so a plan a script
27
+ computed is submitted without retyping it. A tool argument named like a global flag (`fields` on `get_models`) is
28
+ spelled `--tool-<name>`. `--no-context` sends only what you typed, for tools that refuse a
29
+ `projectId` next to another selector. `martini <tool> --help` prints the tool's own description, every flag with
30
+ its type and whether it is required, the result fields when the tool declares them (as `--fields` paths), and one
31
+ example.
28
32
 
29
33
  `projectId`, `canvasId`, and `runId` are filled from context when a tool takes them and the caller did not say:
30
34
  `--project` / `--canvas` / `--run`, else `MARTINI_PROJECT_ID` / `MARTINI_CANVAS_ID` / `MARTINI_RUN_ID`, else the
31
- config file.
35
+ config file. A typed selector that replaces one of them keeps it out (`get_board_overview --project-query`,
36
+ `run_workflow --workflow-id`, which runs a saved workflow on a canvas of its own).
32
37
 
33
38
  ## Credentials and context
34
39
 
@@ -36,18 +41,26 @@ Most specific first:
36
41
 
37
42
  1. Flags: `--api-key`, `--api-url`, `--profile`.
38
43
  2. Environment: `MARTINI_API_KEY`, `MARTINI_API_URL`, `MARTINI_PROFILE`, `MARTINI_CONFIG_FILE`.
39
- 3. The nearest `.martini/config.json` above the working directory — what a workflow run's sandbox has.
40
- 4. `~/.config/martini/config.json` — the profiles `martini login` saves, one per organization, with a default.
44
+ 3. The nearest `.martini/config.json` above the working directory — a Martini workflow run provides one.
45
+ 4. `~/.config/martini/config.json` — the profiles `martini login` saves, with a default (the key `default`). Approving "as you" saves the profile `account`, a key that acts in every organization you belong to; approving for one organization saves a profile named after it (`test-team`). Tools run as you either way and the project you name decides who is billed; an organization key additionally reaches that organization's REST API and is listed in its Settings.
41
46
 
42
- A workflow run's sandbox therefore needs nothing but its working directory; a laptop needs one `martini login`;
43
- a script sets `MARTINI_API_KEY`. A raw Martini API key (`mtn_live_…`) always works.
47
+ `--project-id`, `--canvas-id`, and `--run-id` (the tools' spelling) are accepted wherever `--project`, `--canvas`,
48
+ and `--run` are.
49
+
50
+ Inside a workflow run the CLI is therefore already signed in; a laptop needs one `martini login`;
51
+ a script sets `MARTINI_API_KEY`. A raw Martini API key (`mtn_live_…`) always works. Signing in as you
52
+ needs CLI 0.3.0 or newer; the approval page offers only what the CLI that asked can collect.
44
53
 
45
54
  ## Output and exit codes
46
55
 
47
56
  Results are JSON on stdout — compact when piped, indented on a terminal. `--fields a,b.c` keeps only those
48
- dotted paths, applied on the server so a large listing never crosses the wire. `--out <path>` writes the result
49
- (or, with `--raw`, the media bytes of tools like `view_asset`) to a file and prints one summary line. `--quiet`
50
- prints nothing on success. Errors are one JSON object on stderr: `{ "error": { "code", "message", "hint", "tool",
57
+ dotted paths, applied on the server so a large listing never crosses the wire; a `*` segment steps into every value of
58
+ an id-keyed map (`assets.*.status`) and is applied in the CLI. With `--wait` (including default
59
+ waits), the CLI keeps the submission identifiers for polling and applies `--fields` to the final result.
60
+ `--out <path>` writes the result
61
+ (or, with `--raw`, the media bytes of tools like `view_asset`) to a file and prints one summary line. Printed to
62
+ stdout, a media block is a stub (`mimeType`, `bytes`, a hint) rather than base64, and `--raw` to a terminal without
63
+ `--out` is a usage error. `--quiet` prints nothing on success. Errors are one JSON object on stderr: `{ "error": { "code", "message", "hint", "tool",
51
64
  "exitCode" } }`, with the tool's own MCP error code (`ASSET_NOT_READY`, `NODE_NOT_FOUND`, …).
52
65
 
53
66
  | Exit | Meaning |
@@ -63,14 +76,30 @@ prints nothing on success. Errors are one JSON object on stderr: `{ "error": { "
63
76
 
64
77
  Generation and rendering are asynchronous. `--wait` blocks until the produced assets (or the render) settle and
65
78
  adds `waited` to the result; it is on by default for single-item generation and rendering tools and off for batch
66
- tools, where you fan out and then `martini wait <ids…>` once. `--timeout <seconds>` (default 50, under the 60 s a
67
- sandbox command has) ends the wait with exit 4 and the pending ids, so the next command can resume it.
79
+ tools, where you fan out and then `martini wait <ids…>` once. `waited` has one shape whatever was waited on:
80
+ `{ kind, status, assets? | job? | run? | delivery? }` — `status` is the terminal status (for assets, `failed` when
81
+ any failed) and the settled records sit under the key that names them; `martini wait` prints the same object.
82
+ `--timeout <seconds>` (default `MARTINI_WAIT_TIMEOUT_SECONDS` when set, else 50; a malformed value is a usage error) ends the wait with exit 4: the
83
+ result the command produced is still printed on stdout, with `pending` (and `settled`) ids, and the error on
84
+ stderr names the `martini wait …` command that resumes it. Size `--timeout` to what your shell step allows — a
85
+ video generation takes minutes.
86
+
87
+ ## Approving a quote
88
+
89
+ `generate_nodes`, `upscale_assets`, and `enhance_draft` answer a quote first (`approvalNeeded: true`, `planHash`,
90
+ the estimated olives) and start nothing until called again with that `planHash` (plus `batchRequestId` for
91
+ upscales) and the approval argument. `--approve --max-olives <n>` does both in one command: it takes the quote,
92
+ refuses when the estimated total is over the cap (`PLAN_OVER_BUDGET`) or has no number (`PLAN_UNPRICED`), with
93
+ the quote on stdout and nothing started, and otherwise re-calls the tool with exactly what it asked for; the
94
+ result carries `approvedPlan`. The cap is required: an approval always states how much it is for. A tool with an
95
+ approval argument but no quote step (`create_nodes_and_generate`) is only attested by `--approve` and cannot be
96
+ capped — for a capped batch, `create_nodes` then `generate_nodes --approve --max-olives <n>`.
68
97
 
69
98
  ## Compound commands
70
99
 
71
100
  | Command | Does |
72
101
  | ------------------------------------ | ----------------------------------------------------------------------------------------------------- |
73
- | `login`, `logout`, `whoami` | device-code pairing, forget a profile, who the CLI acts as |
102
+ | `login`, `logout`, `whoami` | device-code pairing (a started pairing is resumed by running `login` again; `--no-wait` returns at once), forget a profile, who the CLI acts as |
74
103
  | `tools`, `models` | the manifest this build knows (and whether the server has a newer one); the cached model catalog |
75
104
  | `upload <paths…>` | prepare → PUT → complete from local files, then wait for processing |
76
105
  | `download <ids…>` | presigned URL → bytes → file |
@@ -79,18 +108,10 @@ sandbox command has) ends the wait with exit 4 and the pending ids, so the next
79
108
  | `probe <path\|id>…` | ffprobe + sha256 in one JSON report |
80
109
  | `init [--write]` | the AGENTS.md snippet that teaches a repo's agents to use the CLI |
81
110
 
82
- ## Inside a workflow run
83
-
84
- The sandbox of a Martini workflow run carries a run key in `.martini/config.json`, written when the run's agent
85
- environment opens and revoked when it closes. Calls made with it go through the run's own supervisor — the same
86
- budgets, spend fences, and trace as the run's tool calls — and the tool set is the run's. A run that is not
87
- executing answers `RUN_NOT_ACTIVE` (exit 4).
88
-
89
111
  ## Single-file binary
90
112
 
91
113
  `pnpm run build:binary` compiles `dist/bin.js` into `dist/martini-linux-x64` with Bun for environments without
92
- Node (the agent-environment sandbox). Bun is only needed on the build machine. Every `cli-v<version>` tag builds
93
- it in CI and publishes it at `https://downloads.martini.film/cli-releases/<version>/martini-linux-x64`
94
- (`.github/workflows/cli-release.yml`); the npm package is published by hand (`AGENTS.md` → Releasing).
114
+ Node. Bun is only needed on the build machine. Every release publishes it at `https://downloads.martini.film/cli-releases/<version>/martini-linux-x64`;
115
+ the npm package is published separately.
95
116
 
96
117
  Docs: <https://www.martini.film/docs/cli>.
package/dist/api.js CHANGED
@@ -1,17 +1,10 @@
1
- /**
2
- * The wire: one HTTPS request per call against the API-key surface —
3
- * `POST /v1/tools/{name}` for every tool, `/v1/tools` for the manifest,
4
- * `/v1/me`, and the two login routes. Static key, no session. The CLI names
5
- * itself with `X-Martini-Client` and a User-Agent that also carries the host
6
- * agent it runs inside, so analytics can tell "the CLI under Claude Code" from
7
- * "Claude Code over MCP".
8
- */
9
1
  import { detectHostAgent } from './host.js';
10
- export const CLI_VERSION = '0.1.0';
2
+ export const CLI_VERSION = '0.3.0';
11
3
  export class CliApiError extends Error {
12
4
  code;
13
5
  status;
14
6
  tool;
7
+ result;
15
8
  constructor(message, details) {
16
9
  super(message);
17
10
  this.name = 'CliApiError';
@@ -35,6 +28,10 @@ export function createApiClient(config, options = {}) {
35
28
  };
36
29
  if (config.apiKey)
37
30
  base.Authorization = `Bearer ${config.apiKey}`;
31
+ if (config.workerId)
32
+ base['X-Martini-Worker'] = config.workerId;
33
+ if (config.executionId)
34
+ base['X-Martini-Execution'] = config.executionId;
38
35
  return base;
39
36
  }
40
37
  async function readError(response, tool) {
@@ -44,7 +41,11 @@ export function createApiClient(config, options = {}) {
44
41
  body = JSON.parse(text);
45
42
  }
46
43
  catch {
47
- body = { error: text };
44
+ const html = /^\s*<(!doctype|html)/i.test(text);
45
+ const title = html ? /<title>([^<]*)<\/title>/i.exec(text)?.[1]?.trim() : undefined;
46
+ body = {
47
+ error: html ? `The API did not answer (HTTP ${response.status}${title ? `: ${title}` : ''}). Try again.` : text,
48
+ };
48
49
  }
49
50
  const message = typeof body.error === 'string' && body.error ? body.error : `Request failed (${response.status})`;
50
51
  return new CliApiError(message, {
@@ -77,7 +78,6 @@ export function createApiClient(config, options = {}) {
77
78
  }
78
79
  return {
79
80
  config,
80
- /** `POST /v1/tools/{name}` → the tool's JSON result. */
81
81
  async callTool(name, args, options = {}) {
82
82
  requireKey();
83
83
  const query = new URLSearchParams();
@@ -91,7 +91,6 @@ export function createApiClient(config, options = {}) {
91
91
  ...(options.signal ? { signal: options.signal } : {}),
92
92
  });
93
93
  },
94
- /** `POST /v1/tools/{name}?format=raw` → the media bytes of a single-media result. */
95
94
  async callToolRaw(name, args) {
96
95
  requireKey();
97
96
  const response = await fetchImpl(`${config.apiUrl}/v1/tools/${encodeURIComponent(name)}?format=raw`, {
@@ -121,6 +120,33 @@ export function createApiClient(config, options = {}) {
121
120
  requireKey();
122
121
  return requestJson('/v1/tools', { method: 'GET' });
123
122
  },
123
+ async serverManifestHash(localHash) {
124
+ requireKey();
125
+ const response = await fetchImpl(`${config.apiUrl}/v1/tools`, {
126
+ method: 'GET',
127
+ headers: headers({ 'If-None-Match': `"${localHash}"` }),
128
+ });
129
+ if (response.status === 304)
130
+ return localHash;
131
+ if (!response.ok)
132
+ throw await readError(response);
133
+ const etag = response.headers
134
+ .get('etag')
135
+ ?.replace(/^W\//, '')
136
+ .replace(/^"(.*)"$/, '$1');
137
+ if (etag) {
138
+ await response.body?.cancel().catch(() => undefined);
139
+ return etag;
140
+ }
141
+ const body = (await response.json());
142
+ if (typeof body.hash !== 'string') {
143
+ throw new CliApiError('The server answered GET /v1/tools without a manifest hash.', {
144
+ code: 'INVALID_RESPONSE',
145
+ status: response.status,
146
+ });
147
+ }
148
+ return body.hash;
149
+ },
124
150
  async me() {
125
151
  requireKey();
126
152
  return requestJson('/v1/me', { method: 'GET' });
@@ -131,7 +157,6 @@ export function createApiClient(config, options = {}) {
131
157
  async pollLogin(pollToken) {
132
158
  return requestJson(`/v1/cli/login/${encodeURIComponent(pollToken)}`, { method: 'GET' });
133
159
  },
134
- /** A plain GET of an absolute URL (presigned downloads), with no Martini headers. */
135
160
  async fetchBytes(url) {
136
161
  const response = await fetchImpl(url);
137
162
  if (!response.ok) {
@@ -145,7 +170,6 @@ export function createApiClient(config, options = {}) {
145
170
  contentType: response.headers.get('content-type') ?? 'application/octet-stream',
146
171
  };
147
172
  },
148
- /** A plain PUT of bytes to a presigned URL with the exact headers the server signed. */
149
173
  async putBytes(url, bytes, putHeaders) {
150
174
  const response = await fetchImpl(url, { method: 'PUT', headers: putHeaders, body: bytes });
151
175
  if (!response.ok) {
package/dist/api.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAG3C,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAA;AAElC,MAAM,OAAO,WAAY,SAAQ,KAAK;IAC3B,IAAI,CAAQ;IACZ,MAAM,CAAQ;IACd,IAAI,CAAe;IAC5B,YAAY,OAAe,EAAE,OAA+D;QAC1F,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,aAAa,CAAA;QACzB,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;QACxB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAA;QAC5B,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,IAAI,CAAA;IAClC,CAAC;CACF;AAmBD,MAAM,UAAU,SAAS,CAAC,MAAyB,OAAO,CAAC,GAAG;IAC5D,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,CAAA;IACjC,OAAO,eAAe,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;AAChE,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAsB,EAAE,UAA4B,EAAE;IACpF,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,IAAI,KAAK,CAAA;IACxC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAA;IAEtC,SAAS,OAAO,CAAC,QAAgC,EAAE;QACjD,MAAM,IAAI,GAA2B;YACnC,YAAY,EAAE,SAAS,CAAC,GAAG,CAAC;YAC5B,kBAAkB,EAAE,eAAe,WAAW,EAAE;YAChD,GAAG,KAAK;SACT,CAAA;QACD,IAAI,MAAM,CAAC,MAAM;YAAE,IAAI,CAAC,aAAa,GAAG,UAAU,MAAM,CAAC,MAAM,EAAE,CAAA;QACjE,OAAO,IAAI,CAAA;IACb,CAAC;IAED,KAAK,UAAU,SAAS,CAAC,QAAkB,EAAE,IAAa;QACxD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;QAClC,IAAI,IAAI,GAAwD,EAAE,CAAA;QAClE,IAAI,CAAC;YACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAgB,CAAA;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;QACxB,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB,QAAQ,CAAC,MAAM,GAAG,CAAA;QACjH,OAAO,IAAI,WAAW,CAAC,OAAO,EAAE;YAC9B,IAAI,EAAE,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB;YAClE,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,IAAI,EAAE,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC;SACjE,CAAC,CAAA;IACJ,CAAC;IAED,SAAS,UAAU;QACjB,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACnB,MAAM,IAAI,WAAW,CAAC,gEAAgE,EAAE;gBACtF,IAAI,EAAE,YAAY;gBAClB,MAAM,EAAE,CAAC;aACV,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,KAAK,UAAU,WAAW,CAAI,IAAY,EAAE,OAAwC,EAAE;QACpF,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,IAAI,EAAE,EAAE;YAC1D,GAAG,IAAI;YACP,OAAO,EAAE,OAAO,CAAC;gBACf,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5D,GAAI,IAAI,CAAC,OAA8C;aACxD,CAAC;SACH,CAAC,CAAA;QACF,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,MAAM,MAAM,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;QAC5D,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,SAAc,CAAA;QAClD,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAM,CAAA;IACrC,CAAC;IAED,OAAO;QACL,MAAM;QAEN,wDAAwD;QACxD,KAAK,CAAC,QAAQ,CACZ,IAAY,EACZ,IAA6B,EAC7B,UAA2B,EAAE;YAE7B,UAAU,EAAE,CAAA;YACZ,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAA;YACnC,IAAI,OAAO,CAAC,MAAM,EAAE,MAAM;gBAAE,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;YACzE,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;YAChD,OAAO,WAAW,CAAI,aAAa,kBAAkB,CAAC,IAAI,CAAC,GAAG,MAAM,EAAE,EAAE;gBACtE,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAC1B,IAAI,EAAE,IAAI;gBACV,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACtD,CAAC,CAAA;QACJ,CAAC;QAED,qFAAqF;QACrF,KAAK,CAAC,WAAW,CAAC,IAAY,EAAE,IAA6B;YAC3D,UAAU,EAAE,CAAA;YACZ,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,MAAM,CAAC,MAAM,aAAa,kBAAkB,CAAC,IAAI,CAAC,aAAa,EAAE;gBACnG,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,OAAO,CAAC,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;gBACxD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;aAC3B,CAAC,CAAA;YACF,IAAI,CAAC,QAAQ,CAAC,EAAE;gBAAE,MAAM,MAAM,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;YACvD,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAA;YAChE,IAAI,IAAI,GAAY,IAAI,CAAA;YACxB,IAAI,UAAU,EAAE,CAAC;gBACf,IAAI,CAAC;oBACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;gBAC/B,CAAC;gBAAC,MAAM,CAAC;oBACP,IAAI,GAAG,UAAU,CAAA;gBACnB,CAAC;YACH,CAAC;YACD,OAAO;gBACL,KAAK,EAAE,IAAI,UAAU,CAAC,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;gBACnD,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,0BAA0B;gBAC/E,IAAI;aACL,CAAA;QACH,CAAC;QAED,KAAK,CAAC,SAAS;YACb,UAAU,EAAE,CAAA;YACZ,OAAO,WAAW,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAA;QACpD,CAAC;QAED,KAAK,CAAC,EAAE;YAKN,UAAU,EAAE,CAAA;YACZ,OAAO,WAAW,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAA;QACjD,CAAC;QAED,KAAK,CAAC,UAAU,CAAC,WAAmB;YAOlC,OAAO,WAAW,CAAC,eAAe,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAAA;QAChG,CAAC;QAED,KAAK,CAAC,SAAS,CACb,SAAiB;YAMjB,OAAO,WAAW,CAAC,iBAAiB,kBAAkB,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAA;QACzF,CAAC;QAED,qFAAqF;QACrF,KAAK,CAAC,UAAU,CAAC,GAAW;YAC1B,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,CAAA;YACrC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,WAAW,CAAC,oBAAoB,QAAQ,CAAC,MAAM,IAAI,EAAE;oBAC7D,IAAI,EAAE,iBAAiB;oBACvB,MAAM,EAAE,QAAQ,CAAC,MAAM;iBACxB,CAAC,CAAA;YACJ,CAAC;YACD,OAAO;gBACL,KAAK,EAAE,IAAI,UAAU,CAAC,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;gBACnD,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,0BAA0B;aAChF,CAAA;QACH,CAAC;QAED,wFAAwF;QACxF,KAAK,CAAC,QAAQ,CAAC,GAAW,EAAE,KAAiB,EAAE,UAAkC;YAC/E,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,KAA4B,EAAE,CAAC,CAAA;YACjH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,WAAW,CAAC,sBAAsB,QAAQ,CAAC,MAAM,IAAI,EAAE;oBAC/D,IAAI,EAAE,mBAAmB;oBACzB,MAAM,EAAE,QAAQ,CAAC,MAAM;iBACxB,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ import { CliApiError } from './api.js';
2
+ import { ArgumentError, kebab } from './schema.js';
3
+ export function approvalSupport(tool) {
4
+ const properties = tool.inputSchema.properties ?? {};
5
+ const argument = 'batchApproval' in properties ? 'batchApproval' : 'approval' in properties ? 'approval' : null;
6
+ if (!argument)
7
+ return null;
8
+ return {
9
+ kind: 'planHash' in properties ? 'quote' : 'attest',
10
+ argument,
11
+ echoesBatchRequestId: 'batchRequestId' in properties,
12
+ };
13
+ }
14
+ export function isQuote(result) {
15
+ if (!result || typeof result !== 'object' || Array.isArray(result))
16
+ return false;
17
+ const record = result;
18
+ return record.approvalNeeded === true || record.generated === false;
19
+ }
20
+ function quotedOlives(quote) {
21
+ const total = quote.totalEstimatedOlives ?? quote.estimatedOlives;
22
+ return typeof total === 'number' && Number.isFinite(total) ? total : null;
23
+ }
24
+ function itemCount(quote, args) {
25
+ if (Array.isArray(quote?.items))
26
+ return quote.items.length;
27
+ for (const key of ['nodeIds', 'nodes'])
28
+ if (Array.isArray(args[key]))
29
+ return args[key].length;
30
+ return 1;
31
+ }
32
+ export async function runWithApproval(tool, client, args, support, options) {
33
+ const { maxOlives } = options;
34
+ if (support.kind === 'attest') {
35
+ if (maxOlives !== undefined) {
36
+ throw new ArgumentError(`${tool.name} has no quote step, so --max-olives cannot be enforced on it. For a capped batch, create the drafts (create_nodes) and run generate_nodes --approve --max-olives ${maxOlives}.`);
37
+ }
38
+ const count = itemCount(undefined, args);
39
+ const summary = `Approved by martini CLI --approve: ${count} item(s), no server quote.`;
40
+ const approval = support.argument === 'batchApproval' ? { approved: true, summary, itemCount: count } : { approved: true, summary };
41
+ return client.callTool(tool.name, { ...args, [support.argument]: approval });
42
+ }
43
+ if (maxOlives === undefined) {
44
+ throw new ArgumentError(`--approve needs --max-olives <olives> on ${tool.name}: the quote is approved only when its estimated total is at or under that cap.`);
45
+ }
46
+ const quote = await client.callTool(tool.name, args);
47
+ if (!isQuote(quote))
48
+ return quote;
49
+ const total = quotedOlives(quote);
50
+ if (total === null) {
51
+ const error = new CliApiError(`${tool.name} quoted no total (an item has no server-side estimate), so --max-olives ${maxOlives} cannot be checked; nothing was started. Approve by hand: re-run with --plan-hash and --${kebab(support.argument)}.`, { code: 'PLAN_UNPRICED', status: 0, tool: tool.name });
52
+ error.result = quote;
53
+ throw error;
54
+ }
55
+ if (total > maxOlives) {
56
+ const error = new CliApiError(`${tool.name} quoted ${total} olives, over the --max-olives ${maxOlives} cap; nothing was started.`, { code: 'PLAN_OVER_BUDGET', status: 0, tool: tool.name });
57
+ error.result = quote;
58
+ throw error;
59
+ }
60
+ const count = itemCount(quote, args);
61
+ const summary = `Approved by martini CLI --approve: ${count} item(s), ${total} olives estimated, cap ${maxOlives}.`;
62
+ const approval = support.argument === 'batchApproval'
63
+ ? { approved: true, summary, itemCount: count, estimatedTotalCost: String(total) }
64
+ : { approved: true, summary, estimatedCost: String(total) };
65
+ const batchRequestId = support.echoesBatchRequestId && typeof quote.batchRequestId === 'string' ? quote.batchRequestId : undefined;
66
+ const result = await client.callTool(tool.name, {
67
+ ...args,
68
+ planHash: quote.planHash,
69
+ ...(batchRequestId ? { batchRequestId } : {}),
70
+ [support.argument]: approval,
71
+ });
72
+ const approvedPlan = {
73
+ planHash: quote.planHash,
74
+ ...(batchRequestId ? { batchRequestId } : {}),
75
+ itemCount: count,
76
+ estimatedOlives: total,
77
+ maxOlives,
78
+ };
79
+ return result && typeof result === 'object' && !Array.isArray(result)
80
+ ? { ...result, approvedPlan }
81
+ : { result, approvedPlan };
82
+ }
83
+ //# sourceMappingURL=approve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approve.js","sourceRoot":"","sources":["../src/approve.ts"],"names":[],"mappings":"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"}
package/dist/args.js CHANGED
@@ -1,12 +1,9 @@
1
- /**
2
- * Argument parsing without a framework: `martini <command> [positionals] [--flag value | --flag=value | --bool]`.
3
- * Repeated flags collect into arrays. Everything after `--` is positional.
4
- */
5
- export function parseArgs(argv) {
1
+ export function parseArgs(argv, isBoolean = () => false, takesList = () => false) {
6
2
  const flags = new Map();
7
3
  const positionals = [];
8
4
  let command;
9
5
  let onlyPositionals = false;
6
+ const pendingNegations = [];
10
7
  const push = (name, value) => {
11
8
  const existing = flags.get(name);
12
9
  if (existing === undefined) {
@@ -21,6 +18,16 @@ export function parseArgs(argv) {
21
18
  }
22
19
  flags.set(name, Array.isArray(existing) ? [...existing, value] : [existing, value]);
23
20
  };
21
+ const takeListValues = (name, index) => {
22
+ if (command === undefined || !takesList(name, command))
23
+ return index;
24
+ let last = index;
25
+ while (last + 1 < argv.length && !argv[last + 1].startsWith('--')) {
26
+ last += 1;
27
+ push(name, argv[last]);
28
+ }
29
+ return last;
30
+ };
24
31
  for (let i = 0; i < argv.length; i += 1) {
25
32
  const arg = argv[i];
26
33
  if (onlyPositionals) {
@@ -35,31 +42,45 @@ export function parseArgs(argv) {
35
42
  const body = arg.slice(2);
36
43
  const eq = body.indexOf('=');
37
44
  if (eq >= 0) {
38
- push(body.slice(0, eq), body.slice(eq + 1));
45
+ const name = body.slice(0, eq);
46
+ push(name, body.slice(eq + 1));
47
+ i = takeListValues(name, i);
39
48
  continue;
40
49
  }
41
- if (body.startsWith('no-')) {
42
- push(body.slice(3), 'false');
50
+ if (body.startsWith('no-') && !isBoolean(body, command)) {
51
+ if (command === undefined)
52
+ pendingNegations.push(body);
53
+ else
54
+ push(body.slice(3), 'false');
43
55
  continue;
44
56
  }
45
57
  const next = argv[i + 1];
46
- if (next !== undefined && !next.startsWith('--')) {
58
+ const boolean = isBoolean(body, command);
59
+ if (next !== undefined && !next.startsWith('--') && (!boolean || /^(true|false|1|0|yes|no)$/.test(next))) {
47
60
  push(body, next);
48
- i += 1;
61
+ i = takeListValues(body, i + 1);
49
62
  }
50
63
  else {
51
64
  push(body, true);
52
65
  }
53
66
  continue;
54
67
  }
55
- if (command === undefined)
68
+ if (command === undefined) {
56
69
  command = arg;
70
+ for (const body of pendingNegations.splice(0)) {
71
+ if (isBoolean(body, command))
72
+ push(body, true);
73
+ else
74
+ push(body.slice(3), 'false');
75
+ }
76
+ }
57
77
  else
58
78
  positionals.push(arg);
59
79
  }
80
+ for (const body of pendingNegations)
81
+ push(body.slice(3), 'false');
60
82
  return { command, positionals, flags };
61
83
  }
62
- /** One value for a flag, or undefined; an array flag yields its last value. */
63
84
  export function flagString(flags, name) {
64
85
  const value = flags.get(name);
65
86
  if (value === undefined || value === true)
package/dist/args.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,MAAM,UAAU,SAAS,CAAC,IAAuB;IAC/C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAqB,CAAA;IAC1C,MAAM,WAAW,GAAa,EAAE,CAAA;IAChC,IAAI,OAA2B,CAAA;IAC/B,IAAI,eAAe,GAAG,KAAK,CAAA;IAE3B,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,KAAoB,EAAE,EAAE;QAClD,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAChC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;YACtB,OAAM;QACR,CAAC;QACD,IAAI,KAAK,KAAK,IAAI;YAAE,OAAM;QAC1B,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACtB,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;YACtB,OAAM;QACR,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAA;IACrF,CAAC,CAAA;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAE,CAAA;QACpB,IAAI,eAAe,EAAE,CAAC;YACpB,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YACrB,SAAQ;QACV,CAAC;QACD,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACjB,eAAe,GAAG,IAAI,CAAA;YACtB,SAAQ;QACV,CAAC;QACD,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;YACzB,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YAC5B,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;gBACZ,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAA;gBAC3C,SAAQ;YACV,CAAC;YACD,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC3B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;gBAC5B,SAAQ;YACV,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;YACxB,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACjD,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;gBAChB,CAAC,IAAI,CAAC,CAAA;YACR,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;YAClB,CAAC;YACD,SAAQ;QACV,CAAC;QACD,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,GAAG,GAAG,CAAA;;YACnC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,CAAA;AACxC,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,UAAU,CAAC,KAA6B,EAAE,IAAY;IACpE,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC7B,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,SAAS,CAAA;IAC3D,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;AAC/D,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAA6B,EAAE,IAAY;IACrE,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC7B,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IACzC,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAA;IAC/B,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;IACnE,OAAO,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI,CAAA;AAC1D,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAA6B,EAAE,IAAY;IAClE,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC7B,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,EAAE,CAAA;IACpD,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;AAC/C,CAAC"}
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"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"}