makaron-cli 0.7.10 → 0.8.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
@@ -134,6 +134,23 @@ Outputs one JSON per line as artifacts appear:
134
134
  {"event":"done","status":"completed"}
135
135
  ```
136
136
 
137
+ ### New Agent quickstart
138
+
139
+ For a new Agent, keep the default service flow to two response commands:
140
+
141
+ ```bash
142
+ npx makaron-cli responses next <runId> --json
143
+ npx makaron-cli responses handle <messageId> --run <runId> --choice approve
144
+ ```
145
+
146
+ `responses next` emits a compact timeline, detects text-only checkpoints for creative/service work, and returns `next_commands` when the Agent must handle a Makaron message before waiting for artifacts. It exits with code `3` on an unhandled checkpoint so wrappers stop instead of silently waiting. After handling a checkpoint, run the returned `next_commands.inspect` command to continue. A non-checkpoint response returns `status: "ready"` or `status: "has_artifacts"`. Use `--no-fail` to inspect the JSON without failing. For pure Q&A runs, use:
147
+
148
+ ```bash
149
+ npx makaron-cli responses next <runId> --json --checkpoint-mode off
150
+ ```
151
+
152
+ `responses handle` is the single checkpoint action command. Valid choices are `approve`, `revise`, `ask_user`, and `continue`.
153
+
137
154
  ### Dialogue events for external Agents
138
155
 
139
156
  Use this when another Agent needs to read what Makaron said, handle text checkpoints, and relay artifacts without inventing customer-service wording.
@@ -145,6 +162,8 @@ npx makaron-cli responses events <runId> --jsonl
145
162
  # pure Q&A view: npx makaron-cli responses timeline <runId> --jsonl --checkpoint-mode off
146
163
  ```
147
164
 
165
+ `events` and `timeline` are lower-level commands. New Agents should start with `responses next` and use these only when they need raw event streams.
166
+
148
167
  Events use only three factual types:
149
168
 
150
169
  ```json
@@ -160,6 +179,7 @@ npx makaron-cli responses approve msg_1 --run <runId> --note "Proceed."
160
179
  npx makaron-cli responses revise msg_1 --run <runId> "make it softer"
161
180
  npx makaron-cli responses ask-user msg_1 --run <runId>
162
181
  npx makaron-cli responses continue msg_1 --run <runId>
182
+ npx makaron-cli responses handle msg_1 --run <runId> --choice approve
163
183
  ```
164
184
 
165
185
  Important: approvals are a local Agent gate in v0. They are recorded by the CLI so wrappers and Skills can fail fast, but they do not pause or resume the remote Makaron runtime yet. Wrappers can enforce the local gate with:
@@ -310,18 +330,15 @@ RUN_ID=$(echo "$RUN_JSON" | jq -r .runId)
310
330
  PROJECT_URL=$(echo "$RUN_JSON" | jq -r .projectUrl)
311
331
  send_message "Project created: $PROJECT_URL"
312
332
 
313
- if ! npx makaron-cli responses timeline "$RUN_ID" --jsonl --compact --checkpoint-mode service --fail-on-unapproved > /tmp/makaron-events.jsonl; then
314
- npx makaron-cli responses timeline "$RUN_ID" --jsonl --compact | while read -r event; do
315
- TYPE=$(echo "$event" | jq -r .type)
316
- REQUIRES=$(echo "$event" | jq -r ".requires_approval // false")
317
- TEXT=$(echo "$event" | jq -r ".text // empty")
318
- MSG_ID=$(echo "$event" | jq -r ".id // empty")
319
- if [ "$TYPE" = "message" ] && [ "$REQUIRES" = "true" ]; then
320
- send_message "$TEXT"
321
- npx makaron-cli responses ask-user "$MSG_ID" --run "$RUN_ID"
322
- exit 3
323
- fi
324
- done
333
+ if ! NEXT=$(npx makaron-cli responses next "$RUN_ID" --json); then
334
+ STATUS=$(echo "$NEXT" | jq -r .status)
335
+ if [ "$STATUS" = "needs_approval" ]; then
336
+ MSG_ID=$(echo "$NEXT" | jq -r .checkpoint.id)
337
+ TEXT=$(echo "$NEXT" | jq -r .checkpoint.text)
338
+ send_message "$TEXT"
339
+ npx makaron-cli responses handle "$MSG_ID" --run "$RUN_ID" --choice ask_user
340
+ exit 3
341
+ fi
325
342
  fi
326
343
 
327
344
  RESULT=$(npx makaron-cli responses get "$RUN_ID" --wait --json)
package/SKILL.md CHANGED
@@ -126,6 +126,23 @@ Outputs one JSON per line as artifacts appear:
126
126
  {"event":"done","status":"completed"}
127
127
  ```
128
128
 
129
+ ### New Agent quickstart
130
+
131
+ For a new Agent, keep the default service flow to two response commands:
132
+
133
+ ```bash
134
+ npx makaron-cli responses next <runId> --json
135
+ npx makaron-cli responses handle <messageId> --run <runId> --choice approve
136
+ ```
137
+
138
+ `responses next` emits a compact timeline, detects text-only checkpoints for creative/service work, and returns `next_commands` when the Agent must handle a Makaron message before waiting for artifacts. It exits with code `3` on an unhandled checkpoint so wrappers stop instead of silently waiting. After handling a checkpoint, run the returned `next_commands.inspect` command to continue. A non-checkpoint response returns `status: "ready"` or `status: "has_artifacts"`. Use `--no-fail` to inspect the JSON without failing. For pure Q&A runs, use:
139
+
140
+ ```bash
141
+ npx makaron-cli responses next <runId> --json --checkpoint-mode off
142
+ ```
143
+
144
+ `responses handle` is the single checkpoint action command. Valid choices are `approve`, `revise`, `ask_user`, and `continue`.
145
+
129
146
  ### Dialogue events for external Agents
130
147
 
131
148
  Use this when another Agent needs to read what Makaron said, handle text checkpoints, and relay artifacts without inventing customer-service wording.
@@ -137,6 +154,8 @@ npx makaron-cli responses events <runId> --jsonl
137
154
  # pure Q&A view: npx makaron-cli responses timeline <runId> --jsonl --checkpoint-mode off
138
155
  ```
139
156
 
157
+ `events` and `timeline` are lower-level commands. New Agents should start with `responses next` and use these only when they need raw event streams.
158
+
140
159
  Events use only three factual types:
141
160
 
142
161
  ```json
@@ -152,6 +171,7 @@ npx makaron-cli responses approve msg_1 --run <runId> --note "Proceed."
152
171
  npx makaron-cli responses revise msg_1 --run <runId> "make it softer"
153
172
  npx makaron-cli responses ask-user msg_1 --run <runId>
154
173
  npx makaron-cli responses continue msg_1 --run <runId>
174
+ npx makaron-cli responses handle msg_1 --run <runId> --choice approve
155
175
  ```
156
176
 
157
177
  Important: approvals are a local Agent gate in v0. They are recorded by the CLI so wrappers and Skills can fail fast, but they do not pause or resume the remote Makaron runtime yet. Wrappers can enforce the local gate with:
@@ -299,18 +319,15 @@ RUN_ID=$(echo "$RUN_JSON" | jq -r .runId)
299
319
  PROJECT_URL=$(echo "$RUN_JSON" | jq -r .projectUrl)
300
320
  send_message "Project created: $PROJECT_URL"
301
321
 
302
- if ! npx makaron-cli responses timeline "$RUN_ID" --jsonl --compact --checkpoint-mode service --fail-on-unapproved > /tmp/makaron-events.jsonl; then
303
- npx makaron-cli responses timeline "$RUN_ID" --jsonl --compact | while read -r event; do
304
- TYPE=$(echo "$event" | jq -r .type)
305
- REQUIRES=$(echo "$event" | jq -r ".requires_approval // false")
306
- TEXT=$(echo "$event" | jq -r ".text // empty")
307
- MSG_ID=$(echo "$event" | jq -r ".id // empty")
308
- if [ "$TYPE" = "message" ] && [ "$REQUIRES" = "true" ]; then
309
- send_message "$TEXT"
310
- npx makaron-cli responses ask-user "$MSG_ID" --run "$RUN_ID"
311
- exit 3
312
- fi
313
- done
322
+ if ! NEXT=$(npx makaron-cli responses next "$RUN_ID" --json); then
323
+ STATUS=$(echo "$NEXT" | jq -r .status)
324
+ if [ "$STATUS" = "needs_approval" ]; then
325
+ MSG_ID=$(echo "$NEXT" | jq -r .checkpoint.id)
326
+ TEXT=$(echo "$NEXT" | jq -r .checkpoint.text)
327
+ send_message "$TEXT"
328
+ npx makaron-cli responses handle "$MSG_ID" --run "$RUN_ID" --choice ask_user
329
+ exit 3
330
+ fi
314
331
  fi
315
332
 
316
333
  RESULT=$(npx makaron-cli responses get "$RUN_ID" --wait --json)
package/bin/makaron.mjs CHANGED
@@ -608,14 +608,18 @@ function compactDialogueEvents(events) {
608
608
  && prev.type === 'message'
609
609
  && ev.source_type === 'content'
610
610
  && prev.source_type === 'content'
611
- && !ev.requires_approval
612
- && !prev.requires_approval
613
611
  && !ev.proposal
614
- && !prev.proposal;
612
+ && !prev.proposal
613
+ && Boolean(ev.requires_approval) === Boolean(prev.requires_approval)
614
+ && (ev.approval_reason || '') === (prev.approval_reason || '');
615
615
  if (canMerge) {
616
616
  prev.text = `${prev.text}${ev.text}`;
617
617
  prev.id = `${prev.id}+${ev.id}`;
618
618
  prev.seq_end = ev.seq;
619
+ if (ev.requires_approval) {
620
+ prev.requires_approval = true;
621
+ prev.approval_options = prev.approval_options || ev.approval_options;
622
+ }
619
623
  } else {
620
624
  compacted.push({ ...ev });
621
625
  }
@@ -628,6 +632,45 @@ function findUnhandledApprovalMessages(events) {
628
632
  return events.filter(ev => ev.type === 'message' && ev.requires_approval && !approved.has(ev.id));
629
633
  }
630
634
 
635
+ function buildHandleCommand(messageId, runId, choice) {
636
+ return `npx makaron-cli responses handle ${messageId} --run ${runId} --choice ${choice}`;
637
+ }
638
+
639
+ function buildNextCommand(runId) {
640
+ return `npx makaron-cli responses next ${runId} --json`;
641
+ }
642
+
643
+ function buildNextAction(runId, events) {
644
+ const checkpoint = findUnhandledApprovalMessages(events)[0] || null;
645
+ const artifacts = events.filter(ev => ev.type === 'artifact');
646
+ const approvals = events.filter(ev => ev.type === 'approval');
647
+ if (checkpoint) {
648
+ return {
649
+ status: 'needs_approval',
650
+ runId,
651
+ checkpoint,
652
+ next_commands: {
653
+ approve: buildHandleCommand(checkpoint.id, runId, 'approve'),
654
+ revise: `${buildHandleCommand(checkpoint.id, runId, 'revise')} --note "what to change"`,
655
+ ask_user: buildHandleCommand(checkpoint.id, runId, 'ask_user'),
656
+ continue: buildHandleCommand(checkpoint.id, runId, 'continue'),
657
+ inspect: buildNextCommand(runId),
658
+ },
659
+ events,
660
+ };
661
+ }
662
+ return {
663
+ status: artifacts.length ? 'has_artifacts' : 'ready',
664
+ runId,
665
+ artifacts,
666
+ approvals,
667
+ next_commands: {
668
+ inspect: buildNextCommand(runId),
669
+ },
670
+ events,
671
+ };
672
+ }
673
+
631
674
  async function fetchRun(baseUrl, headers, runId, opts = {}) {
632
675
  const params = new URLSearchParams();
633
676
  if (opts.events) params.set('events', 'true');
@@ -666,6 +709,32 @@ async function printDialogueEvents(baseUrl, headers, runId, opts = {}) {
666
709
  }
667
710
  }
668
711
 
712
+ async function printAgentNext(baseUrl, headers, runId, opts = {}) {
713
+ const { json = false, checkpointMode = 'service', failOnCheckpoint = true } = opts;
714
+ const data = await fetchRun(baseUrl, headers, runId, { events: true });
715
+ const events = compactDialogueEvents(buildDialogueEvents(runId, { ...data, checkpointMode }));
716
+ const action = buildNextAction(runId, events);
717
+ if (json) {
718
+ console.log(JSON.stringify(action, null, 2));
719
+ } else if (action.status === 'needs_approval') {
720
+ console.log(`needs_approval: ${action.checkpoint.id}`);
721
+ if (action.checkpoint.text) console.log(action.checkpoint.text);
722
+ console.log(`approve: ${action.next_commands.approve}`);
723
+ console.log(`revise: ${action.next_commands.revise}`);
724
+ console.log(`ask_user: ${action.next_commands.ask_user}`);
725
+ console.log(`continue: ${action.next_commands.continue}`);
726
+ console.log(`inspect: ${action.next_commands.inspect}`);
727
+ } else if (action.status === 'has_artifacts') {
728
+ for (const artifact of action.artifacts) {
729
+ console.log(`${artifact.kind} ${artifact.status}${artifact.url ? ` ${artifact.url}` : ''}`);
730
+ }
731
+ } else {
732
+ console.log('ready');
733
+ console.log(`inspect: ${action.next_commands.inspect}`);
734
+ }
735
+ if (action.status === 'needs_approval' && failOnCheckpoint) process.exit(3);
736
+ }
737
+
669
738
  function recordApproval(runId, messageId, choice, note) {
670
739
  const approvals = loadApprovals();
671
740
  const approval = {
@@ -1317,6 +1386,21 @@ if (command === '--version' || command === '-v' || command === 'version') {
1317
1386
  }
1318
1387
  await watchRun(baseUrl, headers, runId, { interval, jsonl });
1319
1388
 
1389
+ } else if (sub === 'next') {
1390
+ const runId = args[2];
1391
+ if (!runId) { console.error('Usage: makaron responses next <runId> [--json] [--checkpoint-mode service|off] [--no-fail]'); process.exit(1); }
1392
+ let jsonOutput = false, checkpointMode = 'service', failOnCheckpoint = true;
1393
+ for (let i = 3; i < args.length; i++) {
1394
+ if (args[i] === '--json') jsonOutput = true;
1395
+ else if (args[i] === '--checkpoint-mode' && args[i + 1]) checkpointMode = args[++i];
1396
+ else if (args[i] === '--no-fail') failOnCheckpoint = false;
1397
+ }
1398
+ if (!['service', 'off'].includes(checkpointMode)) {
1399
+ console.error('--checkpoint-mode must be service or off');
1400
+ process.exit(1);
1401
+ }
1402
+ await printAgentNext(baseUrl, headers, runId, { json: jsonOutput, checkpointMode, failOnCheckpoint });
1403
+
1320
1404
  } else if (sub === 'events' || sub === 'timeline') {
1321
1405
  const runId = args[2];
1322
1406
  if (!runId) { console.error(`Usage: makaron responses ${sub} <runId> [--jsonl] [--compact] [--checkpoint-mode service|off] [--follow] [--interval <ms>] [--fail-on-unapproved]`); process.exit(1); }
@@ -1335,19 +1419,35 @@ if (command === '--version' || command === '-v' || command === 'version') {
1335
1419
  }
1336
1420
  await printDialogueEvents(baseUrl, headers, runId, { interval, jsonl, follow, failOnUnapproved, compact, checkpointMode });
1337
1421
 
1338
- } else if (['approve', 'revise', 'ask-user', 'continue'].includes(sub)) {
1422
+ } else if (sub === 'handle' || ['approve', 'revise', 'ask-user', 'continue'].includes(sub)) {
1339
1423
  const messageId = args[2];
1340
- if (!messageId) { console.error(`Usage: makaron responses ${sub} <messageId> --run <runId> [--note <text>]`); process.exit(1); }
1341
- let runId = null, note = null;
1424
+ if (!messageId) {
1425
+ console.error(sub === 'handle'
1426
+ ? 'Usage: makaron responses handle <messageId> --run <runId> --choice approve|revise|ask_user|continue [--note <text>]'
1427
+ : `Usage: makaron responses ${sub} <messageId> --run <runId> [--note <text>]`);
1428
+ process.exit(1);
1429
+ }
1430
+ let runId = null, note = null, choice = sub === 'handle' ? null : sub;
1342
1431
  const noteParts = [];
1343
1432
  for (let i = 3; i < args.length; i++) {
1344
1433
  if (args[i] === '--run' && args[i + 1]) runId = args[++i];
1345
1434
  else if (args[i] === '--note' && args[i + 1]) note = args[++i];
1435
+ else if (args[i] === '--choice' && args[i + 1]) choice = args[++i];
1346
1436
  else noteParts.push(args[i]);
1347
1437
  }
1348
- if (!runId) { console.error(`Usage: makaron responses ${sub} <messageId> --run <runId> [--note <text>]`); process.exit(1); }
1438
+ if (!runId || !choice) {
1439
+ console.error(sub === 'handle'
1440
+ ? 'Usage: makaron responses handle <messageId> --run <runId> --choice approve|revise|ask_user|continue [--note <text>]'
1441
+ : `Usage: makaron responses ${sub} <messageId> --run <runId> [--note <text>]`);
1442
+ process.exit(1);
1443
+ }
1444
+ choice = choice === 'ask-user' ? 'ask_user' : choice;
1445
+ if (!['approve', 'revise', 'ask_user', 'continue'].includes(choice)) {
1446
+ console.error('--choice must be approve, revise, ask_user, or continue');
1447
+ process.exit(1);
1448
+ }
1349
1449
  if (!note && noteParts.length) note = noteParts.join(' ');
1350
- recordApproval(runId, messageId, sub === 'ask-user' ? 'ask_user' : sub, note);
1450
+ recordApproval(runId, messageId, choice, note);
1351
1451
 
1352
1452
  } else if (sub === 'list') {
1353
1453
  let projectId = null;
@@ -1372,6 +1472,8 @@ if (command === '--version' || command === '-v' || command === 'version') {
1372
1472
  responses get <runId> Get status and output (JSON)
1373
1473
  responses get <runId> --wait Poll until completed
1374
1474
  responses get <runId> --pick <field> Extract: first_image_url, first_video_url, project_url, output
1475
+ responses next <runId> --json New Agent entry: compact timeline + checkpoint guidance
1476
+ responses handle <messageId> --run <runId> --choice approve|revise|ask_user|continue
1375
1477
  responses events <runId> --jsonl Emit message/approval/artifact events for external Agents
1376
1478
  responses timeline <runId> --jsonl Alias for responses events
1377
1479
  responses timeline <runId> --checkpoint-mode off Disable text-only checkpoints for pure Q&A
@@ -1816,6 +1918,8 @@ Commands:
1816
1918
 
1817
1919
  responses get <runId> Get run status and results
1818
1920
  responses get <runId> --wait Poll until completed
1921
+ responses next <runId> --json New Agent entry: compact timeline + checkpoint guidance
1922
+ responses handle <messageId> --run <runId> --choice approve|revise|ask_user|continue
1819
1923
  responses events <runId> --jsonl Emit message/approval/artifact events
1820
1924
  responses timeline <runId> --checkpoint-mode off Disable text-only checkpoints for pure Q&A
1821
1925
  responses list --project <id> List runs for a project
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "makaron-cli",
3
- "version": "0.7.10",
3
+ "version": "0.8.0",
4
4
  "description": "Talk to Makaron Agent from the terminal — create projects, edit images, generate videos",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -126,6 +126,23 @@ Outputs one JSON per line as artifacts appear:
126
126
  {"event":"done","status":"completed"}
127
127
  ```
128
128
 
129
+ ### New Agent quickstart
130
+
131
+ For a new Agent, keep the default service flow to two response commands:
132
+
133
+ ```bash
134
+ npx makaron-cli responses next <runId> --json
135
+ npx makaron-cli responses handle <messageId> --run <runId> --choice approve
136
+ ```
137
+
138
+ `responses next` emits a compact timeline, detects text-only checkpoints for creative/service work, and returns `next_commands` when the Agent must handle a Makaron message before waiting for artifacts. It exits with code `3` on an unhandled checkpoint so wrappers stop instead of silently waiting. After handling a checkpoint, run the returned `next_commands.inspect` command to continue. A non-checkpoint response returns `status: "ready"` or `status: "has_artifacts"`. Use `--no-fail` to inspect the JSON without failing. For pure Q&A runs, use:
139
+
140
+ ```bash
141
+ npx makaron-cli responses next <runId> --json --checkpoint-mode off
142
+ ```
143
+
144
+ `responses handle` is the single checkpoint action command. Valid choices are `approve`, `revise`, `ask_user`, and `continue`.
145
+
129
146
  ### Dialogue events for external Agents
130
147
 
131
148
  Use this when another Agent needs to read what Makaron said, handle text checkpoints, and relay artifacts without inventing customer-service wording.
@@ -137,6 +154,8 @@ npx makaron-cli responses events <runId> --jsonl
137
154
  # pure Q&A view: npx makaron-cli responses timeline <runId> --jsonl --checkpoint-mode off
138
155
  ```
139
156
 
157
+ `events` and `timeline` are lower-level commands. New Agents should start with `responses next` and use these only when they need raw event streams.
158
+
140
159
  Events use only three factual types:
141
160
 
142
161
  ```json
@@ -152,6 +171,7 @@ npx makaron-cli responses approve msg_1 --run <runId> --note "Proceed."
152
171
  npx makaron-cli responses revise msg_1 --run <runId> "make it softer"
153
172
  npx makaron-cli responses ask-user msg_1 --run <runId>
154
173
  npx makaron-cli responses continue msg_1 --run <runId>
174
+ npx makaron-cli responses handle msg_1 --run <runId> --choice approve
155
175
  ```
156
176
 
157
177
  Important: approvals are a local Agent gate in v0. They are recorded by the CLI so wrappers and Skills can fail fast, but they do not pause or resume the remote Makaron runtime yet. Wrappers can enforce the local gate with:
@@ -299,18 +319,15 @@ RUN_ID=$(echo "$RUN_JSON" | jq -r .runId)
299
319
  PROJECT_URL=$(echo "$RUN_JSON" | jq -r .projectUrl)
300
320
  send_message "Project created: $PROJECT_URL"
301
321
 
302
- if ! npx makaron-cli responses timeline "$RUN_ID" --jsonl --compact --checkpoint-mode service --fail-on-unapproved > /tmp/makaron-events.jsonl; then
303
- npx makaron-cli responses timeline "$RUN_ID" --jsonl --compact | while read -r event; do
304
- TYPE=$(echo "$event" | jq -r .type)
305
- REQUIRES=$(echo "$event" | jq -r ".requires_approval // false")
306
- TEXT=$(echo "$event" | jq -r ".text // empty")
307
- MSG_ID=$(echo "$event" | jq -r ".id // empty")
308
- if [ "$TYPE" = "message" ] && [ "$REQUIRES" = "true" ]; then
309
- send_message "$TEXT"
310
- npx makaron-cli responses ask-user "$MSG_ID" --run "$RUN_ID"
311
- exit 3
312
- fi
313
- done
322
+ if ! NEXT=$(npx makaron-cli responses next "$RUN_ID" --json); then
323
+ STATUS=$(echo "$NEXT" | jq -r .status)
324
+ if [ "$STATUS" = "needs_approval" ]; then
325
+ MSG_ID=$(echo "$NEXT" | jq -r .checkpoint.id)
326
+ TEXT=$(echo "$NEXT" | jq -r .checkpoint.text)
327
+ send_message "$TEXT"
328
+ npx makaron-cli responses handle "$MSG_ID" --run "$RUN_ID" --choice ask_user
329
+ exit 3
330
+ fi
314
331
  fi
315
332
 
316
333
  RESULT=$(npx makaron-cli responses get "$RUN_ID" --wait --json)