@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
@@ -0,0 +1,8 @@
1
+ import type { ConversationEventKind, ConversationRole } from "@relay-baton/shared";
2
+ import { ProjectOpts } from "./projectOptions";
3
+ export interface ConversationAppendOpts extends ProjectOpts {
4
+ json?: boolean;
5
+ role?: ConversationRole;
6
+ kind?: ConversationEventKind;
7
+ }
8
+ export declare function conversationAppendCommand(text: string, opts?: ConversationAppendOpts): Promise<void>;
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.conversationAppendCommand = conversationAppendCommand;
37
+ const fs = __importStar(require("fs"));
38
+ const core_1 = require("@relay-baton/core");
39
+ const projectOptions_1 = require("./projectOptions");
40
+ const ROLES = ["user", "relay-baton", "codex", "claude"];
41
+ const KINDS = [
42
+ "message",
43
+ "command",
44
+ "prompt_preview",
45
+ "agent_run",
46
+ "plan",
47
+ "execute",
48
+ "review",
49
+ "diagnose",
50
+ "handoff",
51
+ "status",
52
+ "budget",
53
+ ];
54
+ function parseRole(value) {
55
+ const role = (value ?? "user");
56
+ if (!ROLES.includes(role)) {
57
+ console.error(`[relay-baton] invalid conversation role: ${value}`);
58
+ process.exit(2);
59
+ }
60
+ return role;
61
+ }
62
+ function parseKind(value) {
63
+ const kind = (value ?? "message");
64
+ if (!KINDS.includes(kind)) {
65
+ console.error(`[relay-baton] invalid conversation kind: ${value}`);
66
+ process.exit(2);
67
+ }
68
+ return kind;
69
+ }
70
+ async function conversationAppendCommand(text, opts = {}) {
71
+ const repoRoot = (0, projectOptions_1.resolveRepoRoot)(opts);
72
+ const { config } = core_1.ConfigLoader.load(repoRoot);
73
+ const sm = new core_1.SessionManager(repoRoot, config);
74
+ const meta = sm.getMeta();
75
+ if (!meta || !fs.existsSync(sm.files.dir)) {
76
+ console.error("[relay-baton] no session. Run `relay-baton init`.");
77
+ process.exit(2);
78
+ }
79
+ const event = new core_1.ConversationLog(repoRoot).append({
80
+ role: parseRole(opts.role),
81
+ kind: parseKind(opts.kind),
82
+ text,
83
+ sessionId: meta.id,
84
+ });
85
+ if (opts.json) {
86
+ console.log(JSON.stringify(event, null, 2));
87
+ return;
88
+ }
89
+ console.log(`[relay-baton] appended ${event.kind} event ${event.id}`);
90
+ }
@@ -0,0 +1,23 @@
1
+ import type { RelayBatonConfig } from "@relay-baton/shared";
2
+ export type CheckStatus = "ok" | "warn" | "fail" | "info";
3
+ export interface Check {
4
+ status: CheckStatus;
5
+ label: string;
6
+ value: string;
7
+ }
8
+ /** Arguments that relay-baton must never pass to an agent (security / policy). */
9
+ export declare const DEPRECATED_AGENT_ARGS: string[];
10
+ /** Expected default adapter args (sanity baseline), derived from the registry. */
11
+ export declare const EXPECTED_AGENT_ARGS: Record<string, string[]>;
12
+ /**
13
+ * Core checks shared by `doctor` and `verify`. Environment + agents + auth
14
+ * presence, never printing secret values.
15
+ */
16
+ export declare function coreChecks(repoRoot: string, cfg: RelayBatonConfig): Check[];
17
+ /** Extended diagnostics for `doctor --deep`. */
18
+ export declare function deepChecks(repoRoot: string, cfg: RelayBatonConfig): Check[];
19
+ export declare function loadConfig(repoRoot: string): {
20
+ config: RelayBatonConfig;
21
+ source: "default" | "file";
22
+ error?: string;
23
+ };
@@ -0,0 +1,254 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.EXPECTED_AGENT_ARGS = exports.DEPRECATED_AGENT_ARGS = void 0;
37
+ exports.coreChecks = coreChecks;
38
+ exports.deepChecks = deepChecks;
39
+ exports.loadConfig = loadConfig;
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const os = __importStar(require("os"));
43
+ const core_1 = require("@relay-baton/core");
44
+ const core_2 = require("@relay-baton/core");
45
+ const core_3 = require("@relay-baton/core");
46
+ const core_4 = require("@relay-baton/core");
47
+ const core_5 = require("@relay-baton/core");
48
+ const handoffHistory_1 = require("./handoffHistory");
49
+ /** Arguments that relay-baton must never pass to an agent (security / policy). */
50
+ exports.DEPRECATED_AGENT_ARGS = [
51
+ "--full-auto",
52
+ "--ask-for-approval",
53
+ "--dangerously-bypass-approvals-and-sandbox",
54
+ "bypassPermissions",
55
+ ];
56
+ /** Expected default adapter args (sanity baseline), derived from the registry. */
57
+ exports.EXPECTED_AGENT_ARGS = Object.fromEntries(core_5.ALL_AGENT_IDS.map((id) => [id, core_5.AGENT_REGISTRY[id].defaultArgs]));
58
+ function toolVersion(cmd) {
59
+ const r = (0, core_1.safeSpawnSync)(cmd, ["--version"], { encoding: "utf8" });
60
+ if (r.error != null)
61
+ return null;
62
+ const out = `${r.stdout ?? ""}${r.stderr ?? ""}`.trim();
63
+ return out.split(/\r?\n/)[0] || "available";
64
+ }
65
+ function readSafe(p) {
66
+ try {
67
+ return fs.readFileSync(p, "utf8");
68
+ }
69
+ catch {
70
+ return "";
71
+ }
72
+ }
73
+ /**
74
+ * Core checks shared by `doctor` and `verify`. Environment + agents + auth
75
+ * presence, never printing secret values.
76
+ */
77
+ function coreChecks(repoRoot, cfg) {
78
+ const checks = [];
79
+ const gitOk = fs.existsSync(path.join(repoRoot, ".git"));
80
+ checks.push({ status: gitOk ? "ok" : "fail", label: "git repository", value: gitOk ? "yes" : "no (run inside a git repo)" });
81
+ const gitV = toolVersion("git");
82
+ checks.push({ status: gitV ? "ok" : "fail", label: "git command", value: gitV ?? "MISSING" });
83
+ // Agent availability (v2.3): first-class agents warn when missing (they are the
84
+ // default relay); supported agents are info-only (optional, opt-in).
85
+ for (const id of core_5.ALL_AGENT_IDS) {
86
+ const desc = core_5.AGENT_REGISTRY[id];
87
+ const cmd = cfg.agents[id]?.command ?? desc.command;
88
+ const v = toolVersion(cmd);
89
+ const missingStatus = desc.tier === "first-class" ? "warn" : "info";
90
+ checks.push({
91
+ status: v ? "ok" : missingStatus,
92
+ label: `${id} command`,
93
+ value: v ?? `missing — run \`relay-baton login ${id}\` (${desc.tier})`,
94
+ });
95
+ }
96
+ // Auth: presence only, never values.
97
+ for (const ev of cfg.authPolicy.blockedEnvVars) {
98
+ const set = !!process.env[ev];
99
+ if (set && !cfg.authPolicy.allowApiKeyEnv) {
100
+ checks.push({ status: "warn", label: ev, value: "set — blocked by default (use --allow-api-key-env to pass through)" });
101
+ }
102
+ else {
103
+ checks.push({ status: "info", label: ev, value: set ? "set (passed through)" : "not set" });
104
+ }
105
+ }
106
+ const sm = new core_2.SessionManager(repoRoot, cfg);
107
+ const hasSession = fs.existsSync(sm.files.dir);
108
+ checks.push({ status: hasSession ? "ok" : "warn", label: ".ai-session", value: hasSession ? sm.files.dir : "missing — run `relay-baton init`" });
109
+ return checks;
110
+ }
111
+ /** Extended diagnostics for `doctor --deep`. */
112
+ function deepChecks(repoRoot, cfg) {
113
+ const checks = [];
114
+ // Tooling versions.
115
+ const node = process.version;
116
+ const major = Number(node.replace(/^v/, "").split(".")[0]);
117
+ checks.push({ status: major >= 20 ? "ok" : "warn", label: "node version", value: `${node}${major >= 20 ? "" : " (>=20 recommended)"}` });
118
+ const pnpmV = toolVersion("pnpm");
119
+ checks.push({ status: pnpmV ? "ok" : "info", label: "pnpm version", value: pnpmV ?? "not found (only needed for development)" });
120
+ // Adapter args sanity.
121
+ for (const [id, expected] of Object.entries(exports.EXPECTED_AGENT_ARGS)) {
122
+ const args = cfg.agents[id]?.args ?? [];
123
+ const deprecated = args.filter(a => exports.DEPRECATED_AGENT_ARGS.includes(a));
124
+ if (deprecated.length > 0) {
125
+ checks.push({ status: "fail", label: `${id} args`, value: `uses forbidden arg(s): ${deprecated.join(", ")}` });
126
+ }
127
+ else if (JSON.stringify(args) === JSON.stringify(expected)) {
128
+ checks.push({ status: "ok", label: `${id} args`, value: args.join(" ") });
129
+ }
130
+ else {
131
+ checks.push({ status: "warn", label: `${id} args`, value: `custom: ${args.join(" ") || "(empty)"} (default: ${expected.join(" ")})` });
132
+ }
133
+ }
134
+ // .gitattributes / CRLF hints (Windows-relevant).
135
+ const gaPath = path.join(repoRoot, ".gitattributes");
136
+ const hasGa = fs.existsSync(gaPath);
137
+ if (os.platform() === "win32") {
138
+ checks.push({
139
+ status: hasGa ? "ok" : "warn",
140
+ label: ".gitattributes",
141
+ value: hasGa ? "present (EOL normalization configured)" : "missing — add `* text=auto eol=lf` to avoid CRLF churn on Windows",
142
+ });
143
+ }
144
+ else {
145
+ checks.push({ status: "info", label: ".gitattributes", value: hasGa ? "present" : "absent (ok on this platform)" });
146
+ }
147
+ // Registry health.
148
+ const registryPath = process.env.RELAY_BATON_PROJECTS_FILE
149
+ ?? path.join(os.homedir(), ".relay-baton", "projects.json");
150
+ if (fs.existsSync(registryPath)) {
151
+ try {
152
+ const data = JSON.parse(readSafe(registryPath));
153
+ const count = Array.isArray(data?.projects) ? data.projects.length : 0;
154
+ checks.push({ status: "ok", label: "project registry", value: `${count} project(s) — ${registryPath}` });
155
+ }
156
+ catch {
157
+ checks.push({ status: "fail", label: "project registry", value: `unparseable JSON — ${registryPath}` });
158
+ }
159
+ }
160
+ else {
161
+ checks.push({ status: "info", label: "project registry", value: "none (cwd-based mode)" });
162
+ }
163
+ // Config contract validation (v1.0 frozen schema).
164
+ {
165
+ const r = (0, core_4.validateConfig)(cfg);
166
+ checks.push({
167
+ status: r.ok ? "ok" : "fail",
168
+ label: "config contract",
169
+ value: r.ok ? `valid (v${cfg.configVersion ?? "?"})` : r.errors.join("; "),
170
+ });
171
+ for (const w of r.warnings) {
172
+ checks.push({ status: "warn", label: "config contract", value: w });
173
+ }
174
+ }
175
+ // .ai-session artifact shape validation (v1.0 frozen artifacts).
176
+ {
177
+ const report = (0, core_4.validateArtifacts)(repoRoot);
178
+ if (!report.exists) {
179
+ checks.push({ status: "info", label: "artifact shapes", value: "no .ai-session yet" });
180
+ }
181
+ else {
182
+ for (const c of report.checks) {
183
+ const status = c.status === "absent" ? "info" : c.status === "warn" ? "warn" : c.status === "fail" ? "fail" : "ok";
184
+ checks.push({ status, label: `artifact: ${c.file}`, value: c.detail });
185
+ }
186
+ }
187
+ }
188
+ // .ai-session artifact schema versions (v2.0 migration checks).
189
+ {
190
+ const schema = new core_4.SchemaInspector(repoRoot).inspect();
191
+ if (!schema.exists) {
192
+ checks.push({ status: "info", label: "artifact schemas", value: "no .ai-session yet" });
193
+ }
194
+ else {
195
+ for (const c of schema.checks) {
196
+ if (c.status === "absent")
197
+ continue;
198
+ const status = c.status === "ok" ? "ok" : c.status === "ahead" || c.status === "unreadable" ? "fail" : "warn";
199
+ const found = c.foundVersion == null ? "-" : `v${c.foundVersion}`;
200
+ checks.push({ status, label: `schema: ${c.file}`, value: `${c.status} (${found}/v${c.currentVersion})` });
201
+ }
202
+ if (schema.migratable) {
203
+ checks.push({ status: "info", label: "migration", value: "run `relay-baton migrate --check` for guidance" });
204
+ }
205
+ }
206
+ }
207
+ // .ai-session health.
208
+ const sm = new core_2.SessionManager(repoRoot, cfg);
209
+ if (fs.existsSync(sm.files.dir)) {
210
+ const meta = sm.getMeta();
211
+ checks.push({ status: meta ? "ok" : "warn", label: "session.json", value: meta ? `status=${meta.status} agent=${meta.activeAgent}` : "missing or unreadable" });
212
+ // Latest handoff + budget.
213
+ const history = (0, handoffHistory_1.collectHandoffHistory)(repoRoot);
214
+ const current = history.find(h => h.current);
215
+ if (current) {
216
+ const activeProfile = meta?.tokenDietProfile ?? cfg.tokenDiet.profile;
217
+ const max = cfg.tokenDiet.profiles[activeProfile]?.maxHandoffChars ?? 0;
218
+ const over = max > 0 && current.size > max;
219
+ checks.push({ status: over ? "warn" : "ok", label: "latest handoff", value: `${current.size}B / ${max} budget (${activeProfile})${over ? " — over budget" : ""}` });
220
+ }
221
+ else {
222
+ checks.push({ status: "info", label: "latest handoff", value: "none yet" });
223
+ }
224
+ // plan.md status.
225
+ const planMd = readSafe(sm.files.p("plan"));
226
+ if (planMd.trim().length > 0) {
227
+ const missing = core_3.PLAN_SECTIONS.filter(s => (0, core_3.planSectionBody)(planMd, s).length === 0);
228
+ checks.push({
229
+ status: missing.length === 0 ? "ok" : "warn",
230
+ label: "plan.md",
231
+ value: missing.length === 0 ? `present (${core_3.PLAN_SECTIONS.length} sections)` : `present, empty sections: ${missing.join(", ")}`,
232
+ });
233
+ }
234
+ else {
235
+ checks.push({ status: "info", label: "plan.md", value: "none" });
236
+ }
237
+ // compress-context status (rotated raw artifacts).
238
+ const rotated = fs.existsSync(sm.files.dir)
239
+ ? fs.readdirSync(sm.files.dir).filter(n => n.startsWith("commands.log.full."))
240
+ : [];
241
+ checks.push({
242
+ status: "info",
243
+ label: "compress-context",
244
+ value: rotated.length > 0 ? `${rotated.length} rotated log(s) — last compression occurred` : "no rotations yet",
245
+ });
246
+ }
247
+ else {
248
+ checks.push({ status: "info", label: ".ai-session contents", value: "not initialized" });
249
+ }
250
+ return checks;
251
+ }
252
+ function loadConfig(repoRoot) {
253
+ return core_2.ConfigLoader.load(repoRoot);
254
+ }
@@ -0,0 +1,5 @@
1
+ import { ProjectOpts } from "./projectOptions";
2
+ export interface DoctorOpts extends ProjectOpts {
3
+ deep?: boolean;
4
+ }
5
+ export declare function doctorCommand(opts?: DoctorOpts): Promise<void>;
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.doctorCommand = doctorCommand;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const core_1 = require("@relay-baton/core");
40
+ const projectOptions_1 = require("./projectOptions");
41
+ const diagnostics_1 = require("./diagnostics");
42
+ const GREEN = "\x1b[32m";
43
+ const RED = "\x1b[31m";
44
+ const YELLOW = "\x1b[33m";
45
+ const CYAN = "\x1b[36m";
46
+ const DIM = "\x1b[2m";
47
+ const BOLD = "\x1b[1m";
48
+ const RESET = "\x1b[0m";
49
+ function icon(status) {
50
+ return status === "ok" ? `${GREEN}✓${RESET}`
51
+ : status === "warn" ? `${YELLOW}!${RESET}`
52
+ : status === "info" ? `${CYAN}•${RESET}`
53
+ : `${RED}✗${RESET}`;
54
+ }
55
+ function printCheck(c) {
56
+ console.log(` ${icon(c.status)} ${c.label.padEnd(26)} ${DIM}${c.value}${RESET}`);
57
+ }
58
+ function section(title) {
59
+ console.log(`\n${CYAN}${BOLD}${title}${RESET}`);
60
+ }
61
+ async function doctorCommand(opts = {}) {
62
+ const repoRoot = (0, projectOptions_1.resolveRepoRoot)(opts);
63
+ const cfgLoad = core_1.ConfigLoader.load(repoRoot);
64
+ const cfg = cfgLoad.config;
65
+ console.log(`${BOLD}relay-baton doctor${opts.deep ? " --deep" : ""}${RESET} ${DIM}${repoRoot}${RESET}`);
66
+ const core = (0, diagnostics_1.coreChecks)(repoRoot, cfg);
67
+ section("Core");
68
+ for (const c of core)
69
+ printCheck(c);
70
+ printCheck({ status: "info", label: "config source", value: cfgLoad.source + (cfgLoad.error ? ` (error: ${cfgLoad.error})` : "") });
71
+ printCheck({ status: "info", label: "AGENTS.md", value: fs.existsSync(path.join(repoRoot, "AGENTS.md")) ? "exists" : "missing" });
72
+ printCheck({ status: "info", label: "CLAUDE.md", value: fs.existsSync(path.join(repoRoot, "CLAUDE.md")) ? "exists" : "missing" });
73
+ let deep = [];
74
+ if (opts.deep) {
75
+ deep = (0, diagnostics_1.deepChecks)(repoRoot, cfg);
76
+ section("Deep diagnostics");
77
+ for (const c of deep)
78
+ printCheck(c);
79
+ }
80
+ const all = [...core, ...deep];
81
+ const fails = all.filter(c => c.status === "fail").length;
82
+ const warns = all.filter(c => c.status === "warn").length;
83
+ section("Summary");
84
+ if (fails > 0) {
85
+ console.log(` ${RED}${fails} failure(s)${RESET}, ${warns} warning(s).`);
86
+ }
87
+ else if (warns > 0) {
88
+ console.log(` ${YELLOW}${warns} warning(s)${RESET}, no failures.`);
89
+ }
90
+ else {
91
+ console.log(` ${GREEN}All checks passed.${RESET}`);
92
+ }
93
+ if (!opts.deep) {
94
+ console.log(` ${DIM}Run \`relay-baton doctor --deep\` for extended diagnostics.${RESET}`);
95
+ }
96
+ // doctor never exits non-zero on warnings; only on hard failures.
97
+ if (fails > 0)
98
+ process.exitCode = 1;
99
+ // Touch SessionManager so an uninitialized repo still gives a hint.
100
+ const sm = new core_1.SessionManager(repoRoot, cfg);
101
+ if (!fs.existsSync(sm.files.dir)) {
102
+ console.log(` ${DIM}→ Run \`relay-baton init\` to create .ai-session/.${RESET}`);
103
+ }
104
+ }
@@ -0,0 +1,9 @@
1
+ import { ProjectOpts } from "./projectOptions";
2
+ export interface ExecuteOpts extends ProjectOpts {
3
+ diet?: string;
4
+ with?: string;
5
+ from?: string;
6
+ force?: boolean;
7
+ allowApiKeyEnv?: boolean;
8
+ }
9
+ export declare function executeCommand(opts: ExecuteOpts): Promise<void>;