@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.
- package/LICENSE +21 -0
- package/dist/commands/agentFor.d.ts +8 -0
- package/dist/commands/agentFor.js +28 -0
- package/dist/commands/auditApiKeyEnv.d.ts +6 -0
- package/dist/commands/auditApiKeyEnv.js +27 -0
- package/dist/commands/budget.d.ts +5 -0
- package/dist/commands/budget.js +86 -0
- package/dist/commands/chat.d.ts +5 -0
- package/dist/commands/chat.js +218 -0
- package/dist/commands/checkpoint.d.ts +10 -0
- package/dist/commands/checkpoint.js +78 -0
- package/dist/commands/compact.d.ts +4 -0
- package/dist/commands/compact.js +22 -0
- package/dist/commands/compress.d.ts +4 -0
- package/dist/commands/compress.js +61 -0
- package/dist/commands/compressContext.d.ts +8 -0
- package/dist/commands/compressContext.js +51 -0
- package/dist/commands/conversation.d.ts +8 -0
- package/dist/commands/conversation.js +90 -0
- package/dist/commands/diagnostics.d.ts +23 -0
- package/dist/commands/diagnostics.js +254 -0
- package/dist/commands/doctor.d.ts +5 -0
- package/dist/commands/doctor.js +104 -0
- package/dist/commands/execute.d.ts +9 -0
- package/dist/commands/execute.js +183 -0
- package/dist/commands/git.d.ts +6 -0
- package/dist/commands/git.js +82 -0
- package/dist/commands/guard.d.ts +7 -0
- package/dist/commands/guard.js +30 -0
- package/dist/commands/handoff.d.ts +10 -0
- package/dist/commands/handoff.js +133 -0
- package/dist/commands/handoffBundle.d.ts +12 -0
- package/dist/commands/handoffBundle.js +64 -0
- package/dist/commands/handoffHistory.d.ts +23 -0
- package/dist/commands/handoffHistory.js +129 -0
- package/dist/commands/handoffShow.d.ts +12 -0
- package/dist/commands/handoffShow.js +73 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +19 -0
- package/dist/commands/inventory.d.ts +5 -0
- package/dist/commands/inventory.js +23 -0
- package/dist/commands/login.d.ts +3 -0
- package/dist/commands/login.js +80 -0
- package/dist/commands/migrate.d.ts +8 -0
- package/dist/commands/migrate.js +55 -0
- package/dist/commands/plan.d.ts +13 -0
- package/dist/commands/plan.js +159 -0
- package/dist/commands/profile.d.ts +5 -0
- package/dist/commands/profile.js +23 -0
- package/dist/commands/project.d.ts +18 -0
- package/dist/commands/project.js +173 -0
- package/dist/commands/projectOptions.d.ts +7 -0
- package/dist/commands/projectOptions.js +21 -0
- package/dist/commands/receipt.d.ts +8 -0
- package/dist/commands/receipt.js +48 -0
- package/dist/commands/replay.d.ts +8 -0
- package/dist/commands/replay.js +35 -0
- package/dist/commands/report.d.ts +6 -0
- package/dist/commands/report.js +54 -0
- package/dist/commands/review.d.ts +8 -0
- package/dist/commands/review.js +63 -0
- package/dist/commands/risk.d.ts +5 -0
- package/dist/commands/risk.js +25 -0
- package/dist/commands/run.d.ts +31 -0
- package/dist/commands/run.js +323 -0
- package/dist/commands/session.d.ts +40 -0
- package/dist/commands/session.js +158 -0
- package/dist/commands/sessionWorkspace.d.ts +25 -0
- package/dist/commands/sessionWorkspace.js +193 -0
- package/dist/commands/status.d.ts +5 -0
- package/dist/commands/status.js +116 -0
- package/dist/commands/tui.d.ts +4 -0
- package/dist/commands/tui.js +46 -0
- package/dist/commands/usage.d.ts +11 -0
- package/dist/commands/usage.js +40 -0
- package/dist/commands/verify.d.ts +15 -0
- package/dist/commands/verify.js +197 -0
- package/dist/commands/workspace.d.ts +5 -0
- package/dist/commands/workspace.js +27 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +394 -0
- 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
|
+
}
|