@relay-baton/cli 1.0.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.
Files changed (82) hide show
  1. package/LICENSE +21 -0
  2. package/dist/commands/agentFor.d.ts +8 -0
  3. package/dist/commands/agentFor.js +28 -0
  4. package/dist/commands/auditApiKeyEnv.d.ts +6 -0
  5. package/dist/commands/auditApiKeyEnv.js +27 -0
  6. package/dist/commands/budget.d.ts +5 -0
  7. package/dist/commands/budget.js +86 -0
  8. package/dist/commands/chat.d.ts +5 -0
  9. package/dist/commands/chat.js +218 -0
  10. package/dist/commands/checkpoint.d.ts +10 -0
  11. package/dist/commands/checkpoint.js +78 -0
  12. package/dist/commands/compact.d.ts +4 -0
  13. package/dist/commands/compact.js +22 -0
  14. package/dist/commands/compress.d.ts +4 -0
  15. package/dist/commands/compress.js +61 -0
  16. package/dist/commands/compressContext.d.ts +8 -0
  17. package/dist/commands/compressContext.js +51 -0
  18. package/dist/commands/conversation.d.ts +8 -0
  19. package/dist/commands/conversation.js +90 -0
  20. package/dist/commands/diagnostics.d.ts +23 -0
  21. package/dist/commands/diagnostics.js +254 -0
  22. package/dist/commands/doctor.d.ts +5 -0
  23. package/dist/commands/doctor.js +104 -0
  24. package/dist/commands/execute.d.ts +9 -0
  25. package/dist/commands/execute.js +183 -0
  26. package/dist/commands/git.d.ts +6 -0
  27. package/dist/commands/git.js +82 -0
  28. package/dist/commands/guard.d.ts +7 -0
  29. package/dist/commands/guard.js +30 -0
  30. package/dist/commands/handoff.d.ts +10 -0
  31. package/dist/commands/handoff.js +133 -0
  32. package/dist/commands/handoffBundle.d.ts +12 -0
  33. package/dist/commands/handoffBundle.js +64 -0
  34. package/dist/commands/handoffHistory.d.ts +23 -0
  35. package/dist/commands/handoffHistory.js +129 -0
  36. package/dist/commands/handoffShow.d.ts +12 -0
  37. package/dist/commands/handoffShow.js +73 -0
  38. package/dist/commands/init.d.ts +2 -0
  39. package/dist/commands/init.js +19 -0
  40. package/dist/commands/inventory.d.ts +5 -0
  41. package/dist/commands/inventory.js +23 -0
  42. package/dist/commands/login.d.ts +3 -0
  43. package/dist/commands/login.js +80 -0
  44. package/dist/commands/migrate.d.ts +8 -0
  45. package/dist/commands/migrate.js +55 -0
  46. package/dist/commands/plan.d.ts +13 -0
  47. package/dist/commands/plan.js +159 -0
  48. package/dist/commands/profile.d.ts +5 -0
  49. package/dist/commands/profile.js +23 -0
  50. package/dist/commands/project.d.ts +18 -0
  51. package/dist/commands/project.js +173 -0
  52. package/dist/commands/projectOptions.d.ts +7 -0
  53. package/dist/commands/projectOptions.js +21 -0
  54. package/dist/commands/receipt.d.ts +8 -0
  55. package/dist/commands/receipt.js +48 -0
  56. package/dist/commands/replay.d.ts +8 -0
  57. package/dist/commands/replay.js +35 -0
  58. package/dist/commands/report.d.ts +6 -0
  59. package/dist/commands/report.js +54 -0
  60. package/dist/commands/review.d.ts +8 -0
  61. package/dist/commands/review.js +63 -0
  62. package/dist/commands/risk.d.ts +5 -0
  63. package/dist/commands/risk.js +25 -0
  64. package/dist/commands/run.d.ts +31 -0
  65. package/dist/commands/run.js +323 -0
  66. package/dist/commands/session.d.ts +40 -0
  67. package/dist/commands/session.js +158 -0
  68. package/dist/commands/sessionWorkspace.d.ts +25 -0
  69. package/dist/commands/sessionWorkspace.js +193 -0
  70. package/dist/commands/status.d.ts +5 -0
  71. package/dist/commands/status.js +116 -0
  72. package/dist/commands/tui.d.ts +4 -0
  73. package/dist/commands/tui.js +46 -0
  74. package/dist/commands/usage.d.ts +11 -0
  75. package/dist/commands/usage.js +40 -0
  76. package/dist/commands/verify.d.ts +15 -0
  77. package/dist/commands/verify.js +197 -0
  78. package/dist/commands/workspace.d.ts +5 -0
  79. package/dist/commands/workspace.js +27 -0
  80. package/dist/index.d.ts +2 -0
  81. package/dist/index.js +394 -0
  82. package/package.json +57 -0
package/dist/index.js ADDED
@@ -0,0 +1,394 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const commander_1 = require("commander");
5
+ const init_1 = require("./commands/init");
6
+ const doctor_1 = require("./commands/doctor");
7
+ const verify_1 = require("./commands/verify");
8
+ const status_1 = require("./commands/status");
9
+ const review_1 = require("./commands/review");
10
+ const receipt_1 = require("./commands/receipt");
11
+ const checkpoint_1 = require("./commands/checkpoint");
12
+ const guard_1 = require("./commands/guard");
13
+ const risk_1 = require("./commands/risk");
14
+ const workspace_1 = require("./commands/workspace");
15
+ const profile_1 = require("./commands/profile");
16
+ const inventory_1 = require("./commands/inventory");
17
+ const run_1 = require("./commands/run");
18
+ const handoff_1 = require("./commands/handoff");
19
+ const handoffHistory_1 = require("./commands/handoffHistory");
20
+ const handoffShow_1 = require("./commands/handoffShow");
21
+ const handoffBundle_1 = require("./commands/handoffBundle");
22
+ const report_1 = require("./commands/report");
23
+ const migrate_1 = require("./commands/migrate");
24
+ const plan_1 = require("./commands/plan");
25
+ const execute_1 = require("./commands/execute");
26
+ const compressContext_1 = require("./commands/compressContext");
27
+ const compact_1 = require("./commands/compact");
28
+ const budget_1 = require("./commands/budget");
29
+ const usage_1 = require("./commands/usage");
30
+ const compress_1 = require("./commands/compress");
31
+ const tui_1 = require("./commands/tui");
32
+ const chat_1 = require("./commands/chat");
33
+ const replay_1 = require("./commands/replay");
34
+ const conversation_1 = require("./commands/conversation");
35
+ const git_1 = require("./commands/git");
36
+ const session_1 = require("./commands/session");
37
+ const sessionWorkspace_1 = require("./commands/sessionWorkspace");
38
+ const login_1 = require("./commands/login");
39
+ const project_1 = require("./commands/project");
40
+ const program = new commander_1.Command();
41
+ program
42
+ .name("relay-baton")
43
+ .description("Token-aware handoff harness for Codex CLI and Claude Code")
44
+ .version("1.0.0");
45
+ function addProjectOptions(cmd) {
46
+ return cmd
47
+ .option("--project <name-or-id>", "registered project name or id")
48
+ .option("--path <repoPath>", "repository path");
49
+ }
50
+ addProjectOptions(program.command("init").description("Initialize .ai-session in the current repository")).action(init_1.initCommand);
51
+ addProjectOptions(program.command("doctor").description("Check local environment").option("--deep", "run extended diagnostics")).action(doctor_1.doctorCommand);
52
+ addProjectOptions(program.command("status").description("Show current session status").option("--json", "print machine-readable JSON")).action(status_1.statusCommand);
53
+ addProjectOptions(program
54
+ .command("review")
55
+ .description("Deterministically review the working-tree diff against the current plan (no model call)")
56
+ .option("--json", "print machine-readable JSON")).action(review_1.reviewCommand);
57
+ addProjectOptions(program
58
+ .command("verify")
59
+ .description("Simulated end-to-end check of the relay-baton pipeline (no real model calls)")
60
+ .option("--diet <profile>", "diet profile: off|lite|balanced|caveman|ultra")
61
+ .option("--real-agents", "EXPERIMENTAL scaffold only; never executes real agents")
62
+ .option("--keep-temp", "keep the throwaway temp repo used for the handoff check")
63
+ .option("--verbose", "print per-step detail")).action(verify_1.verifyCommand);
64
+ program
65
+ .command("run")
66
+ .description("Run a relay chain: first agent runs the task; on fallback, hand off to the next agent")
67
+ .argument("<task>", "task description")
68
+ .option("--diet <profile>", "diet profile: off|lite|balanced|caveman|ultra")
69
+ .option("--force", "ignore quality gate failures")
70
+ .option("--allow-api-key-env", "allow passing API key env vars to child processes")
71
+ .option("--primary <agent>", "first agent in the relay chain (default: config primaryAgent)")
72
+ .option("--fallback <agent>", "second agent in the relay chain (default: config fallbackAgent)")
73
+ .option("--chain <a,b,c>", "explicit N-way relay chain (overrides --primary/--fallback)")
74
+ .option("--until <n>", "bounded auto-orchestration: up to N extra continue-steps (guardrail-gated, confirm each)")
75
+ .option("--yes", "pre-approve bounded --until steps (still capped + guardrail-gated)")
76
+ .option("--project <name-or-id>", "registered project name or id")
77
+ .option("--path <repoPath>", "repository path")
78
+ .action((task, opts) => (0, run_1.runCommand)(task, opts));
79
+ const handoff = program
80
+ .command("handoff")
81
+ .description("Generate a handoff and optionally launch the next agent")
82
+ .option("--to <agent>", "next agent (claude)")
83
+ .option("--diet <profile>", "diet profile: off|lite|balanced|caveman|ultra")
84
+ .option("--force", "ignore quality gate failures")
85
+ .option("--no-run", "do not launch the next agent")
86
+ .option("--allow-api-key-env", "allow passing API key env vars to child processes")
87
+ .option("--project <name-or-id>", "registered project name or id")
88
+ .option("--path <repoPath>", "repository path")
89
+ .action((opts) => {
90
+ if (!opts.to) {
91
+ console.error("[relay-baton] missing required option: --to <agent>");
92
+ process.exit(2);
93
+ }
94
+ return (0, handoff_1.handoffCommand)(opts);
95
+ });
96
+ handoff
97
+ .command("history")
98
+ .description("List past handoff documents (current + timestamped backups)")
99
+ .option("--project <name-or-id>", "registered project name or id")
100
+ .option("--path <repoPath>", "repository path")
101
+ .action(handoffHistory_1.handoffHistoryCommand);
102
+ handoff
103
+ .command("show")
104
+ .description("Print a handoff document read-only (current handoff.md by default)")
105
+ .option("--file <name>", "a history file name from `handoff history` instead of the current one")
106
+ .option("--json", "print machine-readable JSON")
107
+ .option("--project <name-or-id>", "registered project name or id")
108
+ .option("--path <repoPath>", "repository path")
109
+ .action(handoffShow_1.handoffShowCommand);
110
+ handoff
111
+ .command("bundle")
112
+ .description("Build a portable handoff bundle (curated artifacts + git summary + redaction pass). Read-only on the repo")
113
+ .option("--json", "print machine-readable JSON")
114
+ .option("--dry-run", "show what would be bundled without writing")
115
+ .option("--out <dir>", "bundle root directory (default: ~/.relay-baton/handoff-bundles)")
116
+ .option("--project <name-or-id>", "registered project name or id")
117
+ .option("--path <repoPath>", "repository path")
118
+ .action(handoffBundle_1.handoffBundleCommand);
119
+ handoff
120
+ .command("inspect")
121
+ .description("Validate a handoff bundle and print what it contains (read-only, applies nothing)")
122
+ .argument("<bundle>", "bundle id or path under the bundle root")
123
+ .option("--json", "print machine-readable JSON")
124
+ .option("--out <dir>", "bundle root directory (default: ~/.relay-baton/handoff-bundles)")
125
+ .action(handoffBundle_1.handoffInspectCommand);
126
+ addProjectOptions(program
127
+ .command("report")
128
+ .description("Generate a human-readable markdown status report from existing artifacts (read-only, no model call)")
129
+ .option("--out <file>", "write the report to a file instead of stdout")
130
+ .option("--json", "wrap the markdown in JSON")).action(report_1.reportCommand);
131
+ addProjectOptions(program
132
+ .command("migrate")
133
+ .description("Check .ai-session artifact schema versions; with --apply, normalize legacy artifacts (backs up first)")
134
+ .option("--check", "report only (default behavior, read-only)")
135
+ .option("--apply", "apply safe migrations (writes a .bak backup before each change)")
136
+ .option("--dry-run", "with --apply, show the plan without writing")
137
+ .option("--json", "print machine-readable JSON")).action(migrate_1.migrateCommand);
138
+ program
139
+ .command("plan")
140
+ .description("Plan-execute mode: a planner agent writes .ai-session/plan.md")
141
+ .argument("<task>", "task description")
142
+ .option("--diet <profile>", "diet profile: off|lite|balanced|caveman|ultra")
143
+ .option("--with <agent>", "planner agent (default: config planExecute.defaultPlanner)")
144
+ .option("--planner <agent>", "planner agent (alias of --with)")
145
+ .option("--executor <agent>", "executor agent for --then-execute")
146
+ .option("--no-run", "scaffold an empty plan template instead of launching the planner")
147
+ .option("--then-execute", "run the execute phase immediately after a passing plan")
148
+ .option("--force", "ignore plan quality gate failures")
149
+ .option("--allow-api-key-env", "allow passing API key env vars to child processes")
150
+ .option("--project <name-or-id>", "registered project name or id")
151
+ .option("--path <repoPath>", "repository path")
152
+ .action((task, opts) => (0, plan_1.planCommand)(task, opts));
153
+ program
154
+ .command("execute")
155
+ .description("Plan-execute mode: an executor agent implements .ai-session/plan.md")
156
+ .option("--diet <profile>", "diet profile: off|lite|balanced|caveman|ultra")
157
+ .option("--with <agent>", "executor agent (default: config planExecute.defaultExecutor)")
158
+ .option("--from <path>", "read the plan from a custom path")
159
+ .option("--force", "ignore quality gate failures")
160
+ .option("--allow-api-key-env", "allow passing API key env vars to child processes")
161
+ .option("--project <name-or-id>", "registered project name or id")
162
+ .option("--path <repoPath>", "repository path")
163
+ .action(execute_1.executeCommand);
164
+ program
165
+ .command("compact")
166
+ .description("Recompute compact-state, repo-map, diff snapshot")
167
+ .option("--diet <profile>", "diet profile: off|lite|balanced|caveman|ultra")
168
+ .option("--project <name-or-id>", "registered project name or id")
169
+ .option("--path <repoPath>", "repository path")
170
+ .action(compact_1.compactCommand);
171
+ program
172
+ .command("squeeze")
173
+ .description("Alias of compact")
174
+ .option("--diet <profile>", "diet profile: off|lite|balanced|caveman|ultra")
175
+ .option("--project <name-or-id>", "registered project name or id")
176
+ .option("--path <repoPath>", "repository path")
177
+ .action(compact_1.compactCommand);
178
+ addProjectOptions(program.command("budget").description("Show context budget usage").option("--json", "print machine-readable JSON")).action(budget_1.budgetCommand);
179
+ addProjectOptions(program.command("usage").description("Show local per-session usage (token proxy; never transmitted)").option("--json", "print machine-readable JSON")).action(usage_1.usageCommand);
180
+ const receipt = program.command("receipt").description("Append-only execution receipts for plan steps");
181
+ addProjectOptions(receipt.command("done").description("Mark a plan step done").argument("<step>", "1-based step index").option("--note <text>", "short note")).action((step, opts) => (0, receipt_1.receiptDoneCommand)(step, opts));
182
+ addProjectOptions(receipt.command("skip").description("Mark a plan step skipped").argument("<step>", "1-based step index").option("--note <text>", "short note")).action((step, opts) => (0, receipt_1.receiptSkipCommand)(step, opts));
183
+ addProjectOptions(receipt.command("list").description("List recorded receipts").option("--json", "print machine-readable JSON")).action(receipt_1.receiptListCommand);
184
+ const checkpoint = program
185
+ .command("checkpoint")
186
+ .description("Append-only execution checkpoints (command, changed files, git, budget, result) per step");
187
+ addProjectOptions(checkpoint
188
+ .command("add")
189
+ .description("Record an execution checkpoint for a step")
190
+ .argument("<step>", "1-based step index")
191
+ .option("--command <text>", "command preview this step ran")
192
+ .option("--result <result>", "step result: ok|fail|pending (default: pending)")
193
+ .option("--note <text>", "short note")
194
+ .option("--json", "print machine-readable JSON")).action((step, opts) => (0, checkpoint_1.checkpointCommand)(step, opts));
195
+ addProjectOptions(checkpoint.command("list").description("List recorded execution checkpoints").option("--json", "print machine-readable JSON")).action(checkpoint_1.checkpointListCommand);
196
+ addProjectOptions(checkpoint.command("summary").description("Compact execution receipt derived from checkpoints").option("--json", "print machine-readable JSON")).action(checkpoint_1.checkpointSummaryCommand);
197
+ addProjectOptions(program
198
+ .command("guard")
199
+ .description("Evaluate stop-condition guardrails against checkpoints + live git/budget (advisory, read-only)")
200
+ .option("--json", "print machine-readable JSON")
201
+ .option("--exit-code", "exit non-zero (10) when a stop condition is triggered")).action(guard_1.guardCommand);
202
+ addProjectOptions(program
203
+ .command("risk")
204
+ .description("Flag risky surfaces in the working tree (deps, deletions, release/CI, env/config, binaries). Read-only")
205
+ .option("--json", "print machine-readable JSON")).action(risk_1.riskCommand);
206
+ addProjectOptions(program
207
+ .command("workspace")
208
+ .description("Deterministic workspace map: package managers, languages, monorepo packages, scripts, entry points, docs. Read-only")
209
+ .option("--json", "print machine-readable JSON")).action(workspace_1.workspaceCommand);
210
+ addProjectOptions(program
211
+ .command("profile")
212
+ .description("Deterministic project profile hints: framework tags, recommended build/test, diet/agents, entry points. Read-only")
213
+ .option("--json", "print machine-readable JSON")).action(profile_1.profileCommand);
214
+ addProjectOptions(program
215
+ .command("inventory")
216
+ .description("Bounded inventory: package scripts, workspace packages, CI workflows, release files. Read-only")
217
+ .option("--json", "print machine-readable JSON")).action(inventory_1.inventoryCommand);
218
+ program
219
+ .command("compress-context")
220
+ .description("Compress running session context (state.md / commands.log) when over budget")
221
+ .option("--diet <profile>", "diet profile: off|lite|balanced|caveman|ultra")
222
+ .option("--threshold <ratio>", "compress when weight/budget exceeds this ratio (0..1)")
223
+ .option("--dry-run", "report what would change without writing")
224
+ .option("--force", "compress regardless of threshold")
225
+ .option("--project <name-or-id>", "registered project name or id")
226
+ .option("--path <repoPath>", "repository path")
227
+ .action(compressContext_1.compressContextCommand);
228
+ program
229
+ .command("compress")
230
+ .description("Deterministically compress a markdown/instruction file")
231
+ .argument("<file>")
232
+ .option("--write", "rewrite file in place")
233
+ .option("--out <path>", "write to a different path")
234
+ .action(compress_1.compressCommand);
235
+ program
236
+ .command("login")
237
+ .description("Run an agent CLI login flow interactively (codex/claude/opencode/gemini/aider/cursor)")
238
+ .argument("[agent]", "codex | claude | opencode | gemini | aider | cursor | all (default: all = first-class pair)")
239
+ .option("--allow-api-key-env", "allow passing API key env vars to login process")
240
+ .action((agent, opts) => (0, login_1.loginCommand)(agent, opts));
241
+ const project = program.command("project").description("Manage registered projects");
242
+ project.command("add").argument("<path>", "repository path").option("--name <name>").option("--diet <profile>").option("--primary <agent>").option("--fallback <agent>").option("--json", "print machine-readable JSON").action(project_1.projectAddCommand);
243
+ project.command("list").description("List registered projects").option("--json", "print machine-readable JSON").action(project_1.projectListCommand);
244
+ project.command("switch").argument("<name-or-id>").description("Switch active project").action(project_1.projectSwitchCommand);
245
+ project.command("current").description("Show active project").option("--json", "print machine-readable JSON").action(project_1.projectCurrentCommand);
246
+ project.command("remove").argument("<name-or-id>").description("Remove a project").option("--json", "print machine-readable JSON").action(project_1.projectRemoveCommand);
247
+ project.command("doctor").description("Check registered projects").action(project_1.projectDoctorCommand);
248
+ const git = program.command("git").description("Read-only git tracking helpers");
249
+ git
250
+ .command("status")
251
+ .description("Show branch, ahead/behind, and working-tree change counts")
252
+ .option("--json", "print machine-readable JSON")
253
+ .option("--limit <n>", "max changed files to include")
254
+ .option("--project <name-or-id>", "registered project name or id")
255
+ .option("--path <repoPath>", "repository path")
256
+ .action(git_1.gitStatusCommand);
257
+ const session = program.command("session").description("Manage work items (named sessions) + archives/recovery");
258
+ // v2.6 multi-session workspace — named work items within one repo.
259
+ session
260
+ .command("new")
261
+ .description("Create a named work item (session); the legacy flat session is `default`")
262
+ .argument("<name>", "work-item name (letters/digits/._-)")
263
+ .option("--switch", "switch the active session to the new one")
264
+ .option("--agent <id>", "pin this work item to an agent (codex|claude|opencode|gemini|aider|cursor)")
265
+ .option("--no-init", "do not initialize .ai-session artifacts for the new item")
266
+ .option("--json", "print machine-readable JSON")
267
+ .option("--project <name-or-id>", "registered project name or id")
268
+ .option("--path <repoPath>", "repository path")
269
+ .action(sessionWorkspace_1.sessionNewCommand);
270
+ session
271
+ .command("switch")
272
+ .aliases(["use"])
273
+ .description("Switch the active work item (use `default` for the legacy flat session)")
274
+ .argument("<name>", "work-item name")
275
+ .option("--json", "print machine-readable JSON")
276
+ .option("--project <name-or-id>", "registered project name or id")
277
+ .option("--path <repoPath>", "repository path")
278
+ .action(sessionWorkspace_1.sessionSwitchCommand);
279
+ session
280
+ .command("items")
281
+ .description("List work items in this repo and which one is active (read-only)")
282
+ .option("--json", "print machine-readable JSON")
283
+ .option("--project <name-or-id>", "registered project name or id")
284
+ .option("--path <repoPath>", "repository path")
285
+ .action(sessionWorkspace_1.sessionItemsCommand);
286
+ session
287
+ .command("assign")
288
+ .description("Pin a work item to an agent (or `none` to clear)")
289
+ .argument("<name>", "work-item name")
290
+ .argument("<agent>", "agent id or `none`")
291
+ .option("--project <name-or-id>", "registered project name or id")
292
+ .option("--path <repoPath>", "repository path")
293
+ .action(sessionWorkspace_1.sessionAssignCommand);
294
+ session
295
+ .command("remove")
296
+ .description("Remove a named work item (never `default`)")
297
+ .argument("<name>", "work-item name")
298
+ .option("--delete-files", "also delete the work item's .ai-session/sessions/<name> dir")
299
+ .option("--project <name-or-id>", "registered project name or id")
300
+ .option("--path <repoPath>", "repository path")
301
+ .action(sessionWorkspace_1.sessionRemoveCommand);
302
+ const sessionWorktree = session
303
+ .command("worktree")
304
+ .description("Back a work item with an isolated git worktree for safe parallel execution");
305
+ sessionWorktree
306
+ .command("add")
307
+ .description("Create a git worktree for a work item; run/handoff then execute there")
308
+ .argument("<name>", "work-item name")
309
+ .option("--branch <b>", "branch to create (default: relay/<name>)")
310
+ .option("--worktree-path <dir>", "worktree location (default: <parent>/<repo>.worktrees/<name>)")
311
+ .option("--project <name-or-id>", "registered project name or id")
312
+ .option("--path <repoPath>", "repository path")
313
+ .action(sessionWorkspace_1.sessionWorktreeAddCommand);
314
+ sessionWorktree
315
+ .command("remove")
316
+ .description("Remove a work item's git worktree (commit/stash first, or --force)")
317
+ .argument("<name>", "work-item name")
318
+ .option("--force", "remove even if the worktree has changes")
319
+ .option("--project <name-or-id>", "registered project name or id")
320
+ .option("--path <repoPath>", "repository path")
321
+ .action(sessionWorkspace_1.sessionWorktreeRemoveCommand);
322
+ session
323
+ .command("archive")
324
+ .description("Archive the current .ai-session artifacts without modifying the source repo")
325
+ .option("--json", "print machine-readable JSON")
326
+ .option("--dry-run", "show what would be archived without writing")
327
+ .option("--out <dir>", "archive root directory (default: ~/.relay-baton/session-archives)")
328
+ .option("--project <name-or-id>", "registered project name or id")
329
+ .option("--path <repoPath>", "repository path")
330
+ .action(session_1.sessionArchiveCommand);
331
+ session
332
+ .command("list")
333
+ .description("List archived sessions (read-only)")
334
+ .option("--json", "print machine-readable JSON")
335
+ .option("--out <dir>", "archive root directory (default: ~/.relay-baton/session-archives)")
336
+ .action(session_1.sessionListCommand);
337
+ session
338
+ .command("inspect")
339
+ .description("Validate an archived session's manifest and file integrity (read-only)")
340
+ .argument("<archive>", "archive id or path under the archive root")
341
+ .option("--json", "print machine-readable JSON")
342
+ .option("--out <dir>", "archive root directory (default: ~/.relay-baton/session-archives)")
343
+ .action(session_1.sessionInspectCommand);
344
+ session
345
+ .command("resume")
346
+ .description("Diagnose the current .ai-session and suggest the safest next command (read-only)")
347
+ .option("--json", "print machine-readable JSON")
348
+ .option("--stale-hours <n>", "treat the session as stale when older than N hours (default: 24)")
349
+ .option("--project <name-or-id>", "registered project name or id")
350
+ .option("--path <repoPath>", "repository path")
351
+ .action(session_1.sessionResumeCommand);
352
+ session
353
+ .command("export")
354
+ .description("Copy an archived session out to a destination directory for sharing/backup (read-only on the archive)")
355
+ .argument("<archive>", "archive id or path under the archive root")
356
+ .requiredOption("--to <dir>", "destination directory")
357
+ .option("--overwrite", "overwrite an existing destination")
358
+ .option("--json", "print machine-readable JSON")
359
+ .option("--out <dir>", "archive root directory (default: ~/.relay-baton/session-archives)")
360
+ .action(session_1.sessionExportCommand);
361
+ session
362
+ .command("prune")
363
+ .description("Apply an archive retention policy (disabled by default; dry-run unless --apply)")
364
+ .option("--max-age-days <n>", "prune archives older than N days")
365
+ .option("--max-count <n>", "keep only the newest N archives")
366
+ .option("--apply", "actually delete (default is a dry-run preview)")
367
+ .option("--json", "print machine-readable JSON")
368
+ .option("--out <dir>", "archive root directory (default: ~/.relay-baton/session-archives)")
369
+ .action(session_1.sessionPruneCommand);
370
+ addProjectOptions(program.command("tui").description("Start the relay-baton TUI")).action(tui_1.tuiCommand);
371
+ addProjectOptions(program
372
+ .command("chat")
373
+ .aliases(["room"])
374
+ .description("Agent Room (v0.8 first cut): turn-based, confirmation-first multi-agent REPL")
375
+ .option("--allow-api-key-env", "allow passing API key env vars to confirmed agent runs")).action(chat_1.chatCommand);
376
+ addProjectOptions(program
377
+ .command("replay")
378
+ .description("Replay the recorded conversation timeline (read-only, no model call)")
379
+ .option("--json", "print machine-readable JSON")
380
+ .option("--session <id>", "filter to a single session id")
381
+ .option("--kind <kinds>", "comma-separated event kinds to include")
382
+ .option("--limit <n>", "keep only the most recent N events")).action(replay_1.replayCommand);
383
+ const conversation = program.command("conversation").description("Append/read Agent Room conversation events");
384
+ addProjectOptions(conversation
385
+ .command("append")
386
+ .description("Append a single conversation event to the current session")
387
+ .argument("<text>", "event text")
388
+ .option("--json", "print machine-readable JSON")
389
+ .option("--role <role>", "event role: user|relay-baton|codex|claude")
390
+ .option("--kind <kind>", "event kind, e.g. message|command|status|budget|prompt_preview")).action((text, opts) => (0, conversation_1.conversationAppendCommand)(text, opts));
391
+ program.parseAsync(process.argv).catch(err => {
392
+ console.error(err?.stack ?? err);
393
+ process.exit(1);
394
+ });
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@relay-baton/cli",
3
+ "version": "1.0.0",
4
+ "description": "Token-aware handoff harness that lets Codex CLI and Claude Code take turns on the same repo",
5
+ "license": "MIT",
6
+ "author": "DongGeon Lee",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/dgl1231/relay-baton.git",
10
+ "directory": "packages/cli"
11
+ },
12
+ "homepage": "https://github.com/dgl1231/relay-baton#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/dgl1231/relay-baton/issues"
15
+ },
16
+ "keywords": [
17
+ "codex",
18
+ "claude",
19
+ "handoff",
20
+ "cli",
21
+ "token-diet",
22
+ "ai-agents"
23
+ ],
24
+ "main": "dist/index.js",
25
+ "bin": {
26
+ "relay-baton": "dist/index.js"
27
+ },
28
+ "files": [
29
+ "dist",
30
+ "README.md",
31
+ "LICENSE"
32
+ ],
33
+ "publishConfig": {
34
+ "access": "public"
35
+ },
36
+ "engines": {
37
+ "node": ">=20"
38
+ },
39
+ "dependencies": {
40
+ "commander": "^12.1.0",
41
+ "@relay-baton/tui": "1.0.0",
42
+ "@relay-baton/core": "1.0.0",
43
+ "@relay-baton/shared": "1.0.0"
44
+ },
45
+ "devDependencies": {
46
+ "typescript": "^5.5.4",
47
+ "vitest": "^2.0.5",
48
+ "@types/node": "^20.14.10"
49
+ },
50
+ "scripts": {
51
+ "build": "tsc -p tsconfig.json",
52
+ "typecheck": "tsc -p tsconfig.json --noEmit",
53
+ "test": "vitest run",
54
+ "start": "node dist/index.js",
55
+ "dev": "tsc -p tsconfig.json --watch"
56
+ }
57
+ }