debugsk 0.0.3 → 0.0.5

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/dist/cli.js CHANGED
@@ -24,10 +24,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  ));
25
25
 
26
26
  // src/cli.ts
27
- var import_promises3 = __toESM(require("fs/promises"));
28
- var import_node_os = __toESM(require("os"));
29
- var import_node_path4 = __toESM(require("path"));
30
- var import_promises4 = __toESM(require("readline/promises"));
31
27
  var import_minimist = __toESM(require("minimist"));
32
28
 
33
29
  // src/constants.ts
@@ -37,6 +33,173 @@ var DEFAULT_BASE_PATH = "/";
37
33
  var DEFAULT_LOGS_DIR = ".logs";
38
34
  var DEFAULT_MAX_BODY_KB = 256;
39
35
 
36
+ // src/skill.ts
37
+ var import_promises = __toESM(require("fs/promises"));
38
+ var import_node_os = __toESM(require("os"));
39
+ var import_node_path = __toESM(require("path"));
40
+ var import_promises2 = __toESM(require("readline/promises"));
41
+ var PLATFORMS = {
42
+ codex: {
43
+ home: ".codex",
44
+ skillName: "code-debug-skill",
45
+ projectLocal: ".codex/skills"
46
+ },
47
+ claude: {
48
+ home: ".claude",
49
+ skillName: "code-debug-skill",
50
+ projectLocal: ".claude/skills"
51
+ }
52
+ };
53
+ async function resolveSkillSource(skillName = "code-debug-skill") {
54
+ const packageRoot = import_node_path.default.resolve(__dirname, "..");
55
+ const repoRoot = import_node_path.default.resolve(packageRoot, "..", "..");
56
+ const repoSource = import_node_path.default.join(repoRoot, "skills", skillName);
57
+ if (await pathExists(repoSource)) return repoSource;
58
+ const packaged = import_node_path.default.join(packageRoot, "skills", skillName);
59
+ if (await pathExists(packaged)) return packaged;
60
+ throw new Error(`missing_skill_source:${skillName}`);
61
+ }
62
+ async function resolveSkillDest(platform, options = {}) {
63
+ const config = PLATFORMS[platform];
64
+ const useUser = Boolean(options.userScope);
65
+ const scope2 = useUser ? "user" : "local";
66
+ const platformHome = useUser ? import_node_path.default.join(import_node_os.default.homedir(), config.home) : import_node_path.default.join(process.cwd(), config.projectLocal.split("/")[0]);
67
+ const exists = await pathExists(platformHome);
68
+ if (!exists && options.createIfMissing) {
69
+ await ensurePlatformHome(platform, platformHome, scope2);
70
+ }
71
+ const skillsDir = useUser ? import_node_path.default.join(platformHome, "skills") : import_node_path.default.join(platformHome, "skills");
72
+ return {
73
+ dest: import_node_path.default.join(skillsDir, config.skillName),
74
+ scope: scope2,
75
+ homeExists: exists
76
+ };
77
+ }
78
+ async function installSkill(platform, options = {}) {
79
+ const config = PLATFORMS[platform];
80
+ const source = await resolveSkillSource(config.skillName);
81
+ const { dest, scope: scope2 } = await resolveSkillDest(platform, {
82
+ userScope: options.userScope,
83
+ createIfMissing: true
84
+ });
85
+ const exists = await pathExists(dest);
86
+ if (exists && !options.force) {
87
+ throw new Error(`${platform}_skill_already_installed`);
88
+ }
89
+ await ensureSafeDest(dest);
90
+ if (exists) {
91
+ await import_promises.default.rm(dest, { recursive: true, force: true });
92
+ }
93
+ await import_promises.default.mkdir(import_node_path.default.dirname(dest), { recursive: true });
94
+ await import_promises.default.cp(source, dest, { recursive: true });
95
+ return {
96
+ ok: true,
97
+ action: options.force ? "update" : "install",
98
+ scope: scope2,
99
+ dest,
100
+ source,
101
+ replaced: exists
102
+ };
103
+ }
104
+ async function removeSkill(platform, options = {}) {
105
+ const config = PLATFORMS[platform];
106
+ const { dest, scope: scope2, homeExists } = await resolveSkillDest(platform, {
107
+ userScope: options.userScope,
108
+ createIfMissing: false
109
+ });
110
+ if (!homeExists) {
111
+ return {
112
+ ok: true,
113
+ action: "remove",
114
+ scope: scope2,
115
+ dest,
116
+ removed: false,
117
+ reason: `${platform}_home_missing`
118
+ };
119
+ }
120
+ await ensureSafeDest(dest);
121
+ const exists = await pathExists(dest);
122
+ if (exists) {
123
+ await import_promises.default.rm(dest, { recursive: true, force: true });
124
+ }
125
+ return {
126
+ ok: true,
127
+ action: "remove",
128
+ scope: scope2,
129
+ dest,
130
+ removed: exists
131
+ };
132
+ }
133
+ async function ensureSafeDest(dest) {
134
+ const resolved = import_node_path.default.resolve(dest);
135
+ const root = import_node_path.default.parse(resolved).root;
136
+ if (resolved === root || resolved === import_node_os.default.homedir()) {
137
+ throw new Error("unsafe_dest");
138
+ }
139
+ }
140
+ async function ensurePlatformHome(platform, platformHome, scope2) {
141
+ if (await pathExists(platformHome)) return;
142
+ if (!process.stdin.isTTY) {
143
+ throw new Error(`${platform}_home_missing`);
144
+ }
145
+ const prompt = `Create ${platformHome} for ${scope2} scope? [y/N]: `;
146
+ const approved = await confirmPrompt(prompt);
147
+ if (!approved) {
148
+ throw new Error(`${platform}_home_missing`);
149
+ }
150
+ await import_promises.default.mkdir(platformHome, { recursive: true });
151
+ }
152
+ async function confirmPrompt(prompt) {
153
+ const rl = import_promises2.default.createInterface({ input: process.stdin, output: process.stderr });
154
+ const answer = await rl.question(prompt);
155
+ rl.close();
156
+ return /^y(es)?$/i.test(answer.trim());
157
+ }
158
+ async function pathExists(target) {
159
+ try {
160
+ await import_promises.default.access(target);
161
+ return true;
162
+ } catch {
163
+ return false;
164
+ }
165
+ }
166
+
167
+ // src/claude.ts
168
+ async function claudeInstall(force, userScope) {
169
+ try {
170
+ const result = await installSkill("claude", { force, userScope });
171
+ outputJsonResult(result);
172
+ } catch (error) {
173
+ outputError(error instanceof Error ? error.message : "unexpected_error");
174
+ }
175
+ }
176
+ async function claudeUpdate(userScope) {
177
+ await claudeInstall(true, userScope);
178
+ }
179
+ async function claudeRemove(userScope) {
180
+ try {
181
+ const result = await removeSkill("claude", { userScope });
182
+ outputJsonResult(result);
183
+ } catch (error) {
184
+ outputError(error instanceof Error ? error.message : "unexpected_error");
185
+ }
186
+ }
187
+ function outputJsonResult(payload) {
188
+ const action = String(payload.action ?? "result");
189
+ const ok = payload.ok ? "ok" : "error";
190
+ const dest = payload.dest ? `dest=${payload.dest}` : "";
191
+ const status = payload.removed !== void 0 ? payload.removed ? "removed" : "not-removed" : "";
192
+ const replaced = payload.replaced !== void 0 ? payload.replaced ? "replaced" : "new" : "";
193
+ const reason = payload.reason ? `reason=${payload.reason}` : "";
194
+ const parts = [action, ok, dest, status, replaced, reason].filter(Boolean);
195
+ process.stdout.write(`${parts.join(" ")}
196
+ `);
197
+ }
198
+ function outputError(message) {
199
+ process.stderr.write(`${message}
200
+ `);
201
+ }
202
+
40
203
  // src/process.ts
41
204
  function isProcessAlive(pid) {
42
205
  if (!pid) return false;
@@ -74,50 +237,50 @@ function sleep(ms) {
74
237
  }
75
238
 
76
239
  // src/paths.ts
77
- var import_node_path = __toESM(require("path"));
240
+ var import_node_path2 = __toESM(require("path"));
78
241
  function resolveLogsDir({ cwd, logsDir }) {
79
242
  const dir = logsDir && logsDir.length > 0 ? logsDir : DEFAULT_LOGS_DIR;
80
- return import_node_path.default.resolve(cwd, dir);
243
+ return import_node_path2.default.resolve(cwd, dir);
81
244
  }
82
245
  function getRuntimeDir(logsDir) {
83
246
  return logsDir;
84
247
  }
85
248
  function getRuntimePath(logsDir) {
86
- return import_node_path.default.join(getRuntimeDir(logsDir), "runtime.json");
249
+ return import_node_path2.default.join(getRuntimeDir(logsDir), "runtime.json");
87
250
  }
88
251
  function getPidPath(logsDir) {
89
- return import_node_path.default.join(getRuntimeDir(logsDir), "server.pid");
252
+ return import_node_path2.default.join(getRuntimeDir(logsDir), "server.pid");
90
253
  }
91
254
  function getSessionLogPath(logsDir, sessionId, runId) {
92
255
  const safeSession = sanitizePathSegment(sessionId);
93
256
  const safeRun = sanitizePathSegment(runId);
94
- return import_node_path.default.join(getRuntimeDir(logsDir), `${safeSession}-${safeRun}.jsonl`);
257
+ return import_node_path2.default.join(getRuntimeDir(logsDir), `${safeSession}-${safeRun}.jsonl`);
95
258
  }
96
259
  function sanitizePathSegment(value) {
97
260
  return value.replace(/[\\/]/g, "_").replace(/\.\./g, "_").trim() || "unknown";
98
261
  }
99
262
 
100
263
  // src/runtime.ts
101
- var import_promises = __toESM(require("fs/promises"));
264
+ var import_promises3 = __toESM(require("fs/promises"));
102
265
  async function readRuntime(logsDir) {
103
266
  try {
104
- const raw = await import_promises.default.readFile(getRuntimePath(logsDir), "utf8");
267
+ const raw = await import_promises3.default.readFile(getRuntimePath(logsDir), "utf8");
105
268
  return JSON.parse(raw);
106
269
  } catch {
107
270
  return null;
108
271
  }
109
272
  }
110
273
  async function writeRuntime(logsDir, info) {
111
- await import_promises.default.mkdir(getRuntimeDir(logsDir), { recursive: true });
112
- await import_promises.default.writeFile(getRuntimePath(logsDir), JSON.stringify(info, null, 2), "utf8");
274
+ await import_promises3.default.mkdir(getRuntimeDir(logsDir), { recursive: true });
275
+ await import_promises3.default.writeFile(getRuntimePath(logsDir), JSON.stringify(info, null, 2), "utf8");
113
276
  }
114
277
  async function writePid(logsDir, pid) {
115
- await import_promises.default.mkdir(getRuntimeDir(logsDir), { recursive: true });
116
- await import_promises.default.writeFile(getPidPath(logsDir), String(pid), "utf8");
278
+ await import_promises3.default.mkdir(getRuntimeDir(logsDir), { recursive: true });
279
+ await import_promises3.default.writeFile(getPidPath(logsDir), String(pid), "utf8");
117
280
  }
118
281
  async function removePid(logsDir) {
119
282
  try {
120
- await import_promises.default.unlink(getPidPath(logsDir));
283
+ await import_promises3.default.unlink(getPidPath(logsDir));
121
284
  } catch {
122
285
  return;
123
286
  }
@@ -135,8 +298,8 @@ async function markStopped(logsDir) {
135
298
 
136
299
  // src/server.ts
137
300
  var import_node_http = __toESM(require("http"));
138
- var import_promises2 = __toESM(require("fs/promises"));
139
- var import_node_path3 = __toESM(require("path"));
301
+ var import_promises4 = __toESM(require("fs/promises"));
302
+ var import_node_path4 = __toESM(require("path"));
140
303
 
141
304
  // src/net.ts
142
305
  var import_node_net = __toESM(require("net"));
@@ -189,7 +352,7 @@ function getRandomPort(host) {
189
352
 
190
353
  // src/version.ts
191
354
  var import_node_fs = __toESM(require("fs"));
192
- var import_node_path2 = __toESM(require("path"));
355
+ var import_node_path3 = __toESM(require("path"));
193
356
  function getPackageVersion() {
194
357
  try {
195
358
  const pkgPath = findPackageJsonPath();
@@ -201,17 +364,16 @@ function getPackageVersion() {
201
364
  }
202
365
  }
203
366
  function findPackageJsonPath() {
204
- let current = import_node_path2.default.resolve(__dirname);
367
+ let current = import_node_path3.default.resolve(__dirname);
205
368
  for (let i = 0; i < 5; i += 1) {
206
- const candidate = import_node_path2.default.join(current, "package.json");
369
+ const candidate = import_node_path3.default.join(current, "package.json");
207
370
  if (import_node_fs.default.existsSync(candidate)) return candidate;
208
- current = import_node_path2.default.dirname(current);
371
+ current = import_node_path3.default.dirname(current);
209
372
  }
210
- return import_node_path2.default.join(process.cwd(), "package.json");
373
+ return import_node_path3.default.join(process.cwd(), "package.json");
211
374
  }
212
375
 
213
376
  // src/server.ts
214
- var REQUIRED_FIELDS = ["timestamp", "message", "sessionId", "runId", "hypothesisId"];
215
377
  var CORS_HEADERS = {
216
378
  "Access-Control-Allow-Origin": "*",
217
379
  "Access-Control-Allow-Methods": "GET,POST,OPTIONS",
@@ -263,24 +425,28 @@ async function startServer(options) {
263
425
  respondJson(res, 400, { ok: false, error: "invalid_body" });
264
426
  return;
265
427
  }
266
- const missing = REQUIRED_FIELDS.filter((field) => !(field in payload));
267
- if (missing.length > 0) {
268
- respondJson(res, 400, { ok: false, error: "missing_fields", missing });
269
- return;
270
- }
271
428
  const event = payload;
272
- const sessionId = String(event.sessionId);
273
- const runId = String(event.runId);
274
- const logPath = getSessionLogPath(logsDir, sessionId, runId);
275
- await import_promises2.default.mkdir(import_node_path3.default.dirname(logPath), { recursive: true });
429
+ const timestamp = "timestamp" in event ? event.timestamp : Date.now();
430
+ const message = "message" in event ? event.message : "";
431
+ const sessionId = "sessionId" in event ? String(event.sessionId) : "";
432
+ const runId = "runId" in event ? String(event.runId) : "";
433
+ const hypothesisId = "hypothesisId" in event ? String(event.hypothesisId) : "";
276
434
  const enriched = {
435
+ timestamp,
436
+ message,
437
+ sessionId,
438
+ runId,
439
+ hypothesisId,
277
440
  ...event,
441
+ // Original values take precedence if present
278
442
  _meta: {
279
443
  streamId,
280
444
  receivedAt: Date.now()
281
445
  }
282
446
  };
283
- await import_promises2.default.appendFile(logPath, `${JSON.stringify(enriched)}
447
+ const logPath = getSessionLogPath(logsDir, sessionId, runId);
448
+ await import_promises4.default.mkdir(import_node_path4.default.dirname(logPath), { recursive: true });
449
+ await import_promises4.default.appendFile(logPath, `${JSON.stringify(enriched)}
284
450
  `, "utf8");
285
451
  if (options.idleTtlMs && options.idleTtlMs > 0) {
286
452
  resetIdleTimer(options.idleTtlMs);
@@ -429,12 +595,11 @@ var args = (0, import_minimist.default)(process.argv.slice(2), {
429
595
  });
430
596
  var primary = String(args._[0] ?? "help");
431
597
  var secondary = args._[1] ? String(args._[1]) : void 0;
432
- var scope = primary === "server" || primary === "codex" ? primary : "server";
598
+ var scope = primary === "server" || primary === "codex" || primary === "claude" ? primary : "server";
433
599
  var command = scope === "server" ? String(primary === "server" ? secondary ?? "help" : primary) : String(secondary ?? "help");
434
600
  var json = Boolean(args.json);
435
- var SKILL_NAME = "code-debug-skill";
436
601
  void main().catch((error) => {
437
- outputError(error instanceof Error ? error.message : "unexpected_error");
602
+ outputError2(error instanceof Error ? error.message : "unexpected_error");
438
603
  process.exitCode = 1;
439
604
  });
440
605
  async function main() {
@@ -446,13 +611,17 @@ async function main() {
446
611
  await handleCodex(command);
447
612
  return;
448
613
  }
614
+ if (scope === "claude") {
615
+ await handleClaude(command);
616
+ return;
617
+ }
449
618
  switch (command) {
450
619
  case "start":
451
620
  await handleStart();
452
621
  return;
453
622
  case "run":
454
623
  if (!process.env.DEBUGSK_CHILD) {
455
- outputError("use_start_command");
624
+ outputError2("use_start_command");
456
625
  return;
457
626
  }
458
627
  await handleRun();
@@ -464,7 +633,7 @@ async function main() {
464
633
  await handleStop();
465
634
  return;
466
635
  default:
467
- outputError(`unknown_command:${command}`);
636
+ outputError2(`unknown_command:${command}`);
468
637
  }
469
638
  }
470
639
  function getCommonOptions() {
@@ -511,12 +680,12 @@ async function handleStart() {
511
680
  });
512
681
  const finalRuntime = await waitForRuntime(resolvedLogsDir, 5e3);
513
682
  if (!finalRuntime) {
514
- outputError("start_failed");
683
+ outputError2("start_failed");
515
684
  return;
516
685
  }
517
686
  const ok = await waitForHealth(finalRuntime, 5e3);
518
687
  if (!ok) {
519
- outputError("health_check_failed");
688
+ outputError2("health_check_failed");
520
689
  return;
521
690
  }
522
691
  const payload = buildStartOutput(finalRuntime, false, spawnResult?.pid);
@@ -577,121 +746,51 @@ async function handleStop() {
577
746
  outputStop({ ok: true, stopped, pid: runtime.pid });
578
747
  }
579
748
  async function handleCodex(subcommand) {
749
+ const userScope = Boolean(args.user);
580
750
  switch (subcommand) {
581
751
  case "install":
582
- await codexInstall(false);
752
+ await codexInstall(false, userScope);
583
753
  return;
584
754
  case "update":
585
- await codexInstall(true);
755
+ await codexInstall(true, userScope);
586
756
  return;
587
757
  case "remove":
588
- await codexRemove();
758
+ await codexRemove(userScope);
589
759
  return;
590
760
  default:
591
- outputError(`unknown_command:codex:${subcommand}`);
761
+ outputError2(`unknown_command:codex:${subcommand}`);
592
762
  }
593
763
  }
594
- async function codexInstall(force) {
595
- const source = await resolveSkillSource();
596
- const { dest, scope: scope2 } = await resolveCodexDest({ createIfMissing: true });
597
- const exists = await pathExists(dest);
598
- if (exists && !force) {
599
- outputError("codex_skill_already_installed");
600
- return;
601
- }
602
- await ensureSafeDest(dest);
603
- if (exists) {
604
- await import_promises3.default.rm(dest, { recursive: true, force: true });
605
- }
606
- await import_promises3.default.mkdir(import_node_path4.default.dirname(dest), { recursive: true });
607
- await import_promises3.default.cp(source, dest, { recursive: true });
608
- outputJsonResult({
609
- ok: true,
610
- action: force ? "update" : "install",
611
- scope: scope2,
612
- dest,
613
- source,
614
- replaced: exists
615
- });
616
- }
617
- async function codexRemove() {
618
- const { dest, scope: scope2, homeExists } = await resolveCodexDest({ createIfMissing: false });
619
- if (!homeExists) {
620
- outputJsonResult({
621
- ok: true,
622
- action: "remove",
623
- scope: scope2,
624
- dest,
625
- removed: false,
626
- reason: "codex_home_missing"
627
- });
628
- return;
629
- }
630
- await ensureSafeDest(dest);
631
- const exists = await pathExists(dest);
632
- if (exists) {
633
- await import_promises3.default.rm(dest, { recursive: true, force: true });
634
- }
635
- outputJsonResult({
636
- ok: true,
637
- action: "remove",
638
- scope: scope2,
639
- dest,
640
- removed: exists
641
- });
642
- }
643
- async function resolveSkillSource() {
644
- const packageRoot = import_node_path4.default.resolve(__dirname, "..");
645
- const repoRoot = import_node_path4.default.resolve(packageRoot, "..", "..");
646
- const repoSource = import_node_path4.default.join(repoRoot, "skills", SKILL_NAME);
647
- if (await pathExists(repoSource)) return repoSource;
648
- const packaged = import_node_path4.default.join(packageRoot, "skills", SKILL_NAME);
649
- if (await pathExists(packaged)) return packaged;
650
- throw new Error(`missing_skill_source:${SKILL_NAME}`);
651
- }
652
- async function resolveCodexDest({
653
- createIfMissing
654
- }) {
655
- const useUser = Boolean(args.user);
656
- const scope2 = useUser ? "user" : "local";
657
- const codexHome = useUser ? import_node_path4.default.join(import_node_os.default.homedir(), ".codex") : import_node_path4.default.join(process.cwd(), ".codex");
658
- const exists = await pathExists(codexHome);
659
- if (!exists && createIfMissing) {
660
- await ensureCodexHome(codexHome, scope2);
661
- }
662
- return { dest: import_node_path4.default.join(codexHome, "skills", SKILL_NAME), scope: scope2, homeExists: exists };
663
- }
664
- async function ensureSafeDest(dest) {
665
- const resolved = import_node_path4.default.resolve(dest);
666
- const root = import_node_path4.default.parse(resolved).root;
667
- if (resolved === root || resolved === import_node_os.default.homedir()) {
668
- throw new Error("unsafe_dest");
764
+ async function handleClaude(subcommand) {
765
+ const userScope = Boolean(args.user);
766
+ switch (subcommand) {
767
+ case "install":
768
+ await claudeInstall(false, userScope);
769
+ return;
770
+ case "update":
771
+ await claudeUpdate(userScope);
772
+ return;
773
+ case "remove":
774
+ await claudeRemove(userScope);
775
+ return;
776
+ default:
777
+ outputError2(`unknown_command:claude:${subcommand}`);
669
778
  }
670
779
  }
671
- async function ensureCodexHome(codexHome, scope2) {
672
- if (await pathExists(codexHome)) return;
673
- if (!process.stdin.isTTY) {
674
- throw new Error("codex_home_missing");
675
- }
676
- const prompt = `Create ${codexHome} for ${scope2} scope? [y/N]: `;
677
- const approved = await confirmPrompt(prompt);
678
- if (!approved) {
679
- throw new Error("codex_home_missing");
780
+ async function codexInstall(force, userScope) {
781
+ try {
782
+ const result = await installSkill("codex", { force, userScope });
783
+ outputJsonResult2(result);
784
+ } catch (error) {
785
+ outputError2(error instanceof Error ? error.message : "unexpected_error");
680
786
  }
681
- await import_promises3.default.mkdir(codexHome, { recursive: true });
682
- }
683
- async function confirmPrompt(prompt) {
684
- const rl = import_promises4.default.createInterface({ input: process.stdin, output: process.stderr });
685
- const answer = await rl.question(prompt);
686
- rl.close();
687
- return /^y(es)?$/i.test(answer.trim());
688
787
  }
689
- async function pathExists(target) {
788
+ async function codexRemove(userScope) {
690
789
  try {
691
- await import_promises3.default.access(target);
692
- return true;
693
- } catch {
694
- return false;
790
+ const result = await removeSkill("codex", { userScope });
791
+ outputJsonResult2(result);
792
+ } catch (error) {
793
+ outputError2(error instanceof Error ? error.message : "unexpected_error");
695
794
  }
696
795
  }
697
796
  async function spawnBackground(options) {
@@ -791,7 +890,7 @@ function outputJson(payload) {
791
890
  process.stdout.write(`${JSON.stringify(payload)}
792
891
  `);
793
892
  }
794
- function outputJsonResult(payload) {
893
+ function outputJsonResult2(payload) {
795
894
  if (json) {
796
895
  outputJson(payload);
797
896
  return;
@@ -802,7 +901,7 @@ function outputJsonResult(payload) {
802
901
  process.stdout.write(`${action} ${ok} ${dest}
803
902
  `);
804
903
  }
805
- function outputError(message) {
904
+ function outputError2(message) {
806
905
  if (json) {
807
906
  outputJson({ ok: false, error: message });
808
907
  } else {
@@ -869,6 +968,10 @@ Usage:
869
968
  codex update Update Codex skill (user scope)
870
969
  codex remove Remove Codex skill (user scope)
871
970
 
971
+ claude install Install Claude skill (user scope)
972
+ claude update Update Claude skill (user scope)
973
+ claude remove Remove Claude skill (user scope)
974
+
872
975
  Aliases:
873
976
  start/status/stop Same as "server <command>"
874
977
 
@@ -882,7 +985,7 @@ Options:
882
985
  --idle-ttl-ms (optional)
883
986
  --force (restart even if already running)
884
987
  --json (stdout JSON only)
885
- -u, --user (install Codex skill to user scope)
988
+ -u, --user (install skill to user scope)
886
989
  `;
887
990
  if (json) {
888
991
  outputJson({ ok: true, help: text });
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/constants.ts","../src/process.ts","../src/paths.ts","../src/runtime.ts","../src/server.ts","../src/net.ts","../src/version.ts"],"sourcesContent":["#!/usr/bin/env node\nimport fs from 'node:fs/promises'\nimport os from 'node:os'\nimport path from 'node:path'\nimport readline from 'node:readline/promises'\nimport minimist from 'minimist'\nimport {\n DEFAULT_BASE_PATH,\n DEFAULT_HOST,\n DEFAULT_LOGS_DIR,\n DEFAULT_MAX_BODY_KB,\n DEFAULT_PORT,\n} from './constants'\nimport { isProcessAlive, terminateProcess } from './process'\nimport { resolveLogsDir } from './paths'\nimport { RuntimeInfo, markStopped, readRuntime, removePid } from './runtime'\nimport { startServer } from './server'\n\nconst args = minimist(process.argv.slice(2), {\n boolean: ['json', 'force', 'help', 'user'],\n string: ['host', 'base-path', 'logs-dir', 'token'],\n alias: {\n h: 'help',\n u: 'user',\n },\n})\n\nconst primary = String(args._[0] ?? 'help')\nconst secondary = args._[1] ? String(args._[1]) : undefined\nconst scope = primary === 'server' || primary === 'codex' ? primary : 'server'\nconst command =\n scope === 'server' ? String(primary === 'server' ? secondary ?? 'help' : primary) : String(secondary ?? 'help')\n\nconst json = Boolean(args.json)\nconst SKILL_NAME = 'code-debug-skill'\n\nvoid main().catch((error) => {\n outputError(error instanceof Error ? error.message : 'unexpected_error')\n process.exitCode = 1\n})\n\nasync function main(): Promise<void> {\n if (args.help || command === 'help') {\n printHelp()\n return\n }\n\n if (scope === 'codex') {\n await handleCodex(command)\n return\n }\n\n switch (command) {\n case 'start':\n await handleStart()\n return\n case 'run':\n if (!process.env.DEBUGSK_CHILD) {\n outputError('use_start_command')\n return\n }\n await handleRun()\n return\n case 'status':\n await handleStatus()\n return\n case 'stop':\n await handleStop()\n return\n default:\n outputError(`unknown_command:${command}`)\n }\n}\n\nfunction getCommonOptions() {\n const host = String(args.host ?? DEFAULT_HOST)\n const port = parseNumber(args.port, DEFAULT_PORT) ?? DEFAULT_PORT\n const basePath = String(args['base-path'] ?? DEFAULT_BASE_PATH)\n const logsDir = args['logs-dir'] ? String(args['logs-dir']) : undefined\n const maxBodyKB = parseNumber(args['max-body-kb'], DEFAULT_MAX_BODY_KB) ?? DEFAULT_MAX_BODY_KB\n const token = args.token ? String(args.token) : undefined\n const idleTtlMs = parseNumber(args['idle-ttl-ms'], undefined)\n return { host, port, basePath, logsDir, maxBodyKB, token, idleTtlMs }\n}\n\nasync function handleStart(): Promise<void> {\n const { host, port, basePath, logsDir, maxBodyKB, token, idleTtlMs } = getCommonOptions()\n const cwd = process.cwd()\n const resolvedLogsDir = resolveLogsDir({ cwd, logsDir })\n const runtime = await readRuntime(resolvedLogsDir)\n\n if (runtime && !runtime.options) {\n outputLegacyRuntimeError()\n return\n }\n\n if (runtime && isProcessAlive(runtime.pid) && !args.force) {\n const payload = buildStartOutput(runtime, true)\n outputStart(payload)\n return\n }\n\n if (runtime && isProcessAlive(runtime.pid) && args.force) {\n await terminateProcess(runtime.pid, 3000)\n await markStopped(resolvedLogsDir)\n await removePid(resolvedLogsDir)\n }\n\n if (runtime && !isProcessAlive(runtime.pid)) {\n await markStopped(resolvedLogsDir)\n await removePid(resolvedLogsDir)\n }\n\n const spawnResult = await spawnBackground({\n host,\n port,\n basePath,\n logsDir,\n maxBodyKB,\n token,\n idleTtlMs,\n })\n\n const finalRuntime = await waitForRuntime(resolvedLogsDir, 5000)\n if (!finalRuntime) {\n outputError('start_failed')\n return\n }\n\n const ok = await waitForHealth(finalRuntime, 5000)\n if (!ok) {\n outputError('health_check_failed')\n return\n }\n\n const payload = buildStartOutput(finalRuntime, false, spawnResult?.pid)\n outputStart(payload)\n}\n\nasync function handleRun(): Promise<void> {\n const { host, port, basePath, logsDir, maxBodyKB, token, idleTtlMs } = getCommonOptions()\n const cwd = process.cwd()\n\n const started = await startServer({\n host,\n port,\n basePath,\n logsDir,\n maxBodyKB,\n token,\n idleTtlMs,\n cwd,\n })\n\n installSignalHandlers(started.logsDir, started.close)\n\n if (!json) {\n logInfo(`debugsk server listening at ${started.baseUrl}`)\n }\n}\n\nasync function handleStatus(): Promise<void> {\n const cwd = process.cwd()\n const logsDir = args['logs-dir'] ? String(args['logs-dir']) : undefined\n const resolvedLogsDir = resolveLogsDir({ cwd, logsDir })\n const runtime = await readRuntime(resolvedLogsDir)\n\n if (!runtime) {\n outputStatus({ ok: false, running: false, error: 'not_running' })\n return\n }\n if (!runtime.options) {\n outputLegacyRuntimeError()\n return\n }\n\n const running = isProcessAlive(runtime.pid)\n const payload = {\n ...runtime,\n running,\n }\n outputStatus(payload)\n}\n\nasync function handleStop(): Promise<void> {\n const cwd = process.cwd()\n const logsDir = args['logs-dir'] ? String(args['logs-dir']) : undefined\n const resolvedLogsDir = resolveLogsDir({ cwd, logsDir })\n const runtime = await readRuntime(resolvedLogsDir)\n\n if (!runtime) {\n outputStop({ ok: true, stopped: false, running: false })\n return\n }\n\n const stopped = await terminateProcess(runtime.pid, 3000)\n if (stopped) {\n await markStopped(resolvedLogsDir)\n await removePid(resolvedLogsDir)\n }\n\n outputStop({ ok: true, stopped, pid: runtime.pid })\n}\n\nasync function handleCodex(subcommand: string): Promise<void> {\n switch (subcommand) {\n case 'install':\n await codexInstall(false)\n return\n case 'update':\n await codexInstall(true)\n return\n case 'remove':\n await codexRemove()\n return\n default:\n outputError(`unknown_command:codex:${subcommand}`)\n }\n}\n\nasync function codexInstall(force: boolean): Promise<void> {\n const source = await resolveSkillSource()\n const { dest, scope } = await resolveCodexDest({ createIfMissing: true })\n const exists = await pathExists(dest)\n\n if (exists && !force) {\n outputError('codex_skill_already_installed')\n return\n }\n\n await ensureSafeDest(dest)\n if (exists) {\n await fs.rm(dest, { recursive: true, force: true })\n }\n\n await fs.mkdir(path.dirname(dest), { recursive: true })\n await fs.cp(source, dest, { recursive: true })\n\n outputJsonResult({\n ok: true,\n action: force ? 'update' : 'install',\n scope,\n dest,\n source,\n replaced: exists,\n })\n}\n\nasync function codexRemove(): Promise<void> {\n const { dest, scope, homeExists } = await resolveCodexDest({ createIfMissing: false })\n if (!homeExists) {\n outputJsonResult({\n ok: true,\n action: 'remove',\n scope,\n dest,\n removed: false,\n reason: 'codex_home_missing',\n })\n return\n }\n await ensureSafeDest(dest)\n const exists = await pathExists(dest)\n if (exists) {\n await fs.rm(dest, { recursive: true, force: true })\n }\n outputJsonResult({\n ok: true,\n action: 'remove',\n scope,\n dest,\n removed: exists,\n })\n}\n\nasync function resolveSkillSource(): Promise<string> {\n const packageRoot = path.resolve(__dirname, '..')\n const repoRoot = path.resolve(packageRoot, '..', '..')\n const repoSource = path.join(repoRoot, 'skills', SKILL_NAME)\n if (await pathExists(repoSource)) return repoSource\n const packaged = path.join(packageRoot, 'skills', SKILL_NAME)\n if (await pathExists(packaged)) return packaged\n throw new Error(`missing_skill_source:${SKILL_NAME}`)\n}\n\nasync function resolveCodexDest({\n createIfMissing,\n}: {\n createIfMissing: boolean\n}): Promise<{ dest: string; scope: 'user' | 'local'; homeExists: boolean }> {\n const useUser = Boolean(args.user)\n const scope: 'user' | 'local' = useUser ? 'user' : 'local'\n const codexHome = useUser ? path.join(os.homedir(), '.codex') : path.join(process.cwd(), '.codex')\n const exists = await pathExists(codexHome)\n if (!exists && createIfMissing) {\n await ensureCodexHome(codexHome, scope)\n }\n return { dest: path.join(codexHome, 'skills', SKILL_NAME), scope, homeExists: exists }\n}\n\nasync function ensureSafeDest(dest: string): Promise<void> {\n const resolved = path.resolve(dest)\n const root = path.parse(resolved).root\n if (resolved === root || resolved === os.homedir()) {\n throw new Error('unsafe_dest')\n }\n}\n\nasync function ensureCodexHome(codexHome: string, scope: 'user' | 'local'): Promise<void> {\n if (await pathExists(codexHome)) return\n if (!process.stdin.isTTY) {\n throw new Error('codex_home_missing')\n }\n const prompt = `Create ${codexHome} for ${scope} scope? [y/N]: `\n const approved = await confirmPrompt(prompt)\n if (!approved) {\n throw new Error('codex_home_missing')\n }\n await fs.mkdir(codexHome, { recursive: true })\n}\n\nasync function confirmPrompt(prompt: string): Promise<boolean> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stderr })\n const answer = await rl.question(prompt)\n rl.close()\n return /^y(es)?$/i.test(answer.trim())\n}\n\nasync function pathExists(target: string): Promise<boolean> {\n try {\n await fs.access(target)\n return true\n } catch {\n return false\n }\n}\n\nasync function spawnBackground(options: {\n host: string\n port: number\n basePath: string\n logsDir?: string\n maxBodyKB: number\n token?: string\n idleTtlMs?: number\n}): Promise<{ pid: number } | null> {\n const nodeArgs = [...process.execArgv, process.argv[1]]\n const cmdArgs = ['run']\n\n cmdArgs.push('--host', options.host)\n cmdArgs.push('--port', String(options.port))\n cmdArgs.push('--base-path', options.basePath)\n cmdArgs.push('--max-body-kb', String(options.maxBodyKB))\n if (options.logsDir) cmdArgs.push('--logs-dir', options.logsDir)\n if (options.token) cmdArgs.push('--token', options.token)\n if (options.idleTtlMs) cmdArgs.push('--idle-ttl-ms', String(options.idleTtlMs))\n\n const spawn = await import('node:child_process')\n const child = spawn.spawn(process.execPath, [...nodeArgs, ...cmdArgs], {\n detached: true,\n stdio: 'ignore',\n env: {\n ...process.env,\n DEBUGSK_CHILD: '1',\n },\n })\n child.unref()\n return child.pid ? { pid: child.pid } : null\n}\n\nasync function waitForRuntime(logsDir: string, timeoutMs: number): Promise<RuntimeInfo | null> {\n const start = Date.now()\n while (Date.now() - start < timeoutMs) {\n const runtime = await readRuntime(logsDir)\n if (runtime && runtime.pid) return runtime\n await sleep(100)\n }\n return null\n}\n\nasync function waitForHealth(runtime: RuntimeInfo, timeoutMs: number): Promise<boolean> {\n const url = new URL(runtime.server.endpoints.health, runtime.server.baseUrl)\n const start = Date.now()\n while (Date.now() - start < timeoutMs) {\n const ok = await checkHealth(url)\n if (ok) return true\n await sleep(100)\n }\n return false\n}\n\nasync function checkHealth(url: URL): Promise<boolean> {\n const http = await import('node:http')\n return new Promise((resolve) => {\n const req = http.get(url, (res) => {\n res.resume()\n resolve(res.statusCode === 200)\n })\n req.on('error', () => resolve(false))\n })\n}\n\nfunction buildStartOutput(runtime: RuntimeInfo, existing: boolean, spawnedPid?: number) {\n const ingestPath = runtime.server.endpoints.ingestTemplate\n const ingestUrl = new URL(ingestPath.replace('{streamId}', '{streamId}'), runtime.server.baseUrl)\n const snippetHeaders: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n const tokenEnabled = runtime.options.tokenEnabled\n if (tokenEnabled) {\n snippetHeaders.Authorization = 'Bearer YOUR_TOKEN'\n }\n\n const jsFetch = `fetch(\"${ingestUrl.toString()}\",{method:\"POST\",headers:${JSON.stringify(\n snippetHeaders,\n )},body:JSON.stringify({...})}).catch(()=>{});`\n\n return {\n ok: true,\n version: runtime.version,\n pid: runtime.pid,\n cwd: runtime.cwd,\n logsDir: runtime.logsDir,\n server: {\n host: runtime.server.host,\n port: runtime.server.port,\n baseUrl: runtime.server.baseUrl,\n endpoints: runtime.server.endpoints,\n },\n snippets: {\n jsFetch,\n },\n existing,\n spawnedPid,\n }\n}\n\nfunction installSignalHandlers(logsDir: string, close: () => Promise<void>): void {\n const shutdown = async () => {\n await close()\n await markStopped(logsDir)\n await removePid(logsDir)\n process.exit(0)\n }\n\n process.on('SIGTERM', () => void shutdown())\n process.on('SIGINT', () => void shutdown())\n}\n\nfunction outputJson(payload: unknown): void {\n process.stdout.write(`${JSON.stringify(payload)}\\n`)\n}\n\nfunction outputJsonResult(payload: Record<string, unknown>): void {\n if (json) {\n outputJson(payload)\n return\n }\n const action = String(payload.action ?? 'result')\n const ok = payload.ok ? 'ok' : 'error'\n const dest = payload.dest ? `dest=${payload.dest}` : ''\n process.stdout.write(`${action} ${ok} ${dest}\\n`)\n}\n\nfunction outputError(message: string): void {\n if (json) {\n outputJson({ ok: false, error: message })\n } else {\n process.stderr.write(`${message}\\n`)\n }\n}\n\nfunction outputLegacyRuntimeError(): void {\n const error = 'legacy_runtime_incompatible'\n const hint = 'delete .logs/runtime.json or the entire .logs directory, then retry'\n if (json) {\n outputJson({ ok: false, error, hint })\n } else {\n process.stderr.write(`${error}: ${hint}\\n`)\n }\n}\n\nfunction logInfo(message: string): void {\n process.stderr.write(`${message}\\n`)\n}\n\nfunction outputStart(payload: Record<string, unknown>): void {\n if (json) {\n outputJson(payload)\n return\n }\n const server = payload.server as RuntimeInfo['server']\n const pid = payload.pid as number\n const logsDir = payload.logsDir as string\n process.stdout.write(\n `started pid=${pid} baseUrl=${server.baseUrl} logsDir=${logsDir}\\n`,\n )\n}\n\nfunction outputStatus(payload: Record<string, unknown>): void {\n if (json) {\n outputJson(payload)\n return\n }\n const running = payload.running ? 'running' : 'stopped'\n const pid = payload.pid ? `pid=${payload.pid}` : 'pid=unknown'\n process.stdout.write(`status ${running} ${pid}\\n`)\n}\n\nfunction outputStop(payload: Record<string, unknown>): void {\n if (json) {\n outputJson(payload)\n return\n }\n const stopped = payload.stopped ? 'stopped' : 'not-stopped'\n const pid = payload.pid ? `pid=${payload.pid}` : ''\n process.stdout.write(`stop ${stopped} ${pid}\\n`)\n}\n\nfunction printHelp(): void {\n const text = `debugsk\n\nUsage:\n server start --json Start server in background and print JSON\n server status --json Show server status\n server stop --json Stop background server\n\n codex install Install Codex skill (user scope)\n codex update Update Codex skill (user scope)\n codex remove Remove Codex skill (user scope)\n\nAliases:\n start/status/stop Same as \"server <command>\"\n\nOptions:\n --host (default ${DEFAULT_HOST})\n --port (default ${DEFAULT_PORT})\n --base-path (default ${DEFAULT_BASE_PATH})\n --logs-dir (default ${DEFAULT_LOGS_DIR})\n --max-body-kb (default ${DEFAULT_MAX_BODY_KB})\n --token (optional)\n --idle-ttl-ms (optional)\n --force (restart even if already running)\n --json (stdout JSON only)\n -u, --user (install Codex skill to user scope)\n`\n if (json) {\n outputJson({ ok: true, help: text })\n } else {\n process.stdout.write(`${text}\\n`)\n }\n}\n\nfunction parseNumber(value: unknown, fallback: number | undefined): number | undefined {\n if (value === undefined || value === null || value === '') {\n return fallback\n }\n const parsed = Number(value)\n if (Number.isFinite(parsed)) return parsed\n return fallback\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n","export const DEFAULT_HOST = '127.0.0.1'\nexport const DEFAULT_PORT = 7242\nexport const DEFAULT_BASE_PATH = '/'\nexport const DEFAULT_LOGS_DIR = '.logs'\nexport const DEFAULT_MAX_BODY_KB = 256\n","export function isProcessAlive(pid: number): boolean {\n if (!pid) return false\n try {\n process.kill(pid, 0)\n return true\n } catch (error) {\n const err = error as NodeJS.ErrnoException\n return err.code === 'EPERM'\n }\n}\n\nexport async function terminateProcess(pid: number, timeoutMs: number): Promise<boolean> {\n if (!isProcessAlive(pid)) return true\n try {\n process.kill(pid, 'SIGTERM')\n } catch (error) {\n const err = error as NodeJS.ErrnoException\n if (err.code === 'ESRCH') return true\n }\n\n const start = Date.now()\n while (Date.now() - start < timeoutMs) {\n if (!isProcessAlive(pid)) return true\n await sleep(100)\n }\n\n try {\n process.kill(pid, 'SIGKILL')\n } catch (error) {\n const err = error as NodeJS.ErrnoException\n if (err.code === 'ESRCH') return true\n }\n\n return !isProcessAlive(pid)\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n","import path from 'node:path'\nimport { DEFAULT_LOGS_DIR } from './constants'\n\ntype PathOptions = {\n cwd: string\n logsDir?: string\n}\n\nexport function resolveLogsDir({ cwd, logsDir }: PathOptions): string {\n const dir = logsDir && logsDir.length > 0 ? logsDir : DEFAULT_LOGS_DIR\n return path.resolve(cwd, dir)\n}\n\nexport function getRuntimeDir(logsDir: string): string {\n return logsDir\n}\n\nexport function getRuntimePath(logsDir: string): string {\n return path.join(getRuntimeDir(logsDir), 'runtime.json')\n}\n\nexport function getPidPath(logsDir: string): string {\n return path.join(getRuntimeDir(logsDir), 'server.pid')\n}\n\nexport function getSessionLogPath(\n logsDir: string,\n sessionId: string,\n runId: string,\n): string {\n const safeSession = sanitizePathSegment(sessionId)\n const safeRun = sanitizePathSegment(runId)\n return path.join(getRuntimeDir(logsDir), `${safeSession}-${safeRun}.jsonl`)\n}\n\nfunction sanitizePathSegment(value: string): string {\n return value.replace(/[\\\\/]/g, '_').replace(/\\.\\./g, '_').trim() || 'unknown'\n}\n","import fs from 'node:fs/promises'\nimport { getPidPath, getRuntimeDir, getRuntimePath } from './paths'\n\nexport type RuntimeInfo = {\n ok: boolean\n version: string\n pid: number\n cwd: string\n logsDir: string\n running: boolean\n server: {\n host: string\n port: number\n baseUrl: string\n basePath: string\n endpoints: {\n health: string\n ingestTemplate: string\n }\n }\n startedAt: string\n stoppedAt?: string\n options: {\n maxBodyKB: number\n tokenEnabled: boolean\n idleTtlMs?: number\n }\n}\n\nexport async function readRuntime(logsDir: string): Promise<RuntimeInfo | null> {\n try {\n const raw = await fs.readFile(getRuntimePath(logsDir), 'utf8')\n return JSON.parse(raw) as RuntimeInfo\n } catch {\n return null\n }\n}\n\nexport async function writeRuntime(logsDir: string, info: RuntimeInfo): Promise<void> {\n await fs.mkdir(getRuntimeDir(logsDir), { recursive: true })\n await fs.writeFile(getRuntimePath(logsDir), JSON.stringify(info, null, 2), 'utf8')\n}\n\nexport async function writePid(logsDir: string, pid: number): Promise<void> {\n await fs.mkdir(getRuntimeDir(logsDir), { recursive: true })\n await fs.writeFile(getPidPath(logsDir), String(pid), 'utf8')\n}\n\nexport async function removePid(logsDir: string): Promise<void> {\n try {\n await fs.unlink(getPidPath(logsDir))\n } catch {\n return\n }\n}\n\nexport async function markStopped(logsDir: string): Promise<void> {\n const current = await readRuntime(logsDir)\n if (!current) return\n const updated: RuntimeInfo = {\n ...current,\n running: false,\n stoppedAt: new Date().toISOString(),\n }\n await writeRuntime(logsDir, updated)\n}\n","import http from 'node:http'\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\nimport { formatBaseUrl, resolvePort } from './net'\nimport { getSessionLogPath, resolveLogsDir } from './paths'\nimport { RuntimeInfo, markStopped, removePid, writePid, writeRuntime } from './runtime'\nimport { getPackageVersion } from './version'\n\nexport type StartOptions = {\n host: string\n port?: number\n basePath: string\n logsDir?: string\n maxBodyKB: number\n token?: string\n idleTtlMs?: number\n cwd: string\n}\n\nexport type StartedServer = {\n server: http.Server\n host: string\n port: number\n basePath: string\n baseUrl: string\n logsDir: string\n close: () => Promise<void>\n}\n\nconst REQUIRED_FIELDS = ['timestamp', 'message', 'sessionId', 'runId', 'hypothesisId'] as const\nconst CORS_HEADERS = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET,POST,OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Debug-Token',\n 'Access-Control-Max-Age': '86400',\n} as const\n\nexport async function startServer(options: StartOptions): Promise<StartedServer> {\n const logsDir = resolveLogsDir({ cwd: options.cwd, logsDir: options.logsDir })\n const host = options.host\n const basePath = normalizeBasePath(options.basePath)\n const port = await resolvePort(host, options.port)\n const baseUrl = formatBaseUrl(host, port)\n\n let idleTimer: NodeJS.Timeout | undefined\n const server = http.createServer(async (req, res) => {\n applyCorsHeaders(res)\n try {\n const url = new URL(req.url ?? '/', baseUrl)\n const normalizedPath = stripBasePath(url.pathname, basePath)\n\n if (normalizedPath == null) {\n respondJson(res, 404, { ok: false, error: 'not_found' })\n return\n }\n\n if (req.method === 'OPTIONS') {\n respondNoContent(res, 204)\n return\n }\n\n if (req.method === 'GET' && normalizedPath === '/health') {\n respondJson(res, 200, { ok: true })\n return\n }\n\n if (req.method === 'POST' && normalizedPath.startsWith('/ingest/')) {\n const streamId = decodeURIComponent(normalizedPath.replace('/ingest/', ''))\n if (!authorizeRequest(req, options.token)) {\n respondJson(res, 401, { ok: false, error: 'unauthorized' })\n return\n }\n\n let payload: unknown\n try {\n payload = await readJsonBody(req, options.maxBodyKB)\n } catch (error) {\n if (error instanceof BodyTooLargeError) {\n respondJson(res, 413, { ok: false, error: 'body_too_large' })\n return\n }\n respondJson(res, 400, { ok: false, error: 'invalid_json' })\n return\n }\n\n if (!payload || typeof payload !== 'object') {\n respondJson(res, 400, { ok: false, error: 'invalid_body' })\n return\n }\n\n const missing = REQUIRED_FIELDS.filter((field) => !(field in payload))\n if (missing.length > 0) {\n respondJson(res, 400, { ok: false, error: 'missing_fields', missing })\n return\n }\n\n const event = payload as Record<string, unknown>\n const sessionId = String(event.sessionId)\n const runId = String(event.runId)\n const logPath = getSessionLogPath(logsDir, sessionId, runId)\n await fs.mkdir(path.dirname(logPath), { recursive: true })\n\n const enriched = {\n ...event,\n _meta: {\n streamId,\n receivedAt: Date.now(),\n },\n }\n\n await fs.appendFile(logPath, `${JSON.stringify(enriched)}\\n`, 'utf8')\n\n if (options.idleTtlMs && options.idleTtlMs > 0) {\n resetIdleTimer(options.idleTtlMs)\n }\n\n respondJson(res, 200, { ok: true, written: true, path: logPath })\n return\n }\n\n respondJson(res, 404, { ok: false, error: 'not_found' })\n } catch {\n respondJson(res, 500, { ok: false, error: 'internal_error' })\n }\n })\n\n const close = async (): Promise<void> => {\n if (idleTimer) clearTimeout(idleTimer)\n await new Promise<void>((resolve, reject) => {\n server.close((err) => {\n if (err) reject(err)\n else resolve()\n })\n })\n }\n\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject)\n server.listen(port, host, () => resolve())\n })\n\n const runtime: RuntimeInfo = {\n ok: true,\n version: getPackageVersion(),\n pid: process.pid,\n cwd: options.cwd,\n logsDir,\n running: true,\n server: {\n host,\n port,\n baseUrl,\n basePath,\n endpoints: {\n health: `${basePath}/health`,\n ingestTemplate: `${basePath}/ingest/{streamId}`,\n },\n },\n startedAt: new Date().toISOString(),\n options: {\n maxBodyKB: options.maxBodyKB,\n tokenEnabled: Boolean(options.token),\n idleTtlMs: options.idleTtlMs,\n },\n }\n\n await writeRuntime(logsDir, runtime)\n await writePid(logsDir, process.pid)\n\n if (options.idleTtlMs && options.idleTtlMs > 0) {\n resetIdleTimer(options.idleTtlMs)\n }\n\n return { server, host, port, basePath, baseUrl, logsDir, close }\n\n function resetIdleTimer(ttl: number): void {\n if (idleTimer) clearTimeout(idleTimer)\n idleTimer = setTimeout(async () => {\n await close()\n await markStopped(logsDir)\n await removePid(logsDir)\n process.exit(0)\n }, ttl)\n }\n}\n\nfunction normalizeBasePath(basePath: string): string {\n if (!basePath || basePath === '/') return ''\n const trimmed = basePath.startsWith('/') ? basePath : `/${basePath}`\n return trimmed.endsWith('/') ? trimmed.slice(0, -1) : trimmed\n}\n\nfunction stripBasePath(pathname: string, basePath: string): string | null {\n if (!basePath) return pathname\n if (!pathname.startsWith(basePath)) return null\n const sliced = pathname.slice(basePath.length)\n return sliced.length === 0 ? '/' : sliced\n}\n\nfunction authorizeRequest(req: http.IncomingMessage, token?: string): boolean {\n if (!token) return true\n const authHeader = req.headers.authorization\n if (authHeader && authHeader === `Bearer ${token}`) return true\n const headerToken = req.headers['x-debug-token']\n if (typeof headerToken === 'string' && headerToken === token) return true\n return false\n}\n\nfunction respondJson(res: http.ServerResponse, status: number, payload: unknown): void {\n const data = JSON.stringify(payload)\n res.statusCode = status\n res.setHeader('Content-Type', 'application/json')\n res.setHeader('Content-Length', Buffer.byteLength(data))\n res.end(data)\n}\n\nfunction respondNoContent(res: http.ServerResponse, status: number): void {\n res.statusCode = status\n res.end()\n}\n\nfunction applyCorsHeaders(res: http.ServerResponse): void {\n for (const [key, value] of Object.entries(CORS_HEADERS)) {\n res.setHeader(key, value)\n }\n}\n\nclass BodyTooLargeError extends Error {}\n\nfunction readJsonBody(req: http.IncomingMessage, maxBodyKB: number): Promise<unknown> {\n const maxBytes = maxBodyKB * 1024\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = []\n let size = 0\n let finished = false\n\n req.on('data', (chunk) => {\n if (finished) return\n size += chunk.length\n if (size > maxBytes) {\n finished = true\n req.destroy()\n reject(new BodyTooLargeError())\n return\n }\n chunks.push(chunk)\n })\n\n req.on('end', () => {\n if (finished) return\n finished = true\n try {\n const raw = Buffer.concat(chunks).toString('utf8')\n resolve(raw.length === 0 ? {} : JSON.parse(raw))\n } catch (error) {\n reject(error)\n }\n })\n\n req.on('error', (error) => {\n if (finished) return\n finished = true\n reject(error)\n })\n })\n}\n","import net from 'node:net'\n\nexport async function resolvePort(host: string, port: number | undefined): Promise<number> {\n if (!port || port === 0) {\n return getRandomPort(host)\n }\n\n try {\n await checkPort(host, port)\n return port\n } catch {\n return getRandomPort(host)\n }\n}\n\nexport function formatBaseUrl(host: string, port: number): string {\n const needsBrackets = host.includes(':') && !host.startsWith('[')\n const safeHost = needsBrackets ? `[${host}]` : host\n return `http://${safeHost}:${port}`\n}\n\nfunction checkPort(host: string, port: number): Promise<void> {\n return new Promise((resolve, reject) => {\n const server = net.createServer()\n server.once('error', (error) => {\n server.close()\n reject(error)\n })\n server.listen(port, host, () => {\n server.close(() => resolve())\n })\n })\n}\n\nfunction getRandomPort(host: string): Promise<number> {\n return new Promise((resolve, reject) => {\n const server = net.createServer()\n server.once('error', (error) => {\n server.close()\n reject(error)\n })\n server.listen(0, host, () => {\n const address = server.address()\n if (!address || typeof address === 'string') {\n server.close(() => reject(new Error('Failed to resolve port')))\n return\n }\n const selected = address.port\n server.close(() => resolve(selected))\n })\n })\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\n\nexport function getPackageVersion(): string {\n try {\n const pkgPath = findPackageJsonPath()\n const raw = fs.readFileSync(pkgPath, 'utf8')\n const data = JSON.parse(raw) as { version?: string }\n return data.version ?? '0.0.0'\n } catch {\n return '0.0.0'\n }\n}\n\nfunction findPackageJsonPath(): string {\n let current = path.resolve(__dirname)\n for (let i = 0; i < 5; i += 1) {\n const candidate = path.join(current, 'package.json')\n if (fs.existsSync(candidate)) return candidate\n current = path.dirname(current)\n }\n return path.join(process.cwd(), 'package.json')\n}\n"],"mappings":"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","names":["import_promises","import_node_path","path","fs","import_promises","import_node_path","net","import_node_path","fs","path","http","fs","path","minimist","payload","scope","fs","path","os","readline","sleep","http"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/constants.ts","../src/skill.ts","../src/claude.ts","../src/process.ts","../src/paths.ts","../src/runtime.ts","../src/server.ts","../src/net.ts","../src/version.ts"],"sourcesContent":["#!/usr/bin/env node\nimport fs from 'node:fs/promises'\nimport os from 'node:os'\nimport path from 'node:path'\nimport readline from 'node:readline/promises'\nimport minimist from 'minimist'\nimport {\n DEFAULT_BASE_PATH,\n DEFAULT_HOST,\n DEFAULT_LOGS_DIR,\n DEFAULT_MAX_BODY_KB,\n DEFAULT_PORT,\n} from './constants'\nimport { claudeInstall, claudeRemove, claudeUpdate } from './claude'\nimport { installSkill, removeSkill } from './skill'\nimport { isProcessAlive, terminateProcess } from './process'\nimport { resolveLogsDir } from './paths'\nimport { RuntimeInfo, markStopped, readRuntime, removePid } from './runtime'\nimport { startServer } from './server'\n\nconst args = minimist(process.argv.slice(2), {\n boolean: ['json', 'force', 'help', 'user'],\n string: ['host', 'base-path', 'logs-dir', 'token'],\n alias: {\n h: 'help',\n u: 'user',\n },\n})\n\nconst primary = String(args._[0] ?? 'help')\nconst secondary = args._[1] ? String(args._[1]) : undefined\nconst scope = primary === 'server' || primary === 'codex' || primary === 'claude' ? primary : 'server'\nconst command =\n scope === 'server' ? String(primary === 'server' ? secondary ?? 'help' : primary) : String(secondary ?? 'help')\n\nconst json = Boolean(args.json)\nconst SKILL_NAME = 'code-debug-skill'\n\nvoid main().catch((error) => {\n outputError(error instanceof Error ? error.message : 'unexpected_error')\n process.exitCode = 1\n})\n\nasync function main(): Promise<void> {\n if (args.help || command === 'help') {\n printHelp()\n return\n }\n\n if (scope === 'codex') {\n await handleCodex(command)\n return\n }\n\n if (scope === 'claude') {\n await handleClaude(command)\n return\n }\n\n switch (command) {\n case 'start':\n await handleStart()\n return\n case 'run':\n if (!process.env.DEBUGSK_CHILD) {\n outputError('use_start_command')\n return\n }\n await handleRun()\n return\n case 'status':\n await handleStatus()\n return\n case 'stop':\n await handleStop()\n return\n default:\n outputError(`unknown_command:${command}`)\n }\n}\n\nfunction getCommonOptions() {\n const host = String(args.host ?? DEFAULT_HOST)\n const port = parseNumber(args.port, DEFAULT_PORT) ?? DEFAULT_PORT\n const basePath = String(args['base-path'] ?? DEFAULT_BASE_PATH)\n const logsDir = args['logs-dir'] ? String(args['logs-dir']) : undefined\n const maxBodyKB = parseNumber(args['max-body-kb'], DEFAULT_MAX_BODY_KB) ?? DEFAULT_MAX_BODY_KB\n const token = args.token ? String(args.token) : undefined\n const idleTtlMs = parseNumber(args['idle-ttl-ms'], undefined)\n return { host, port, basePath, logsDir, maxBodyKB, token, idleTtlMs }\n}\n\nasync function handleStart(): Promise<void> {\n const { host, port, basePath, logsDir, maxBodyKB, token, idleTtlMs } = getCommonOptions()\n const cwd = process.cwd()\n const resolvedLogsDir = resolveLogsDir({ cwd, logsDir })\n const runtime = await readRuntime(resolvedLogsDir)\n\n if (runtime && !runtime.options) {\n outputLegacyRuntimeError()\n return\n }\n\n if (runtime && isProcessAlive(runtime.pid) && !args.force) {\n const payload = buildStartOutput(runtime, true)\n outputStart(payload)\n return\n }\n\n if (runtime && isProcessAlive(runtime.pid) && args.force) {\n await terminateProcess(runtime.pid, 3000)\n await markStopped(resolvedLogsDir)\n await removePid(resolvedLogsDir)\n }\n\n if (runtime && !isProcessAlive(runtime.pid)) {\n await markStopped(resolvedLogsDir)\n await removePid(resolvedLogsDir)\n }\n\n const spawnResult = await spawnBackground({\n host,\n port,\n basePath,\n logsDir,\n maxBodyKB,\n token,\n idleTtlMs,\n })\n\n const finalRuntime = await waitForRuntime(resolvedLogsDir, 5000)\n if (!finalRuntime) {\n outputError('start_failed')\n return\n }\n\n const ok = await waitForHealth(finalRuntime, 5000)\n if (!ok) {\n outputError('health_check_failed')\n return\n }\n\n const payload = buildStartOutput(finalRuntime, false, spawnResult?.pid)\n outputStart(payload)\n}\n\nasync function handleRun(): Promise<void> {\n const { host, port, basePath, logsDir, maxBodyKB, token, idleTtlMs } = getCommonOptions()\n const cwd = process.cwd()\n\n const started = await startServer({\n host,\n port,\n basePath,\n logsDir,\n maxBodyKB,\n token,\n idleTtlMs,\n cwd,\n })\n\n installSignalHandlers(started.logsDir, started.close)\n\n if (!json) {\n logInfo(`debugsk server listening at ${started.baseUrl}`)\n }\n}\n\nasync function handleStatus(): Promise<void> {\n const cwd = process.cwd()\n const logsDir = args['logs-dir'] ? String(args['logs-dir']) : undefined\n const resolvedLogsDir = resolveLogsDir({ cwd, logsDir })\n const runtime = await readRuntime(resolvedLogsDir)\n\n if (!runtime) {\n outputStatus({ ok: false, running: false, error: 'not_running' })\n return\n }\n if (!runtime.options) {\n outputLegacyRuntimeError()\n return\n }\n\n const running = isProcessAlive(runtime.pid)\n const payload = {\n ...runtime,\n running,\n }\n outputStatus(payload)\n}\n\nasync function handleStop(): Promise<void> {\n const cwd = process.cwd()\n const logsDir = args['logs-dir'] ? String(args['logs-dir']) : undefined\n const resolvedLogsDir = resolveLogsDir({ cwd, logsDir })\n const runtime = await readRuntime(resolvedLogsDir)\n\n if (!runtime) {\n outputStop({ ok: true, stopped: false, running: false })\n return\n }\n\n const stopped = await terminateProcess(runtime.pid, 3000)\n if (stopped) {\n await markStopped(resolvedLogsDir)\n await removePid(resolvedLogsDir)\n }\n\n outputStop({ ok: true, stopped, pid: runtime.pid })\n}\n\nasync function handleCodex(subcommand: string): Promise<void> {\n const userScope = Boolean(args.user)\n switch (subcommand) {\n case 'install':\n await codexInstall(false, userScope)\n return\n case 'update':\n await codexInstall(true, userScope)\n return\n case 'remove':\n await codexRemove(userScope)\n return\n default:\n outputError(`unknown_command:codex:${subcommand}`)\n }\n}\n\nasync function handleClaude(subcommand: string): Promise<void> {\n const userScope = Boolean(args.user)\n switch (subcommand) {\n case 'install':\n await claudeInstall(false, userScope)\n return\n case 'update':\n await claudeUpdate(userScope)\n return\n case 'remove':\n await claudeRemove(userScope)\n return\n default:\n outputError(`unknown_command:claude:${subcommand}`)\n }\n}\n\nasync function codexInstall(force: boolean, userScope: boolean): Promise<void> {\n try {\n const result = await installSkill('codex', { force, userScope })\n outputJsonResult(result as unknown as Record<string, unknown>)\n } catch (error) {\n outputError(error instanceof Error ? error.message : 'unexpected_error')\n }\n}\n\nasync function codexRemove(userScope: boolean): Promise<void> {\n try {\n const result = await removeSkill('codex', { userScope })\n outputJsonResult(result as unknown as Record<string, unknown>)\n } catch (error) {\n outputError(error instanceof Error ? error.message : 'unexpected_error')\n }\n}\n\nasync function spawnBackground(options: {\n host: string\n port: number\n basePath: string\n logsDir?: string\n maxBodyKB: number\n token?: string\n idleTtlMs?: number\n}): Promise<{ pid: number } | null> {\n const nodeArgs = [...process.execArgv, process.argv[1]]\n const cmdArgs = ['run']\n\n cmdArgs.push('--host', options.host)\n cmdArgs.push('--port', String(options.port))\n cmdArgs.push('--base-path', options.basePath)\n cmdArgs.push('--max-body-kb', String(options.maxBodyKB))\n if (options.logsDir) cmdArgs.push('--logs-dir', options.logsDir)\n if (options.token) cmdArgs.push('--token', options.token)\n if (options.idleTtlMs) cmdArgs.push('--idle-ttl-ms', String(options.idleTtlMs))\n\n const spawn = await import('node:child_process')\n const child = spawn.spawn(process.execPath, [...nodeArgs, ...cmdArgs], {\n detached: true,\n stdio: 'ignore',\n env: {\n ...process.env,\n DEBUGSK_CHILD: '1',\n },\n })\n child.unref()\n return child.pid ? { pid: child.pid } : null\n}\n\nasync function waitForRuntime(logsDir: string, timeoutMs: number): Promise<RuntimeInfo | null> {\n const start = Date.now()\n while (Date.now() - start < timeoutMs) {\n const runtime = await readRuntime(logsDir)\n if (runtime && runtime.pid) return runtime\n await sleep(100)\n }\n return null\n}\n\nasync function waitForHealth(runtime: RuntimeInfo, timeoutMs: number): Promise<boolean> {\n const url = new URL(runtime.server.endpoints.health, runtime.server.baseUrl)\n const start = Date.now()\n while (Date.now() - start < timeoutMs) {\n const ok = await checkHealth(url)\n if (ok) return true\n await sleep(100)\n }\n return false\n}\n\nasync function checkHealth(url: URL): Promise<boolean> {\n const http = await import('node:http')\n return new Promise((resolve) => {\n const req = http.get(url, (res) => {\n res.resume()\n resolve(res.statusCode === 200)\n })\n req.on('error', () => resolve(false))\n })\n}\n\nfunction buildStartOutput(runtime: RuntimeInfo, existing: boolean, spawnedPid?: number) {\n const ingestPath = runtime.server.endpoints.ingestTemplate\n const ingestUrl = new URL(ingestPath.replace('{streamId}', '{streamId}'), runtime.server.baseUrl)\n const snippetHeaders: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n const tokenEnabled = runtime.options.tokenEnabled\n if (tokenEnabled) {\n snippetHeaders.Authorization = 'Bearer YOUR_TOKEN'\n }\n\n const jsFetch = `fetch(\"${ingestUrl.toString()}\",{method:\"POST\",headers:${JSON.stringify(\n snippetHeaders,\n )},body:JSON.stringify({...})}).catch(()=>{});`\n\n return {\n ok: true,\n version: runtime.version,\n pid: runtime.pid,\n cwd: runtime.cwd,\n logsDir: runtime.logsDir,\n server: {\n host: runtime.server.host,\n port: runtime.server.port,\n baseUrl: runtime.server.baseUrl,\n endpoints: runtime.server.endpoints,\n },\n snippets: {\n jsFetch,\n },\n existing,\n spawnedPid,\n }\n}\n\nfunction installSignalHandlers(logsDir: string, close: () => Promise<void>): void {\n const shutdown = async () => {\n await close()\n await markStopped(logsDir)\n await removePid(logsDir)\n process.exit(0)\n }\n\n process.on('SIGTERM', () => void shutdown())\n process.on('SIGINT', () => void shutdown())\n}\n\nfunction outputJson(payload: unknown): void {\n process.stdout.write(`${JSON.stringify(payload)}\\n`)\n}\n\nfunction outputJsonResult(payload: Record<string, unknown>): void {\n if (json) {\n outputJson(payload)\n return\n }\n const action = String(payload.action ?? 'result')\n const ok = payload.ok ? 'ok' : 'error'\n const dest = payload.dest ? `dest=${payload.dest}` : ''\n process.stdout.write(`${action} ${ok} ${dest}\\n`)\n}\n\nfunction outputError(message: string): void {\n if (json) {\n outputJson({ ok: false, error: message })\n } else {\n process.stderr.write(`${message}\\n`)\n }\n}\n\nfunction outputLegacyRuntimeError(): void {\n const error = 'legacy_runtime_incompatible'\n const hint = 'delete .logs/runtime.json or the entire .logs directory, then retry'\n if (json) {\n outputJson({ ok: false, error, hint })\n } else {\n process.stderr.write(`${error}: ${hint}\\n`)\n }\n}\n\nfunction logInfo(message: string): void {\n process.stderr.write(`${message}\\n`)\n}\n\nfunction outputStart(payload: Record<string, unknown>): void {\n if (json) {\n outputJson(payload)\n return\n }\n const server = payload.server as RuntimeInfo['server']\n const pid = payload.pid as number\n const logsDir = payload.logsDir as string\n process.stdout.write(\n `started pid=${pid} baseUrl=${server.baseUrl} logsDir=${logsDir}\\n`,\n )\n}\n\nfunction outputStatus(payload: Record<string, unknown>): void {\n if (json) {\n outputJson(payload)\n return\n }\n const running = payload.running ? 'running' : 'stopped'\n const pid = payload.pid ? `pid=${payload.pid}` : 'pid=unknown'\n process.stdout.write(`status ${running} ${pid}\\n`)\n}\n\nfunction outputStop(payload: Record<string, unknown>): void {\n if (json) {\n outputJson(payload)\n return\n }\n const stopped = payload.stopped ? 'stopped' : 'not-stopped'\n const pid = payload.pid ? `pid=${payload.pid}` : ''\n process.stdout.write(`stop ${stopped} ${pid}\\n`)\n}\n\nfunction printHelp(): void {\n const text = `debugsk\n\nUsage:\n server start --json Start server in background and print JSON\n server status --json Show server status\n server stop --json Stop background server\n\n codex install Install Codex skill (user scope)\n codex update Update Codex skill (user scope)\n codex remove Remove Codex skill (user scope)\n\n claude install Install Claude skill (user scope)\n claude update Update Claude skill (user scope)\n claude remove Remove Claude skill (user scope)\n\nAliases:\n start/status/stop Same as \"server <command>\"\n\nOptions:\n --host (default ${DEFAULT_HOST})\n --port (default ${DEFAULT_PORT})\n --base-path (default ${DEFAULT_BASE_PATH})\n --logs-dir (default ${DEFAULT_LOGS_DIR})\n --max-body-kb (default ${DEFAULT_MAX_BODY_KB})\n --token (optional)\n --idle-ttl-ms (optional)\n --force (restart even if already running)\n --json (stdout JSON only)\n -u, --user (install skill to user scope)\n`\n if (json) {\n outputJson({ ok: true, help: text })\n } else {\n process.stdout.write(`${text}\\n`)\n }\n}\n\nfunction parseNumber(value: unknown, fallback: number | undefined): number | undefined {\n if (value === undefined || value === null || value === '') {\n return fallback\n }\n const parsed = Number(value)\n if (Number.isFinite(parsed)) return parsed\n return fallback\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n","export const DEFAULT_HOST = '127.0.0.1'\nexport const DEFAULT_PORT = 7242\nexport const DEFAULT_BASE_PATH = '/'\nexport const DEFAULT_LOGS_DIR = '.logs'\nexport const DEFAULT_MAX_BODY_KB = 256\n","import fs from 'node:fs/promises'\nimport os from 'node:os'\nimport path from 'node:path'\nimport readline from 'node:readline/promises'\n\nexport type Platform = 'codex' | 'claude'\n\nexport interface PlatformConfig {\n home: string\n skillName: string\n projectLocal: string\n}\n\nexport const PLATFORMS: Record<Platform, PlatformConfig> = {\n codex: {\n home: '.codex',\n skillName: 'code-debug-skill',\n projectLocal: '.codex/skills',\n },\n claude: {\n home: '.claude',\n skillName: 'code-debug-skill',\n projectLocal: '.claude/skills',\n },\n}\n\nexport interface InstallOptions {\n force?: boolean\n userScope?: boolean\n}\n\nexport interface RemoveOptions {\n userScope?: boolean\n}\n\nexport interface InstallResult {\n ok: boolean\n action: 'install' | 'update'\n scope: 'user' | 'local'\n dest: string\n source: string\n replaced: boolean\n}\n\nexport interface RemoveResult {\n ok: boolean\n action: 'remove'\n scope: 'user' | 'local'\n dest: string\n removed: boolean\n reason?: string\n}\n\nexport async function resolveSkillSource(skillName: string = 'code-debug-skill'): Promise<string> {\n const packageRoot = path.resolve(__dirname, '..')\n const repoRoot = path.resolve(packageRoot, '..', '..')\n const repoSource = path.join(repoRoot, 'skills', skillName)\n if (await pathExists(repoSource)) return repoSource\n const packaged = path.join(packageRoot, 'skills', skillName)\n if (await pathExists(packaged)) return packaged\n throw new Error(`missing_skill_source:${skillName}`)\n}\n\nexport async function resolveSkillDest(\n platform: Platform,\n options: { userScope?: boolean; createIfMissing?: boolean } = {},\n): Promise<{ dest: string; scope: 'user' | 'local'; homeExists: boolean }> {\n const config = PLATFORMS[platform]\n const useUser = Boolean(options.userScope)\n const scope: 'user' | 'local' = useUser ? 'user' : 'local'\n\n const platformHome = useUser\n ? path.join(os.homedir(), config.home)\n : path.join(process.cwd(), config.projectLocal.split('/')[0])\n\n const exists = await pathExists(platformHome)\n if (!exists && options.createIfMissing) {\n await ensurePlatformHome(platform, platformHome, scope)\n }\n\n const skillsDir = useUser ? path.join(platformHome, 'skills') : path.join(platformHome, 'skills')\n return {\n dest: path.join(skillsDir, config.skillName),\n scope,\n homeExists: exists,\n }\n}\n\nexport async function installSkill(\n platform: Platform,\n options: InstallOptions = {},\n): Promise<InstallResult> {\n const config = PLATFORMS[platform]\n const source = await resolveSkillSource(config.skillName)\n const { dest, scope } = await resolveSkillDest(platform, {\n userScope: options.userScope,\n createIfMissing: true,\n })\n const exists = await pathExists(dest)\n\n if (exists && !options.force) {\n throw new Error(`${platform}_skill_already_installed`)\n }\n\n await ensureSafeDest(dest)\n if (exists) {\n await fs.rm(dest, { recursive: true, force: true })\n }\n\n await fs.mkdir(path.dirname(dest), { recursive: true })\n await fs.cp(source, dest, { recursive: true })\n\n return {\n ok: true,\n action: options.force ? 'update' : 'install',\n scope,\n dest,\n source,\n replaced: exists,\n }\n}\n\nexport async function removeSkill(\n platform: Platform,\n options: RemoveOptions = {},\n): Promise<RemoveResult> {\n const config = PLATFORMS[platform]\n const { dest, scope, homeExists } = await resolveSkillDest(platform, {\n userScope: options.userScope,\n createIfMissing: false,\n })\n\n if (!homeExists) {\n return {\n ok: true,\n action: 'remove',\n scope,\n dest,\n removed: false,\n reason: `${platform}_home_missing`,\n }\n }\n\n await ensureSafeDest(dest)\n const exists = await pathExists(dest)\n if (exists) {\n await fs.rm(dest, { recursive: true, force: true })\n }\n\n return {\n ok: true,\n action: 'remove',\n scope,\n dest,\n removed: exists,\n }\n}\n\nexport async function ensureSafeDest(dest: string): Promise<void> {\n const resolved = path.resolve(dest)\n const root = path.parse(resolved).root\n if (resolved === root || resolved === os.homedir()) {\n throw new Error('unsafe_dest')\n }\n}\n\nasync function ensurePlatformHome(\n platform: Platform,\n platformHome: string,\n scope: 'user' | 'local',\n): Promise<void> {\n if (await pathExists(platformHome)) return\n if (!process.stdin.isTTY) {\n throw new Error(`${platform}_home_missing`)\n }\n const prompt = `Create ${platformHome} for ${scope} scope? [y/N]: `\n const approved = await confirmPrompt(prompt)\n if (!approved) {\n throw new Error(`${platform}_home_missing`)\n }\n await fs.mkdir(platformHome, { recursive: true })\n}\n\nasync function confirmPrompt(prompt: string): Promise<boolean> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stderr })\n const answer = await rl.question(prompt)\n rl.close()\n return /^y(es)?$/i.test(answer.trim())\n}\n\nexport async function pathExists(target: string): Promise<boolean> {\n try {\n await fs.access(target)\n return true\n } catch {\n return false\n }\n}\n","import { installSkill, removeSkill } from './skill'\n\nexport async function claudeInstall(force: boolean, userScope: boolean): Promise<void> {\n try {\n const result = await installSkill('claude', { force, userScope })\n outputJsonResult(result)\n } catch (error) {\n outputError(error instanceof Error ? error.message : 'unexpected_error')\n }\n}\n\nexport async function claudeUpdate(userScope: boolean): Promise<void> {\n await claudeInstall(true, userScope)\n}\n\nexport async function claudeRemove(userScope: boolean): Promise<void> {\n try {\n const result = await removeSkill('claude', { userScope })\n outputJsonResult(result)\n } catch (error) {\n outputError(error instanceof Error ? error.message : 'unexpected_error')\n }\n}\n\nfunction outputJsonResult(payload: {\n ok: boolean\n action: string\n scope: string\n dest: string\n removed?: boolean\n replaced?: boolean\n reason?: string\n}): void {\n const action = String(payload.action ?? 'result')\n const ok = payload.ok ? 'ok' : 'error'\n const dest = payload.dest ? `dest=${payload.dest}` : ''\n const status = payload.removed !== undefined ? (payload.removed ? 'removed' : 'not-removed') : ''\n const replaced = payload.replaced !== undefined ? (payload.replaced ? 'replaced' : 'new') : ''\n const reason = payload.reason ? `reason=${payload.reason}` : ''\n const parts = [action, ok, dest, status, replaced, reason].filter(Boolean)\n process.stdout.write(`${parts.join(' ')}\\n`)\n}\n\nfunction outputError(message: string): void {\n process.stderr.write(`${message}\\n`)\n}\n","export function isProcessAlive(pid: number): boolean {\n if (!pid) return false\n try {\n process.kill(pid, 0)\n return true\n } catch (error) {\n const err = error as NodeJS.ErrnoException\n return err.code === 'EPERM'\n }\n}\n\nexport async function terminateProcess(pid: number, timeoutMs: number): Promise<boolean> {\n if (!isProcessAlive(pid)) return true\n try {\n process.kill(pid, 'SIGTERM')\n } catch (error) {\n const err = error as NodeJS.ErrnoException\n if (err.code === 'ESRCH') return true\n }\n\n const start = Date.now()\n while (Date.now() - start < timeoutMs) {\n if (!isProcessAlive(pid)) return true\n await sleep(100)\n }\n\n try {\n process.kill(pid, 'SIGKILL')\n } catch (error) {\n const err = error as NodeJS.ErrnoException\n if (err.code === 'ESRCH') return true\n }\n\n return !isProcessAlive(pid)\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n","import path from 'node:path'\nimport { DEFAULT_LOGS_DIR } from './constants'\n\ntype PathOptions = {\n cwd: string\n logsDir?: string\n}\n\nexport function resolveLogsDir({ cwd, logsDir }: PathOptions): string {\n const dir = logsDir && logsDir.length > 0 ? logsDir : DEFAULT_LOGS_DIR\n return path.resolve(cwd, dir)\n}\n\nexport function getRuntimeDir(logsDir: string): string {\n return logsDir\n}\n\nexport function getRuntimePath(logsDir: string): string {\n return path.join(getRuntimeDir(logsDir), 'runtime.json')\n}\n\nexport function getPidPath(logsDir: string): string {\n return path.join(getRuntimeDir(logsDir), 'server.pid')\n}\n\nexport function getSessionLogPath(\n logsDir: string,\n sessionId: string,\n runId: string,\n): string {\n const safeSession = sanitizePathSegment(sessionId)\n const safeRun = sanitizePathSegment(runId)\n return path.join(getRuntimeDir(logsDir), `${safeSession}-${safeRun}.jsonl`)\n}\n\nfunction sanitizePathSegment(value: string): string {\n return value.replace(/[\\\\/]/g, '_').replace(/\\.\\./g, '_').trim() || 'unknown'\n}\n","import fs from 'node:fs/promises'\nimport { getPidPath, getRuntimeDir, getRuntimePath } from './paths'\n\nexport type RuntimeInfo = {\n ok: boolean\n version: string\n pid: number\n cwd: string\n logsDir: string\n running: boolean\n server: {\n host: string\n port: number\n baseUrl: string\n basePath: string\n endpoints: {\n health: string\n ingestTemplate: string\n }\n }\n startedAt: string\n stoppedAt?: string\n options: {\n maxBodyKB: number\n tokenEnabled: boolean\n idleTtlMs?: number\n }\n}\n\nexport async function readRuntime(logsDir: string): Promise<RuntimeInfo | null> {\n try {\n const raw = await fs.readFile(getRuntimePath(logsDir), 'utf8')\n return JSON.parse(raw) as RuntimeInfo\n } catch {\n return null\n }\n}\n\nexport async function writeRuntime(logsDir: string, info: RuntimeInfo): Promise<void> {\n await fs.mkdir(getRuntimeDir(logsDir), { recursive: true })\n await fs.writeFile(getRuntimePath(logsDir), JSON.stringify(info, null, 2), 'utf8')\n}\n\nexport async function writePid(logsDir: string, pid: number): Promise<void> {\n await fs.mkdir(getRuntimeDir(logsDir), { recursive: true })\n await fs.writeFile(getPidPath(logsDir), String(pid), 'utf8')\n}\n\nexport async function removePid(logsDir: string): Promise<void> {\n try {\n await fs.unlink(getPidPath(logsDir))\n } catch {\n return\n }\n}\n\nexport async function markStopped(logsDir: string): Promise<void> {\n const current = await readRuntime(logsDir)\n if (!current) return\n const updated: RuntimeInfo = {\n ...current,\n running: false,\n stoppedAt: new Date().toISOString(),\n }\n await writeRuntime(logsDir, updated)\n}\n","import http from 'node:http'\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\nimport { formatBaseUrl, resolvePort } from './net'\nimport { getSessionLogPath, resolveLogsDir } from './paths'\nimport { RuntimeInfo, markStopped, removePid, writePid, writeRuntime } from './runtime'\nimport { getPackageVersion } from './version'\n\nexport type StartOptions = {\n host: string\n port?: number\n basePath: string\n logsDir?: string\n maxBodyKB: number\n token?: string\n idleTtlMs?: number\n cwd: string\n}\n\nexport type StartedServer = {\n server: http.Server\n host: string\n port: number\n basePath: string\n baseUrl: string\n logsDir: string\n close: () => Promise<void>\n}\n\n// Note: While these fields should always be provided for proper investigation,\n// the server will use fallback values if missing to ensure no logs are lost.\nconst LOG_FIELDS = ['timestamp', 'message', 'sessionId', 'runId', 'hypothesisId'] as const\nconst CORS_HEADERS = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET,POST,OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Debug-Token',\n 'Access-Control-Max-Age': '86400',\n} as const\n\nexport async function startServer(options: StartOptions): Promise<StartedServer> {\n const logsDir = resolveLogsDir({ cwd: options.cwd, logsDir: options.logsDir })\n const host = options.host\n const basePath = normalizeBasePath(options.basePath)\n const port = await resolvePort(host, options.port)\n const baseUrl = formatBaseUrl(host, port)\n\n let idleTimer: NodeJS.Timeout | undefined\n const server = http.createServer(async (req, res) => {\n applyCorsHeaders(res)\n try {\n const url = new URL(req.url ?? '/', baseUrl)\n const normalizedPath = stripBasePath(url.pathname, basePath)\n\n if (normalizedPath == null) {\n respondJson(res, 404, { ok: false, error: 'not_found' })\n return\n }\n\n if (req.method === 'OPTIONS') {\n respondNoContent(res, 204)\n return\n }\n\n if (req.method === 'GET' && normalizedPath === '/health') {\n respondJson(res, 200, { ok: true })\n return\n }\n\n if (req.method === 'POST' && normalizedPath.startsWith('/ingest/')) {\n const streamId = decodeURIComponent(normalizedPath.replace('/ingest/', ''))\n if (!authorizeRequest(req, options.token)) {\n respondJson(res, 401, { ok: false, error: 'unauthorized' })\n return\n }\n\n let payload: unknown\n try {\n payload = await readJsonBody(req, options.maxBodyKB)\n } catch (error) {\n if (error instanceof BodyTooLargeError) {\n respondJson(res, 413, { ok: false, error: 'body_too_large' })\n return\n }\n respondJson(res, 400, { ok: false, error: 'invalid_json' })\n return\n }\n\n if (!payload || typeof payload !== 'object') {\n respondJson(res, 400, { ok: false, error: 'invalid_body' })\n return\n }\n\n const event = payload as Record<string, unknown>\n\n // Apply fallback values for missing fields to ensure no logs are lost\n const timestamp = 'timestamp' in event ? event.timestamp : Date.now()\n const message = 'message' in event ? event.message : ''\n const sessionId = 'sessionId' in event ? String(event.sessionId) : ''\n const runId = 'runId' in event ? String(event.runId) : ''\n const hypothesisId = 'hypothesisId' in event ? String(event.hypothesisId) : ''\n\n const enriched = {\n timestamp,\n message,\n sessionId,\n runId,\n hypothesisId,\n ...event, // Original values take precedence if present\n _meta: {\n streamId,\n receivedAt: Date.now(),\n },\n }\n const logPath = getSessionLogPath(logsDir, sessionId, runId)\n await fs.mkdir(path.dirname(logPath), { recursive: true })\n\n await fs.appendFile(logPath, `${JSON.stringify(enriched)}\\n`, 'utf8')\n\n if (options.idleTtlMs && options.idleTtlMs > 0) {\n resetIdleTimer(options.idleTtlMs)\n }\n\n respondJson(res, 200, { ok: true, written: true, path: logPath })\n return\n }\n\n respondJson(res, 404, { ok: false, error: 'not_found' })\n } catch {\n respondJson(res, 500, { ok: false, error: 'internal_error' })\n }\n })\n\n const close = async (): Promise<void> => {\n if (idleTimer) clearTimeout(idleTimer)\n await new Promise<void>((resolve, reject) => {\n server.close((err) => {\n if (err) reject(err)\n else resolve()\n })\n })\n }\n\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject)\n server.listen(port, host, () => resolve())\n })\n\n const runtime: RuntimeInfo = {\n ok: true,\n version: getPackageVersion(),\n pid: process.pid,\n cwd: options.cwd,\n logsDir,\n running: true,\n server: {\n host,\n port,\n baseUrl,\n basePath,\n endpoints: {\n health: `${basePath}/health`,\n ingestTemplate: `${basePath}/ingest/{streamId}`,\n },\n },\n startedAt: new Date().toISOString(),\n options: {\n maxBodyKB: options.maxBodyKB,\n tokenEnabled: Boolean(options.token),\n idleTtlMs: options.idleTtlMs,\n },\n }\n\n await writeRuntime(logsDir, runtime)\n await writePid(logsDir, process.pid)\n\n if (options.idleTtlMs && options.idleTtlMs > 0) {\n resetIdleTimer(options.idleTtlMs)\n }\n\n return { server, host, port, basePath, baseUrl, logsDir, close }\n\n function resetIdleTimer(ttl: number): void {\n if (idleTimer) clearTimeout(idleTimer)\n idleTimer = setTimeout(async () => {\n await close()\n await markStopped(logsDir)\n await removePid(logsDir)\n process.exit(0)\n }, ttl)\n }\n}\n\nfunction normalizeBasePath(basePath: string): string {\n if (!basePath || basePath === '/') return ''\n const trimmed = basePath.startsWith('/') ? basePath : `/${basePath}`\n return trimmed.endsWith('/') ? trimmed.slice(0, -1) : trimmed\n}\n\nfunction stripBasePath(pathname: string, basePath: string): string | null {\n if (!basePath) return pathname\n if (!pathname.startsWith(basePath)) return null\n const sliced = pathname.slice(basePath.length)\n return sliced.length === 0 ? '/' : sliced\n}\n\nfunction authorizeRequest(req: http.IncomingMessage, token?: string): boolean {\n if (!token) return true\n const authHeader = req.headers.authorization\n if (authHeader && authHeader === `Bearer ${token}`) return true\n const headerToken = req.headers['x-debug-token']\n if (typeof headerToken === 'string' && headerToken === token) return true\n return false\n}\n\nfunction respondJson(res: http.ServerResponse, status: number, payload: unknown): void {\n const data = JSON.stringify(payload)\n res.statusCode = status\n res.setHeader('Content-Type', 'application/json')\n res.setHeader('Content-Length', Buffer.byteLength(data))\n res.end(data)\n}\n\nfunction respondNoContent(res: http.ServerResponse, status: number): void {\n res.statusCode = status\n res.end()\n}\n\nfunction applyCorsHeaders(res: http.ServerResponse): void {\n for (const [key, value] of Object.entries(CORS_HEADERS)) {\n res.setHeader(key, value)\n }\n}\n\nclass BodyTooLargeError extends Error {}\n\nfunction readJsonBody(req: http.IncomingMessage, maxBodyKB: number): Promise<unknown> {\n const maxBytes = maxBodyKB * 1024\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = []\n let size = 0\n let finished = false\n\n req.on('data', (chunk) => {\n if (finished) return\n size += chunk.length\n if (size > maxBytes) {\n finished = true\n req.destroy()\n reject(new BodyTooLargeError())\n return\n }\n chunks.push(chunk)\n })\n\n req.on('end', () => {\n if (finished) return\n finished = true\n try {\n const raw = Buffer.concat(chunks).toString('utf8')\n resolve(raw.length === 0 ? {} : JSON.parse(raw))\n } catch (error) {\n reject(error)\n }\n })\n\n req.on('error', (error) => {\n if (finished) return\n finished = true\n reject(error)\n })\n })\n}\n","import net from 'node:net'\n\nexport async function resolvePort(host: string, port: number | undefined): Promise<number> {\n if (!port || port === 0) {\n return getRandomPort(host)\n }\n\n try {\n await checkPort(host, port)\n return port\n } catch {\n return getRandomPort(host)\n }\n}\n\nexport function formatBaseUrl(host: string, port: number): string {\n const needsBrackets = host.includes(':') && !host.startsWith('[')\n const safeHost = needsBrackets ? `[${host}]` : host\n return `http://${safeHost}:${port}`\n}\n\nfunction checkPort(host: string, port: number): Promise<void> {\n return new Promise((resolve, reject) => {\n const server = net.createServer()\n server.once('error', (error) => {\n server.close()\n reject(error)\n })\n server.listen(port, host, () => {\n server.close(() => resolve())\n })\n })\n}\n\nfunction getRandomPort(host: string): Promise<number> {\n return new Promise((resolve, reject) => {\n const server = net.createServer()\n server.once('error', (error) => {\n server.close()\n reject(error)\n })\n server.listen(0, host, () => {\n const address = server.address()\n if (!address || typeof address === 'string') {\n server.close(() => reject(new Error('Failed to resolve port')))\n return\n }\n const selected = address.port\n server.close(() => resolve(selected))\n })\n })\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\n\nexport function getPackageVersion(): string {\n try {\n const pkgPath = findPackageJsonPath()\n const raw = fs.readFileSync(pkgPath, 'utf8')\n const data = JSON.parse(raw) as { version?: string }\n return data.version ?? '0.0.0'\n } catch {\n return '0.0.0'\n }\n}\n\nfunction findPackageJsonPath(): string {\n let current = path.resolve(__dirname)\n for (let i = 0; i < 5; i += 1) {\n const candidate = path.join(current, 'package.json')\n if (fs.existsSync(candidate)) return candidate\n current = path.dirname(current)\n }\n return path.join(process.cwd(), 'package.json')\n}\n"],"mappings":"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","names":["import_promises","path","scope","os","fs","readline","import_node_path","path","import_promises","fs","import_promises","import_node_path","net","import_node_path","fs","path","http","fs","path","minimist","outputError","payload","outputJsonResult","sleep","http"]}
package/dist/index.js CHANGED
@@ -186,7 +186,6 @@ function findPackageJsonPath() {
186
186
  }
187
187
 
188
188
  // src/server.ts
189
- var REQUIRED_FIELDS = ["timestamp", "message", "sessionId", "runId", "hypothesisId"];
190
189
  var CORS_HEADERS = {
191
190
  "Access-Control-Allow-Origin": "*",
192
191
  "Access-Control-Allow-Methods": "GET,POST,OPTIONS",
@@ -238,23 +237,27 @@ async function startServer(options) {
238
237
  respondJson(res, 400, { ok: false, error: "invalid_body" });
239
238
  return;
240
239
  }
241
- const missing = REQUIRED_FIELDS.filter((field) => !(field in payload));
242
- if (missing.length > 0) {
243
- respondJson(res, 400, { ok: false, error: "missing_fields", missing });
244
- return;
245
- }
246
240
  const event = payload;
247
- const sessionId = String(event.sessionId);
248
- const runId = String(event.runId);
249
- const logPath = getSessionLogPath(logsDir, sessionId, runId);
250
- await import_promises2.default.mkdir(import_node_path3.default.dirname(logPath), { recursive: true });
241
+ const timestamp = "timestamp" in event ? event.timestamp : Date.now();
242
+ const message = "message" in event ? event.message : "";
243
+ const sessionId = "sessionId" in event ? String(event.sessionId) : "";
244
+ const runId = "runId" in event ? String(event.runId) : "";
245
+ const hypothesisId = "hypothesisId" in event ? String(event.hypothesisId) : "";
251
246
  const enriched = {
247
+ timestamp,
248
+ message,
249
+ sessionId,
250
+ runId,
251
+ hypothesisId,
252
252
  ...event,
253
+ // Original values take precedence if present
253
254
  _meta: {
254
255
  streamId,
255
256
  receivedAt: Date.now()
256
257
  }
257
258
  };
259
+ const logPath = getSessionLogPath(logsDir, sessionId, runId);
260
+ await import_promises2.default.mkdir(import_node_path3.default.dirname(logPath), { recursive: true });
258
261
  await import_promises2.default.appendFile(logPath, `${JSON.stringify(enriched)}
259
262
  `, "utf8");
260
263
  if (options.idleTtlMs && options.idleTtlMs > 0) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/server.ts","../src/net.ts","../src/paths.ts","../src/constants.ts","../src/runtime.ts","../src/version.ts"],"sourcesContent":["export { startServer, type StartOptions, type StartedServer } from './server'\nexport {\n DEFAULT_BASE_PATH,\n DEFAULT_HOST,\n DEFAULT_LOGS_DIR,\n DEFAULT_MAX_BODY_KB,\n DEFAULT_PORT,\n} from './constants'\n","import http from 'node:http'\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\nimport { formatBaseUrl, resolvePort } from './net'\nimport { getSessionLogPath, resolveLogsDir } from './paths'\nimport { RuntimeInfo, markStopped, removePid, writePid, writeRuntime } from './runtime'\nimport { getPackageVersion } from './version'\n\nexport type StartOptions = {\n host: string\n port?: number\n basePath: string\n logsDir?: string\n maxBodyKB: number\n token?: string\n idleTtlMs?: number\n cwd: string\n}\n\nexport type StartedServer = {\n server: http.Server\n host: string\n port: number\n basePath: string\n baseUrl: string\n logsDir: string\n close: () => Promise<void>\n}\n\nconst REQUIRED_FIELDS = ['timestamp', 'message', 'sessionId', 'runId', 'hypothesisId'] as const\nconst CORS_HEADERS = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET,POST,OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Debug-Token',\n 'Access-Control-Max-Age': '86400',\n} as const\n\nexport async function startServer(options: StartOptions): Promise<StartedServer> {\n const logsDir = resolveLogsDir({ cwd: options.cwd, logsDir: options.logsDir })\n const host = options.host\n const basePath = normalizeBasePath(options.basePath)\n const port = await resolvePort(host, options.port)\n const baseUrl = formatBaseUrl(host, port)\n\n let idleTimer: NodeJS.Timeout | undefined\n const server = http.createServer(async (req, res) => {\n applyCorsHeaders(res)\n try {\n const url = new URL(req.url ?? '/', baseUrl)\n const normalizedPath = stripBasePath(url.pathname, basePath)\n\n if (normalizedPath == null) {\n respondJson(res, 404, { ok: false, error: 'not_found' })\n return\n }\n\n if (req.method === 'OPTIONS') {\n respondNoContent(res, 204)\n return\n }\n\n if (req.method === 'GET' && normalizedPath === '/health') {\n respondJson(res, 200, { ok: true })\n return\n }\n\n if (req.method === 'POST' && normalizedPath.startsWith('/ingest/')) {\n const streamId = decodeURIComponent(normalizedPath.replace('/ingest/', ''))\n if (!authorizeRequest(req, options.token)) {\n respondJson(res, 401, { ok: false, error: 'unauthorized' })\n return\n }\n\n let payload: unknown\n try {\n payload = await readJsonBody(req, options.maxBodyKB)\n } catch (error) {\n if (error instanceof BodyTooLargeError) {\n respondJson(res, 413, { ok: false, error: 'body_too_large' })\n return\n }\n respondJson(res, 400, { ok: false, error: 'invalid_json' })\n return\n }\n\n if (!payload || typeof payload !== 'object') {\n respondJson(res, 400, { ok: false, error: 'invalid_body' })\n return\n }\n\n const missing = REQUIRED_FIELDS.filter((field) => !(field in payload))\n if (missing.length > 0) {\n respondJson(res, 400, { ok: false, error: 'missing_fields', missing })\n return\n }\n\n const event = payload as Record<string, unknown>\n const sessionId = String(event.sessionId)\n const runId = String(event.runId)\n const logPath = getSessionLogPath(logsDir, sessionId, runId)\n await fs.mkdir(path.dirname(logPath), { recursive: true })\n\n const enriched = {\n ...event,\n _meta: {\n streamId,\n receivedAt: Date.now(),\n },\n }\n\n await fs.appendFile(logPath, `${JSON.stringify(enriched)}\\n`, 'utf8')\n\n if (options.idleTtlMs && options.idleTtlMs > 0) {\n resetIdleTimer(options.idleTtlMs)\n }\n\n respondJson(res, 200, { ok: true, written: true, path: logPath })\n return\n }\n\n respondJson(res, 404, { ok: false, error: 'not_found' })\n } catch {\n respondJson(res, 500, { ok: false, error: 'internal_error' })\n }\n })\n\n const close = async (): Promise<void> => {\n if (idleTimer) clearTimeout(idleTimer)\n await new Promise<void>((resolve, reject) => {\n server.close((err) => {\n if (err) reject(err)\n else resolve()\n })\n })\n }\n\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject)\n server.listen(port, host, () => resolve())\n })\n\n const runtime: RuntimeInfo = {\n ok: true,\n version: getPackageVersion(),\n pid: process.pid,\n cwd: options.cwd,\n logsDir,\n running: true,\n server: {\n host,\n port,\n baseUrl,\n basePath,\n endpoints: {\n health: `${basePath}/health`,\n ingestTemplate: `${basePath}/ingest/{streamId}`,\n },\n },\n startedAt: new Date().toISOString(),\n options: {\n maxBodyKB: options.maxBodyKB,\n tokenEnabled: Boolean(options.token),\n idleTtlMs: options.idleTtlMs,\n },\n }\n\n await writeRuntime(logsDir, runtime)\n await writePid(logsDir, process.pid)\n\n if (options.idleTtlMs && options.idleTtlMs > 0) {\n resetIdleTimer(options.idleTtlMs)\n }\n\n return { server, host, port, basePath, baseUrl, logsDir, close }\n\n function resetIdleTimer(ttl: number): void {\n if (idleTimer) clearTimeout(idleTimer)\n idleTimer = setTimeout(async () => {\n await close()\n await markStopped(logsDir)\n await removePid(logsDir)\n process.exit(0)\n }, ttl)\n }\n}\n\nfunction normalizeBasePath(basePath: string): string {\n if (!basePath || basePath === '/') return ''\n const trimmed = basePath.startsWith('/') ? basePath : `/${basePath}`\n return trimmed.endsWith('/') ? trimmed.slice(0, -1) : trimmed\n}\n\nfunction stripBasePath(pathname: string, basePath: string): string | null {\n if (!basePath) return pathname\n if (!pathname.startsWith(basePath)) return null\n const sliced = pathname.slice(basePath.length)\n return sliced.length === 0 ? '/' : sliced\n}\n\nfunction authorizeRequest(req: http.IncomingMessage, token?: string): boolean {\n if (!token) return true\n const authHeader = req.headers.authorization\n if (authHeader && authHeader === `Bearer ${token}`) return true\n const headerToken = req.headers['x-debug-token']\n if (typeof headerToken === 'string' && headerToken === token) return true\n return false\n}\n\nfunction respondJson(res: http.ServerResponse, status: number, payload: unknown): void {\n const data = JSON.stringify(payload)\n res.statusCode = status\n res.setHeader('Content-Type', 'application/json')\n res.setHeader('Content-Length', Buffer.byteLength(data))\n res.end(data)\n}\n\nfunction respondNoContent(res: http.ServerResponse, status: number): void {\n res.statusCode = status\n res.end()\n}\n\nfunction applyCorsHeaders(res: http.ServerResponse): void {\n for (const [key, value] of Object.entries(CORS_HEADERS)) {\n res.setHeader(key, value)\n }\n}\n\nclass BodyTooLargeError extends Error {}\n\nfunction readJsonBody(req: http.IncomingMessage, maxBodyKB: number): Promise<unknown> {\n const maxBytes = maxBodyKB * 1024\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = []\n let size = 0\n let finished = false\n\n req.on('data', (chunk) => {\n if (finished) return\n size += chunk.length\n if (size > maxBytes) {\n finished = true\n req.destroy()\n reject(new BodyTooLargeError())\n return\n }\n chunks.push(chunk)\n })\n\n req.on('end', () => {\n if (finished) return\n finished = true\n try {\n const raw = Buffer.concat(chunks).toString('utf8')\n resolve(raw.length === 0 ? {} : JSON.parse(raw))\n } catch (error) {\n reject(error)\n }\n })\n\n req.on('error', (error) => {\n if (finished) return\n finished = true\n reject(error)\n })\n })\n}\n","import net from 'node:net'\n\nexport async function resolvePort(host: string, port: number | undefined): Promise<number> {\n if (!port || port === 0) {\n return getRandomPort(host)\n }\n\n try {\n await checkPort(host, port)\n return port\n } catch {\n return getRandomPort(host)\n }\n}\n\nexport function formatBaseUrl(host: string, port: number): string {\n const needsBrackets = host.includes(':') && !host.startsWith('[')\n const safeHost = needsBrackets ? `[${host}]` : host\n return `http://${safeHost}:${port}`\n}\n\nfunction checkPort(host: string, port: number): Promise<void> {\n return new Promise((resolve, reject) => {\n const server = net.createServer()\n server.once('error', (error) => {\n server.close()\n reject(error)\n })\n server.listen(port, host, () => {\n server.close(() => resolve())\n })\n })\n}\n\nfunction getRandomPort(host: string): Promise<number> {\n return new Promise((resolve, reject) => {\n const server = net.createServer()\n server.once('error', (error) => {\n server.close()\n reject(error)\n })\n server.listen(0, host, () => {\n const address = server.address()\n if (!address || typeof address === 'string') {\n server.close(() => reject(new Error('Failed to resolve port')))\n return\n }\n const selected = address.port\n server.close(() => resolve(selected))\n })\n })\n}\n","import path from 'node:path'\nimport { DEFAULT_LOGS_DIR } from './constants'\n\ntype PathOptions = {\n cwd: string\n logsDir?: string\n}\n\nexport function resolveLogsDir({ cwd, logsDir }: PathOptions): string {\n const dir = logsDir && logsDir.length > 0 ? logsDir : DEFAULT_LOGS_DIR\n return path.resolve(cwd, dir)\n}\n\nexport function getRuntimeDir(logsDir: string): string {\n return logsDir\n}\n\nexport function getRuntimePath(logsDir: string): string {\n return path.join(getRuntimeDir(logsDir), 'runtime.json')\n}\n\nexport function getPidPath(logsDir: string): string {\n return path.join(getRuntimeDir(logsDir), 'server.pid')\n}\n\nexport function getSessionLogPath(\n logsDir: string,\n sessionId: string,\n runId: string,\n): string {\n const safeSession = sanitizePathSegment(sessionId)\n const safeRun = sanitizePathSegment(runId)\n return path.join(getRuntimeDir(logsDir), `${safeSession}-${safeRun}.jsonl`)\n}\n\nfunction sanitizePathSegment(value: string): string {\n return value.replace(/[\\\\/]/g, '_').replace(/\\.\\./g, '_').trim() || 'unknown'\n}\n","export const DEFAULT_HOST = '127.0.0.1'\nexport const DEFAULT_PORT = 7242\nexport const DEFAULT_BASE_PATH = '/'\nexport const DEFAULT_LOGS_DIR = '.logs'\nexport const DEFAULT_MAX_BODY_KB = 256\n","import fs from 'node:fs/promises'\nimport { getPidPath, getRuntimeDir, getRuntimePath } from './paths'\n\nexport type RuntimeInfo = {\n ok: boolean\n version: string\n pid: number\n cwd: string\n logsDir: string\n running: boolean\n server: {\n host: string\n port: number\n baseUrl: string\n basePath: string\n endpoints: {\n health: string\n ingestTemplate: string\n }\n }\n startedAt: string\n stoppedAt?: string\n options: {\n maxBodyKB: number\n tokenEnabled: boolean\n idleTtlMs?: number\n }\n}\n\nexport async function readRuntime(logsDir: string): Promise<RuntimeInfo | null> {\n try {\n const raw = await fs.readFile(getRuntimePath(logsDir), 'utf8')\n return JSON.parse(raw) as RuntimeInfo\n } catch {\n return null\n }\n}\n\nexport async function writeRuntime(logsDir: string, info: RuntimeInfo): Promise<void> {\n await fs.mkdir(getRuntimeDir(logsDir), { recursive: true })\n await fs.writeFile(getRuntimePath(logsDir), JSON.stringify(info, null, 2), 'utf8')\n}\n\nexport async function writePid(logsDir: string, pid: number): Promise<void> {\n await fs.mkdir(getRuntimeDir(logsDir), { recursive: true })\n await fs.writeFile(getPidPath(logsDir), String(pid), 'utf8')\n}\n\nexport async function removePid(logsDir: string): Promise<void> {\n try {\n await fs.unlink(getPidPath(logsDir))\n } catch {\n return\n }\n}\n\nexport async function markStopped(logsDir: string): Promise<void> {\n const current = await readRuntime(logsDir)\n if (!current) return\n const updated: RuntimeInfo = {\n ...current,\n running: false,\n stoppedAt: new Date().toISOString(),\n }\n await writeRuntime(logsDir, updated)\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\n\nexport function getPackageVersion(): string {\n try {\n const pkgPath = findPackageJsonPath()\n const raw = fs.readFileSync(pkgPath, 'utf8')\n const data = JSON.parse(raw) as { version?: string }\n return data.version ?? '0.0.0'\n } catch {\n return '0.0.0'\n }\n}\n\nfunction findPackageJsonPath(): string {\n let current = path.resolve(__dirname)\n for (let i = 0; i < 5; i += 1) {\n const candidate = path.join(current, 'package.json')\n if (fs.existsSync(candidate)) return candidate\n current = path.dirname(current)\n }\n return path.join(process.cwd(), 'package.json')\n}\n"],"mappings":"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","names":["import_promises","import_node_path","net","path","fs","import_node_path","fs","path","http","fs","path"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/server.ts","../src/net.ts","../src/paths.ts","../src/constants.ts","../src/runtime.ts","../src/version.ts"],"sourcesContent":["export { startServer, type StartOptions, type StartedServer } from './server'\nexport {\n DEFAULT_BASE_PATH,\n DEFAULT_HOST,\n DEFAULT_LOGS_DIR,\n DEFAULT_MAX_BODY_KB,\n DEFAULT_PORT,\n} from './constants'\n","import http from 'node:http'\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\nimport { formatBaseUrl, resolvePort } from './net'\nimport { getSessionLogPath, resolveLogsDir } from './paths'\nimport { RuntimeInfo, markStopped, removePid, writePid, writeRuntime } from './runtime'\nimport { getPackageVersion } from './version'\n\nexport type StartOptions = {\n host: string\n port?: number\n basePath: string\n logsDir?: string\n maxBodyKB: number\n token?: string\n idleTtlMs?: number\n cwd: string\n}\n\nexport type StartedServer = {\n server: http.Server\n host: string\n port: number\n basePath: string\n baseUrl: string\n logsDir: string\n close: () => Promise<void>\n}\n\n// Note: While these fields should always be provided for proper investigation,\n// the server will use fallback values if missing to ensure no logs are lost.\nconst LOG_FIELDS = ['timestamp', 'message', 'sessionId', 'runId', 'hypothesisId'] as const\nconst CORS_HEADERS = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET,POST,OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Debug-Token',\n 'Access-Control-Max-Age': '86400',\n} as const\n\nexport async function startServer(options: StartOptions): Promise<StartedServer> {\n const logsDir = resolveLogsDir({ cwd: options.cwd, logsDir: options.logsDir })\n const host = options.host\n const basePath = normalizeBasePath(options.basePath)\n const port = await resolvePort(host, options.port)\n const baseUrl = formatBaseUrl(host, port)\n\n let idleTimer: NodeJS.Timeout | undefined\n const server = http.createServer(async (req, res) => {\n applyCorsHeaders(res)\n try {\n const url = new URL(req.url ?? '/', baseUrl)\n const normalizedPath = stripBasePath(url.pathname, basePath)\n\n if (normalizedPath == null) {\n respondJson(res, 404, { ok: false, error: 'not_found' })\n return\n }\n\n if (req.method === 'OPTIONS') {\n respondNoContent(res, 204)\n return\n }\n\n if (req.method === 'GET' && normalizedPath === '/health') {\n respondJson(res, 200, { ok: true })\n return\n }\n\n if (req.method === 'POST' && normalizedPath.startsWith('/ingest/')) {\n const streamId = decodeURIComponent(normalizedPath.replace('/ingest/', ''))\n if (!authorizeRequest(req, options.token)) {\n respondJson(res, 401, { ok: false, error: 'unauthorized' })\n return\n }\n\n let payload: unknown\n try {\n payload = await readJsonBody(req, options.maxBodyKB)\n } catch (error) {\n if (error instanceof BodyTooLargeError) {\n respondJson(res, 413, { ok: false, error: 'body_too_large' })\n return\n }\n respondJson(res, 400, { ok: false, error: 'invalid_json' })\n return\n }\n\n if (!payload || typeof payload !== 'object') {\n respondJson(res, 400, { ok: false, error: 'invalid_body' })\n return\n }\n\n const event = payload as Record<string, unknown>\n\n // Apply fallback values for missing fields to ensure no logs are lost\n const timestamp = 'timestamp' in event ? event.timestamp : Date.now()\n const message = 'message' in event ? event.message : ''\n const sessionId = 'sessionId' in event ? String(event.sessionId) : ''\n const runId = 'runId' in event ? String(event.runId) : ''\n const hypothesisId = 'hypothesisId' in event ? String(event.hypothesisId) : ''\n\n const enriched = {\n timestamp,\n message,\n sessionId,\n runId,\n hypothesisId,\n ...event, // Original values take precedence if present\n _meta: {\n streamId,\n receivedAt: Date.now(),\n },\n }\n const logPath = getSessionLogPath(logsDir, sessionId, runId)\n await fs.mkdir(path.dirname(logPath), { recursive: true })\n\n await fs.appendFile(logPath, `${JSON.stringify(enriched)}\\n`, 'utf8')\n\n if (options.idleTtlMs && options.idleTtlMs > 0) {\n resetIdleTimer(options.idleTtlMs)\n }\n\n respondJson(res, 200, { ok: true, written: true, path: logPath })\n return\n }\n\n respondJson(res, 404, { ok: false, error: 'not_found' })\n } catch {\n respondJson(res, 500, { ok: false, error: 'internal_error' })\n }\n })\n\n const close = async (): Promise<void> => {\n if (idleTimer) clearTimeout(idleTimer)\n await new Promise<void>((resolve, reject) => {\n server.close((err) => {\n if (err) reject(err)\n else resolve()\n })\n })\n }\n\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject)\n server.listen(port, host, () => resolve())\n })\n\n const runtime: RuntimeInfo = {\n ok: true,\n version: getPackageVersion(),\n pid: process.pid,\n cwd: options.cwd,\n logsDir,\n running: true,\n server: {\n host,\n port,\n baseUrl,\n basePath,\n endpoints: {\n health: `${basePath}/health`,\n ingestTemplate: `${basePath}/ingest/{streamId}`,\n },\n },\n startedAt: new Date().toISOString(),\n options: {\n maxBodyKB: options.maxBodyKB,\n tokenEnabled: Boolean(options.token),\n idleTtlMs: options.idleTtlMs,\n },\n }\n\n await writeRuntime(logsDir, runtime)\n await writePid(logsDir, process.pid)\n\n if (options.idleTtlMs && options.idleTtlMs > 0) {\n resetIdleTimer(options.idleTtlMs)\n }\n\n return { server, host, port, basePath, baseUrl, logsDir, close }\n\n function resetIdleTimer(ttl: number): void {\n if (idleTimer) clearTimeout(idleTimer)\n idleTimer = setTimeout(async () => {\n await close()\n await markStopped(logsDir)\n await removePid(logsDir)\n process.exit(0)\n }, ttl)\n }\n}\n\nfunction normalizeBasePath(basePath: string): string {\n if (!basePath || basePath === '/') return ''\n const trimmed = basePath.startsWith('/') ? basePath : `/${basePath}`\n return trimmed.endsWith('/') ? trimmed.slice(0, -1) : trimmed\n}\n\nfunction stripBasePath(pathname: string, basePath: string): string | null {\n if (!basePath) return pathname\n if (!pathname.startsWith(basePath)) return null\n const sliced = pathname.slice(basePath.length)\n return sliced.length === 0 ? '/' : sliced\n}\n\nfunction authorizeRequest(req: http.IncomingMessage, token?: string): boolean {\n if (!token) return true\n const authHeader = req.headers.authorization\n if (authHeader && authHeader === `Bearer ${token}`) return true\n const headerToken = req.headers['x-debug-token']\n if (typeof headerToken === 'string' && headerToken === token) return true\n return false\n}\n\nfunction respondJson(res: http.ServerResponse, status: number, payload: unknown): void {\n const data = JSON.stringify(payload)\n res.statusCode = status\n res.setHeader('Content-Type', 'application/json')\n res.setHeader('Content-Length', Buffer.byteLength(data))\n res.end(data)\n}\n\nfunction respondNoContent(res: http.ServerResponse, status: number): void {\n res.statusCode = status\n res.end()\n}\n\nfunction applyCorsHeaders(res: http.ServerResponse): void {\n for (const [key, value] of Object.entries(CORS_HEADERS)) {\n res.setHeader(key, value)\n }\n}\n\nclass BodyTooLargeError extends Error {}\n\nfunction readJsonBody(req: http.IncomingMessage, maxBodyKB: number): Promise<unknown> {\n const maxBytes = maxBodyKB * 1024\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = []\n let size = 0\n let finished = false\n\n req.on('data', (chunk) => {\n if (finished) return\n size += chunk.length\n if (size > maxBytes) {\n finished = true\n req.destroy()\n reject(new BodyTooLargeError())\n return\n }\n chunks.push(chunk)\n })\n\n req.on('end', () => {\n if (finished) return\n finished = true\n try {\n const raw = Buffer.concat(chunks).toString('utf8')\n resolve(raw.length === 0 ? {} : JSON.parse(raw))\n } catch (error) {\n reject(error)\n }\n })\n\n req.on('error', (error) => {\n if (finished) return\n finished = true\n reject(error)\n })\n })\n}\n","import net from 'node:net'\n\nexport async function resolvePort(host: string, port: number | undefined): Promise<number> {\n if (!port || port === 0) {\n return getRandomPort(host)\n }\n\n try {\n await checkPort(host, port)\n return port\n } catch {\n return getRandomPort(host)\n }\n}\n\nexport function formatBaseUrl(host: string, port: number): string {\n const needsBrackets = host.includes(':') && !host.startsWith('[')\n const safeHost = needsBrackets ? `[${host}]` : host\n return `http://${safeHost}:${port}`\n}\n\nfunction checkPort(host: string, port: number): Promise<void> {\n return new Promise((resolve, reject) => {\n const server = net.createServer()\n server.once('error', (error) => {\n server.close()\n reject(error)\n })\n server.listen(port, host, () => {\n server.close(() => resolve())\n })\n })\n}\n\nfunction getRandomPort(host: string): Promise<number> {\n return new Promise((resolve, reject) => {\n const server = net.createServer()\n server.once('error', (error) => {\n server.close()\n reject(error)\n })\n server.listen(0, host, () => {\n const address = server.address()\n if (!address || typeof address === 'string') {\n server.close(() => reject(new Error('Failed to resolve port')))\n return\n }\n const selected = address.port\n server.close(() => resolve(selected))\n })\n })\n}\n","import path from 'node:path'\nimport { DEFAULT_LOGS_DIR } from './constants'\n\ntype PathOptions = {\n cwd: string\n logsDir?: string\n}\n\nexport function resolveLogsDir({ cwd, logsDir }: PathOptions): string {\n const dir = logsDir && logsDir.length > 0 ? logsDir : DEFAULT_LOGS_DIR\n return path.resolve(cwd, dir)\n}\n\nexport function getRuntimeDir(logsDir: string): string {\n return logsDir\n}\n\nexport function getRuntimePath(logsDir: string): string {\n return path.join(getRuntimeDir(logsDir), 'runtime.json')\n}\n\nexport function getPidPath(logsDir: string): string {\n return path.join(getRuntimeDir(logsDir), 'server.pid')\n}\n\nexport function getSessionLogPath(\n logsDir: string,\n sessionId: string,\n runId: string,\n): string {\n const safeSession = sanitizePathSegment(sessionId)\n const safeRun = sanitizePathSegment(runId)\n return path.join(getRuntimeDir(logsDir), `${safeSession}-${safeRun}.jsonl`)\n}\n\nfunction sanitizePathSegment(value: string): string {\n return value.replace(/[\\\\/]/g, '_').replace(/\\.\\./g, '_').trim() || 'unknown'\n}\n","export const DEFAULT_HOST = '127.0.0.1'\nexport const DEFAULT_PORT = 7242\nexport const DEFAULT_BASE_PATH = '/'\nexport const DEFAULT_LOGS_DIR = '.logs'\nexport const DEFAULT_MAX_BODY_KB = 256\n","import fs from 'node:fs/promises'\nimport { getPidPath, getRuntimeDir, getRuntimePath } from './paths'\n\nexport type RuntimeInfo = {\n ok: boolean\n version: string\n pid: number\n cwd: string\n logsDir: string\n running: boolean\n server: {\n host: string\n port: number\n baseUrl: string\n basePath: string\n endpoints: {\n health: string\n ingestTemplate: string\n }\n }\n startedAt: string\n stoppedAt?: string\n options: {\n maxBodyKB: number\n tokenEnabled: boolean\n idleTtlMs?: number\n }\n}\n\nexport async function readRuntime(logsDir: string): Promise<RuntimeInfo | null> {\n try {\n const raw = await fs.readFile(getRuntimePath(logsDir), 'utf8')\n return JSON.parse(raw) as RuntimeInfo\n } catch {\n return null\n }\n}\n\nexport async function writeRuntime(logsDir: string, info: RuntimeInfo): Promise<void> {\n await fs.mkdir(getRuntimeDir(logsDir), { recursive: true })\n await fs.writeFile(getRuntimePath(logsDir), JSON.stringify(info, null, 2), 'utf8')\n}\n\nexport async function writePid(logsDir: string, pid: number): Promise<void> {\n await fs.mkdir(getRuntimeDir(logsDir), { recursive: true })\n await fs.writeFile(getPidPath(logsDir), String(pid), 'utf8')\n}\n\nexport async function removePid(logsDir: string): Promise<void> {\n try {\n await fs.unlink(getPidPath(logsDir))\n } catch {\n return\n }\n}\n\nexport async function markStopped(logsDir: string): Promise<void> {\n const current = await readRuntime(logsDir)\n if (!current) return\n const updated: RuntimeInfo = {\n ...current,\n running: false,\n stoppedAt: new Date().toISOString(),\n }\n await writeRuntime(logsDir, updated)\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\n\nexport function getPackageVersion(): string {\n try {\n const pkgPath = findPackageJsonPath()\n const raw = fs.readFileSync(pkgPath, 'utf8')\n const data = JSON.parse(raw) as { version?: string }\n return data.version ?? '0.0.0'\n } catch {\n return '0.0.0'\n }\n}\n\nfunction findPackageJsonPath(): string {\n let current = path.resolve(__dirname)\n for (let i = 0; i < 5; i += 1) {\n const candidate = path.join(current, 'package.json')\n if (fs.existsSync(candidate)) return candidate\n current = path.dirname(current)\n }\n return path.join(process.cwd(), 'package.json')\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,uBAAiB;AACjB,IAAAA,mBAAe;AACf,IAAAC,oBAAiB;;;ACFjB,sBAAgB;AAEhB,eAAsB,YAAY,MAAc,MAA2C;AACzF,MAAI,CAAC,QAAQ,SAAS,GAAG;AACvB,WAAO,cAAc,IAAI;AAAA,EAC3B;AAEA,MAAI;AACF,UAAM,UAAU,MAAM,IAAI;AAC1B,WAAO;AAAA,EACT,QAAQ;AACN,WAAO,cAAc,IAAI;AAAA,EAC3B;AACF;AAEO,SAAS,cAAc,MAAc,MAAsB;AAChE,QAAM,gBAAgB,KAAK,SAAS,GAAG,KAAK,CAAC,KAAK,WAAW,GAAG;AAChE,QAAM,WAAW,gBAAgB,IAAI,IAAI,MAAM;AAC/C,SAAO,UAAU,QAAQ,IAAI,IAAI;AACnC;AAEA,SAAS,UAAU,MAAc,MAA6B;AAC5D,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,SAAS,gBAAAC,QAAI,aAAa;AAChC,WAAO,KAAK,SAAS,CAAC,UAAU;AAC9B,aAAO,MAAM;AACb,aAAO,KAAK;AAAA,IACd,CAAC;AACD,WAAO,OAAO,MAAM,MAAM,MAAM;AAC9B,aAAO,MAAM,MAAM,QAAQ,CAAC;AAAA,IAC9B,CAAC;AAAA,EACH,CAAC;AACH;AAEA,SAAS,cAAc,MAA+B;AACpD,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,SAAS,gBAAAA,QAAI,aAAa;AAChC,WAAO,KAAK,SAAS,CAAC,UAAU;AAC9B,aAAO,MAAM;AACb,aAAO,KAAK;AAAA,IACd,CAAC;AACD,WAAO,OAAO,GAAG,MAAM,MAAM;AAC3B,YAAM,UAAU,OAAO,QAAQ;AAC/B,UAAI,CAAC,WAAW,OAAO,YAAY,UAAU;AAC3C,eAAO,MAAM,MAAM,OAAO,IAAI,MAAM,wBAAwB,CAAC,CAAC;AAC9D;AAAA,MACF;AACA,YAAM,WAAW,QAAQ;AACzB,aAAO,MAAM,MAAM,QAAQ,QAAQ,CAAC;AAAA,IACtC,CAAC;AAAA,EACH,CAAC;AACH;;;ACnDA,uBAAiB;;;ACAV,IAAM,eAAe;AACrB,IAAM,eAAe;AACrB,IAAM,oBAAoB;AAC1B,IAAM,mBAAmB;AACzB,IAAM,sBAAsB;;;ADI5B,SAAS,eAAe,EAAE,KAAK,QAAQ,GAAwB;AACpE,QAAM,MAAM,WAAW,QAAQ,SAAS,IAAI,UAAU;AACtD,SAAO,iBAAAC,QAAK,QAAQ,KAAK,GAAG;AAC9B;AAEO,SAAS,cAAc,SAAyB;AACrD,SAAO;AACT;AAEO,SAAS,eAAe,SAAyB;AACtD,SAAO,iBAAAA,QAAK,KAAK,cAAc,OAAO,GAAG,cAAc;AACzD;AAEO,SAAS,WAAW,SAAyB;AAClD,SAAO,iBAAAA,QAAK,KAAK,cAAc,OAAO,GAAG,YAAY;AACvD;AAEO,SAAS,kBACd,SACA,WACA,OACQ;AACR,QAAM,cAAc,oBAAoB,SAAS;AACjD,QAAM,UAAU,oBAAoB,KAAK;AACzC,SAAO,iBAAAA,QAAK,KAAK,cAAc,OAAO,GAAG,GAAG,WAAW,IAAI,OAAO,QAAQ;AAC5E;AAEA,SAAS,oBAAoB,OAAuB;AAClD,SAAO,MAAM,QAAQ,UAAU,GAAG,EAAE,QAAQ,SAAS,GAAG,EAAE,KAAK,KAAK;AACtE;;;AErCA,sBAAe;AA6Bf,eAAsB,YAAY,SAA8C;AAC9E,MAAI;AACF,UAAM,MAAM,MAAM,gBAAAC,QAAG,SAAS,eAAe,OAAO,GAAG,MAAM;AAC7D,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,aAAa,SAAiB,MAAkC;AACpF,QAAM,gBAAAA,QAAG,MAAM,cAAc,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;AAC1D,QAAM,gBAAAA,QAAG,UAAU,eAAe,OAAO,GAAG,KAAK,UAAU,MAAM,MAAM,CAAC,GAAG,MAAM;AACnF;AAEA,eAAsB,SAAS,SAAiB,KAA4B;AAC1E,QAAM,gBAAAA,QAAG,MAAM,cAAc,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;AAC1D,QAAM,gBAAAA,QAAG,UAAU,WAAW,OAAO,GAAG,OAAO,GAAG,GAAG,MAAM;AAC7D;AAEA,eAAsB,UAAU,SAAgC;AAC9D,MAAI;AACF,UAAM,gBAAAA,QAAG,OAAO,WAAW,OAAO,CAAC;AAAA,EACrC,QAAQ;AACN;AAAA,EACF;AACF;AAEA,eAAsB,YAAY,SAAgC;AAChE,QAAM,UAAU,MAAM,YAAY,OAAO;AACzC,MAAI,CAAC,QAAS;AACd,QAAM,UAAuB;AAAA,IAC3B,GAAG;AAAA,IACH,SAAS;AAAA,IACT,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC;AACA,QAAM,aAAa,SAAS,OAAO;AACrC;;;ACjEA,qBAAe;AACf,IAAAC,oBAAiB;AAEV,SAAS,oBAA4B;AAC1C,MAAI;AACF,UAAM,UAAU,oBAAoB;AACpC,UAAM,MAAM,eAAAC,QAAG,aAAa,SAAS,MAAM;AAC3C,UAAM,OAAO,KAAK,MAAM,GAAG;AAC3B,WAAO,KAAK,WAAW;AAAA,EACzB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,sBAA8B;AACrC,MAAI,UAAU,kBAAAC,QAAK,QAAQ,SAAS;AACpC,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG;AAC7B,UAAM,YAAY,kBAAAA,QAAK,KAAK,SAAS,cAAc;AACnD,QAAI,eAAAD,QAAG,WAAW,SAAS,EAAG,QAAO;AACrC,cAAU,kBAAAC,QAAK,QAAQ,OAAO;AAAA,EAChC;AACA,SAAO,kBAAAA,QAAK,KAAK,QAAQ,IAAI,GAAG,cAAc;AAChD;;;ALUA,IAAM,eAAe;AAAA,EACnB,+BAA+B;AAAA,EAC/B,gCAAgC;AAAA,EAChC,gCAAgC;AAAA,EAChC,0BAA0B;AAC5B;AAEA,eAAsB,YAAY,SAA+C;AAC/E,QAAM,UAAU,eAAe,EAAE,KAAK,QAAQ,KAAK,SAAS,QAAQ,QAAQ,CAAC;AAC7E,QAAM,OAAO,QAAQ;AACrB,QAAM,WAAW,kBAAkB,QAAQ,QAAQ;AACnD,QAAM,OAAO,MAAM,YAAY,MAAM,QAAQ,IAAI;AACjD,QAAM,UAAU,cAAc,MAAM,IAAI;AAExC,MAAI;AACJ,QAAM,SAAS,iBAAAC,QAAK,aAAa,OAAO,KAAK,QAAQ;AACnD,qBAAiB,GAAG;AACpB,QAAI;AACF,YAAM,MAAM,IAAI,IAAI,IAAI,OAAO,KAAK,OAAO;AAC3C,YAAM,iBAAiB,cAAc,IAAI,UAAU,QAAQ;AAE3D,UAAI,kBAAkB,MAAM;AAC1B,oBAAY,KAAK,KAAK,EAAE,IAAI,OAAO,OAAO,YAAY,CAAC;AACvD;AAAA,MACF;AAEA,UAAI,IAAI,WAAW,WAAW;AAC5B,yBAAiB,KAAK,GAAG;AACzB;AAAA,MACF;AAEA,UAAI,IAAI,WAAW,SAAS,mBAAmB,WAAW;AACxD,oBAAY,KAAK,KAAK,EAAE,IAAI,KAAK,CAAC;AAClC;AAAA,MACF;AAEA,UAAI,IAAI,WAAW,UAAU,eAAe,WAAW,UAAU,GAAG;AAClE,cAAM,WAAW,mBAAmB,eAAe,QAAQ,YAAY,EAAE,CAAC;AAC1E,YAAI,CAAC,iBAAiB,KAAK,QAAQ,KAAK,GAAG;AACzC,sBAAY,KAAK,KAAK,EAAE,IAAI,OAAO,OAAO,eAAe,CAAC;AAC1D;AAAA,QACF;AAEA,YAAI;AACJ,YAAI;AACF,oBAAU,MAAM,aAAa,KAAK,QAAQ,SAAS;AAAA,QACrD,SAAS,OAAO;AACd,cAAI,iBAAiB,mBAAmB;AACtC,wBAAY,KAAK,KAAK,EAAE,IAAI,OAAO,OAAO,iBAAiB,CAAC;AAC5D;AAAA,UACF;AACA,sBAAY,KAAK,KAAK,EAAE,IAAI,OAAO,OAAO,eAAe,CAAC;AAC1D;AAAA,QACF;AAEA,YAAI,CAAC,WAAW,OAAO,YAAY,UAAU;AAC3C,sBAAY,KAAK,KAAK,EAAE,IAAI,OAAO,OAAO,eAAe,CAAC;AAC1D;AAAA,QACF;AAEA,cAAM,QAAQ;AAGd,cAAM,YAAY,eAAe,QAAQ,MAAM,YAAY,KAAK,IAAI;AACpE,cAAM,UAAU,aAAa,QAAQ,MAAM,UAAU;AACrD,cAAM,YAAY,eAAe,QAAQ,OAAO,MAAM,SAAS,IAAI;AACnE,cAAM,QAAQ,WAAW,QAAQ,OAAO,MAAM,KAAK,IAAI;AACvD,cAAM,eAAe,kBAAkB,QAAQ,OAAO,MAAM,YAAY,IAAI;AAE5E,cAAM,WAAW;AAAA,UACf;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,GAAG;AAAA;AAAA,UACH,OAAO;AAAA,YACL;AAAA,YACA,YAAY,KAAK,IAAI;AAAA,UACvB;AAAA,QACF;AACA,cAAM,UAAU,kBAAkB,SAAS,WAAW,KAAK;AAC3D,cAAM,iBAAAC,QAAG,MAAM,kBAAAC,QAAK,QAAQ,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;AAEzD,cAAM,iBAAAD,QAAG,WAAW,SAAS,GAAG,KAAK,UAAU,QAAQ,CAAC;AAAA,GAAM,MAAM;AAEpE,YAAI,QAAQ,aAAa,QAAQ,YAAY,GAAG;AAC9C,yBAAe,QAAQ,SAAS;AAAA,QAClC;AAEA,oBAAY,KAAK,KAAK,EAAE,IAAI,MAAM,SAAS,MAAM,MAAM,QAAQ,CAAC;AAChE;AAAA,MACF;AAEA,kBAAY,KAAK,KAAK,EAAE,IAAI,OAAO,OAAO,YAAY,CAAC;AAAA,IACzD,QAAQ;AACN,kBAAY,KAAK,KAAK,EAAE,IAAI,OAAO,OAAO,iBAAiB,CAAC;AAAA,IAC9D;AAAA,EACF,CAAC;AAED,QAAM,QAAQ,YAA2B;AACvC,QAAI,UAAW,cAAa,SAAS;AACrC,UAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,aAAO,MAAM,CAAC,QAAQ;AACpB,YAAI,IAAK,QAAO,GAAG;AAAA,YACd,SAAQ;AAAA,MACf,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAEA,QAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,WAAO,KAAK,SAAS,MAAM;AAC3B,WAAO,OAAO,MAAM,MAAM,MAAM,QAAQ,CAAC;AAAA,EAC3C,CAAC;AAED,QAAM,UAAuB;AAAA,IAC3B,IAAI;AAAA,IACJ,SAAS,kBAAkB;AAAA,IAC3B,KAAK,QAAQ;AAAA,IACb,KAAK,QAAQ;AAAA,IACb;AAAA,IACA,SAAS;AAAA,IACT,QAAQ;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW;AAAA,QACT,QAAQ,GAAG,QAAQ;AAAA,QACnB,gBAAgB,GAAG,QAAQ;AAAA,MAC7B;AAAA,IACF;AAAA,IACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC,SAAS;AAAA,MACP,WAAW,QAAQ;AAAA,MACnB,cAAc,QAAQ,QAAQ,KAAK;AAAA,MACnC,WAAW,QAAQ;AAAA,IACrB;AAAA,EACF;AAEA,QAAM,aAAa,SAAS,OAAO;AACnC,QAAM,SAAS,SAAS,QAAQ,GAAG;AAEnC,MAAI,QAAQ,aAAa,QAAQ,YAAY,GAAG;AAC9C,mBAAe,QAAQ,SAAS;AAAA,EAClC;AAEA,SAAO,EAAE,QAAQ,MAAM,MAAM,UAAU,SAAS,SAAS,MAAM;AAE/D,WAAS,eAAe,KAAmB;AACzC,QAAI,UAAW,cAAa,SAAS;AACrC,gBAAY,WAAW,YAAY;AACjC,YAAM,MAAM;AACZ,YAAM,YAAY,OAAO;AACzB,YAAM,UAAU,OAAO;AACvB,cAAQ,KAAK,CAAC;AAAA,IAChB,GAAG,GAAG;AAAA,EACR;AACF;AAEA,SAAS,kBAAkB,UAA0B;AACnD,MAAI,CAAC,YAAY,aAAa,IAAK,QAAO;AAC1C,QAAM,UAAU,SAAS,WAAW,GAAG,IAAI,WAAW,IAAI,QAAQ;AAClE,SAAO,QAAQ,SAAS,GAAG,IAAI,QAAQ,MAAM,GAAG,EAAE,IAAI;AACxD;AAEA,SAAS,cAAc,UAAkB,UAAiC;AACxE,MAAI,CAAC,SAAU,QAAO;AACtB,MAAI,CAAC,SAAS,WAAW,QAAQ,EAAG,QAAO;AAC3C,QAAM,SAAS,SAAS,MAAM,SAAS,MAAM;AAC7C,SAAO,OAAO,WAAW,IAAI,MAAM;AACrC;AAEA,SAAS,iBAAiB,KAA2B,OAAyB;AAC5E,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,aAAa,IAAI,QAAQ;AAC/B,MAAI,cAAc,eAAe,UAAU,KAAK,GAAI,QAAO;AAC3D,QAAM,cAAc,IAAI,QAAQ,eAAe;AAC/C,MAAI,OAAO,gBAAgB,YAAY,gBAAgB,MAAO,QAAO;AACrE,SAAO;AACT;AAEA,SAAS,YAAY,KAA0B,QAAgB,SAAwB;AACrF,QAAM,OAAO,KAAK,UAAU,OAAO;AACnC,MAAI,aAAa;AACjB,MAAI,UAAU,gBAAgB,kBAAkB;AAChD,MAAI,UAAU,kBAAkB,OAAO,WAAW,IAAI,CAAC;AACvD,MAAI,IAAI,IAAI;AACd;AAEA,SAAS,iBAAiB,KAA0B,QAAsB;AACxE,MAAI,aAAa;AACjB,MAAI,IAAI;AACV;AAEA,SAAS,iBAAiB,KAAgC;AACxD,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,YAAY,GAAG;AACvD,QAAI,UAAU,KAAK,KAAK;AAAA,EAC1B;AACF;AAEA,IAAM,oBAAN,cAAgC,MAAM;AAAC;AAEvC,SAAS,aAAa,KAA2B,WAAqC;AACpF,QAAM,WAAW,YAAY;AAC7B,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,SAAmB,CAAC;AAC1B,QAAI,OAAO;AACX,QAAI,WAAW;AAEf,QAAI,GAAG,QAAQ,CAAC,UAAU;AACxB,UAAI,SAAU;AACd,cAAQ,MAAM;AACd,UAAI,OAAO,UAAU;AACnB,mBAAW;AACX,YAAI,QAAQ;AACZ,eAAO,IAAI,kBAAkB,CAAC;AAC9B;AAAA,MACF;AACA,aAAO,KAAK,KAAK;AAAA,IACnB,CAAC;AAED,QAAI,GAAG,OAAO,MAAM;AAClB,UAAI,SAAU;AACd,iBAAW;AACX,UAAI;AACF,cAAM,MAAM,OAAO,OAAO,MAAM,EAAE,SAAS,MAAM;AACjD,gBAAQ,IAAI,WAAW,IAAI,CAAC,IAAI,KAAK,MAAM,GAAG,CAAC;AAAA,MACjD,SAAS,OAAO;AACd,eAAO,KAAK;AAAA,MACd;AAAA,IACF,CAAC;AAED,QAAI,GAAG,SAAS,CAAC,UAAU;AACzB,UAAI,SAAU;AACd,iBAAW;AACX,aAAO,KAAK;AAAA,IACd,CAAC;AAAA,EACH,CAAC;AACH;","names":["import_promises","import_node_path","net","path","fs","import_node_path","fs","path","http","fs","path"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "debugsk",
3
- "version": "0.0.3",
4
- "description": "Debug investigation CLI: server + Codex skill management for hypothesis-driven workflows.",
3
+ "version": "0.0.5",
4
+ "description": "Debug investigation CLI: server + skill management for Claude Code and Codex hypothesis-driven workflows.",
5
5
  "bin": {
6
6
  "debugsk": "dist/cli.js"
7
7
  },
@@ -62,6 +62,7 @@ description: Standardized, hypothesis-driven debug investigation workflow for un
62
62
  - Use native logs as reference alongside the added instrumentation.
63
63
  - Logs must never throw, avoid secrets/PII, and be easy to remove.
64
64
  - Record location, message, timestamp, and correlation fields in every event.
65
+ - **YOU MUST ALWAYS include all log fields (timestamp, message, sessionId, runId, hypothesisId, location) in every log event. Never omit any field.**
65
66
  - Do not guard instrumentation behind environment flags. Write logs for the investigation, then remove them after completion.
66
67
  - AI inserts instrumentation and provides the exact reproduction steps; the user performs the reproduction run and shares the resulting logs.
67
68
 
@@ -2,12 +2,14 @@
2
2
 
3
3
  Use this schema when instrumenting. Keep fields small, structured, and correlated.
4
4
 
5
- ## Required fields
6
- - `timestamp`: ms epoch or ISO-8601 string
7
- - `message`: short, human-readable message
8
- - `sessionId`: investigation session identifier
9
- - `runId`: single reproduction run identifier
10
- - `hypothesisId`: hypothesis identifier (e.g. "H1")
5
+ **IMPORTANT: You MUST ALWAYS include all required fields when logging. Never omit any of them.**
6
+
7
+ ## Required fields (MUST ALWAYS be specified)
8
+ - `timestamp`: ms epoch or ISO-8601 string — **ALWAYS include this**
9
+ - `message`: short, human-readable message — **ALWAYS include this**
10
+ - `sessionId`: investigation session identifier **ALWAYS include this**
11
+ - `runId`: single reproduction run identifier — **ALWAYS include this**
12
+ - `hypothesisId`: hypothesis identifier (e.g. "H1") — **ALWAYS include this**
11
13
 
12
14
  ## Recommended fields
13
15
  - `location`: file:line or function name