linkshell-cli 0.6.1 → 0.6.3

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 (108) hide show
  1. package/README.md +47 -132
  2. package/dist/cli/src/auth.js +1 -1
  3. package/dist/cli/src/auth.js.map +1 -1
  4. package/dist/cli/src/commands/doctor.d.ts +1 -1
  5. package/dist/cli/src/commands/doctor.js +76 -36
  6. package/dist/cli/src/commands/doctor.js.map +1 -1
  7. package/dist/cli/src/commands/host.d.ts +15 -0
  8. package/dist/cli/src/commands/host.js +101 -20
  9. package/dist/cli/src/commands/host.js.map +1 -1
  10. package/dist/cli/src/commands/logout.d.ts +1 -1
  11. package/dist/cli/src/commands/logout.js +10 -2
  12. package/dist/cli/src/commands/logout.js.map +1 -1
  13. package/dist/cli/src/commands/upgrade.js +11 -0
  14. package/dist/cli/src/commands/upgrade.js.map +1 -1
  15. package/dist/cli/src/config.js +1 -1
  16. package/dist/cli/src/config.js.map +1 -1
  17. package/dist/cli/src/index.js +105 -120
  18. package/dist/cli/src/index.js.map +1 -1
  19. package/dist/cli/src/utils/daemon.d.ts +2 -0
  20. package/dist/cli/src/utils/daemon.js +4 -0
  21. package/dist/cli/src/utils/daemon.js.map +1 -1
  22. package/dist/cli/tsconfig.tsbuildinfo +1 -1
  23. package/dist/host/src/carry.d.ts +15 -0
  24. package/dist/host/src/carry.js +83 -0
  25. package/dist/host/src/carry.js.map +1 -0
  26. package/dist/host/src/drivers/acp/driver.d.ts +21 -3
  27. package/dist/host/src/drivers/acp/driver.js +99 -13
  28. package/dist/host/src/drivers/acp/driver.js.map +1 -1
  29. package/dist/host/src/drivers/acp/mapper.d.ts +5 -1
  30. package/dist/host/src/drivers/acp/mapper.js +58 -6
  31. package/dist/host/src/drivers/acp/mapper.js.map +1 -1
  32. package/dist/host/src/drivers/claude/driver.d.ts +76 -8
  33. package/dist/host/src/drivers/claude/driver.js +510 -29
  34. package/dist/host/src/drivers/claude/driver.js.map +1 -1
  35. package/dist/host/src/drivers/claude/holders.d.ts +9 -0
  36. package/dist/host/src/drivers/claude/holders.js +61 -0
  37. package/dist/host/src/drivers/claude/holders.js.map +1 -0
  38. package/dist/host/src/drivers/claude/transcript.d.ts +105 -61
  39. package/dist/host/src/drivers/claude/transcript.js +260 -22
  40. package/dist/host/src/drivers/claude/transcript.js.map +1 -1
  41. package/dist/host/src/drivers/codex/commands.d.ts +27 -0
  42. package/dist/host/src/drivers/codex/commands.js +23 -0
  43. package/dist/host/src/drivers/codex/commands.js.map +1 -0
  44. package/dist/host/src/drivers/codex/driver.d.ts +21 -1
  45. package/dist/host/src/drivers/codex/driver.js +140 -1
  46. package/dist/host/src/drivers/codex/driver.js.map +1 -1
  47. package/dist/host/src/drivers/codex/mapper.d.ts +4 -0
  48. package/dist/host/src/drivers/codex/mapper.js +29 -5
  49. package/dist/host/src/drivers/codex/mapper.js.map +1 -1
  50. package/dist/host/src/drivers/types.d.ts +45 -4
  51. package/dist/host/src/fs.d.ts +26 -4
  52. package/dist/host/src/fs.js +71 -17
  53. package/dist/host/src/fs.js.map +1 -1
  54. package/dist/host/src/gateway.d.ts +3 -0
  55. package/dist/host/src/gateway.js +10 -1
  56. package/dist/host/src/gateway.js.map +1 -1
  57. package/dist/host/src/host.d.ts +7 -3
  58. package/dist/host/src/host.js +53 -21
  59. package/dist/host/src/host.js.map +1 -1
  60. package/dist/host/src/hub.d.ts +98 -14
  61. package/dist/host/src/hub.js +639 -27
  62. package/dist/host/src/hub.js.map +1 -1
  63. package/dist/host/src/index.d.ts +1 -1
  64. package/dist/host/src/index.js +1 -1
  65. package/dist/host/src/index.js.map +1 -1
  66. package/dist/host/src/legacy.d.ts +7 -0
  67. package/dist/host/src/legacy.js +36 -0
  68. package/dist/host/src/legacy.js.map +1 -0
  69. package/dist/host/src/rpc/server.d.ts +4 -2
  70. package/dist/host/src/rpc/server.js +62 -5
  71. package/dist/host/src/rpc/server.js.map +1 -1
  72. package/dist/host/src/screen.d.ts +11 -0
  73. package/dist/host/src/screen.js +54 -2
  74. package/dist/host/src/screen.js.map +1 -1
  75. package/dist/host/src/shell-env.d.ts +6 -0
  76. package/dist/host/src/shell-env.js +48 -0
  77. package/dist/host/src/shell-env.js.map +1 -1
  78. package/dist/host/src/slim.d.ts +17 -0
  79. package/dist/host/src/slim.js +66 -0
  80. package/dist/host/src/slim.js.map +1 -0
  81. package/dist/host/src/store.d.ts +81 -3
  82. package/dist/host/src/store.js +249 -16
  83. package/dist/host/src/store.js.map +1 -1
  84. package/dist/host/src/terminals.d.ts +4 -4
  85. package/dist/host/src/terminals.js +19 -4
  86. package/dist/host/src/terminals.js.map +1 -1
  87. package/dist/host/src/worktrees.d.ts +36 -0
  88. package/dist/host/src/worktrees.js +96 -0
  89. package/dist/host/src/worktrees.js.map +1 -0
  90. package/dist/wire/src/model.d.ts +334 -139
  91. package/dist/wire/src/model.js +68 -0
  92. package/dist/wire/src/model.js.map +1 -1
  93. package/dist/wire/src/relay-client.d.ts +2 -0
  94. package/dist/wire/src/relay-client.js +12 -0
  95. package/dist/wire/src/relay-client.js.map +1 -1
  96. package/dist/wire/src/rpc.d.ts +7273 -890
  97. package/dist/wire/src/rpc.js +154 -6
  98. package/dist/wire/src/rpc.js.map +1 -1
  99. package/dist/wire/src/updates.d.ts +498 -498
  100. package/package.json +5 -5
  101. package/src/auth.ts +1 -1
  102. package/src/commands/doctor.ts +76 -34
  103. package/src/commands/host.ts +109 -19
  104. package/src/commands/logout.ts +10 -2
  105. package/src/commands/upgrade.ts +11 -0
  106. package/src/config.ts +1 -1
  107. package/src/index.ts +104 -137
  108. package/src/utils/daemon.ts +5 -0
@@ -1 +1 @@
1
- {"version":3,"file":"screen.js","sourceRoot":"","sources":["../../../../host/src/screen.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"screen.js","sourceRoot":"","sources":["../../../../host/src/screen.ts"],"names":[],"mappings":"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"}
@@ -6,3 +6,9 @@
6
6
  * agents would fail auth. Falls back to the current environment.
7
7
  */
8
8
  export declare function resolveLoginShellEnv(timeoutMs?: number): Promise<NodeJS.ProcessEnv>;
9
+ /**
10
+ * The environment without what a surrounding Claude Code session added —
11
+ * LinkShell started from inside one (its terminal, a command it ran). Only
12
+ * then: `CLAUDECODE` marks it.
13
+ */
14
+ export declare function withoutClaudeSession(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
@@ -36,4 +36,52 @@ export async function resolveLoginShellEnv(timeoutMs = 10_000) {
36
36
  return process.env;
37
37
  }
38
38
  }
39
+ // What a running Claude Code session puts in its children's environment: who
40
+ // the parent is, how to reach it, and how it tuned itself. Inherited by an
41
+ // agent LinkShell starts, they make that agent a child of the other session
42
+ // (Claude then keeps no transcript, so no handoff) and override the phone's
43
+ // choices (CLAUDE_EFFORT). The user's own settings (API keys, CLAUDE_CONFIG_DIR,
44
+ // ANTHROPIC_BASE_URL…) are not in the list.
45
+ const CLAUDE_SESSION_VARIABLES = [
46
+ "CLAUDECODE",
47
+ "CLAUDE_PID",
48
+ "CLAUDE_EFFORT",
49
+ "CLAUDE_AGENT_SDK_VERSION",
50
+ "CLAUDE_PREVIEW_CLASSIFIER_FLOOR",
51
+ "CLAUDE_CODE_ENTRYPOINT",
52
+ "CLAUDE_CODE_EXECPATH",
53
+ "CLAUDE_CODE_SESSION_ID",
54
+ "CLAUDE_CODE_CHILD_SESSION",
55
+ "CLAUDE_CODE_HOST_SESSION_ID",
56
+ "CLAUDE_CODE_SESSION_ATTENDED",
57
+ "CLAUDE_CODE_SSE_PORT",
58
+ "CLAUDE_CODE_MESSAGING_SOCKET",
59
+ "CLAUDE_CODE_MESSAGING_TOKEN",
60
+ "CLAUDE_CODE_DESKTOP_APP_VERSION",
61
+ "CLAUDE_CODE_OAUTH_SCOPES",
62
+ "CLAUDE_CODE_ORGANIZATION_UUID",
63
+ "CLAUDE_CODE_ACCOUNT_UUID",
64
+ "CLAUDE_CODE_SDK_HAS_HOST_AUTH_REFRESH",
65
+ "CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING",
66
+ "CLAUDE_CODE_ENABLE_ASK_USER_QUESTION_TOOL",
67
+ "CLAUDE_CODE_EMIT_TOOL_USE_SUMMARIES",
68
+ "CLAUDE_CODE_DISABLE_TERMINAL_TITLE",
69
+ "CLAUDE_CODE_DISABLE_CRON",
70
+ "CLAUDE_CODE_TERMINAL_MCP_TOOLS",
71
+ "CLAUDE_CODE_EAGER_FLUSH",
72
+ "CLAUDE_CODE_REPORT_FINDINGS",
73
+ ];
74
+ /**
75
+ * The environment without what a surrounding Claude Code session added —
76
+ * LinkShell started from inside one (its terminal, a command it ran). Only
77
+ * then: `CLAUDECODE` marks it.
78
+ */
79
+ export function withoutClaudeSession(env) {
80
+ if (!env.CLAUDECODE)
81
+ return env;
82
+ const clean = { ...env };
83
+ for (const name of CLAUDE_SESSION_VARIABLES)
84
+ delete clean[name];
85
+ return clean;
86
+ }
39
87
  //# sourceMappingURL=shell-env.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shell-env.js","sourceRoot":"","sources":["../../../../host/src/shell-env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,SAAS,GAAG,MAAM;IAC3D,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC;IACrD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,UAAU,CAAC;IAC9C,MAAM,MAAM,GAAG,mBAAmB,UAAU,EAAE,IAAI,CAAC;IACnD,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,gBAAgB,MAAM,mBAAmB,CAAC,EAAE;YACjG,OAAO,EAAE,SAAS;YAClB,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;YAC3B,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,6BAA6B,EAAE,GAAG,EAAE;SAC5D,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,KAAK,GAAG,CAAC;YAAE,OAAO,OAAO,CAAC,GAAG,CAAC;QAClC,MAAM,QAAQ,GAAsB,EAAE,CAAC;QACvC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACpE,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACjC,IAAI,KAAK,GAAG,CAAC;gBAAE,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO,QAAQ,CAAC,6BAA6B,CAAC;QAC9C,OAAO,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC,GAAG,CAAC;IACrB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"shell-env.js","sourceRoot":"","sources":["../../../../host/src/shell-env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,SAAS,GAAG,MAAM;IAC3D,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC;IACrD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,UAAU,CAAC;IAC9C,MAAM,MAAM,GAAG,mBAAmB,UAAU,EAAE,IAAI,CAAC;IACnD,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,gBAAgB,MAAM,mBAAmB,CAAC,EAAE;YACjG,OAAO,EAAE,SAAS;YAClB,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;YAC3B,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,6BAA6B,EAAE,GAAG,EAAE;SAC5D,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,KAAK,GAAG,CAAC;YAAE,OAAO,OAAO,CAAC,GAAG,CAAC;QAClC,MAAM,QAAQ,GAAsB,EAAE,CAAC;QACvC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACpE,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACjC,IAAI,KAAK,GAAG,CAAC;gBAAE,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO,QAAQ,CAAC,6BAA6B,CAAC;QAC9C,OAAO,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC,GAAG,CAAC;IACrB,CAAC;AACH,CAAC;AAED,6EAA6E;AAC7E,2EAA2E;AAC3E,4EAA4E;AAC5E,4EAA4E;AAC5E,iFAAiF;AACjF,4CAA4C;AAC5C,MAAM,wBAAwB,GAAG;IAC/B,YAAY;IACZ,YAAY;IACZ,eAAe;IACf,0BAA0B;IAC1B,iCAAiC;IACjC,wBAAwB;IACxB,sBAAsB;IACtB,wBAAwB;IACxB,2BAA2B;IAC3B,6BAA6B;IAC7B,8BAA8B;IAC9B,sBAAsB;IACtB,8BAA8B;IAC9B,6BAA6B;IAC7B,iCAAiC;IACjC,0BAA0B;IAC1B,+BAA+B;IAC/B,0BAA0B;IAC1B,uCAAuC;IACvC,2CAA2C;IAC3C,2CAA2C;IAC3C,qCAAqC;IACrC,oCAAoC;IACpC,0BAA0B;IAC1B,gCAAgC;IAChC,yBAAyB;IACzB,6BAA6B;CAC9B,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAsB;IACzD,IAAI,CAAC,GAAG,CAAC,UAAU;QAAE,OAAO,GAAG,CAAC;IAChC,MAAM,KAAK,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC;IACzB,KAAK,MAAM,IAAI,IAAI,wBAAwB;QAAE,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC;IAChE,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { SessionEvent } from "@linkshell/wire";
2
+ export interface SlimOptions {
3
+ /** The client fetches pictures itself (`sessions.image`); otherwise they become a note. */
4
+ lazyImages?: boolean;
5
+ }
6
+ /** The event as sent to a client; the same object when nothing in it is heavy. */
7
+ export declare function slimEvent(event: SessionEvent, options?: SlimOptions): SessionEvent;
8
+ /** Which event and which of its pictures a `linkshell-event:` uri names. */
9
+ export declare function parseImageUri(uri: string): {
10
+ seq: number;
11
+ index: number;
12
+ } | undefined;
13
+ /** The picture `slimEvent` replaced with reference `index`. */
14
+ export declare function imageOf(event: SessionEvent, index: number): {
15
+ mimeType: string;
16
+ data: string;
17
+ } | undefined;
@@ -0,0 +1,66 @@
1
+ // What a client is sent of an event. The log keeps everything an agent
2
+ // produced; a phone reading a session through a relay needs the conversation,
3
+ // not every screenshot and file dump in it. Pictures become references the
4
+ // client loads when it shows them, and very long text is cut.
5
+ /** Pictures up to this size (base64 characters) travel inline. */
6
+ const INLINE_IMAGE = 16 * 1024;
7
+ /** Text beyond this is cut. */
8
+ const MAX_TEXT = 32 * 1024;
9
+ const KEPT_TEXT = 24 * 1024;
10
+ const IMAGE_URI = /^linkshell-event:(\d+)\/(\d+)$/;
11
+ function isLargeImage(value) {
12
+ const block = value;
13
+ return block?.type === "image" && typeof block.data === "string" && block.data.length > INLINE_IMAGE && typeof block.mimeType === "string";
14
+ }
15
+ /** Visits every large picture in an update, in a fixed order; `replace` returns what takes its place. */
16
+ function walk(value, state, replace, cut) {
17
+ if (typeof value === "string") {
18
+ if (!cut || value.length <= MAX_TEXT)
19
+ return value;
20
+ return `${value.slice(0, KEPT_TEXT)}\n… [已省略 ${Math.round((value.length - KEPT_TEXT) / 1024)} KB,完整内容在电脑上]`;
21
+ }
22
+ if (Array.isArray(value)) {
23
+ let out;
24
+ value.forEach((entry, i) => {
25
+ const next = walk(entry, state, replace, cut);
26
+ if (next !== entry)
27
+ (out ??= value.slice())[i] = next;
28
+ });
29
+ return out ?? value;
30
+ }
31
+ if (value && typeof value === "object") {
32
+ if (isLargeImage(value))
33
+ return replace(value, state.images++);
34
+ let out;
35
+ for (const [key, entry] of Object.entries(value)) {
36
+ const next = walk(entry, state, replace, cut);
37
+ if (next !== entry)
38
+ (out ??= { ...value })[key] = next;
39
+ }
40
+ return out ?? value;
41
+ }
42
+ return value;
43
+ }
44
+ /** The event as sent to a client; the same object when nothing in it is heavy. */
45
+ export function slimEvent(event, options = {}) {
46
+ const update = walk(event.update, { images: 0 }, (image, index) => options.lazyImages
47
+ ? { type: "image", mimeType: image.mimeType, uri: `linkshell-event:${event.seq}/${index}` }
48
+ : { type: "text", text: "[图片]" }, true);
49
+ return update === event.update ? event : { ...event, update: update };
50
+ }
51
+ /** Which event and which of its pictures a `linkshell-event:` uri names. */
52
+ export function parseImageUri(uri) {
53
+ const match = IMAGE_URI.exec(uri);
54
+ return match ? { seq: Number(match[1]), index: Number(match[2]) } : undefined;
55
+ }
56
+ /** The picture `slimEvent` replaced with reference `index`. */
57
+ export function imageOf(event, index) {
58
+ let found;
59
+ walk(event.update, { images: 0 }, (image, at) => {
60
+ if (at === index)
61
+ found = { mimeType: image.mimeType, data: image.data };
62
+ return image;
63
+ }, false);
64
+ return found;
65
+ }
66
+ //# sourceMappingURL=slim.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slim.js","sourceRoot":"","sources":["../../../../host/src/slim.ts"],"names":[],"mappings":"AAEA,uEAAuE;AACvE,8EAA8E;AAC9E,2EAA2E;AAC3E,8DAA8D;AAE9D,kEAAkE;AAClE,MAAM,YAAY,GAAG,EAAE,GAAG,IAAI,CAAC;AAC/B,+BAA+B;AAC/B,MAAM,QAAQ,GAAG,EAAE,GAAG,IAAI,CAAC;AAC3B,MAAM,SAAS,GAAG,EAAE,GAAG,IAAI,CAAC;AAE5B,MAAM,SAAS,GAAG,gCAAgC,CAAC;AASnD,SAAS,YAAY,CAAC,KAAW;IAC/B,MAAM,KAAK,GAAG,KAA+D,CAAC;IAC9E,OAAO,KAAK,EAAE,IAAI,KAAK,OAAO,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,YAAY,IAAI,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ,CAAC;AAC7I,CAAC;AAED,yGAAyG;AACzG,SAAS,IAAI,CAAC,KAAW,EAAE,KAAyB,EAAE,OAA2E,EAAE,GAAY;IAC7I,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC,GAAG,IAAI,KAAK,CAAC,MAAM,IAAI,QAAQ;YAAE,OAAO,KAAK,CAAC;QACnD,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,YAAY,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC;IAC9G,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,IAAI,GAAuB,CAAC;QAC5B,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;YACzB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;YAC9C,IAAI,IAAI,KAAK,KAAK;gBAAE,CAAC,GAAG,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;QACxD,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,IAAI,KAAK,CAAC;IACtB,CAAC;IACD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,IAAI,YAAY,CAAC,KAAK,CAAC;YAAE,OAAO,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAC/D,IAAI,GAAqC,CAAC;QAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACjD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;YAC9C,IAAI,IAAI,KAAK,KAAK;gBAAE,CAAC,GAAG,KAAK,EAAE,GAAI,KAA8B,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;QACnF,CAAC;QACD,OAAO,GAAG,IAAI,KAAK,CAAC;IACtB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,SAAS,CAAC,KAAmB,EAAE,UAAuB,EAAE;IACtE,MAAM,MAAM,GAAG,IAAI,CACjB,KAAK,CAAC,MAAM,EACZ,EAAE,MAAM,EAAE,CAAC,EAAE,EACb,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CACf,OAAO,CAAC,UAAU;QAChB,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,GAAG,EAAE,mBAAmB,KAAK,CAAC,GAAG,IAAI,KAAK,EAAE,EAAE;QAC3F,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EACpC,IAAI,CACL,CAAC;IACF,OAAO,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,MAAgC,EAAE,CAAC;AAClG,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClC,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAChF,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,OAAO,CAAC,KAAmB,EAAE,KAAa;IACxD,IAAI,KAAqD,CAAC;IAC1D,IAAI,CACF,KAAK,CAAC,MAAM,EACZ,EAAE,MAAM,EAAE,CAAC,EAAE,EACb,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;QACZ,IAAI,EAAE,KAAK,KAAK;YAAE,KAAK,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;QACzE,OAAO,KAAK,CAAC;IACf,CAAC,EACD,KAAK,CACN,CAAC;IACF,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -34,7 +34,35 @@ export type SessionPatch = Partial<{
34
34
  model: string | null;
35
35
  updatedAt: number;
36
36
  archived: boolean;
37
+ customTitle: string | null;
37
38
  }>;
39
+ /** A git worktree made for sessions (see worktrees.ts). */
40
+ export interface WorktreeRecord {
41
+ /** The worktree's top directory. */
42
+ path: string;
43
+ branch: string;
44
+ /** The repository's top directory. */
45
+ source: string;
46
+ /** The directory the first session in it was started from (a project, possibly inside the repository). */
47
+ sourceCwd: string;
48
+ /** The commit it started at. */
49
+ base: string;
50
+ createdAt: number;
51
+ }
52
+ /** The worktree `cwd` is in, if any. */
53
+ export declare function worktreeOf(cwd: string, worktrees: WorktreeRecord[]): WorktreeRecord | undefined;
54
+ /** How much history one page carries (see `pageStart`). */
55
+ export interface PageBudget {
56
+ /** A page goes back whole turns until it has this many events or bytes… */
57
+ minEvents: number;
58
+ minBytes: number;
59
+ /** …and never more than this, even inside one turn. */
60
+ maxEvents: number;
61
+ maxBytes: number;
62
+ /** What one event counts for at most: its size as sent, not as stored. */
63
+ eventBytes: number;
64
+ }
65
+ export declare const PAGE: PageBudget;
38
66
  /**
39
67
  * Durable host state: session summaries plus one append-only event log per
40
68
  * session. Every update a client sees gets a per-session `seq`, so a client
@@ -43,6 +71,11 @@ export type SessionPatch = Partial<{
43
71
  export declare class HostStore {
44
72
  private readonly db;
45
73
  constructor(path: string);
74
+ /** Columns added after the first release. */
75
+ private migrate;
76
+ /** Deleted by the user: forgotten, and kept out of rediscovery. */
77
+ removeSession(id: string): void;
78
+ isRemoved(id: string): boolean;
46
79
  close(): void;
47
80
  saveTerminal(t: TerminalRecord): void;
48
81
  listTerminals(): TerminalRecord[];
@@ -60,9 +93,54 @@ export declare class HostStore {
60
93
  includeArchived?: boolean;
61
94
  }): SessionSummary[];
62
95
  listProjects(limit?: number): ProjectSummary[];
63
- /** Appends one update to the session's log and returns it with its seq. */
64
- appendEvent(sessionId: string, update: SessionUpdate, ts?: number): SessionEvent;
65
- readEvents(sessionId: string, afterSeq: number, limit?: number): SessionEvent[];
96
+ saveWorktree(worktree: WorktreeRecord): void;
97
+ listWorktrees(): WorktreeRecord[];
98
+ deleteWorktree(path: string): void;
99
+ /** Sessions whose directory is `path` or inside it. */
100
+ sessionsUnder(path: string): string[];
101
+ /** The seq of the latest event that mentions message or tool call `itemId`, and how many turns had started by then. */
102
+ locateItem(sessionId: string, itemId: string): {
103
+ seq: number;
104
+ turn: number;
105
+ } | undefined;
106
+ /** Where the exchange that `seq` is in ends: just before the user speaks next, or the end of the session. */
107
+ turnEnd(sessionId: string, seq: number): number;
108
+ /**
109
+ * Appends one update to the session's log and returns it with its seq.
110
+ * `activity` false: the session's "last updated" stays (a setting or a name
111
+ * is not something happening in the session).
112
+ */
113
+ appendEvent(sessionId: string, update: SessionUpdate, ts?: number, activity?: boolean): SessionEvent;
114
+ /** Events after `afterSeq`, up to and including `upToSeq` when given. */
115
+ readEvents(sessionId: string, afterSeq: number, limit?: number, upToSeq?: number): SessionEvent[];
116
+ readEvent(sessionId: string, seq: number): SessionEvent | undefined;
117
+ /** How much was logged after `afterSeq`. */
118
+ sizeAfter(sessionId: string, afterSeq: number): {
119
+ events: number;
120
+ bytes: number;
121
+ };
122
+ /**
123
+ * Where a page of history ending at `beforeSeq` starts: the seq before its
124
+ * first event (0: the beginning of the log). Pages are whole turns, going
125
+ * back until one is worth showing; a single turn too big for a page is cut.
126
+ */
127
+ pageStart(sessionId: string, beforeSeq: number, page?: PageBudget): number;
128
+ /** The calls that started a sub-agent, oldest first. */
129
+ subagentCalls(sessionId: string): SessionEvent[];
130
+ /** A tool call's own events (the call and its updates), oldest first. */
131
+ toolEvents(sessionId: string, toolCallId: string): SessionEvent[];
132
+ /** The latest `limit` events of the sub-agent under a tool call, oldest first. */
133
+ eventsUnder(sessionId: string, toolCallId: string, limit: number): SessionEvent[];
134
+ /** A tool call's latest status, whether the sub-agent under it is in a turn, and when that sub-agent last did anything. */
135
+ toolState(sessionId: string, toolCallId: string): {
136
+ status?: string;
137
+ ts?: number;
138
+ turnActive?: boolean;
139
+ lastChildTs?: number;
140
+ };
141
+ private joined;
142
+ /** The latest event of `kind` at or before `seq`. */
143
+ latestOfKind(sessionId: string, kind: SessionUpdate["sessionUpdate"], seq: number, limit?: number): SessionEvent[];
66
144
  /** Marks a native item (message, tool call) as present in the log. Returns false if it already was. */
67
145
  markItemLogged(sessionId: string, itemId: string): boolean;
68
146
  isItemLogged(sessionId: string, itemId: string): boolean;
@@ -27,6 +27,18 @@ CREATE TABLE IF NOT EXISTS events (
27
27
  body TEXT NOT NULL,
28
28
  PRIMARY KEY (session_id, seq)
29
29
  ) WITHOUT ROWID;
30
+ CREATE TABLE IF NOT EXISTS event_meta (
31
+ session_id TEXT NOT NULL,
32
+ seq INTEGER NOT NULL,
33
+ kind TEXT NOT NULL,
34
+ bytes INTEGER NOT NULL,
35
+ opens_turn INTEGER NOT NULL DEFAULT 0,
36
+ tool TEXT,
37
+ parent TEXT,
38
+ spawns INTEGER NOT NULL DEFAULT 0,
39
+ PRIMARY KEY (session_id, seq)
40
+ ) WITHOUT ROWID;
41
+ CREATE INDEX IF NOT EXISTS event_meta_by_kind ON event_meta (session_id, kind, seq);
30
42
  CREATE TABLE IF NOT EXISTS logged_items (
31
43
  session_id TEXT NOT NULL,
32
44
  item_id TEXT NOT NULL,
@@ -44,6 +56,18 @@ CREATE TABLE IF NOT EXISTS client_messages (
44
56
  ts INTEGER NOT NULL,
45
57
  PRIMARY KEY (session_id, client_message_id)
46
58
  ) WITHOUT ROWID;
59
+ CREATE TABLE IF NOT EXISTS removed_sessions (
60
+ id TEXT PRIMARY KEY,
61
+ ts INTEGER NOT NULL
62
+ ) WITHOUT ROWID;
63
+ CREATE TABLE IF NOT EXISTS worktrees (
64
+ path TEXT PRIMARY KEY,
65
+ branch TEXT NOT NULL,
66
+ source TEXT NOT NULL,
67
+ source_cwd TEXT NOT NULL,
68
+ base TEXT NOT NULL,
69
+ created_at INTEGER NOT NULL
70
+ ) WITHOUT ROWID;
47
71
  CREATE TABLE IF NOT EXISTS terminals (
48
72
  id TEXT PRIMARY KEY,
49
73
  cwd TEXT NOT NULL,
@@ -68,13 +92,15 @@ const PATCH_COLUMNS = {
68
92
  model: "model",
69
93
  updatedAt: "updated_at",
70
94
  archived: "archived",
95
+ customTitle: "custom_title",
71
96
  };
72
97
  function toSummary(row) {
73
98
  return {
74
99
  id: row.id,
75
100
  agent: row.agent,
76
101
  nativeId: row.native_id,
77
- title: row.title ?? undefined,
102
+ // A name given in LinkShell wins over the agent's own.
103
+ title: row.custom_title ?? row.title ?? undefined,
78
104
  preview: row.preview ?? undefined,
79
105
  cwd: row.cwd,
80
106
  state: row.state,
@@ -87,6 +113,15 @@ function toSummary(row) {
87
113
  archived: row.archived === 1,
88
114
  };
89
115
  }
116
+ /** The worktree `cwd` is in, if any. */
117
+ export function worktreeOf(cwd, worktrees) {
118
+ return worktrees.find((worktree) => cwd === worktree.path || cwd.startsWith(`${worktree.path}/`));
119
+ }
120
+ /** The project a session in `cwd` belongs to: for a worktree, the directory it was made from. */
121
+ function projectOf(cwd, worktrees) {
122
+ return worktreeOf(cwd, worktrees)?.sourceCwd ?? cwd;
123
+ }
124
+ export const PAGE = { minEvents: 120, minBytes: 384 * 1024, maxEvents: 600, maxBytes: 2 * 1024 * 1024, eventBytes: 40 * 1024 };
90
125
  /**
91
126
  * Durable host state: session summaries plus one append-only event log per
92
127
  * session. Every update a client sees gets a per-session `seq`, so a client
@@ -97,6 +132,61 @@ export class HostStore {
97
132
  constructor(path) {
98
133
  this.db = new DatabaseSync(path);
99
134
  this.db.exec(SCHEMA);
135
+ this.migrate();
136
+ }
137
+ /** Columns added after the first release. */
138
+ migrate() {
139
+ const columns = new Set(this.db.prepare("PRAGMA table_info(sessions)").all().map((c) => c.name));
140
+ if (!columns.has("custom_title"))
141
+ this.db.exec("ALTER TABLE sessions ADD COLUMN custom_title TEXT");
142
+ // event_meta came later (and its sub-agent columns later still): describe
143
+ // the events logged before it, once.
144
+ const meta = new Set(this.db.prepare("PRAGMA table_info(event_meta)").all().map((c) => c.name));
145
+ if (!meta.has("tool")) {
146
+ this.db.exec("ALTER TABLE event_meta ADD COLUMN tool TEXT; ALTER TABLE event_meta ADD COLUMN parent TEXT; ALTER TABLE event_meta ADD COLUMN spawns INTEGER NOT NULL DEFAULT 0;");
147
+ }
148
+ this.db.exec(`
149
+ CREATE INDEX IF NOT EXISTS event_meta_by_tool ON event_meta (session_id, tool, seq) WHERE tool IS NOT NULL;
150
+ CREATE INDEX IF NOT EXISTS event_meta_by_parent ON event_meta (session_id, parent, seq) WHERE parent IS NOT NULL;
151
+ CREATE INDEX IF NOT EXISTS event_meta_spawns ON event_meta (session_id, seq) WHERE spawns = 1;
152
+ `);
153
+ const { user_version: version } = this.db.prepare("PRAGMA user_version").get();
154
+ if (version < 2) {
155
+ this.db.exec(`
156
+ INSERT OR REPLACE INTO event_meta (session_id, seq, kind, bytes, opens_turn, tool, parent, spawns)
157
+ SELECT session_id, seq, COALESCE(json_extract(body, '$.sessionUpdate'), ''), length(CAST(body AS BLOB)),
158
+ CASE json_extract(body, '$.sessionUpdate')
159
+ WHEN 'user_message_chunk' THEN 1
160
+ WHEN 'ls_turn' THEN COALESCE(json_extract(body, '$.state') = 'started' AND json_extract(body, '$.parentToolCallId') IS NULL, 0)
161
+ ELSE 0 END,
162
+ json_extract(body, '$.toolCallId'),
163
+ json_extract(body, '$.parentToolCallId'),
164
+ COALESCE(json_extract(body, '$.sessionUpdate') = 'tool_call' AND json_extract(body, '$.detail.type') = 'subagent'
165
+ AND COALESCE(json_extract(body, '$.detail.action'), 'spawn') = 'spawn', 0)
166
+ FROM events;
167
+ PRAGMA user_version = 2;
168
+ `);
169
+ }
170
+ }
171
+ // ── removal ───────────────────────────────────────────────────────
172
+ /** Deleted by the user: forgotten, and kept out of rediscovery. */
173
+ removeSession(id) {
174
+ this.db.exec("BEGIN IMMEDIATE");
175
+ try {
176
+ for (const table of ["sessions", "events", "event_meta", "logged_items", "driver_state", "client_messages"]) {
177
+ const column = table === "sessions" ? "id" : "session_id";
178
+ this.db.prepare(`DELETE FROM ${table} WHERE ${column} = ?`).run(id);
179
+ }
180
+ this.db.prepare("INSERT OR REPLACE INTO removed_sessions (id, ts) VALUES (?, ?)").run(id, Date.now());
181
+ this.db.exec("COMMIT");
182
+ }
183
+ catch (error) {
184
+ this.db.exec("ROLLBACK");
185
+ throw error;
186
+ }
187
+ }
188
+ isRemoved(id) {
189
+ return this.db.prepare("SELECT 1 FROM removed_sessions WHERE id = ?").get(id) !== undefined;
100
190
  }
101
191
  close() {
102
192
  this.db.close();
@@ -192,28 +282,90 @@ export class HostStore {
192
282
  }
193
283
  listProjects(limit = 50) {
194
284
  const rows = this.db
195
- .prepare(`SELECT cwd, MAX(updated_at) AS last_active_at, COUNT(*) AS session_count
196
- FROM sessions WHERE archived = 0 GROUP BY cwd ORDER BY last_active_at DESC LIMIT ?`)
197
- .all(limit);
285
+ .prepare(`SELECT cwd, MAX(updated_at) AS last_active_at, COUNT(*) AS session_count FROM sessions WHERE archived = 0 GROUP BY cwd`)
286
+ .all();
287
+ // A session in a worktree belongs to the project the worktree was made from.
288
+ const worktrees = this.listWorktrees();
289
+ const projects = new Map();
290
+ for (const row of rows) {
291
+ const cwd = projectOf(row.cwd, worktrees);
292
+ const project = projects.get(cwd) ?? { cwd, name: basename(cwd) || cwd, lastActiveAt: 0, sessionCount: 0 };
293
+ project.lastActiveAt = Math.max(project.lastActiveAt, row.last_active_at);
294
+ project.sessionCount += row.session_count;
295
+ projects.set(cwd, project);
296
+ }
297
+ return [...projects.values()].sort((a, b) => b.lastActiveAt - a.lastActiveAt).slice(0, limit);
298
+ }
299
+ // ── worktrees ─────────────────────────────────────────────────────
300
+ saveWorktree(worktree) {
301
+ this.db
302
+ .prepare("INSERT OR REPLACE INTO worktrees (path, branch, source, source_cwd, base, created_at) VALUES (?, ?, ?, ?, ?, ?)")
303
+ .run(worktree.path, worktree.branch, worktree.source, worktree.sourceCwd, worktree.base, worktree.createdAt);
304
+ }
305
+ listWorktrees() {
306
+ const rows = this.db.prepare("SELECT * FROM worktrees ORDER BY created_at DESC").all();
198
307
  return rows.map((row) => ({
199
- cwd: row.cwd,
200
- name: basename(row.cwd) || row.cwd,
201
- lastActiveAt: row.last_active_at,
202
- sessionCount: row.session_count,
308
+ path: String(row.path),
309
+ branch: String(row.branch),
310
+ source: String(row.source),
311
+ sourceCwd: String(row.source_cwd),
312
+ base: String(row.base),
313
+ createdAt: Number(row.created_at),
203
314
  }));
204
315
  }
205
- /** Appends one update to the session's log and returns it with its seq. */
206
- appendEvent(sessionId, update, ts = Date.now()) {
316
+ deleteWorktree(path) {
317
+ this.db.prepare("DELETE FROM worktrees WHERE path = ?").run(path);
318
+ }
319
+ /** Sessions whose directory is `path` or inside it. */
320
+ sessionsUnder(path) {
321
+ const rows = this.db.prepare("SELECT id FROM sessions WHERE cwd = ? OR substr(cwd, 1, ?) = ?").all(path, path.length + 1, `${path}/`);
322
+ return rows.map((row) => row.id);
323
+ }
324
+ /** The seq of the latest event that mentions message or tool call `itemId`, and how many turns had started by then. */
325
+ locateItem(sessionId, itemId) {
326
+ const tool = this.db
327
+ .prepare("SELECT MAX(seq) AS seq FROM event_meta WHERE session_id = ? AND tool = ?")
328
+ .get(sessionId, itemId);
329
+ const needle = `"messageId":${JSON.stringify(itemId)}`;
330
+ const message = this.db
331
+ .prepare("SELECT MAX(seq) AS seq FROM events WHERE session_id = ? AND instr(body, ?) > 0")
332
+ .get(sessionId, needle);
333
+ const seq = Math.max(tool.seq ?? 0, message.seq ?? 0);
334
+ if (seq === 0)
335
+ return undefined;
336
+ const { turn } = this.db
337
+ .prepare("SELECT COUNT(*) AS turn FROM event_meta WHERE session_id = ? AND kind = 'ls_turn' AND opens_turn = 1 AND seq <= ?")
338
+ .get(sessionId, seq);
339
+ return { seq, turn };
340
+ }
341
+ /** Where the exchange that `seq` is in ends: just before the user speaks next, or the end of the session. */
342
+ turnEnd(sessionId, seq) {
343
+ const next = this.db
344
+ .prepare("SELECT MIN(seq) AS seq FROM event_meta WHERE session_id = ? AND kind = 'user_message_chunk' AND seq > ?")
345
+ .get(sessionId, seq);
346
+ return next.seq ? next.seq - 1 : (this.getSession(sessionId)?.lastSeq ?? seq);
347
+ }
348
+ /**
349
+ * Appends one update to the session's log and returns it with its seq.
350
+ * `activity` false: the session's "last updated" stays (a setting or a name
351
+ * is not something happening in the session).
352
+ */
353
+ appendEvent(sessionId, update, ts = Date.now(), activity = true) {
207
354
  this.db.exec("BEGIN IMMEDIATE");
208
355
  try {
209
356
  const row = this.db.prepare("SELECT last_seq FROM sessions WHERE id = ?").get(sessionId);
210
357
  if (!row)
211
358
  throw new Error(`unknown session ${sessionId}`);
212
359
  const seq = row.last_seq + 1;
360
+ const body = JSON.stringify(update);
361
+ this.db.prepare("INSERT INTO events (session_id, seq, ts, body) VALUES (?, ?, ?, ?)").run(sessionId, seq, ts, body);
362
+ const fields = update;
363
+ const opensTurn = update.sessionUpdate === "user_message_chunk" || (update.sessionUpdate === "ls_turn" && update.state === "started" && !fields.parentToolCallId);
364
+ const spawns = update.sessionUpdate === "tool_call" && update.detail?.type === "subagent" && (update.detail.action ?? "spawn") === "spawn";
213
365
  this.db
214
- .prepare("INSERT INTO events (session_id, seq, ts, body) VALUES (?, ?, ?, ?)")
215
- .run(sessionId, seq, ts, JSON.stringify(update));
216
- this.db.prepare("UPDATE sessions SET last_seq = ?, updated_at = MAX(updated_at, ?) WHERE id = ?").run(seq, ts, sessionId);
366
+ .prepare("INSERT INTO event_meta (session_id, seq, kind, bytes, opens_turn, tool, parent, spawns) VALUES (?, ?, ?, ?, ?, ?, ?, ?)")
367
+ .run(sessionId, seq, update.sessionUpdate, Buffer.byteLength(body), opensTurn ? 1 : 0, fields.toolCallId ?? null, fields.parentToolCallId ?? null, spawns ? 1 : 0);
368
+ this.db.prepare("UPDATE sessions SET last_seq = ?, updated_at = MAX(updated_at, ?) WHERE id = ?").run(seq, activity ? ts : 0, sessionId);
217
369
  this.db.exec("COMMIT");
218
370
  return { sessionId, seq, ts, update };
219
371
  }
@@ -222,10 +374,91 @@ export class HostStore {
222
374
  throw error;
223
375
  }
224
376
  }
225
- readEvents(sessionId, afterSeq, limit = 5000) {
377
+ /** Events after `afterSeq`, up to and including `upToSeq` when given. */
378
+ readEvents(sessionId, afterSeq, limit = 5000, upToSeq = Number.MAX_SAFE_INTEGER) {
379
+ const rows = this.db
380
+ .prepare("SELECT seq, ts, body FROM events WHERE session_id = ? AND seq > ? AND seq <= ? ORDER BY seq ASC LIMIT ?")
381
+ .all(sessionId, afterSeq, upToSeq, limit);
382
+ return rows.map((row) => ({ sessionId, seq: row.seq, ts: row.ts, update: JSON.parse(row.body) }));
383
+ }
384
+ readEvent(sessionId, seq) {
385
+ return this.readEvents(sessionId, seq - 1, 1, seq)[0];
386
+ }
387
+ /** How much was logged after `afterSeq`. */
388
+ sizeAfter(sessionId, afterSeq) {
389
+ const row = this.db
390
+ .prepare("SELECT COUNT(*) AS events, COALESCE(SUM(bytes), 0) AS bytes FROM event_meta WHERE session_id = ? AND seq > ?")
391
+ .get(sessionId, afterSeq);
392
+ return row;
393
+ }
394
+ /**
395
+ * Where a page of history ending at `beforeSeq` starts: the seq before its
396
+ * first event (0: the beginning of the log). Pages are whole turns, going
397
+ * back until one is worth showing; a single turn too big for a page is cut.
398
+ */
399
+ pageStart(sessionId, beforeSeq, page = PAGE) {
400
+ const rows = this.db
401
+ .prepare("SELECT seq, bytes, opens_turn FROM event_meta WHERE session_id = ? AND seq <= ? ORDER BY seq DESC LIMIT ?")
402
+ .all(sessionId, beforeSeq, page.maxEvents + 1);
403
+ let events = 0;
404
+ let bytes = 0;
405
+ for (let i = 0; i < rows.length; i++) {
406
+ const row = rows[i];
407
+ const previous = rows[i + 1];
408
+ events += 1;
409
+ // What a client receives: pictures are left out and long text is cut.
410
+ bytes += Math.min(row.bytes, page.eventBytes);
411
+ if (!previous)
412
+ return 0;
413
+ const turnStarts = row.opens_turn === 1 && previous.opens_turn === 0;
414
+ if (turnStarts && (events >= page.minEvents || bytes >= page.minBytes))
415
+ return previous.seq;
416
+ if (events >= page.maxEvents || bytes >= page.maxBytes)
417
+ return previous.seq;
418
+ }
419
+ return 0;
420
+ }
421
+ /** The calls that started a sub-agent, oldest first. */
422
+ subagentCalls(sessionId) {
423
+ return this.joined("m.session_id = ? AND m.spawns = 1 ORDER BY m.seq ASC", [sessionId]);
424
+ }
425
+ /** A tool call's own events (the call and its updates), oldest first. */
426
+ toolEvents(sessionId, toolCallId) {
427
+ return this.joined("m.session_id = ? AND m.tool = ? AND m.parent IS NULL ORDER BY m.seq ASC", [sessionId, toolCallId]);
428
+ }
429
+ /** The latest `limit` events of the sub-agent under a tool call, oldest first. */
430
+ eventsUnder(sessionId, toolCallId, limit) {
431
+ return this.joined("m.session_id = ? AND m.parent = ? ORDER BY m.seq DESC LIMIT ?", [sessionId, toolCallId, limit]).reverse();
432
+ }
433
+ /** A tool call's latest status, whether the sub-agent under it is in a turn, and when that sub-agent last did anything. */
434
+ toolState(sessionId, toolCallId) {
435
+ const last = this.db
436
+ .prepare(`SELECT e.ts, json_extract(e.body, '$.status') AS status FROM event_meta m JOIN events e ON e.session_id = m.session_id AND e.seq = m.seq
437
+ WHERE m.session_id = ? AND m.tool = ? AND m.parent IS NULL AND json_extract(e.body, '$.status') IS NOT NULL ORDER BY m.seq DESC LIMIT 1`)
438
+ .get(sessionId, toolCallId);
439
+ const turn = this.db
440
+ .prepare(`SELECT json_extract(e.body, '$.state') AS state FROM event_meta m JOIN events e ON e.session_id = m.session_id AND e.seq = m.seq
441
+ WHERE m.session_id = ? AND m.parent = ? AND m.kind = 'ls_turn' ORDER BY m.seq DESC LIMIT 1`)
442
+ .get(sessionId, toolCallId);
443
+ const child = this.db
444
+ .prepare(`SELECT e.ts FROM event_meta m JOIN events e ON e.session_id = m.session_id AND e.seq = m.seq
445
+ WHERE m.session_id = ? AND m.parent = ? ORDER BY m.seq DESC LIMIT 1`)
446
+ .get(sessionId, toolCallId);
447
+ return { status: last?.status, ts: last?.ts, turnActive: turn ? turn.state === "started" : undefined, lastChildTs: child?.ts };
448
+ }
449
+ joined(where, values) {
450
+ const rows = this.db
451
+ .prepare(`SELECT e.seq, e.ts, e.body FROM event_meta m JOIN events e ON e.session_id = m.session_id AND e.seq = m.seq WHERE ${where}`)
452
+ .all(...values);
453
+ const sessionId = String(values[0]);
454
+ return rows.map((row) => ({ sessionId, seq: row.seq, ts: row.ts, update: JSON.parse(row.body) }));
455
+ }
456
+ /** The latest event of `kind` at or before `seq`. */
457
+ latestOfKind(sessionId, kind, seq, limit = 1) {
226
458
  const rows = this.db
227
- .prepare("SELECT seq, ts, body FROM events WHERE session_id = ? AND seq > ? ORDER BY seq ASC LIMIT ?")
228
- .all(sessionId, afterSeq, limit);
459
+ .prepare(`SELECT e.seq, e.ts, e.body FROM event_meta m JOIN events e ON e.session_id = m.session_id AND e.seq = m.seq
460
+ WHERE m.session_id = ? AND m.kind = ? AND m.seq <= ? ORDER BY m.seq DESC LIMIT ?`)
461
+ .all(sessionId, kind, seq, limit);
229
462
  return rows.map((row) => ({ sessionId, seq: row.seq, ts: row.ts, update: JSON.parse(row.body) }));
230
463
  }
231
464
  /** Marks a native item (message, tool call) as present in the log. Returns false if it already was. */