@mapled/cli 0.15.0 → 0.16.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
@@ -30,9 +30,10 @@ The browser opens Mapled on that project and the person clicks Authorize; nothin
30
30
  npx @mapled/cli tools
31
31
  npx @mapled/cli tool get_schema
32
32
  npx @mapled/cli tool propose_setup_plan --input plan.json
33
+ npx @mapled/cli tool get_setup_run '{"runId":"…"}' --wait
33
34
  ```
34
35
 
35
- `tools` lists every tool with its input (`--json` for the schemas). `tool <name>` calls one — the same tools the [MCP server](https://www.npmjs.com/package/@mapled/mcp) offers, through the same connection: the input is a JSON object, inline or in a file with `--input`; the answer is printed as Mapled worded it, and a refusal exits 1.
36
+ `tools` lists every tool with its input (`--json` for the schemas). `tool <name>` calls one — the same tools the [MCP server](https://www.npmjs.com/package/@mapled/mcp) offers, through the same connection: the input is a JSON object, inline or in a file with `--input`; the answer is printed as Mapled worded it, and a refusal exits 1. `tool get_setup_run '{"runId":"…"}' --wait` waits while the plan is still waiting for approval and prints the run once the person has decided on the Mapled screen — the agent carries on without being asked; it waits 90 seconds by default (`--wait=<seconds>`, up to 600) and then prints the run as it stands, so the agent runs the same command again.
36
37
 
37
38
  Do the work yourself: the person approves on Mapled screens (the connection, the plan, a destructive change) and is never sent to a terminal or to GitHub. Never ask for a token or a key in the conversation.
38
39
 
@@ -293,6 +294,7 @@ Prints a Preview link — the one the **Preview** button in Mapled opens: the si
293
294
  - `--no-browser` — print the sign-in link instead of opening a browser
294
295
  - `--project <id>` — the project `connect` and `auth login` open the consent on, and the one `project link` links
295
296
  - `--input <file>` — `tool` only: the tool's input as a JSON file
297
+ - `--wait[=<seconds>]` — `tool get_setup_run` only: wait while the plan awaits approval (90 seconds by default, up to 600)
296
298
  - `--json` — machine-readable output (`tools`, `doctor`, `integration report`, `schema diff`, `scan`, `manifest validate`, `forms list`, `preview`)
297
299
  - `--load-config` — `doctor` only: let the site's installed Next load a next.config doctor can't read; runs the site's code, as `next build` does
298
300
  - `MAPLED_CONFIG_DIR` — where credentials live (default: `$XDG_CONFIG_HOME/mapled` or `~/.config/mapled`)
@@ -17,6 +17,8 @@ export type Ctx = {
17
17
  credentialsFile: string;
18
18
  /** How long a sign-in waits for the browser (tests shorten it). */
19
19
  loginTimeoutMs?: number;
20
+ /** How often `tool get_setup_run --wait` asks again (tests shorten it). */
21
+ pollMs?: number;
20
22
  };
21
23
  type Flags = ParsedArgs["flags"];
22
24
  export declare function login(ctx: Ctx, flags: Flags): Promise<Connection>;
package/dist/commands.js CHANGED
@@ -249,13 +249,51 @@ export async function tool(ctx, flags, words) {
249
249
  }
250
250
  if (args === null || typeof args !== "object" || Array.isArray(args))
251
251
  throw new CliError("The input must be a JSON object.");
252
+ const wait = waitSeconds(flags, name);
252
253
  const { session } = await openSession(ctx, flags);
253
- const answer = await session.rpc("tools/call", { name, arguments: args });
254
+ const deadline = Date.now() + wait * 1000;
255
+ let answer = await session.rpc("tools/call", { name, arguments: args });
256
+ // the person approves on a Mapled screen, not in the agent's chat: the
257
+ // agent blocks here instead of ending its turn to wait for a word that
258
+ // never comes
259
+ while (wait > 0 && !answer.isError && awaitingApproval(answer) && Date.now() < deadline) {
260
+ await new Promise((resolve) => setTimeout(resolve, Math.min(ctx.pollMs ?? WAIT_POLL_MS, Math.max(0, deadline - Date.now()))));
261
+ answer = await session.rpc("tools/call", { name, arguments: args });
262
+ }
254
263
  for (const part of answer.content ?? [])
255
264
  if (part.type === "text" && part.text !== undefined)
256
265
  ctx.out(part.text);
257
266
  return answer.isError ? 1 : 0;
258
267
  }
268
+ /** `--wait` waits this long by default: under the two minutes an agent's
269
+ shell gives a command unless it asks for more. */
270
+ const WAIT_SECONDS = 90;
271
+ const WAIT_MAX_SECONDS = 600;
272
+ const WAIT_POLL_MS = 3000;
273
+ /** Seconds `tool <name> --wait[=<seconds>]` may wait; 0 without it. */
274
+ function waitSeconds(flags, name) {
275
+ const value = flags.wait;
276
+ if (value === undefined)
277
+ return 0;
278
+ if (name !== "get_setup_run")
279
+ throw new CliError("--wait works with get_setup_run only.", 2);
280
+ if (value === true)
281
+ return WAIT_SECONDS;
282
+ const seconds = Number(value);
283
+ if (!Number.isInteger(seconds) || seconds < 1 || seconds > WAIT_MAX_SECONDS) {
284
+ throw new CliError(`--wait takes whole seconds from 1 to ${WAIT_MAX_SECONDS}.`, 2);
285
+ }
286
+ return seconds;
287
+ }
288
+ function awaitingApproval(answer) {
289
+ const text = answer.content?.find((part) => part.type === "text")?.text;
290
+ try {
291
+ return JSON.parse(text ?? "").run?.status === "awaiting_approval";
292
+ }
293
+ catch {
294
+ return false;
295
+ }
296
+ }
259
297
  async function openSession(ctx, flags) {
260
298
  const found = await findConfig(ctx.cwd);
261
299
  if (!found)
package/dist/index.js CHANGED
@@ -16,6 +16,7 @@ Usage
16
16
  mapled connect [--project <id>] Connect this repository: sign in, write mapled.json, print the guide for AI agents
17
17
  mapled tools [--json] List the Mapled tools an agent can call
18
18
  mapled tool <name> [<json> | --input <file>] Call one tool — the same ones the MCP server offers
19
+ get_setup_run --wait[=<s>] waits (90 s by default) for the plan's approval
19
20
  mapled auth login [--api <origin>] [--no-browser] Sign in to a project in your browser
20
21
  mapled auth logout [--all] Revoke this machine's access to the linked project
21
22
  mapled project link [--project <id>] Write mapled.json for this repository
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mapled/cli",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "description": "Mapled CLI — sign in, link a project, generate TypeScript types for its content, create forms, preview drafts and check the site's integration.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://mapled.io",