hoomanjs 1.40.2 → 1.41.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 (135) hide show
  1. package/README.md +50 -3
  2. package/dist/acp/acp-agent.d.ts +16 -3
  3. package/dist/acp/acp-agent.js +371 -172
  4. package/dist/acp/acp-agent.js.map +1 -1
  5. package/dist/acp/commands.d.ts +6 -3
  6. package/dist/acp/commands.js +6 -24
  7. package/dist/acp/commands.js.map +1 -1
  8. package/dist/acp/meta/vscode.d.ts +10 -0
  9. package/dist/acp/meta/vscode.js +16 -0
  10. package/dist/acp/meta/vscode.js.map +1 -0
  11. package/dist/acp/questions.d.ts +18 -0
  12. package/dist/acp/questions.js +80 -0
  13. package/dist/acp/questions.js.map +1 -0
  14. package/dist/acp/session-config.d.ts +3 -1
  15. package/dist/acp/session-config.js +20 -8
  16. package/dist/acp/session-config.js.map +1 -1
  17. package/dist/acp/sessions/replay.js +117 -1
  18. package/dist/acp/sessions/replay.js.map +1 -1
  19. package/dist/acp/sessions/store.d.ts +55 -16
  20. package/dist/acp/sessions/store.js +174 -71
  21. package/dist/acp/sessions/store.js.map +1 -1
  22. package/dist/acp/utils/tool-kind.js +1 -0
  23. package/dist/acp/utils/tool-kind.js.map +1 -1
  24. package/dist/acp/utils/tool-result-content.d.ts +1 -0
  25. package/dist/acp/utils/tool-result-content.js +28 -1
  26. package/dist/acp/utils/tool-result-content.js.map +1 -1
  27. package/dist/chat/app.d.ts +3 -1
  28. package/dist/chat/app.js +65 -17
  29. package/dist/chat/app.js.map +1 -1
  30. package/dist/chat/components/BottomChrome.d.ts +12 -3
  31. package/dist/chat/components/BottomChrome.js +2 -2
  32. package/dist/chat/components/BottomChrome.js.map +1 -1
  33. package/dist/chat/components/ChromePicker.d.ts +5 -1
  34. package/dist/chat/components/ChromePicker.js +6 -2
  35. package/dist/chat/components/ChromePicker.js.map +1 -1
  36. package/dist/chat/components/QuestionPrompt.d.ts +8 -0
  37. package/dist/chat/components/QuestionPrompt.js +41 -0
  38. package/dist/chat/components/QuestionPrompt.js.map +1 -0
  39. package/dist/chat/components/StatusBar.d.ts +8 -3
  40. package/dist/chat/components/StatusBar.js +55 -26
  41. package/dist/chat/components/StatusBar.js.map +1 -1
  42. package/dist/chat/index.d.ts +2 -0
  43. package/dist/chat/index.js +1 -1
  44. package/dist/chat/index.js.map +1 -1
  45. package/dist/chat/questions.d.ts +24 -0
  46. package/dist/chat/questions.js +71 -0
  47. package/dist/chat/questions.js.map +1 -0
  48. package/dist/cli.js +9 -0
  49. package/dist/cli.js.map +1 -1
  50. package/dist/core/agent/index.d.ts +3 -0
  51. package/dist/core/agent/index.js +11 -5
  52. package/dist/core/agent/index.js.map +1 -1
  53. package/dist/core/agent/session-title-plugin.d.ts +27 -0
  54. package/dist/core/agent/session-title-plugin.js +77 -0
  55. package/dist/core/agent/session-title-plugin.js.map +1 -0
  56. package/dist/core/config.d.ts +30 -1
  57. package/dist/core/config.js +2 -0
  58. package/dist/core/config.js.map +1 -1
  59. package/dist/core/index.d.ts +12 -0
  60. package/dist/core/index.js +7 -2
  61. package/dist/core/index.js.map +1 -1
  62. package/dist/core/models/azure.js +5 -1
  63. package/dist/core/models/azure.js.map +1 -1
  64. package/dist/core/models/groq.js +5 -1
  65. package/dist/core/models/groq.js.map +1 -1
  66. package/dist/core/models/moonshot.js +5 -1
  67. package/dist/core/models/moonshot.js.map +1 -1
  68. package/dist/core/models/openai.js +6 -1
  69. package/dist/core/models/openai.js.map +1 -1
  70. package/dist/core/models/openrouter.js +5 -1
  71. package/dist/core/models/openrouter.js.map +1 -1
  72. package/dist/core/models/types.d.ts +44 -0
  73. package/dist/core/models/types.js +15 -0
  74. package/dist/core/models/types.js.map +1 -1
  75. package/dist/core/models/usage.d.ts +10 -0
  76. package/dist/core/models/usage.js +45 -0
  77. package/dist/core/models/usage.js.map +1 -0
  78. package/dist/core/models/xai.js +5 -1
  79. package/dist/core/models/xai.js.map +1 -1
  80. package/dist/core/modes/definitions.js +2 -0
  81. package/dist/core/modes/definitions.js.map +1 -1
  82. package/dist/core/prompts/static/ask-user.md +7 -0
  83. package/dist/core/prompts/static/filesystem.md +1 -1
  84. package/dist/core/prompts/system.js +5 -0
  85. package/dist/core/prompts/system.js.map +1 -1
  86. package/dist/core/sessions/generate-title.d.ts +10 -0
  87. package/dist/core/sessions/generate-title.js +113 -0
  88. package/dist/core/sessions/generate-title.js.map +1 -0
  89. package/dist/core/sessions/list-cli-sessions.js +13 -1
  90. package/dist/core/sessions/list-cli-sessions.js.map +1 -1
  91. package/dist/core/skills/built-in/hooman-config/providers.md +17 -0
  92. package/dist/core/skills/built-in/hooman-skills/SKILL.md +1 -1
  93. package/dist/core/state/session-title.d.ts +17 -0
  94. package/dist/core/state/session-title.js +15 -0
  95. package/dist/core/state/session-title.js.map +1 -0
  96. package/dist/core/state/tool-approvals.js +3 -0
  97. package/dist/core/state/tool-approvals.js.map +1 -1
  98. package/dist/core/tools/ask-user.d.ts +38 -0
  99. package/dist/core/tools/ask-user.js +62 -0
  100. package/dist/core/tools/ask-user.js.map +1 -0
  101. package/dist/core/tools/filesystem.d.ts +26 -1
  102. package/dist/core/tools/filesystem.js +44 -23
  103. package/dist/core/tools/filesystem.js.map +1 -1
  104. package/dist/core/tools/index.d.ts +1 -0
  105. package/dist/core/tools/index.js +1 -0
  106. package/dist/core/tools/index.js.map +1 -1
  107. package/dist/core/tools/shell.d.ts +41 -0
  108. package/dist/core/tools/shell.js +8 -1
  109. package/dist/core/tools/shell.js.map +1 -1
  110. package/dist/core/utils/billing.d.ts +49 -0
  111. package/dist/core/utils/billing.js +295 -0
  112. package/dist/core/utils/billing.js.map +1 -0
  113. package/dist/core/utils/edit-replace.d.ts +6 -0
  114. package/dist/core/utils/edit-replace.js +88 -6
  115. package/dist/core/utils/edit-replace.js.map +1 -1
  116. package/dist/core/utils/paths.d.ts +1 -0
  117. package/dist/core/utils/paths.js +1 -0
  118. package/dist/core/utils/paths.js.map +1 -1
  119. package/dist/core/{models → utils}/reasoning-effort.d.ts +9 -0
  120. package/dist/core/utils/reasoning-effort.js.map +1 -0
  121. package/dist/exec/questions.d.ts +9 -0
  122. package/dist/exec/questions.js +50 -0
  123. package/dist/exec/questions.js.map +1 -0
  124. package/dist/index.d.ts +5 -4
  125. package/dist/index.js +5 -4
  126. package/dist/index.js.map +1 -1
  127. package/package.json +2 -2
  128. package/dist/core/models/reasoning-effort.js.map +0 -1
  129. package/dist/core/tools/terminal-backend.d.ts +0 -41
  130. package/dist/core/tools/terminal-backend.js +0 -9
  131. package/dist/core/tools/terminal-backend.js.map +0 -1
  132. package/dist/core/tools/text-fs-backend.d.ts +0 -25
  133. package/dist/core/tools/text-fs-backend.js +0 -9
  134. package/dist/core/tools/text-fs-backend.js.map +0 -1
  135. /package/dist/core/{models → utils}/reasoning-effort.js +0 -0
@@ -2,10 +2,107 @@ import { methods, } from "@agentclientprotocol/sdk";
2
2
  import { ToolResultBlock, ToolUseBlock, } from "@strands-agents/sdk";
3
3
  import { inferToolKind } from "../utils/tool-kind.js";
4
4
  import { toolResultToAcpContent } from "../utils/tool-result-content.js";
5
+ const IMAGE_MIME_BY_FORMAT = {
6
+ jpeg: "image/jpeg",
7
+ jpg: "image/jpeg",
8
+ gif: "image/gif",
9
+ webp: "image/webp",
10
+ png: "image/png",
11
+ };
12
+ const VIDEO_MIME_BY_FORMAT = {
13
+ mp4: "video/mp4",
14
+ webm: "video/webm",
15
+ mov: "video/quicktime",
16
+ mkv: "video/x-matroska",
17
+ mpeg: "video/mpeg",
18
+ mpg: "video/mpeg",
19
+ flv: "video/x-flv",
20
+ wmv: "video/x-ms-wmv",
21
+ "3gp": "video/3gpp",
22
+ };
23
+ const DOCUMENT_MIME_BY_FORMAT = {
24
+ pdf: "application/pdf",
25
+ csv: "text/csv",
26
+ doc: "application/msword",
27
+ docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
28
+ xls: "application/vnd.ms-excel",
29
+ xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
30
+ html: "text/html",
31
+ md: "text/markdown",
32
+ json: "application/json",
33
+ xml: "application/xml",
34
+ txt: "text/plain",
35
+ };
36
+ function attachmentUri(name, context) {
37
+ if (context && /^[a-z][a-z0-9+.-]*:\/\//i.test(context)) {
38
+ return context;
39
+ }
40
+ return `attachment:///${encodeURIComponent(name)}`;
41
+ }
42
+ /**
43
+ * Map a persisted Strands media block back to its standard ACP content block
44
+ * — the inverse of the `session/prompt` ingestion in `prompt-invoke.ts`, so
45
+ * replayed user messages carry the same block types the client originally
46
+ * sent (`image`, embedded blob `resource`). How to render them (pills,
47
+ * thumbnails, ...) is the client's concern. Returns null for non-media
48
+ * blocks and sources without inline bytes.
49
+ */
50
+ function mediaBlockToAcpContent(block) {
51
+ if (block.type === "imageBlock") {
52
+ if (block.source.type !== "imageSourceBytes") {
53
+ return null;
54
+ }
55
+ return {
56
+ type: "image",
57
+ data: Buffer.from(block.source.bytes).toString("base64"),
58
+ mimeType: IMAGE_MIME_BY_FORMAT[block.format] ?? "image/png",
59
+ };
60
+ }
61
+ if (block.type === "videoBlock") {
62
+ if (block.source.type !== "videoSourceBytes") {
63
+ return null;
64
+ }
65
+ const name = `video.${block.format}`;
66
+ return {
67
+ type: "resource",
68
+ resource: {
69
+ uri: attachmentUri(name),
70
+ blob: Buffer.from(block.source.bytes).toString("base64"),
71
+ mimeType: VIDEO_MIME_BY_FORMAT[block.format] ?? "video/mp4",
72
+ },
73
+ };
74
+ }
75
+ if (block.type === "documentBlock") {
76
+ const mimeType = DOCUMENT_MIME_BY_FORMAT[block.format] ?? "text/plain";
77
+ const uri = attachmentUri(block.name, block.context);
78
+ if (block.source.type === "documentSourceBytes") {
79
+ return {
80
+ type: "resource",
81
+ resource: {
82
+ uri,
83
+ blob: Buffer.from(block.source.bytes).toString("base64"),
84
+ mimeType,
85
+ },
86
+ };
87
+ }
88
+ if (block.source.type === "documentSourceText") {
89
+ return {
90
+ type: "resource",
91
+ resource: { uri, text: block.source.text, mimeType },
92
+ };
93
+ }
94
+ return null;
95
+ }
96
+ return null;
97
+ }
5
98
  function blockToFallbackText(block) {
6
99
  if (block.type === "textBlock") {
7
100
  return block.text;
8
101
  }
102
+ // Prompt-caching markers are internal bookkeeping, not conversation content.
103
+ if (block.type === "cachePointBlock") {
104
+ return null;
105
+ }
9
106
  try {
10
107
  return JSON.stringify(block.toJSON?.() ?? block, null, 2);
11
108
  }
@@ -33,6 +130,10 @@ export async function replayConversationHistory(client, sessionId, messages) {
33
130
  const resultsByToolUseId = collectToolResults(messages);
34
131
  for (const message of messages) {
35
132
  const role = message.role;
133
+ // One `messageId` per persisted message, shared by all chunks derived
134
+ // from it (see the `MessageId` RFD: a change in `messageId` indicates a
135
+ // new message has started).
136
+ const messageId = crypto.randomUUID();
36
137
  for (const block of message.content) {
37
138
  if (role === "user") {
38
139
  if (block instanceof ToolResultBlock) {
@@ -45,11 +146,21 @@ export async function replayConversationHistory(client, sessionId, messages) {
45
146
  });
46
147
  continue;
47
148
  }
149
+ const media = mediaBlockToAcpContent(block);
150
+ if (media) {
151
+ await send({
152
+ sessionUpdate: "user_message_chunk",
153
+ content: media,
154
+ messageId,
155
+ });
156
+ continue;
157
+ }
48
158
  const text = blockToFallbackText(block);
49
159
  if (text?.trim()) {
50
160
  await send({
51
161
  sessionUpdate: "user_message_chunk",
52
162
  content: { type: "text", text },
163
+ messageId,
53
164
  });
54
165
  }
55
166
  continue;
@@ -73,16 +184,20 @@ export async function replayConversationHistory(client, sessionId, messages) {
73
184
  await send({
74
185
  sessionUpdate: "agent_message_chunk",
75
186
  content: { type: "text", text: t },
187
+ messageId,
76
188
  });
77
189
  }
78
190
  continue;
79
191
  }
80
192
  if (block.type === "reasoningBlock") {
81
- const t = blockToFallbackText(block);
193
+ // Only the reasoning text belongs in the transcript — never the
194
+ // signature / redacted payload the block also carries.
195
+ const t = block.text;
82
196
  if (t?.trim()) {
83
197
  await send({
84
198
  sessionUpdate: "agent_thought_chunk",
85
199
  content: { type: "text", text: t },
200
+ messageId,
86
201
  });
87
202
  }
88
203
  continue;
@@ -92,6 +207,7 @@ export async function replayConversationHistory(client, sessionId, messages) {
92
207
  await send({
93
208
  sessionUpdate: "agent_message_chunk",
94
209
  content: { type: "text", text: fallback },
210
+ messageId,
95
211
  });
96
212
  }
97
213
  }
@@ -1 +1 @@
1
- {"version":3,"file":"replay.js","sourceRoot":"","sources":["../../../src/acp/sessions/replay.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"replay.js","sourceRoot":"","sources":["../../../src/acp/sessions/replay.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,25 @@
1
- import type { SessionInfo } from "@agentclientprotocol/sdk";
2
- import type { MessageData } from "@strands-agents/sdk";
3
1
  import type { NamedMcpTransport } from "../../core/mcp/config.js";
4
2
  import type { SessionMode } from "../../core/state/session-mode.js";
5
- export type SessionMetaFile = {
3
+ /**
4
+ * ACP session index: a single `sessions.jsonl` under the ACP sessions root.
5
+ *
6
+ * Conversation history is NOT stored here — the Strands `SessionManager`
7
+ * snapshot (`<sessions>/<sessionId>/snapshot_latest.json`) is the source of
8
+ * truth for messages. This file only carries the protocol-facing metadata the
9
+ * ACP layer needs before/outside an agent instance: `session/list` rows and
10
+ * the knobs that drive how a session is re-bootstrapped (`cwd`, session-scoped
11
+ * MCP servers, mode/model/yolo, client user id).
12
+ *
13
+ * Concurrency model: the file is an append-only patch log. Every write is a
14
+ * single-line `appendFile` (O_APPEND — atomic for our record sizes), reads
15
+ * fold all lines last-wins per session id, deletes append a tombstone, and
16
+ * unparseable (torn) lines are skipped. Compaction rewrites the folded state
17
+ * via tmp+rename and aborts when the file changed underneath it, so a lost
18
+ * concurrent patch (worst case: a title or `updatedAt` bump) is the only
19
+ * hazard, and only during the rare compaction cycle.
20
+ */
21
+ export type SessionIndexEntry = {
22
+ sessionId: string;
6
23
  cwd: string;
7
24
  createdAt: string;
8
25
  updatedAt: string;
@@ -12,8 +29,14 @@ export type SessionMetaFile = {
12
29
  /** Session-scoped MCP servers requested by the ACP client. */
13
30
  mcpServers?: NamedMcpTransport[];
14
31
  /**
15
- * Auto-approve tools without ACP permission prompts (`hooman.yolo` on agent appState).
16
- * Persisted so loadSession restores the same behaviour.
32
+ * Session created by the official VS Code extension
33
+ * (`_meta["hoomanjs/vscode"]: true`); loads the local MCP config
34
+ * (home + repo overlays) in addition to session-scoped servers.
35
+ */
36
+ vscode?: boolean;
37
+ /**
38
+ * Auto-approve tools without ACP permission prompts (`hooman.yolo` on agent
39
+ * appState). Persisted so session reactivation restores the same behaviour.
17
40
  */
18
41
  yolo?: boolean;
19
42
  /** Persisted session planning mode (`hooman.sessionMode` / agent appState `mode`). */
@@ -21,14 +44,30 @@ export type SessionMetaFile = {
21
44
  /** Persisted named LLM (`config.llms[].name`) selected via `session/set_config_option`. */
22
45
  model?: string;
23
46
  };
24
- export declare function sessionDir(root: string, sessionId: string): string;
25
- export declare function writeSessionMeta(root: string, sessionId: string, meta: SessionMetaFile): Promise<void>;
26
- export declare function updateSessionMeta(root: string, sessionId: string, patch: Partial<Pick<SessionMetaFile, "title" | "updatedAt">>): Promise<void>;
27
- export declare function patchSessionMeta(root: string, sessionId: string, patch: Partial<SessionMetaFile>): Promise<void>;
28
- export declare function readSessionMeta(root: string, sessionId: string): Promise<SessionMetaFile | null>;
29
- export declare function saveSessionMessages(root: string, sessionId: string, messages: MessageData[]): Promise<void>;
30
- export declare function loadSessionMessages(root: string, sessionId: string): Promise<MessageData[]>;
31
- /** Hard-delete a persisted session. No-op when it does not exist. */
32
- export declare function deleteStoredSession(root: string, sessionId: string): Promise<void>;
33
- export declare function listStoredSessionIds(root: string): Promise<string[]>;
34
- export declare function toSessionInfo(root: string, sessionId: string): Promise<SessionInfo | null>;
47
+ /** All live sessions, folded last-wins from the append log. */
48
+ export declare function readSessionIndex(root: string): Promise<Map<string, SessionIndexEntry>>;
49
+ export declare function readSessionEntry(root: string, sessionId: string): Promise<SessionIndexEntry | null>;
50
+ /** Record a freshly created session (the full entry, not a patch). */
51
+ export declare function writeSessionEntry(root: string, entry: SessionIndexEntry): Promise<void>;
52
+ /** Append a partial update; `updatedAt` is bumped unless the patch sets it. */
53
+ export declare function patchSessionEntry(root: string, sessionId: string, patch: Partial<Omit<SessionIndexEntry, "sessionId">>): Promise<void>;
54
+ /** Bump `updatedAt` (list ordering) after a prompt turn. */
55
+ export declare function touchSessionEntry(root: string, sessionId: string): Promise<void>;
56
+ /** Append a delete tombstone. The Strands snapshot is deleted by the caller. */
57
+ export declare function deleteSessionEntry(root: string, sessionId: string): Promise<void>;
58
+ /**
59
+ * Rewrite the log as one line per live session when enough stale records have
60
+ * accumulated. Best-effort: skipped entirely when the file changes between
61
+ * reading and renaming (a concurrent writer wins).
62
+ */
63
+ export declare function compactSessionIndex(root: string): Promise<void>;
64
+ /**
65
+ * One-time migration from the legacy per-session directory store
66
+ * (`<root>/<sessionId>/{meta.json,messages.json}`) to the JSONL index.
67
+ *
68
+ * Metadata folds into `sessions.jsonl`. Messages were already dual-persisted
69
+ * to the Strands snapshot; when a legacy session somehow lacks one, a minimal
70
+ * messages-only snapshot is backfilled so its history survives. The legacy
71
+ * directories are removed afterwards.
72
+ */
73
+ export declare function migrateLegacySessionStore(root: string, snapshotsRoot: string): Promise<void>;
@@ -1,100 +1,203 @@
1
- import { mkdir, readdir, readFile, rm, writeFile } from "node:fs/promises";
2
- import { join } from "node:path";
3
- const META = "meta.json";
4
- const MESSAGES = "messages.json";
5
- export function sessionDir(root, sessionId) {
6
- return join(root, sessionId);
1
+ import { randomUUID } from "node:crypto";
2
+ import { appendFile, mkdir, readdir, readFile, rename, rm, stat, writeFile, } from "node:fs/promises";
3
+ import { dirname, join } from "node:path";
4
+ import { SNAPSHOT_SCHEMA_VERSION } from "@strands-agents/sdk";
5
+ const INDEX_FILE = "sessions.jsonl";
6
+ /** Compact only once this many superseded/tombstoned records accumulate. */
7
+ const COMPACT_MIN_STALE_RECORDS = 64;
8
+ const indexPath = (root) => join(root, INDEX_FILE);
9
+ async function appendRecord(root, record) {
10
+ await mkdir(root, { recursive: true });
11
+ await appendFile(indexPath(root), `${JSON.stringify(record)}\n`, "utf8");
7
12
  }
8
- export async function writeSessionMeta(root, sessionId, meta) {
9
- const dir = sessionDir(root, sessionId);
10
- await mkdir(dir, { recursive: true });
11
- await writeFile(join(dir, META), `${JSON.stringify(meta, null, 2)}\n`, "utf8");
12
- const msgPath = join(dir, MESSAGES);
13
+ function isCompleteEntry(entry) {
14
+ return (typeof entry.sessionId === "string" &&
15
+ typeof entry.cwd === "string" &&
16
+ typeof entry.createdAt === "string" &&
17
+ typeof entry.updatedAt === "string");
18
+ }
19
+ async function parseIndex(root) {
20
+ let raw;
13
21
  try {
14
- await readFile(msgPath);
22
+ raw = await readFile(indexPath(root), "utf8");
15
23
  }
16
24
  catch {
17
- await writeFile(msgPath, "[]\n", "utf8");
25
+ return { entries: new Map(), recordCount: 0 };
18
26
  }
19
- }
20
- export async function updateSessionMeta(root, sessionId, patch) {
21
- const dir = sessionDir(root, sessionId);
22
- const cur = await readSessionMeta(root, sessionId);
23
- if (!cur) {
24
- return;
27
+ const folded = new Map();
28
+ let recordCount = 0;
29
+ for (const line of raw.split("\n")) {
30
+ const trimmed = line.trim();
31
+ if (!trimmed) {
32
+ continue;
33
+ }
34
+ let record;
35
+ try {
36
+ record = JSON.parse(trimmed);
37
+ }
38
+ catch {
39
+ // Torn line from a concurrent append; skip.
40
+ continue;
41
+ }
42
+ if (!record || typeof record.sessionId !== "string") {
43
+ continue;
44
+ }
45
+ recordCount++;
46
+ if (record.deleted) {
47
+ folded.delete(record.sessionId);
48
+ continue;
49
+ }
50
+ folded.set(record.sessionId, {
51
+ ...folded.get(record.sessionId),
52
+ ...record,
53
+ });
54
+ }
55
+ const entries = new Map();
56
+ for (const [sessionId, entry] of folded) {
57
+ if (isCompleteEntry(entry)) {
58
+ entries.set(sessionId, entry);
59
+ }
25
60
  }
26
- const next = {
27
- ...cur,
61
+ return { entries, recordCount };
62
+ }
63
+ /** All live sessions, folded last-wins from the append log. */
64
+ export async function readSessionIndex(root) {
65
+ return (await parseIndex(root)).entries;
66
+ }
67
+ export async function readSessionEntry(root, sessionId) {
68
+ return (await readSessionIndex(root)).get(sessionId) ?? null;
69
+ }
70
+ /** Record a freshly created session (the full entry, not a patch). */
71
+ export async function writeSessionEntry(root, entry) {
72
+ await appendRecord(root, entry);
73
+ }
74
+ /** Append a partial update; `updatedAt` is bumped unless the patch sets it. */
75
+ export async function patchSessionEntry(root, sessionId, patch) {
76
+ await appendRecord(root, {
77
+ sessionId,
28
78
  ...patch,
29
79
  updatedAt: patch.updatedAt ?? new Date().toISOString(),
30
- };
31
- await writeFile(join(dir, META), `${JSON.stringify(next, null, 2)}\n`, "utf8");
80
+ });
81
+ }
82
+ /** Bump `updatedAt` (list ordering) after a prompt turn. */
83
+ export async function touchSessionEntry(root, sessionId) {
84
+ await patchSessionEntry(root, sessionId, {});
85
+ }
86
+ /** Append a delete tombstone. The Strands snapshot is deleted by the caller. */
87
+ export async function deleteSessionEntry(root, sessionId) {
88
+ await appendRecord(root, {
89
+ sessionId,
90
+ deleted: true,
91
+ updatedAt: new Date().toISOString(),
92
+ });
32
93
  }
33
- export async function patchSessionMeta(root, sessionId, patch) {
34
- const cur = await readSessionMeta(root, sessionId);
35
- if (!cur) {
94
+ /**
95
+ * Rewrite the log as one line per live session when enough stale records have
96
+ * accumulated. Best-effort: skipped entirely when the file changes between
97
+ * reading and renaming (a concurrent writer wins).
98
+ */
99
+ export async function compactSessionIndex(root) {
100
+ const file = indexPath(root);
101
+ let before;
102
+ try {
103
+ before = await stat(file);
104
+ }
105
+ catch {
36
106
  return;
37
107
  }
38
- const next = {
39
- ...cur,
40
- ...patch,
41
- updatedAt: patch.updatedAt ?? new Date().toISOString(),
42
- };
43
- await writeFile(join(sessionDir(root, sessionId), META), `${JSON.stringify(next, null, 2)}\n`, "utf8");
108
+ const { entries, recordCount } = await parseIndex(root);
109
+ if (recordCount - entries.size < COMPACT_MIN_STALE_RECORDS) {
110
+ return;
111
+ }
112
+ const lines = [...entries.values()]
113
+ .map((entry) => JSON.stringify(entry))
114
+ .join("\n");
115
+ const tmp = `${file}.${process.pid}.${randomUUID()}.tmp`;
116
+ await writeFile(tmp, lines.length > 0 ? `${lines}\n` : "", "utf8");
117
+ const after = await stat(file).catch(() => null);
118
+ if (!after ||
119
+ after.size !== before.size ||
120
+ after.mtimeMs !== before.mtimeMs) {
121
+ await rm(tmp, { force: true });
122
+ return;
123
+ }
124
+ await rename(tmp, file);
44
125
  }
45
- export async function readSessionMeta(root, sessionId) {
126
+ /**
127
+ * One-time migration from the legacy per-session directory store
128
+ * (`<root>/<sessionId>/{meta.json,messages.json}`) to the JSONL index.
129
+ *
130
+ * Metadata folds into `sessions.jsonl`. Messages were already dual-persisted
131
+ * to the Strands snapshot; when a legacy session somehow lacks one, a minimal
132
+ * messages-only snapshot is backfilled so its history survives. The legacy
133
+ * directories are removed afterwards.
134
+ */
135
+ export async function migrateLegacySessionStore(root, snapshotsRoot) {
46
136
  try {
47
- const raw = await readFile(join(sessionDir(root, sessionId), META), "utf8");
48
- return JSON.parse(raw);
137
+ await stat(indexPath(root));
138
+ return; // Already migrated (or a fresh index exists).
49
139
  }
50
140
  catch {
51
- return null;
141
+ /* fall through */
52
142
  }
53
- }
54
- export async function saveSessionMessages(root, sessionId, messages) {
55
- const dir = sessionDir(root, sessionId);
56
- await mkdir(dir, { recursive: true });
57
- await writeFile(join(dir, MESSAGES), `${JSON.stringify(messages, null, 2)}\n`, "utf8");
58
- await updateSessionMeta(root, sessionId, {
59
- updatedAt: new Date().toISOString(),
60
- });
61
- }
62
- export async function loadSessionMessages(root, sessionId) {
143
+ let dirents;
63
144
  try {
64
- const raw = await readFile(join(sessionDir(root, sessionId), MESSAGES), "utf8");
65
- const data = JSON.parse(raw);
66
- if (!Array.isArray(data)) {
67
- return [];
145
+ dirents = await readdir(root, { withFileTypes: true });
146
+ }
147
+ catch {
148
+ dirents = [];
149
+ }
150
+ for (const dirent of dirents) {
151
+ if (!dirent.isDirectory()) {
152
+ continue;
68
153
  }
69
- return data;
154
+ const sessionId = dirent.name;
155
+ const legacyDir = join(root, sessionId);
156
+ let meta = null;
157
+ try {
158
+ meta = JSON.parse(await readFile(join(legacyDir, "meta.json"), "utf8"));
159
+ }
160
+ catch {
161
+ meta = null;
162
+ }
163
+ if (meta) {
164
+ await appendRecord(root, { ...meta, sessionId });
165
+ await backfillSnapshotFromLegacyMessages(legacyDir, join(snapshotsRoot, sessionId));
166
+ }
167
+ await rm(legacyDir, { recursive: true, force: true });
168
+ }
169
+ // Leave an (at least empty) index behind so future boots skip the scan.
170
+ try {
171
+ await mkdir(root, { recursive: true });
172
+ await writeFile(indexPath(root), "", { encoding: "utf8", flag: "wx" });
70
173
  }
71
174
  catch {
72
- return [];
175
+ /* index already exists — nothing to do */
73
176
  }
74
177
  }
75
- /** Hard-delete a persisted session. No-op when it does not exist. */
76
- export async function deleteStoredSession(root, sessionId) {
77
- await rm(sessionDir(root, sessionId), { recursive: true, force: true });
78
- }
79
- export async function listStoredSessionIds(root) {
178
+ async function backfillSnapshotFromLegacyMessages(legacyDir, snapshotDir) {
179
+ const snapshotFile = join(snapshotDir, "snapshot_latest.json");
180
+ const hasSnapshot = await stat(snapshotFile).then(() => true, () => false);
181
+ if (hasSnapshot) {
182
+ return;
183
+ }
184
+ let messages;
80
185
  try {
81
- const names = await readdir(root, { withFileTypes: true });
82
- return names.filter((d) => d.isDirectory()).map((d) => d.name);
186
+ messages = JSON.parse(await readFile(join(legacyDir, "messages.json"), "utf8"));
83
187
  }
84
188
  catch {
85
- return [];
189
+ return;
86
190
  }
87
- }
88
- export async function toSessionInfo(root, sessionId) {
89
- const meta = await readSessionMeta(root, sessionId);
90
- if (!meta) {
91
- return null;
191
+ if (!Array.isArray(messages) || messages.length === 0) {
192
+ return;
92
193
  }
93
- return {
94
- sessionId,
95
- cwd: meta.cwd,
96
- title: meta.title ?? null,
97
- updatedAt: meta.updatedAt,
98
- };
194
+ await mkdir(dirname(snapshotFile), { recursive: true });
195
+ await writeFile(snapshotFile, JSON.stringify({
196
+ scope: "agent",
197
+ schemaVersion: SNAPSHOT_SCHEMA_VERSION,
198
+ createdAt: new Date().toISOString(),
199
+ data: { messages },
200
+ appData: {},
201
+ }, null, 2), "utf8");
99
202
  }
100
203
  //# sourceMappingURL=store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/acp/sessions/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/acp/sessions/store.ts"],"names":[],"mappings":"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"}
@@ -23,6 +23,7 @@ const KNOWN_TOOL_KINDS = new Map([
23
23
  ["subagent_review", "other"],
24
24
  ["subagent_test_investigator", "other"],
25
25
  ["update_todos", "other"],
26
+ ["ask_user", "other"],
26
27
  ["get_current_time", "other"],
27
28
  ["convert_time", "other"],
28
29
  [ENTER_PLAN_MODE_TOOL, "switch_mode"],
@@ -1 +1 @@
1
- {"version":3,"file":"tool-kind.js","sourceRoot":"","sources":["../../../src/acp/utils/tool-kind.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,oCAAoC,CAAC;AAE5C,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAmB;IACjD,CAAC,WAAW,EAAE,MAAM,CAAC;IACrB,CAAC,qBAAqB,EAAE,MAAM,CAAC;IAC/B,CAAC,YAAY,EAAE,MAAM,CAAC;IACtB,CAAC,WAAW,EAAE,MAAM,CAAC;IACrB,CAAC,kBAAkB,EAAE,MAAM,CAAC;IAC5B,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAC1B,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAC1B,CAAC,WAAW,EAAE,MAAM,CAAC;IACrB,CAAC,MAAM,EAAE,QAAQ,CAAC;IAClB,CAAC,eAAe,EAAE,MAAM,CAAC;IACzB,CAAC,OAAO,EAAE,SAAS,CAAC;IACpB,CAAC,OAAO,EAAE,OAAO,CAAC;IAClB,CAAC,OAAO,EAAE,OAAO,CAAC;IAClB,CAAC,YAAY,EAAE,QAAQ,CAAC;IACxB,CAAC,QAAQ,EAAE,OAAO,CAAC;IACnB,CAAC,4BAA4B,EAAE,MAAM,CAAC;IACtC,CAAC,eAAe,EAAE,QAAQ,CAAC;IAC3B,CAAC,2BAA2B,EAAE,OAAO,CAAC;IACtC,CAAC,OAAO,EAAE,OAAO,CAAC;IAClB,CAAC,mBAAmB,EAAE,OAAO,CAAC;IAC9B,CAAC,iBAAiB,EAAE,OAAO,CAAC;IAC5B,CAAC,4BAA4B,EAAE,OAAO,CAAC;IACvC,CAAC,cAAc,EAAE,OAAO,CAAC;IACzB,CAAC,kBAAkB,EAAE,OAAO,CAAC;IAC7B,CAAC,cAAc,EAAE,OAAO,CAAC;IACzB,CAAC,oBAAoB,EAAE,aAAa,CAAC;IACrC,CAAC,mBAAmB,EAAE,aAAa,CAAC;CACrC,CAAC,CAAC;AAEH,OAAO,EAAE,uBAAuB,EAAE,CAAC;AAEnC,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,OAAO,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,QAAgB,EAChB,IAAsB;IAEtB,MAAM,IAAI,GAAG,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IACvC,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;QAC/B,OAAO,GAAG,QAAQ,KAAK,IAAI,EAAE,CAAC;IAChC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"tool-kind.js","sourceRoot":"","sources":["../../../src/acp/utils/tool-kind.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,oCAAoC,CAAC;AAE5C,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAmB;IACjD,CAAC,WAAW,EAAE,MAAM,CAAC;IACrB,CAAC,qBAAqB,EAAE,MAAM,CAAC;IAC/B,CAAC,YAAY,EAAE,MAAM,CAAC;IACtB,CAAC,WAAW,EAAE,MAAM,CAAC;IACrB,CAAC,kBAAkB,EAAE,MAAM,CAAC;IAC5B,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAC1B,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAC1B,CAAC,WAAW,EAAE,MAAM,CAAC;IACrB,CAAC,MAAM,EAAE,QAAQ,CAAC;IAClB,CAAC,eAAe,EAAE,MAAM,CAAC;IACzB,CAAC,OAAO,EAAE,SAAS,CAAC;IACpB,CAAC,OAAO,EAAE,OAAO,CAAC;IAClB,CAAC,OAAO,EAAE,OAAO,CAAC;IAClB,CAAC,YAAY,EAAE,QAAQ,CAAC;IACxB,CAAC,QAAQ,EAAE,OAAO,CAAC;IACnB,CAAC,4BAA4B,EAAE,MAAM,CAAC;IACtC,CAAC,eAAe,EAAE,QAAQ,CAAC;IAC3B,CAAC,2BAA2B,EAAE,OAAO,CAAC;IACtC,CAAC,OAAO,EAAE,OAAO,CAAC;IAClB,CAAC,mBAAmB,EAAE,OAAO,CAAC;IAC9B,CAAC,iBAAiB,EAAE,OAAO,CAAC;IAC5B,CAAC,4BAA4B,EAAE,OAAO,CAAC;IACvC,CAAC,cAAc,EAAE,OAAO,CAAC;IACzB,CAAC,UAAU,EAAE,OAAO,CAAC;IACrB,CAAC,kBAAkB,EAAE,OAAO,CAAC;IAC7B,CAAC,cAAc,EAAE,OAAO,CAAC;IACzB,CAAC,oBAAoB,EAAE,aAAa,CAAC;IACrC,CAAC,mBAAmB,EAAE,aAAa,CAAC;CACrC,CAAC,CAAC;AAEH,OAAO,EAAE,uBAAuB,EAAE,CAAC;AAEnC,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,OAAO,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,QAAgB,EAChB,IAAsB;IAEtB,MAAM,IAAI,GAAG,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IACvC,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;QAC/B,OAAO,GAAG,QAAQ,KAAK,IAAI,EAAE,CAAC;IAChC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -9,6 +9,7 @@ export declare function fileToolDiffContent(display: FileToolDisplay | undefined
9
9
  type ToolResultLike = {
10
10
  toolUseId: string;
11
11
  status: string;
12
+ content?: unknown;
12
13
  toJSON?: () => unknown;
13
14
  };
14
15
  export declare function toolResultToAcpContent(result: ToolResultLike): Array<ToolCallContent>;