@dadado/agent-kit-cli 6.3.0 → 6.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dashboard/dashboard-data.mjs +14 -2
  2. package/dashboard/dashboard.html +139 -4
  3. package/dashboard/lib/chat-sessions.d.mts +63 -0
  4. package/dashboard/lib/chat-sessions.mjs +430 -0
  5. package/dashboard/serve.mjs +5 -1
  6. package/dist/{add-VA2W7I6P.js → add-HFDX3U3R.js} +2 -2
  7. package/dist/{chunk-6GYKOHIL.js → chunk-3OM7JODZ.js} +2 -2
  8. package/dist/{chunk-Z7RYIHHX.js → chunk-6OTJEQEC.js} +3 -3
  9. package/dist/{chunk-MAPOQEA2.js → chunk-6RRG3WOE.js} +8 -1
  10. package/dist/{chunk-6KUSG7BJ.js → chunk-7BEHUBEJ.js} +3 -1
  11. package/dist/{chunk-VQBI3JVS.js → chunk-ANPSYWQO.js} +2 -2
  12. package/dist/{chunk-WMVMBPCR.js → chunk-AXLXEAVJ.js} +1 -1
  13. package/dist/{chunk-25J2SMJQ.js → chunk-E465FAWM.js} +1 -1
  14. package/dist/{chunk-U26MRIWN.js → chunk-H46W7NHC.js} +1 -1
  15. package/dist/{chunk-NNKOWUWM.js → chunk-HHR56LJQ.js} +64 -28
  16. package/dist/{chunk-SV2BR2LZ.js → chunk-IMIVTDMK.js} +7 -7
  17. package/dist/chunk-IRTS7WEA.js +374 -0
  18. package/dist/{chunk-MO63KZBP.js → chunk-KX3OUY4W.js} +8 -6
  19. package/dist/chunk-MWTXI6C5.js +223 -0
  20. package/dist/{chunk-JEI6HACW.js → chunk-NJVWTROP.js} +24 -377
  21. package/dist/{chunk-OVOXRH5W.js → chunk-Q4PCMRM5.js} +1 -1
  22. package/dist/{chunk-GUQYNUV4.js → chunk-R7DA4KXG.js} +1 -1
  23. package/dist/{chunk-OWWFKGKS.js → chunk-SE7ZIRLX.js} +2 -2
  24. package/dist/{chunk-KVY425NM.js → chunk-TZ5XYIEF.js} +4 -2
  25. package/dist/{chunk-Z7ABX5QI.js → chunk-WOHZ4T5V.js} +4 -2
  26. package/dist/{chunk-YRFSTHR5.js → chunk-XEEB4YSA.js} +13 -219
  27. package/dist/{chunk-QTBTKEXK.js → chunk-ZPZVROS5.js} +1 -1
  28. package/dist/{contribute-NLM2BN6Z.js → contribute-PP7HMPW7.js} +3 -3
  29. package/dist/{countdown-QXJD6TDB.js → countdown-LAUZMI7U.js} +10 -8
  30. package/dist/{diff-HHG4JEDE.js → diff-HYWC4G6Y.js} +4 -4
  31. package/dist/{doctor-TWF2M3S3.js → doctor-2X3HBRJJ.js} +8 -8
  32. package/dist/engine-info-4ZWEIHSX.js +89 -0
  33. package/dist/{ground-control-NMYYIVCV.js → ground-control-WKV2BMOW.js} +5 -4
  34. package/dist/{guard-EHXF76ID.js → guard-ZZRQW3DJ.js} +107 -8
  35. package/dist/{hook-VP7FHRSZ.js → hook-UEYR4M3Z.js} +10 -4
  36. package/dist/index.js +26 -22
  37. package/dist/{init-UOTV4ASJ.js → init-UF5VEIJX.js} +11 -11
  38. package/dist/{install-VCHPXQV3.js → install-6ILVA22C.js} +11 -11
  39. package/dist/{run-R66G276Q.js → run-2EKD2BEC.js} +12 -9
  40. package/dist/{run-plan-24Z5K4P3.js → run-plan-G72XMC5Z.js} +11 -7
  41. package/dist/sessions-O7MYEMCT.js +343 -0
  42. package/dist/{setup-global-M6LKGJHQ.js → setup-global-ZZEY5KWE.js} +5 -5
  43. package/dist/{status-5UKVIKOI.js → status-4LK2QXVQ.js} +6 -6
  44. package/dist/{update-VQBGEUWS.js → update-FPR2NZND.js} +9 -9
  45. package/package.json +1 -1
@@ -23,15 +23,15 @@ import {
23
23
  } from "./chunk-HAFRAXGV.js";
24
24
  import {
25
25
  stampLastCheckedAt
26
- } from "./chunk-6GYKOHIL.js";
26
+ } from "./chunk-3OM7JODZ.js";
27
27
  import {
28
28
  loadContextConfig
29
29
  } from "./chunk-PFEUZXVT.js";
30
- import "./chunk-VQBI3JVS.js";
31
- import "./chunk-25J2SMJQ.js";
30
+ import "./chunk-ANPSYWQO.js";
31
+ import "./chunk-E465FAWM.js";
32
32
  import {
33
33
  MANIFEST_RELATIVE_PATH
34
- } from "./chunk-6KUSG7BJ.js";
34
+ } from "./chunk-7BEHUBEJ.js";
35
35
  import "./chunk-7HDQEK6T.js";
36
36
  import {
37
37
  HANDOFF_REL
@@ -330,6 +330,7 @@ var HARD_RULES = `# Agent Kit session hard rules (manual mode default)
330
330
  var DOGFOOD_INBOX_HINT = `## Dogfood inbox
331
331
 
332
332
  Unprocessed files are listed under \`dogfood/README.md\` (factory) or \`.cursor/dogfood/README.md\` (consumer). To file a new note, use \`/dogfood <topic> [summary]\`. Follow the ingest ritual (detect \u2192 analyze \u2192 memory WRITE \u2192 triage). Do not auto-start analysis unless the user asks.`;
333
+ var COLONY_HOST_HINT = '**Colony host:** git/forge actions you may not run yourself (merge a PR, rerun failed checks, push a branch) go through `"$COLONY_HOST_CLI" request merge-pr <N> | rerun-checks <run-id>|--pr <N> | push-branch [<branch>] [--reason "..."]`; it waits for the operator\'s click in Colony (exit 0 done, 2 denied: final, 3 failed, 4 timeout).';
333
334
  var UPDATE_CHECK_NUDGE = `## Agent Kit update available
334
335
 
335
336
  Installed **v{installed}**; latest public **v{latest}**.
@@ -503,6 +504,9 @@ async function dogfoodInboxSection(root) {
503
504
  }
504
505
  return null;
505
506
  }
507
+ function colonyHostSection(env = process.env) {
508
+ return env.COLONY_HOST_CLI?.trim() ? COLONY_HOST_HINT : null;
509
+ }
506
510
  async function loadUpdateCheckPrefs(root) {
507
511
  const data = await loadContextConfig(root);
508
512
  if (!data) return null;
@@ -930,6 +934,8 @@ async function buildSessionStartAdditionalContext(rootDir, _payload = {}, deps =
930
934
  }
931
935
  const dogfood = await dogfoodInboxSection(root);
932
936
  if (dogfood) parts.push(dogfood);
937
+ const colonyHost = colonyHostSection();
938
+ if (colonyHost) parts.push(colonyHost);
933
939
  const deadlineMs = deps.deadlineMs ?? SESSION_START_SECTION_DEADLINE_MS;
934
940
  const newAttempt = () => ({ spawned: false, timedOut: false, result: null });
935
941
  const updateAttempt = newAttempt();
package/dist/index.js CHANGED
@@ -1,10 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  rewriteRootArgvToRun
4
- } from "./chunk-Z7ABX5QI.js";
5
- import "./chunk-JEI6HACW.js";
4
+ } from "./chunk-WOHZ4T5V.js";
5
+ import "./chunk-NJVWTROP.js";
6
+ import "./chunk-IRTS7WEA.js";
6
7
  import "./chunk-WGLPZXNU.js";
7
- import "./chunk-MAPOQEA2.js";
8
+ import "./chunk-6RRG3WOE.js";
8
9
  import {
9
10
  HELMET_OUTLINE,
10
11
  SPACE_MARKS,
@@ -131,7 +132,7 @@ var CLI_HELP_GROUPS = [
131
132
  {
132
133
  id: "dashboard",
133
134
  title: "DASHBOARD",
134
- commands: ["dashboard", "dashboard-broadcast", "mission-control", "monitors"]
135
+ commands: ["dashboard", "dashboard-broadcast", "mission-control", "monitors", "sessions"]
135
136
  },
136
137
  {
137
138
  id: "integrity",
@@ -145,7 +146,8 @@ var CLI_HELP_GROUPS = [
145
146
  "remote-issues",
146
147
  "dogfood",
147
148
  "diff",
148
- "contribute"
149
+ "contribute",
150
+ "engine-info"
149
151
  ]
150
152
  }
151
153
  ];
@@ -221,34 +223,36 @@ var main = defineCommand({
221
223
  version: KIT_VERSION
222
224
  },
223
225
  subCommands: {
224
- init: () => import("./init-UOTV4ASJ.js").then((m) => m.initCommand),
225
- install: () => import("./install-VCHPXQV3.js").then((m) => m.installCommand),
226
+ init: () => import("./init-UF5VEIJX.js").then((m) => m.initCommand),
227
+ install: () => import("./install-6ILVA22C.js").then((m) => m.installCommand),
226
228
  scan: () => import("./scan-UX4HARMJ.js").then((m) => m.scanCommand),
227
- add: () => import("./add-VA2W7I6P.js").then((m) => m.addCommand),
228
- doctor: () => import("./doctor-TWF2M3S3.js").then((m) => m.doctorCommand),
229
- "setup-global": () => import("./setup-global-M6LKGJHQ.js").then((m) => m.setupGlobalCommand),
230
- status: () => import("./status-5UKVIKOI.js").then((m) => m.statusCommand),
231
- update: () => import("./update-VQBGEUWS.js").then((m) => m.updateCommand),
229
+ add: () => import("./add-HFDX3U3R.js").then((m) => m.addCommand),
230
+ doctor: () => import("./doctor-2X3HBRJJ.js").then((m) => m.doctorCommand),
231
+ "setup-global": () => import("./setup-global-ZZEY5KWE.js").then((m) => m.setupGlobalCommand),
232
+ status: () => import("./status-4LK2QXVQ.js").then((m) => m.statusCommand),
233
+ update: () => import("./update-FPR2NZND.js").then((m) => m.updateCommand),
232
234
  "cursor-awareness": () => import("./cursor-awareness-TN5JXD2C.js").then((m) => m.cursorAwarenessCommand),
233
235
  "public-inbound-radar": () => import("./public-inbound-radar-5U4JMBRU.js").then((m) => m.publicInboundRadarCommand),
234
236
  "remote-issues": () => import("./remote-issues-APYOMIJC.js").then((m) => m.remoteIssuesCommand),
235
237
  dogfood: () => import("./dogfood-2JAHSYQA.js").then((m) => m.dogfoodCommand),
236
- diff: () => import("./diff-HHG4JEDE.js").then((m) => m.diffCommand),
237
- contribute: () => import("./contribute-NLM2BN6Z.js").then((m) => m.contributeCommand),
238
+ diff: () => import("./diff-HYWC4G6Y.js").then((m) => m.diffCommand),
239
+ contribute: () => import("./contribute-PP7HMPW7.js").then((m) => m.contributeCommand),
238
240
  handoff: () => import("./handoff-5AGE2D3T.js").then((m) => m.handoffCommand),
239
241
  "plan-index": () => import("./plan-index-BNLUU6T5.js").then((m) => m.planIndexCommand),
240
- run: () => import("./run-R66G276Q.js").then((m) => m.runCommand),
241
- "run-plan": () => import("./run-plan-24Z5K4P3.js").then((m) => m.runPlanCommand),
242
- "run-plan-all": () => import("./run-R66G276Q.js").then((m) => m.runPlanAllCommand),
243
- countdown: () => import("./countdown-QXJD6TDB.js").then((m) => m.countdownCommand),
244
- "ground-control": () => import("./ground-control-NMYYIVCV.js").then((m) => m.groundControlCommand),
242
+ run: () => import("./run-2EKD2BEC.js").then((m) => m.runCommand),
243
+ "run-plan": () => import("./run-plan-G72XMC5Z.js").then((m) => m.runPlanCommand),
244
+ "run-plan-all": () => import("./run-2EKD2BEC.js").then((m) => m.runPlanAllCommand),
245
+ countdown: () => import("./countdown-LAUZMI7U.js").then((m) => m.countdownCommand),
246
+ "ground-control": () => import("./ground-control-WKV2BMOW.js").then((m) => m.groundControlCommand),
245
247
  dashboard: () => import("./dashboard-YNCFISNO.js").then((m) => m.dashboardCommand),
246
248
  "dashboard-broadcast": () => import("./dashboard-broadcast-NK7PU72L.js").then((m) => m.dashboardBroadcastCommand),
247
249
  "mission-control": () => import("./mission-control-MHQU73XC.js").then((m) => m.missionControlCommand),
248
- hook: () => import("./hook-VP7FHRSZ.js").then((m) => m.hookCommand),
249
- guard: () => import("./guard-EHXF76ID.js").then((m) => m.guardCommand),
250
+ hook: () => import("./hook-UEYR4M3Z.js").then((m) => m.hookCommand),
251
+ guard: () => import("./guard-ZZRQW3DJ.js").then((m) => m.guardCommand),
250
252
  monitors: () => import("./monitors-PDXBLB3U.js").then((m) => m.monitorsCommand),
251
- validate: () => import("./validate-V2CW7J4B.js").then((m) => m.validateCommand)
253
+ sessions: () => import("./sessions-O7MYEMCT.js").then((m) => m.sessionsCommand),
254
+ validate: () => import("./validate-V2CW7J4B.js").then((m) => m.validateCommand),
255
+ "engine-info": () => import("./engine-info-4ZWEIHSX.js").then((m) => m.engineInfoCommand)
252
256
  },
253
257
  async run({ rawArgs }) {
254
258
  if (hasCliSubcommand(rawArgs)) return;
@@ -2,20 +2,20 @@ import {
2
2
  nextStepAfterInstall,
3
3
  performInstall,
4
4
  printInstallEpilogue
5
- } from "./chunk-SV2BR2LZ.js";
5
+ } from "./chunk-IMIVTDMK.js";
6
6
  import {
7
7
  NON_INTERACTIVE_ROOT_ARGS
8
- } from "./chunk-Z7RYIHHX.js";
8
+ } from "./chunk-6OTJEQEC.js";
9
9
  import {
10
10
  SkippedSymlinkError,
11
11
  logApplyStats
12
12
  } from "./chunk-HS7LVVLO.js";
13
- import "./chunk-U26MRIWN.js";
14
- import "./chunk-WMVMBPCR.js";
13
+ import "./chunk-H46W7NHC.js";
14
+ import "./chunk-AXLXEAVJ.js";
15
15
  import "./chunk-HAFRAXGV.js";
16
- import "./chunk-NNKOWUWM.js";
16
+ import "./chunk-HHR56LJQ.js";
17
17
  import "./chunk-WGLPZXNU.js";
18
- import "./chunk-MAPOQEA2.js";
18
+ import "./chunk-6RRG3WOE.js";
19
19
  import {
20
20
  withCliProgress
21
21
  } from "./chunk-QTON2GQX.js";
@@ -31,15 +31,15 @@ import {
31
31
  confirmProjectRoot,
32
32
  isNonInteractive,
33
33
  syncPathCliToRuntime
34
- } from "./chunk-OWWFKGKS.js";
34
+ } from "./chunk-SE7ZIRLX.js";
35
35
  import {
36
36
  assessEnvironment
37
37
  } from "./chunk-B3VR5YBQ.js";
38
- import "./chunk-6GYKOHIL.js";
38
+ import "./chunk-3OM7JODZ.js";
39
39
  import "./chunk-PFEUZXVT.js";
40
- import "./chunk-VQBI3JVS.js";
41
- import "./chunk-25J2SMJQ.js";
42
- import "./chunk-6KUSG7BJ.js";
40
+ import "./chunk-ANPSYWQO.js";
41
+ import "./chunk-E465FAWM.js";
42
+ import "./chunk-7BEHUBEJ.js";
43
43
  import {
44
44
  KIT_VERSION
45
45
  } from "./chunk-7HDQEK6T.js";
@@ -3,27 +3,27 @@ import {
3
3
  nextStepAfterInstall,
4
4
  performInstall,
5
5
  printInstallEpilogue
6
- } from "./chunk-SV2BR2LZ.js";
7
- import "./chunk-Z7RYIHHX.js";
6
+ } from "./chunk-IMIVTDMK.js";
7
+ import "./chunk-6OTJEQEC.js";
8
8
  import "./chunk-HS7LVVLO.js";
9
- import "./chunk-U26MRIWN.js";
10
- import "./chunk-WMVMBPCR.js";
9
+ import "./chunk-H46W7NHC.js";
10
+ import "./chunk-AXLXEAVJ.js";
11
11
  import "./chunk-HAFRAXGV.js";
12
- import "./chunk-NNKOWUWM.js";
12
+ import "./chunk-HHR56LJQ.js";
13
13
  import "./chunk-WGLPZXNU.js";
14
- import "./chunk-MAPOQEA2.js";
14
+ import "./chunk-6RRG3WOE.js";
15
15
  import "./chunk-QTON2GQX.js";
16
16
  import "./chunk-PNFF6OU3.js";
17
17
  import "./chunk-GO3K752H.js";
18
18
  import "./chunk-F6C3GFKV.js";
19
19
  import "./chunk-ZB43YMHW.js";
20
- import "./chunk-OWWFKGKS.js";
20
+ import "./chunk-SE7ZIRLX.js";
21
21
  import "./chunk-B3VR5YBQ.js";
22
- import "./chunk-6GYKOHIL.js";
22
+ import "./chunk-3OM7JODZ.js";
23
23
  import "./chunk-PFEUZXVT.js";
24
- import "./chunk-VQBI3JVS.js";
25
- import "./chunk-25J2SMJQ.js";
26
- import "./chunk-6KUSG7BJ.js";
24
+ import "./chunk-ANPSYWQO.js";
25
+ import "./chunk-E465FAWM.js";
26
+ import "./chunk-7BEHUBEJ.js";
27
27
  import "./chunk-7HDQEK6T.js";
28
28
  import "./chunk-C4Q77GGJ.js";
29
29
  import "./chunk-5B4DVO6C.js";
@@ -2,21 +2,22 @@ import {
2
2
  runPlanLoop,
3
3
  shouldUseLiveTui,
4
4
  withLiveTui
5
- } from "./chunk-YRFSTHR5.js";
5
+ } from "./chunk-XEEB4YSA.js";
6
+ import "./chunk-MWTXI6C5.js";
6
7
  import {
7
8
  REVIEW_PACK_SLASH,
8
9
  runReviewJob
9
- } from "./chunk-MO63KZBP.js";
10
+ } from "./chunk-KX3OUY4W.js";
10
11
  import {
11
12
  detectAgentBackend,
12
13
  listDetectBackendIds
13
- } from "./chunk-GUQYNUV4.js";
14
- import "./chunk-QTBTKEXK.js";
14
+ } from "./chunk-R7DA4KXG.js";
15
+ import "./chunk-ZPZVROS5.js";
15
16
  import {
16
17
  LAND_ON_GATE_DESCRIPTION,
17
18
  classifyGateExit,
18
19
  landGateExit
19
- } from "./chunk-KVY425NM.js";
20
+ } from "./chunk-TZ5XYIEF.js";
20
21
  import "./chunk-3LLXDHIU.js";
21
22
  import {
22
23
  negatedFlag
@@ -32,15 +33,17 @@ import {
32
33
  readCommandFile,
33
34
  runHeadlessDispatch,
34
35
  unknownSlashMessage
35
- } from "./chunk-Z7ABX5QI.js";
36
+ } from "./chunk-WOHZ4T5V.js";
37
+ import {
38
+ getBackend
39
+ } from "./chunk-NJVWTROP.js";
36
40
  import {
37
41
  HITL_UNANSWERED_EXIT_CODE,
38
42
  formatHitlSummary,
39
- getBackend,
40
43
  hitlExitCode
41
- } from "./chunk-JEI6HACW.js";
44
+ } from "./chunk-IRTS7WEA.js";
42
45
  import "./chunk-WGLPZXNU.js";
43
- import "./chunk-MAPOQEA2.js";
46
+ import "./chunk-6RRG3WOE.js";
44
47
  import "./chunk-QTON2GQX.js";
45
48
  import {
46
49
  logger
@@ -1,14 +1,16 @@
1
1
  import {
2
- DRIVER_EVENTS_FORMATS,
3
2
  runPlanLoop
4
- } from "./chunk-YRFSTHR5.js";
3
+ } from "./chunk-XEEB4YSA.js";
4
+ import {
5
+ DRIVER_EVENTS_FORMATS
6
+ } from "./chunk-MWTXI6C5.js";
5
7
  import {
6
8
  detectAgentBackend,
7
9
  listDetectBackendIds
8
- } from "./chunk-GUQYNUV4.js";
10
+ } from "./chunk-R7DA4KXG.js";
9
11
  import {
10
12
  LAND_ON_GATE_DESCRIPTION
11
- } from "./chunk-KVY425NM.js";
13
+ } from "./chunk-TZ5XYIEF.js";
12
14
  import "./chunk-3LLXDHIU.js";
13
15
  import {
14
16
  negatedFlag
@@ -16,11 +18,13 @@ import {
16
18
  import "./chunk-L5V3W3DY.js";
17
19
  import "./chunk-MUTTNRX4.js";
18
20
  import {
19
- HITL_UNANSWERED_EXIT_CODE,
20
21
  getBackend
21
- } from "./chunk-JEI6HACW.js";
22
+ } from "./chunk-NJVWTROP.js";
23
+ import {
24
+ HITL_UNANSWERED_EXIT_CODE
25
+ } from "./chunk-IRTS7WEA.js";
22
26
  import "./chunk-WGLPZXNU.js";
23
- import "./chunk-MAPOQEA2.js";
27
+ import "./chunk-6RRG3WOE.js";
24
28
  import "./chunk-QTON2GQX.js";
25
29
  import {
26
30
  logger
@@ -0,0 +1,343 @@
1
+ // src/commands/sessions.ts
2
+ import path from "path";
3
+ import { defineCommand } from "citty";
4
+
5
+ // ../../dashboard/lib/chat-sessions.mjs
6
+ import {
7
+ closeSync,
8
+ existsSync,
9
+ fstatSync,
10
+ openSync,
11
+ readdirSync,
12
+ readSync,
13
+ realpathSync,
14
+ statSync
15
+ } from "fs";
16
+ import { join } from "path";
17
+ var CHAT_SESSIONS_CAP = 200;
18
+ var CHAT_TITLE_MAX = 80;
19
+ var CHAT_NAMED_TITLE_MAX = 200;
20
+ var CHAT_FULL_SCAN_MAX_BYTES = 64 * 1024 * 1024;
21
+ var CHAT_HEAD_BYTES = 2 * 1024 * 1024;
22
+ var CHAT_TAIL_BYTES = 8 * 1024 * 1024;
23
+ var CHAT_SCAN_BUDGET_BYTES = 256 * 1024 * 1024;
24
+ var BUDGET_HEAD_BYTES = 256 * 1024;
25
+ var BUDGET_TAIL_BYTES = 1024 * 1024;
26
+ var CHAT_VENDORS = Object.freeze(["claude", "codex", "cursor"]);
27
+ var SESSION_FILE_RE = /^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/i;
28
+ var SLUG_MAX = 200;
29
+ var READ_CHUNK = 1024 * 1024;
30
+ var NEWLINE = 10;
31
+ var MARK_CUSTOM = Buffer.from('"type":"custom-title"');
32
+ var MARK_AI = Buffer.from('"type":"ai-title"');
33
+ var MARK_USER = Buffer.from('"type":"user"');
34
+ var NON_PROMPT_PREFIXES = [
35
+ "<command-name>",
36
+ "<command-message>",
37
+ "<command-args>",
38
+ "<local-command-",
39
+ "<bash-input>",
40
+ "<bash-stdout>",
41
+ "<bash-stderr>",
42
+ "<system-reminder>",
43
+ "<task-notification>",
44
+ "Caveat:",
45
+ "[Request interrupted"
46
+ ];
47
+ function slugHash(value) {
48
+ let h = 0;
49
+ for (let i = 0; i < value.length; i++) h = (h << 5) - h + value.charCodeAt(i) | 0;
50
+ return h;
51
+ }
52
+ function claudeProjectSlug(cwd) {
53
+ const raw = String(cwd ?? "");
54
+ const slug = raw.replace(/[^a-zA-Z0-9]/g, "-");
55
+ if (slug.length <= SLUG_MAX) return slug;
56
+ return `${slug.slice(0, SLUG_MAX)}-${Math.abs(slugHash(raw)).toString(36)}`;
57
+ }
58
+ function claudeProjectDir(cwd, opts = {}) {
59
+ const home = opts.home === void 0 ? process.env.HOME : opts.home;
60
+ if (typeof home !== "string" || !home.trim() || !home.startsWith("/")) return null;
61
+ return join(home, ".claude", "projects", claudeProjectSlug(cwd));
62
+ }
63
+ function cleanChatTitle(value, max = CHAT_TITLE_MAX) {
64
+ const text = String(value ?? "").replace(/[\u0000-\u001f\u007f-\u009f\u200e\u200f\u202a-\u202e\u2066-\u2069]/g, " ").replace(/\s+/g, " ").trim();
65
+ const chars = [...text];
66
+ if (chars.length <= max) return text;
67
+ return `${chars.slice(0, max - 1).join("").trimEnd()}\u2026`;
68
+ }
69
+ function promptText(record) {
70
+ if (record?.type !== "user" || record.isMeta === true || record.isSidechain === true) {
71
+ return "";
72
+ }
73
+ const content = record.message?.content;
74
+ let text = "";
75
+ if (typeof content === "string") {
76
+ text = content;
77
+ } else if (Array.isArray(content)) {
78
+ if (content.some((part) => part && part.type === "tool_result")) return "";
79
+ text = content.filter((part) => part && part.type === "text" && typeof part.text === "string").map((part) => part.text).join(" ");
80
+ }
81
+ const trimmed = text.trim();
82
+ if (!trimmed) return "";
83
+ if (NON_PROMPT_PREFIXES.some((prefix) => trimmed.startsWith(prefix))) return "";
84
+ return trimmed;
85
+ }
86
+ function parseRecord(line) {
87
+ try {
88
+ const value = JSON.parse(line.toString("utf8"));
89
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
90
+ } catch {
91
+ return null;
92
+ }
93
+ }
94
+ function forEachLine(fd, start, end, onLine) {
95
+ const buf = Buffer.allocUnsafe(READ_CHUNK);
96
+ let pending = [];
97
+ let skipFirst = start > 0;
98
+ let pos = start;
99
+ while (pos < end) {
100
+ const n = readSync(fd, buf, 0, Math.min(READ_CHUNK, end - pos), pos);
101
+ if (n <= 0) break;
102
+ pos += n;
103
+ let from = 0;
104
+ for (; ; ) {
105
+ const nl = buf.indexOf(NEWLINE, from);
106
+ if (nl === -1 || nl >= n) {
107
+ if (from < n) pending.push(Buffer.from(buf.subarray(from, n)));
108
+ break;
109
+ }
110
+ const piece = buf.subarray(from, nl);
111
+ const line = pending.length ? Buffer.concat([...pending, piece]) : piece;
112
+ pending = [];
113
+ from = nl + 1;
114
+ if (skipFirst) {
115
+ skipFirst = false;
116
+ continue;
117
+ }
118
+ onLine(line);
119
+ }
120
+ }
121
+ if (pending.length && !skipFirst) onLine(Buffer.concat(pending));
122
+ }
123
+ function readChatTitle(filePath, window = {}) {
124
+ const fullScanMax = window.fullScanMaxBytes ?? CHAT_FULL_SCAN_MAX_BYTES;
125
+ const headBytes = window.headBytes ?? CHAT_HEAD_BYTES;
126
+ const tailBytes = window.tailBytes ?? CHAT_TAIL_BYTES;
127
+ let custom = "";
128
+ let ai = "";
129
+ let prompt = "";
130
+ let fd;
131
+ try {
132
+ fd = openSync(filePath, "r");
133
+ } catch {
134
+ return { title: null, titleSource: "none" };
135
+ }
136
+ try {
137
+ const size = fstatSync(fd).size;
138
+ const visit = (line) => {
139
+ if (line.indexOf(MARK_CUSTOM) !== -1) {
140
+ const rec = parseRecord(line);
141
+ if (rec?.type === "custom-title" && typeof rec.customTitle === "string") {
142
+ const t = cleanChatTitle(rec.customTitle, CHAT_NAMED_TITLE_MAX);
143
+ if (t) custom = t;
144
+ }
145
+ return;
146
+ }
147
+ if (line.indexOf(MARK_AI) !== -1) {
148
+ const rec = parseRecord(line);
149
+ if (rec?.type === "ai-title" && typeof rec.aiTitle === "string") {
150
+ const t = cleanChatTitle(rec.aiTitle, CHAT_NAMED_TITLE_MAX);
151
+ if (t) ai = t;
152
+ }
153
+ return;
154
+ }
155
+ if (!prompt && line.indexOf(MARK_USER) !== -1) {
156
+ prompt = cleanChatTitle(promptText(parseRecord(line)));
157
+ }
158
+ };
159
+ if (size <= fullScanMax || size <= headBytes + tailBytes) {
160
+ forEachLine(fd, 0, size, visit);
161
+ } else {
162
+ forEachLine(fd, 0, headBytes, visit);
163
+ forEachLine(fd, size - tailBytes, size, visit);
164
+ }
165
+ } catch {
166
+ } finally {
167
+ closeSync(fd);
168
+ }
169
+ if (custom) return { title: custom, titleSource: "custom" };
170
+ if (ai) return { title: ai, titleSource: "ai" };
171
+ if (prompt) return { title: prompt, titleSource: "first-prompt" };
172
+ return { title: null, titleSource: "none" };
173
+ }
174
+ var defaultTitleCache = /* @__PURE__ */ new Map();
175
+ function envelope(vendor, status, projectDir, sessions = [], total = 0) {
176
+ return { vendor, status, projectDir, sessions, total };
177
+ }
178
+ function claudeProjectDirCandidates(cwd, home) {
179
+ const out = [];
180
+ const first = claudeProjectDir(cwd, { home });
181
+ if (!first) return out;
182
+ out.push(first);
183
+ try {
184
+ const real = realpathSync(cwd);
185
+ const second = claudeProjectDir(real, { home });
186
+ if (second && second !== first) out.push(second);
187
+ } catch {
188
+ }
189
+ return out;
190
+ }
191
+ function listClaudeSessions(opts) {
192
+ const cap = Number.isInteger(opts?.cap) && opts.cap >= 0 ? opts.cap : CHAT_SESSIONS_CAP;
193
+ const cache = opts?.cache ?? defaultTitleCache;
194
+ const candidates = claudeProjectDirCandidates(String(opts?.cwd ?? ""), opts?.home);
195
+ if (candidates.length === 0) return envelope("claude", "none", null);
196
+ const projectDir = candidates.find((dir) => existsSync(dir)) ?? candidates[0];
197
+ let entries;
198
+ try {
199
+ entries = readdirSync(projectDir, { withFileTypes: true });
200
+ } catch {
201
+ return envelope("claude", "none", projectDir);
202
+ }
203
+ const found = [];
204
+ for (const entry of entries) {
205
+ if (!entry.isFile()) continue;
206
+ const m = SESSION_FILE_RE.exec(entry.name);
207
+ if (!m) continue;
208
+ const path2 = join(projectDir, entry.name);
209
+ try {
210
+ const st = statSync(path2);
211
+ found.push({ id: m[1], path: path2, mtimeMs: st.mtimeMs, size: st.size });
212
+ } catch {
213
+ }
214
+ }
215
+ if (found.length === 0) return envelope("claude", "none", projectDir);
216
+ found.sort((a, b) => b.mtimeMs - a.mtimeMs || (a.id < b.id ? -1 : 1));
217
+ let budget = opts?.scanBudgetBytes ?? CHAT_SCAN_BUDGET_BYTES;
218
+ const sessions = found.slice(0, cap).map((f) => {
219
+ const key = `${f.path}\0${f.mtimeMs}\0${f.size}`;
220
+ let title = cache.get(key);
221
+ if (!title) {
222
+ const cost = f.size <= CHAT_FULL_SCAN_MAX_BYTES ? f.size : CHAT_HEAD_BYTES + CHAT_TAIL_BYTES;
223
+ if (cost <= budget) {
224
+ title = readChatTitle(f.path);
225
+ budget -= cost;
226
+ cache.set(key, title);
227
+ } else {
228
+ title = readChatTitle(f.path, {
229
+ fullScanMaxBytes: 0,
230
+ headBytes: BUDGET_HEAD_BYTES,
231
+ tailBytes: BUDGET_TAIL_BYTES
232
+ });
233
+ }
234
+ }
235
+ return {
236
+ id: f.id,
237
+ title: title.title,
238
+ titleSource: title.titleSource,
239
+ modified: Math.floor(f.mtimeMs),
240
+ sizeBytes: f.size
241
+ };
242
+ });
243
+ return envelope("claude", "ok", projectDir, sessions, found.length);
244
+ }
245
+ function listChatSessions(opts) {
246
+ return CHAT_VENDORS.map(
247
+ (vendor) => vendor === "claude" ? listClaudeSessions(opts) : envelope(vendor, "unsupported", null)
248
+ );
249
+ }
250
+ function collectChats(opts) {
251
+ if (opts?.withhold) return { withheld: true, vendors: [] };
252
+ return { withheld: false, vendors: listChatSessions(opts) };
253
+ }
254
+ function shellQuote(value) {
255
+ const s = String(value ?? "");
256
+ if (/^[A-Za-z0-9_./-]+$/.test(s)) return s;
257
+ return `'${s.replace(/'/g, `'\\''`)}'`;
258
+ }
259
+ function formatChatAge(modifiedMs, nowMs = Date.now()) {
260
+ const secs = Math.floor(Math.max(0, nowMs - modifiedMs) / 1e3);
261
+ if (secs < 5) return "just now";
262
+ if (secs < 60) return `${secs}s ago`;
263
+ const mins = Math.floor(secs / 60);
264
+ if (mins < 60) return `${mins}m ago`;
265
+ const hrs = Math.floor(mins / 60);
266
+ if (hrs < 24) return `${hrs}h ago`;
267
+ return `${Math.floor(hrs / 24)}d ago`;
268
+ }
269
+
270
+ // src/commands/sessions.ts
271
+ var VENDOR_LABEL = {
272
+ claude: "Claude Code",
273
+ codex: "Codex",
274
+ cursor: "Cursor"
275
+ };
276
+ var TITLE_COLUMN = 48;
277
+ function vendorLabel(vendor) {
278
+ return VENDOR_LABEL[vendor] ?? vendor;
279
+ }
280
+ function renderChatSessions(chats, opts) {
281
+ const now = opts.now ?? Date.now();
282
+ const needsCd = path.resolve(opts.cwd ?? opts.workspace) !== path.resolve(opts.workspace);
283
+ const lines = [];
284
+ const claude = chats.vendors.find((v) => v.vendor === "claude");
285
+ if (claude?.status !== "ok") {
286
+ lines.push(`No saved Claude Code chats for ${opts.workspace}.`);
287
+ lines.push(
288
+ "The agent CLI saves sessions per folder: start `claude` in this folder to create one."
289
+ );
290
+ } else {
291
+ const shown = claude.sessions.length;
292
+ const count = shown < claude.total ? `${shown} newest of ${claude.total}` : `${claude.total} saved`;
293
+ lines.push(`Claude Code chats for ${opts.workspace} (${count})`);
294
+ lines.push("");
295
+ const ageWidth = Math.max(...claude.sessions.map((s) => formatChatAge(s.modified, now).length));
296
+ for (const s of claude.sessions) {
297
+ const title = cleanChatTitle(s.title ?? "(untitled)", TITLE_COLUMN).padEnd(TITLE_COLUMN);
298
+ const age = formatChatAge(s.modified, now).padEnd(ageWidth);
299
+ lines.push(` ${title} ${age} ${s.id.slice(0, 8)} claude --resume ${s.id}`);
300
+ }
301
+ if (needsCd) {
302
+ lines.push("");
303
+ lines.push(`Resume from that folder: cd ${shellQuote(opts.workspace)} first.`);
304
+ }
305
+ }
306
+ const unsupported = chats.vendors.filter((v) => v.status === "unsupported");
307
+ if (unsupported.length > 0) {
308
+ lines.push("");
309
+ lines.push(unsupported.map((v) => `${vendorLabel(v.vendor)}: not supported yet`).join(" \xB7 "));
310
+ }
311
+ return lines.join("\n");
312
+ }
313
+ var sessionsCommand = defineCommand({
314
+ meta: {
315
+ name: "sessions",
316
+ description: "List this folder's saved agent chats with the command that resumes each one"
317
+ },
318
+ args: {
319
+ json: {
320
+ type: "boolean",
321
+ description: "Print {withheld, vendors[]} as JSON (one envelope per vendor)",
322
+ default: false
323
+ },
324
+ cwd: {
325
+ type: "string",
326
+ description: "Workspace folder whose chats to list (default: current directory)"
327
+ }
328
+ },
329
+ run({ args }) {
330
+ const cwd = process.cwd();
331
+ const workspace = path.resolve(cwd, typeof args.cwd === "string" && args.cwd ? args.cwd : ".");
332
+ const chats = collectChats({ cwd: workspace });
333
+ process.stdout.write(
334
+ args.json ? `${JSON.stringify(chats, null, 2)}
335
+ ` : `${renderChatSessions(chats, { workspace, cwd })}
336
+ `
337
+ );
338
+ }
339
+ });
340
+ export {
341
+ renderChatSessions,
342
+ sessionsCommand
343
+ };
@@ -2,15 +2,15 @@ import {
2
2
  classifyInstallError,
3
3
  isNonInteractive,
4
4
  pathCliStatus
5
- } from "./chunk-OWWFKGKS.js";
5
+ } from "./chunk-SE7ZIRLX.js";
6
6
  import {
7
7
  assessEnvironment
8
8
  } from "./chunk-B3VR5YBQ.js";
9
- import "./chunk-6GYKOHIL.js";
9
+ import "./chunk-3OM7JODZ.js";
10
10
  import "./chunk-PFEUZXVT.js";
11
- import "./chunk-VQBI3JVS.js";
12
- import "./chunk-25J2SMJQ.js";
13
- import "./chunk-6KUSG7BJ.js";
11
+ import "./chunk-ANPSYWQO.js";
12
+ import "./chunk-E465FAWM.js";
13
+ import "./chunk-7BEHUBEJ.js";
14
14
  import {
15
15
  KIT_VERSION,
16
16
  pinnedCliSpec