@draht/agent-core 2026.7.13-1 → 2026.7.30

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 (131) hide show
  1. package/dist/agent-loop.d.ts +5 -5
  2. package/dist/agent-loop.d.ts.map +1 -1
  3. package/dist/agent-loop.js +11 -7
  4. package/dist/agent-loop.js.map +1 -1
  5. package/dist/agent.d.ts +4 -4
  6. package/dist/agent.d.ts.map +1 -1
  7. package/dist/agent.js +24 -22
  8. package/dist/agent.js.map +1 -1
  9. package/dist/harness/agent-harness.d.ts +11 -12
  10. package/dist/harness/agent-harness.d.ts.map +1 -1
  11. package/dist/harness/agent-harness.js +47 -22
  12. package/dist/harness/agent-harness.js.map +1 -1
  13. package/dist/harness/compaction/branch-summarization.d.ts +5 -1
  14. package/dist/harness/compaction/branch-summarization.d.ts.map +1 -1
  15. package/dist/harness/compaction/branch-summarization.js +6 -7
  16. package/dist/harness/compaction/branch-summarization.js.map +1 -1
  17. package/dist/harness/compaction/compaction.d.ts +17 -5
  18. package/dist/harness/compaction/compaction.d.ts.map +1 -1
  19. package/dist/harness/compaction/compaction.js +81 -26
  20. package/dist/harness/compaction/compaction.js.map +1 -1
  21. package/dist/harness/compaction/utils.d.ts +1 -1
  22. package/dist/harness/compaction/utils.d.ts.map +1 -1
  23. package/dist/harness/compaction/utils.js +6 -17
  24. package/dist/harness/compaction/utils.js.map +1 -1
  25. package/dist/harness/env/nodejs.d.ts +3 -9
  26. package/dist/harness/env/nodejs.d.ts.map +1 -1
  27. package/dist/harness/env/nodejs.js +118 -11
  28. package/dist/harness/env/nodejs.js.map +1 -1
  29. package/dist/harness/session/jsonl-storage.d.ts +11 -3
  30. package/dist/harness/session/jsonl-storage.d.ts.map +1 -1
  31. package/dist/harness/session/jsonl-storage.js +56 -4
  32. package/dist/harness/session/jsonl-storage.js.map +1 -1
  33. package/dist/harness/session/memory-storage.d.ts +11 -3
  34. package/dist/harness/session/memory-storage.d.ts.map +1 -1
  35. package/dist/harness/session/memory-storage.js +56 -4
  36. package/dist/harness/session/memory-storage.js.map +1 -1
  37. package/dist/harness/session/repo-utils.d.ts.map +1 -1
  38. package/dist/harness/session/repo-utils.js +2 -2
  39. package/dist/harness/session/repo-utils.js.map +1 -1
  40. package/dist/harness/session/session.d.ts +6 -4
  41. package/dist/harness/session/session.d.ts.map +1 -1
  42. package/dist/harness/session/session.js +30 -14
  43. package/dist/harness/session/session.js.map +1 -1
  44. package/dist/harness/tools/bash.d.ts +27 -0
  45. package/dist/harness/tools/bash.d.ts.map +1 -0
  46. package/dist/harness/tools/bash.js +132 -0
  47. package/dist/harness/tools/bash.js.map +1 -0
  48. package/dist/harness/tools/edit-diff.d.ts +89 -0
  49. package/dist/harness/tools/edit-diff.d.ts.map +1 -0
  50. package/dist/harness/tools/edit-diff.js +386 -0
  51. package/dist/harness/tools/edit-diff.js.map +1 -0
  52. package/dist/harness/tools/edit.d.ts +19 -0
  53. package/dist/harness/tools/edit.d.ts.map +1 -0
  54. package/dist/harness/tools/edit.js +95 -0
  55. package/dist/harness/tools/edit.js.map +1 -0
  56. package/dist/harness/tools/file-mutation-queue.d.ts +4 -0
  57. package/dist/harness/tools/file-mutation-queue.d.ts.map +1 -0
  58. package/dist/harness/tools/file-mutation-queue.js +46 -0
  59. package/dist/harness/tools/file-mutation-queue.js.map +1 -0
  60. package/dist/harness/tools/image.d.ts +3 -0
  61. package/dist/harness/tools/image.d.ts.map +1 -0
  62. package/dist/harness/tools/image.js +106 -0
  63. package/dist/harness/tools/image.js.map +1 -0
  64. package/dist/harness/tools/index.d.ts +6 -0
  65. package/dist/harness/tools/index.d.ts.map +1 -0
  66. package/dist/harness/tools/index.js +5 -0
  67. package/dist/harness/tools/index.js.map +1 -0
  68. package/dist/harness/tools/path-utils.d.ts +4 -0
  69. package/dist/harness/tools/path-utils.d.ts.map +1 -0
  70. package/dist/harness/tools/path-utils.js +26 -0
  71. package/dist/harness/tools/path-utils.js.map +1 -0
  72. package/dist/harness/tools/read.d.ts +34 -0
  73. package/dist/harness/tools/read.d.ts.map +1 -0
  74. package/dist/harness/tools/read.js +110 -0
  75. package/dist/harness/tools/read.js.map +1 -0
  76. package/dist/harness/tools/tool-context.d.ts +6 -0
  77. package/dist/harness/tools/tool-context.d.ts.map +1 -0
  78. package/dist/harness/tools/tool-context.js +2 -0
  79. package/dist/harness/tools/tool-context.js.map +1 -0
  80. package/dist/harness/tools/write.d.ts +11 -0
  81. package/dist/harness/tools/write.d.ts.map +1 -0
  82. package/dist/harness/tools/write.js +31 -0
  83. package/dist/harness/tools/write.js.map +1 -0
  84. package/dist/harness/types.d.ts +80 -18
  85. package/dist/harness/types.d.ts.map +1 -1
  86. package/dist/harness/types.js.map +1 -1
  87. package/dist/harness/utils/shell-output.d.ts +12 -4
  88. package/dist/harness/utils/shell-output.d.ts.map +1 -1
  89. package/dist/harness/utils/shell-output.js +90 -35
  90. package/dist/harness/utils/shell-output.js.map +1 -1
  91. package/dist/harness/utils/truncate.d.ts.map +1 -1
  92. package/dist/harness/utils/truncate.js +10 -4
  93. package/dist/harness/utils/truncate.js.map +1 -1
  94. package/dist/index.d.ts +4 -2
  95. package/dist/index.d.ts.map +1 -1
  96. package/dist/index.js +5 -2
  97. package/dist/index.js.map +1 -1
  98. package/dist/proxy.js +1 -1
  99. package/dist/proxy.js.map +1 -1
  100. package/dist/stream-fn.d.ts +10 -0
  101. package/dist/stream-fn.d.ts.map +1 -0
  102. package/dist/stream-fn.js +17 -0
  103. package/dist/stream-fn.js.map +1 -0
  104. package/dist/types.d.ts +10 -2
  105. package/dist/types.d.ts.map +1 -1
  106. package/dist/types.js.map +1 -1
  107. package/package.json +4 -3
  108. package/dist/harness/session/repo/jsonl.d.ts +0 -20
  109. package/dist/harness/session/repo/jsonl.d.ts.map +0 -1
  110. package/dist/harness/session/repo/jsonl.js +0 -91
  111. package/dist/harness/session/repo/jsonl.js.map +0 -1
  112. package/dist/harness/session/repo/memory.d.ts +0 -18
  113. package/dist/harness/session/repo/memory.d.ts.map +0 -1
  114. package/dist/harness/session/repo/memory.js +0 -44
  115. package/dist/harness/session/repo/memory.js.map +0 -1
  116. package/dist/harness/session/repo/shared.d.ts +0 -10
  117. package/dist/harness/session/repo/shared.d.ts.map +0 -1
  118. package/dist/harness/session/repo/shared.js +0 -31
  119. package/dist/harness/session/repo/shared.js.map +0 -1
  120. package/dist/harness/session/storage/jsonl.d.ts +0 -30
  121. package/dist/harness/session/storage/jsonl.d.ts.map +0 -1
  122. package/dist/harness/session/storage/jsonl.js +0 -164
  123. package/dist/harness/session/storage/jsonl.js.map +0 -1
  124. package/dist/harness/session/storage/memory.d.ts +0 -26
  125. package/dist/harness/session/storage/memory.d.ts.map +0 -1
  126. package/dist/harness/session/storage/memory.js +0 -85
  127. package/dist/harness/session/storage/memory.js.map +0 -1
  128. package/dist/harness/session/uuid.d.ts +0 -2
  129. package/dist/harness/session/uuid.d.ts.map +0 -1
  130. package/dist/harness/session/uuid.js +0 -50
  131. package/dist/harness/session/uuid.js.map +0 -1
@@ -1,44 +0,0 @@
1
- import { InMemorySessionStorage } from "../storage/memory.js";
2
- import { createSessionId, createTimestamp, getEntriesToFork, toSession } from "./shared.js";
3
- export class InMemorySessionRepo {
4
- constructor() {
5
- this.sessions = new Map();
6
- }
7
- async create(options = {}) {
8
- const metadata = {
9
- id: options.id ?? createSessionId(),
10
- createdAt: createTimestamp(),
11
- };
12
- const storage = new InMemorySessionStorage({ metadata });
13
- const session = toSession(storage);
14
- this.sessions.set(metadata.id, session);
15
- return session;
16
- }
17
- async open(metadata) {
18
- const session = this.sessions.get(metadata.id);
19
- if (!session) {
20
- throw new Error(`Session not found: ${metadata.id}`);
21
- }
22
- return session;
23
- }
24
- async list() {
25
- return Promise.all([...this.sessions.values()].map((session) => session.getMetadata()));
26
- }
27
- async delete(metadata) {
28
- this.sessions.delete(metadata.id);
29
- }
30
- async fork(sourceMetadata, options) {
31
- const source = await this.open(sourceMetadata);
32
- const forkedEntries = await getEntriesToFork(source.getStorage(), options);
33
- const metadata = {
34
- id: options.id ?? createSessionId(),
35
- createdAt: createTimestamp(),
36
- };
37
- const leafId = forkedEntries[forkedEntries.length - 1]?.id ?? null;
38
- const storage = new InMemorySessionStorage({ metadata, entries: forkedEntries, leafId });
39
- const session = toSession(storage);
40
- this.sessions.set(metadata.id, session);
41
- return session;
42
- }
43
- }
44
- //# sourceMappingURL=memory.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../../../src/harness/session/repo/memory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE5F,MAAM,OAAO,mBAAmB;IAAhC;QACS,aAAQ,GAAG,IAAI,GAAG,EAAoC,CAAC;IA6ChE,CAAC;IA3CA,KAAK,CAAC,MAAM,CAAC,OAAO,GAAoB,EAAE;QACzC,MAAM,QAAQ,GAAoB;YACjC,EAAE,EAAE,OAAO,CAAC,EAAE,IAAI,eAAe,EAAE;YACnC,SAAS,EAAE,eAAe,EAAE;SAC5B,CAAC;QACF,MAAM,OAAO,GAAG,IAAI,sBAAsB,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QACzD,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;QACnC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QACxC,OAAO,OAAO,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,QAAyB;QACnC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,sBAAsB,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;QACtD,CAAC;QACD,OAAO,OAAO,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,IAAI;QACT,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACzF,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,QAAyB;QACrC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,IAAI,CACT,cAA+B,EAC/B,OAAsE;QAEtE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC/C,MAAM,aAAa,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,OAAO,CAAC,CAAC;QAC3E,MAAM,QAAQ,GAAoB;YACjC,EAAE,EAAE,OAAO,CAAC,EAAE,IAAI,eAAe,EAAE;YACnC,SAAS,EAAE,eAAe,EAAE;SAC5B,CAAC;QACF,MAAM,MAAM,GAAG,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,EAAE,IAAI,IAAI,CAAC;QACnE,MAAM,OAAO,GAAG,IAAI,sBAAsB,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC,CAAC;QACzF,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;QACnC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QACxC,OAAO,OAAO,CAAC;IAChB,CAAC;CACD","sourcesContent":["import type { Session, SessionMetadata, SessionRepo } from \"../../types.js\";\nimport { InMemorySessionStorage } from \"../storage/memory.js\";\nimport { createSessionId, createTimestamp, getEntriesToFork, toSession } from \"./shared.js\";\n\nexport class InMemorySessionRepo implements SessionRepo<SessionMetadata, { id?: string }, void> {\n\tprivate sessions = new Map<string, Session<SessionMetadata>>();\n\n\tasync create(options: { id?: string } = {}): Promise<Session<SessionMetadata>> {\n\t\tconst metadata: SessionMetadata = {\n\t\t\tid: options.id ?? createSessionId(),\n\t\t\tcreatedAt: createTimestamp(),\n\t\t};\n\t\tconst storage = new InMemorySessionStorage({ metadata });\n\t\tconst session = toSession(storage);\n\t\tthis.sessions.set(metadata.id, session);\n\t\treturn session;\n\t}\n\n\tasync open(metadata: SessionMetadata): Promise<Session<SessionMetadata>> {\n\t\tconst session = this.sessions.get(metadata.id);\n\t\tif (!session) {\n\t\t\tthrow new Error(`Session not found: ${metadata.id}`);\n\t\t}\n\t\treturn session;\n\t}\n\n\tasync list(): Promise<SessionMetadata[]> {\n\t\treturn Promise.all([...this.sessions.values()].map((session) => session.getMetadata()));\n\t}\n\n\tasync delete(metadata: SessionMetadata): Promise<void> {\n\t\tthis.sessions.delete(metadata.id);\n\t}\n\n\tasync fork(\n\t\tsourceMetadata: SessionMetadata,\n\t\toptions: { entryId?: string; position?: \"before\" | \"at\"; id?: string },\n\t): Promise<Session<SessionMetadata>> {\n\t\tconst source = await this.open(sourceMetadata);\n\t\tconst forkedEntries = await getEntriesToFork(source.getStorage(), options);\n\t\tconst metadata: SessionMetadata = {\n\t\t\tid: options.id ?? createSessionId(),\n\t\t\tcreatedAt: createTimestamp(),\n\t\t};\n\t\tconst leafId = forkedEntries[forkedEntries.length - 1]?.id ?? null;\n\t\tconst storage = new InMemorySessionStorage({ metadata, entries: forkedEntries, leafId });\n\t\tconst session = toSession(storage);\n\t\tthis.sessions.set(metadata.id, session);\n\t\treturn session;\n\t}\n}\n"]}
@@ -1,10 +0,0 @@
1
- import type { SessionMetadata, SessionStorage, SessionTreeEntry } from "../../types.js";
2
- import { Session } from "../session.js";
3
- export declare function createSessionId(): string;
4
- export declare function createTimestamp(): string;
5
- export declare function toSession<TMetadata extends SessionMetadata>(storage: SessionStorage<TMetadata>): Session<TMetadata>;
6
- export declare function getEntriesToFork(storage: SessionStorage, options: {
7
- entryId?: string;
8
- position?: "before" | "at";
9
- }): Promise<SessionTreeEntry[]>;
10
- //# sourceMappingURL=shared.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../../src/harness/session/repo/shared.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACxF,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,SAAS,CAAC,SAAS,SAAS,eAAe,EAAE,OAAO,EAAE,cAAc,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,CAEnH;AAED,wBAAsB,gBAAgB,CACrC,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAA;CAAE,GACvD,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAgB7B"}
@@ -1,31 +0,0 @@
1
- import { v7 as uuidv7 } from "uuid";
2
- import { Session } from "../session.js";
3
- export function createSessionId() {
4
- return uuidv7();
5
- }
6
- export function createTimestamp() {
7
- return new Date().toISOString();
8
- }
9
- export function toSession(storage) {
10
- return new Session(storage);
11
- }
12
- export async function getEntriesToFork(storage, options) {
13
- if (!options.entryId)
14
- return storage.getEntries();
15
- const target = await storage.getEntry(options.entryId);
16
- if (!target) {
17
- throw new Error(`Entry ${options.entryId} not found`);
18
- }
19
- let effectiveLeafId;
20
- if ((options.position ?? "before") === "at") {
21
- effectiveLeafId = target.id;
22
- }
23
- else {
24
- if (target.type !== "message" || target.message.role !== "user") {
25
- throw new Error(`Entry ${options.entryId} is not a user message`);
26
- }
27
- effectiveLeafId = target.parentId;
28
- }
29
- return storage.getPathToRoot(effectiveLeafId);
30
- }
31
- //# sourceMappingURL=shared.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../../src/harness/session/repo/shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AAEpC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,MAAM,UAAU,eAAe;IAC9B,OAAO,MAAM,EAAE,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,eAAe;IAC9B,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,SAAS,CAAoC,OAAkC;IAC9F,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACrC,OAAuB,EACvB,OAAyD;IAEzD,IAAI,CAAC,OAAO,CAAC,OAAO;QAAE,OAAO,OAAO,CAAC,UAAU,EAAE,CAAC;IAClD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACvD,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,SAAS,OAAO,CAAC,OAAO,YAAY,CAAC,CAAC;IACvD,CAAC;IACD,IAAI,eAA8B,CAAC;IACnC,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC;QAC7C,eAAe,GAAG,MAAM,CAAC,EAAE,CAAC;IAC7B,CAAC;SAAM,CAAC;QACP,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACjE,MAAM,IAAI,KAAK,CAAC,SAAS,OAAO,CAAC,OAAO,wBAAwB,CAAC,CAAC;QACnE,CAAC;QACD,eAAe,GAAG,MAAM,CAAC,QAAQ,CAAC;IACnC,CAAC;IACD,OAAO,OAAO,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC;AAC/C,CAAC","sourcesContent":["import { v7 as uuidv7 } from \"uuid\";\nimport type { SessionMetadata, SessionStorage, SessionTreeEntry } from \"../../types.js\";\nimport { Session } from \"../session.js\";\n\nexport function createSessionId(): string {\n\treturn uuidv7();\n}\n\nexport function createTimestamp(): string {\n\treturn new Date().toISOString();\n}\n\nexport function toSession<TMetadata extends SessionMetadata>(storage: SessionStorage<TMetadata>): Session<TMetadata> {\n\treturn new Session(storage);\n}\n\nexport async function getEntriesToFork(\n\tstorage: SessionStorage,\n\toptions: { entryId?: string; position?: \"before\" | \"at\" },\n): Promise<SessionTreeEntry[]> {\n\tif (!options.entryId) return storage.getEntries();\n\tconst target = await storage.getEntry(options.entryId);\n\tif (!target) {\n\t\tthrow new Error(`Entry ${options.entryId} not found`);\n\t}\n\tlet effectiveLeafId: string | null;\n\tif ((options.position ?? \"before\") === \"at\") {\n\t\teffectiveLeafId = target.id;\n\t} else {\n\t\tif (target.type !== \"message\" || target.message.role !== \"user\") {\n\t\t\tthrow new Error(`Entry ${options.entryId} is not a user message`);\n\t\t}\n\t\teffectiveLeafId = target.parentId;\n\t}\n\treturn storage.getPathToRoot(effectiveLeafId);\n}\n"]}
@@ -1,30 +0,0 @@
1
- import type { JsonlSessionMetadata, SessionStorage, SessionTreeEntry } from "../../types.js";
2
- export declare function loadJsonlSessionMetadata(filePath: string): Promise<JsonlSessionMetadata>;
3
- export declare class JsonlSessionStorage implements SessionStorage<JsonlSessionMetadata> {
4
- private readonly filePath;
5
- private readonly metadata;
6
- private entries;
7
- private byId;
8
- private labelsById;
9
- private currentLeafId;
10
- private constructor();
11
- static open(filePath: string): Promise<JsonlSessionStorage>;
12
- static create(filePath: string, options: {
13
- cwd: string;
14
- sessionId: string;
15
- parentSessionPath?: string;
16
- }): Promise<JsonlSessionStorage>;
17
- getMetadata(): Promise<JsonlSessionMetadata>;
18
- getLeafId(): Promise<string | null>;
19
- setLeafId(leafId: string | null): Promise<void>;
20
- createEntryId(): Promise<string>;
21
- appendEntry(entry: SessionTreeEntry): Promise<void>;
22
- getEntry(id: string): Promise<SessionTreeEntry | undefined>;
23
- findEntries<TType extends SessionTreeEntry["type"]>(type: TType): Promise<Array<Extract<SessionTreeEntry, {
24
- type: TType;
25
- }>>>;
26
- getLabel(id: string): Promise<string | undefined>;
27
- getPathToRoot(leafId: string | null): Promise<SessionTreeEntry[]>;
28
- getEntries(): Promise<SessionTreeEntry[]>;
29
- }
30
- //# sourceMappingURL=jsonl.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"jsonl.d.ts","sourceRoot":"","sources":["../../../../src/harness/session/storage/jsonl.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,oBAAoB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AA+C7F,wBAAsB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAkB9F;AAkCD,qBAAa,mBAAoB,YAAW,cAAc,CAAC,oBAAoB,CAAC;IAC/E,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuB;IAChD,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,IAAI,CAAgC;IAC5C,OAAO,CAAC,UAAU,CAAsB;IACxC,OAAO,CAAC,aAAa,CAAgB;IAErC,OAAO,eAON;IAED,OAAa,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAIhE;IAED,OAAa,MAAM,CAClB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE;QACR,GAAG,EAAE,MAAM,CAAC;QACZ,SAAS,EAAE,MAAM,CAAC;QAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC3B,GACC,OAAO,CAAC,mBAAmB,CAAC,CAa9B;IAEK,WAAW,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAEjD;IAEK,SAAS,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAExC;IAEK,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAKpD;IAEK,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAErC;IAEK,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAMxD;IAEK,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAEhE;IAEK,WAAW,CAAC,KAAK,SAAS,gBAAgB,CAAC,MAAM,CAAC,EACvD,IAAI,EAAE,KAAK,GACT,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,gBAAgB,EAAE;QAAE,IAAI,EAAE,KAAK,CAAA;KAAE,CAAC,CAAC,CAAC,CAE5D;IAEK,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAEtD;IAEK,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAStE;IAEK,UAAU,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAE9C;CACD"}
@@ -1,164 +0,0 @@
1
- import { randomUUID } from "node:crypto";
2
- import { createReadStream } from "node:fs";
3
- import { appendFile, mkdir, readFile, writeFile } from "node:fs/promises";
4
- import { dirname, resolve } from "node:path";
5
- import { createInterface } from "node:readline";
6
- function updateLabelCache(labelsById, entry) {
7
- if (entry.type !== "label")
8
- return;
9
- const label = entry.label?.trim();
10
- if (label) {
11
- labelsById.set(entry.targetId, label);
12
- }
13
- else {
14
- labelsById.delete(entry.targetId);
15
- }
16
- }
17
- function buildLabelsById(entries) {
18
- const labelsById = new Map();
19
- for (const entry of entries) {
20
- updateLabelCache(labelsById, entry);
21
- }
22
- return labelsById;
23
- }
24
- function generateEntryId(byId) {
25
- for (let i = 0; i < 100; i++) {
26
- const id = randomUUID().slice(0, 8);
27
- if (!byId.has(id))
28
- return id;
29
- }
30
- return randomUUID();
31
- }
32
- function headerToSessionMetadata(header, path) {
33
- return {
34
- id: header.id,
35
- createdAt: header.timestamp,
36
- cwd: header.cwd,
37
- path,
38
- parentSessionPath: header.parentSession,
39
- };
40
- }
41
- export async function loadJsonlSessionMetadata(filePath) {
42
- const stream = createReadStream(filePath, { encoding: "utf8" });
43
- const lines = createInterface({ input: stream, crlfDelay: Infinity });
44
- try {
45
- for await (const line of lines) {
46
- if (!line.trim())
47
- break;
48
- try {
49
- const header = JSON.parse(line);
50
- return headerToSessionMetadata(header, resolve(filePath));
51
- }
52
- catch {
53
- throw new Error(`Invalid JSONL session file ${filePath}: first line is not a valid session header`);
54
- }
55
- }
56
- throw new Error(`Invalid JSONL session file ${filePath}: missing session header`);
57
- }
58
- finally {
59
- lines.close();
60
- stream.destroy();
61
- }
62
- }
63
- async function loadJsonlStorage(filePath) {
64
- const content = await readFile(filePath, "utf8");
65
- const lines = content.split("\n").filter((line) => line.trim());
66
- if (lines.length === 0) {
67
- throw new Error(`Invalid JSONL session file ${filePath}: missing session header`);
68
- }
69
- let header;
70
- try {
71
- header = JSON.parse(lines[0]);
72
- }
73
- catch {
74
- throw new Error(`Invalid JSONL session file ${filePath}: first line is not a valid session header`);
75
- }
76
- const entries = [];
77
- let leafId = null;
78
- for (const line of lines.slice(1)) {
79
- try {
80
- const entry = JSON.parse(line);
81
- entries.push(entry);
82
- leafId = entry.id;
83
- }
84
- catch {
85
- // ignore malformed entry lines
86
- }
87
- }
88
- return { header, entries, leafId };
89
- }
90
- export class JsonlSessionStorage {
91
- constructor(filePath, header, entries, leafId) {
92
- this.filePath = resolve(filePath);
93
- this.metadata = headerToSessionMetadata(header, this.filePath);
94
- this.entries = entries;
95
- this.byId = new Map(entries.map((entry) => [entry.id, entry]));
96
- this.labelsById = buildLabelsById(entries);
97
- this.currentLeafId = leafId;
98
- }
99
- static async open(filePath) {
100
- const resolvedPath = resolve(filePath);
101
- const loaded = await loadJsonlStorage(resolvedPath);
102
- return new JsonlSessionStorage(resolvedPath, loaded.header, loaded.entries, loaded.leafId);
103
- }
104
- static async create(filePath, options) {
105
- const resolvedPath = resolve(filePath);
106
- const header = {
107
- type: "session",
108
- version: 3,
109
- id: options.sessionId,
110
- timestamp: new Date().toISOString(),
111
- cwd: options.cwd,
112
- parentSession: options.parentSessionPath,
113
- };
114
- await mkdir(dirname(resolvedPath), { recursive: true });
115
- await writeFile(resolvedPath, `${JSON.stringify(header)}\n`);
116
- return new JsonlSessionStorage(resolvedPath, header, [], null);
117
- }
118
- async getMetadata() {
119
- return this.metadata;
120
- }
121
- async getLeafId() {
122
- return this.currentLeafId;
123
- }
124
- async setLeafId(leafId) {
125
- if (leafId !== null && !this.byId.has(leafId)) {
126
- throw new Error(`Entry ${leafId} not found`);
127
- }
128
- this.currentLeafId = leafId;
129
- }
130
- async createEntryId() {
131
- return generateEntryId(this.byId);
132
- }
133
- async appendEntry(entry) {
134
- await appendFile(this.filePath, `${JSON.stringify(entry)}\n`);
135
- this.entries.push(entry);
136
- this.byId.set(entry.id, entry);
137
- updateLabelCache(this.labelsById, entry);
138
- this.currentLeafId = entry.id;
139
- }
140
- async getEntry(id) {
141
- return this.byId.get(id);
142
- }
143
- async findEntries(type) {
144
- return this.entries.filter((entry) => entry.type === type);
145
- }
146
- async getLabel(id) {
147
- return this.labelsById.get(id);
148
- }
149
- async getPathToRoot(leafId) {
150
- if (leafId === null)
151
- return [];
152
- const path = [];
153
- let current = this.byId.get(leafId);
154
- while (current) {
155
- path.unshift(current);
156
- current = current.parentId ? this.byId.get(current.parentId) : undefined;
157
- }
158
- return path;
159
- }
160
- async getEntries() {
161
- return [...this.entries];
162
- }
163
- }
164
- //# sourceMappingURL=jsonl.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"jsonl.js","sourceRoot":"","sources":["../../../../src/harness/session/storage/jsonl.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { createReadStream } from \"node:fs\";\nimport { appendFile, mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\nimport { createInterface } from \"node:readline\";\nimport type { JsonlSessionMetadata, SessionStorage, SessionTreeEntry } from \"../../types.js\";\n\ninterface SessionHeader {\n\ttype: \"session\";\n\tversion: 3;\n\tid: string;\n\ttimestamp: string;\n\tcwd: string;\n\tparentSession?: string;\n}\n\nfunction updateLabelCache(labelsById: Map<string, string>, entry: SessionTreeEntry): void {\n\tif (entry.type !== \"label\") return;\n\tconst label = entry.label?.trim();\n\tif (label) {\n\t\tlabelsById.set(entry.targetId, label);\n\t} else {\n\t\tlabelsById.delete(entry.targetId);\n\t}\n}\n\nfunction buildLabelsById(entries: SessionTreeEntry[]): Map<string, string> {\n\tconst labelsById = new Map<string, string>();\n\tfor (const entry of entries) {\n\t\tupdateLabelCache(labelsById, entry);\n\t}\n\treturn labelsById;\n}\n\nfunction generateEntryId(byId: { has(id: string): boolean }): string {\n\tfor (let i = 0; i < 100; i++) {\n\t\tconst id = randomUUID().slice(0, 8);\n\t\tif (!byId.has(id)) return id;\n\t}\n\treturn randomUUID();\n}\n\nfunction headerToSessionMetadata(header: SessionHeader, path: string): JsonlSessionMetadata {\n\treturn {\n\t\tid: header.id,\n\t\tcreatedAt: header.timestamp,\n\t\tcwd: header.cwd,\n\t\tpath,\n\t\tparentSessionPath: header.parentSession,\n\t};\n}\n\nexport async function loadJsonlSessionMetadata(filePath: string): Promise<JsonlSessionMetadata> {\n\tconst stream = createReadStream(filePath, { encoding: \"utf8\" });\n\tconst lines = createInterface({ input: stream, crlfDelay: Infinity });\n\ttry {\n\t\tfor await (const line of lines) {\n\t\t\tif (!line.trim()) break;\n\t\t\ttry {\n\t\t\t\tconst header = JSON.parse(line) as SessionHeader;\n\t\t\t\treturn headerToSessionMetadata(header, resolve(filePath));\n\t\t\t} catch {\n\t\t\t\tthrow new Error(`Invalid JSONL session file ${filePath}: first line is not a valid session header`);\n\t\t\t}\n\t\t}\n\t\tthrow new Error(`Invalid JSONL session file ${filePath}: missing session header`);\n\t} finally {\n\t\tlines.close();\n\t\tstream.destroy();\n\t}\n}\n\nasync function loadJsonlStorage(filePath: string): Promise<{\n\theader: SessionHeader;\n\tentries: SessionTreeEntry[];\n\tleafId: string | null;\n}> {\n\tconst content = await readFile(filePath, \"utf8\");\n\tconst lines = content.split(\"\\n\").filter((line) => line.trim());\n\tif (lines.length === 0) {\n\t\tthrow new Error(`Invalid JSONL session file ${filePath}: missing session header`);\n\t}\n\n\tlet header: SessionHeader;\n\ttry {\n\t\theader = JSON.parse(lines[0]!) as SessionHeader;\n\t} catch {\n\t\tthrow new Error(`Invalid JSONL session file ${filePath}: first line is not a valid session header`);\n\t}\n\n\tconst entries: SessionTreeEntry[] = [];\n\tlet leafId: string | null = null;\n\tfor (const line of lines.slice(1)) {\n\t\ttry {\n\t\t\tconst entry = JSON.parse(line) as SessionTreeEntry;\n\t\t\tentries.push(entry);\n\t\t\tleafId = entry.id;\n\t\t} catch {\n\t\t\t// ignore malformed entry lines\n\t\t}\n\t}\n\treturn { header, entries, leafId };\n}\n\nexport class JsonlSessionStorage implements SessionStorage<JsonlSessionMetadata> {\n\tprivate readonly filePath: string;\n\tprivate readonly metadata: JsonlSessionMetadata;\n\tprivate entries: SessionTreeEntry[];\n\tprivate byId: Map<string, SessionTreeEntry>;\n\tprivate labelsById: Map<string, string>;\n\tprivate currentLeafId: string | null;\n\n\tprivate constructor(filePath: string, header: SessionHeader, entries: SessionTreeEntry[], leafId: string | null) {\n\t\tthis.filePath = resolve(filePath);\n\t\tthis.metadata = headerToSessionMetadata(header, this.filePath);\n\t\tthis.entries = entries;\n\t\tthis.byId = new Map(entries.map((entry) => [entry.id, entry]));\n\t\tthis.labelsById = buildLabelsById(entries);\n\t\tthis.currentLeafId = leafId;\n\t}\n\n\tstatic async open(filePath: string): Promise<JsonlSessionStorage> {\n\t\tconst resolvedPath = resolve(filePath);\n\t\tconst loaded = await loadJsonlStorage(resolvedPath);\n\t\treturn new JsonlSessionStorage(resolvedPath, loaded.header, loaded.entries, loaded.leafId);\n\t}\n\n\tstatic async create(\n\t\tfilePath: string,\n\t\toptions: {\n\t\t\tcwd: string;\n\t\t\tsessionId: string;\n\t\t\tparentSessionPath?: string;\n\t\t},\n\t): Promise<JsonlSessionStorage> {\n\t\tconst resolvedPath = resolve(filePath);\n\t\tconst header: SessionHeader = {\n\t\t\ttype: \"session\",\n\t\t\tversion: 3,\n\t\t\tid: options.sessionId,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tcwd: options.cwd,\n\t\t\tparentSession: options.parentSessionPath,\n\t\t};\n\t\tawait mkdir(dirname(resolvedPath), { recursive: true });\n\t\tawait writeFile(resolvedPath, `${JSON.stringify(header)}\\n`);\n\t\treturn new JsonlSessionStorage(resolvedPath, header, [], null);\n\t}\n\n\tasync getMetadata(): Promise<JsonlSessionMetadata> {\n\t\treturn this.metadata;\n\t}\n\n\tasync getLeafId(): Promise<string | null> {\n\t\treturn this.currentLeafId;\n\t}\n\n\tasync setLeafId(leafId: string | null): Promise<void> {\n\t\tif (leafId !== null && !this.byId.has(leafId)) {\n\t\t\tthrow new Error(`Entry ${leafId} not found`);\n\t\t}\n\t\tthis.currentLeafId = leafId;\n\t}\n\n\tasync createEntryId(): Promise<string> {\n\t\treturn generateEntryId(this.byId);\n\t}\n\n\tasync appendEntry(entry: SessionTreeEntry): Promise<void> {\n\t\tawait appendFile(this.filePath, `${JSON.stringify(entry)}\\n`);\n\t\tthis.entries.push(entry);\n\t\tthis.byId.set(entry.id, entry);\n\t\tupdateLabelCache(this.labelsById, entry);\n\t\tthis.currentLeafId = entry.id;\n\t}\n\n\tasync getEntry(id: string): Promise<SessionTreeEntry | undefined> {\n\t\treturn this.byId.get(id);\n\t}\n\n\tasync findEntries<TType extends SessionTreeEntry[\"type\"]>(\n\t\ttype: TType,\n\t): Promise<Array<Extract<SessionTreeEntry, { type: TType }>>> {\n\t\treturn this.entries.filter((entry): entry is Extract<SessionTreeEntry, { type: TType }> => entry.type === type);\n\t}\n\n\tasync getLabel(id: string): Promise<string | undefined> {\n\t\treturn this.labelsById.get(id);\n\t}\n\n\tasync getPathToRoot(leafId: string | null): Promise<SessionTreeEntry[]> {\n\t\tif (leafId === null) return [];\n\t\tconst path: SessionTreeEntry[] = [];\n\t\tlet current = this.byId.get(leafId);\n\t\twhile (current) {\n\t\t\tpath.unshift(current);\n\t\t\tcurrent = current.parentId ? this.byId.get(current.parentId) : undefined;\n\t\t}\n\t\treturn path;\n\t}\n\n\tasync getEntries(): Promise<SessionTreeEntry[]> {\n\t\treturn [...this.entries];\n\t}\n}\n"]}
@@ -1,26 +0,0 @@
1
- import type { SessionMetadata, SessionStorage, SessionTreeEntry } from "../../types.js";
2
- export declare class InMemorySessionStorage implements SessionStorage {
3
- private readonly metadata;
4
- private entries;
5
- private byId;
6
- private labelsById;
7
- private leafId;
8
- constructor(options?: {
9
- entries?: SessionTreeEntry[];
10
- leafId?: string | null;
11
- metadata?: SessionMetadata;
12
- });
13
- getMetadata(): Promise<SessionMetadata>;
14
- getLeafId(): Promise<string | null>;
15
- setLeafId(leafId: string | null): Promise<void>;
16
- createEntryId(): Promise<string>;
17
- appendEntry(entry: SessionTreeEntry): Promise<void>;
18
- getEntry(id: string): Promise<SessionTreeEntry | undefined>;
19
- findEntries<TType extends SessionTreeEntry["type"]>(type: TType): Promise<Array<Extract<SessionTreeEntry, {
20
- type: TType;
21
- }>>>;
22
- getLabel(id: string): Promise<string | undefined>;
23
- getPathToRoot(leafId: string | null): Promise<SessionTreeEntry[]>;
24
- getEntries(): Promise<SessionTreeEntry[]>;
25
- }
26
- //# sourceMappingURL=memory.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../../src/harness/session/storage/memory.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AA4BxF,qBAAa,sBAAuB,YAAW,cAAc;IAC5D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;IAC3C,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,IAAI,CAAgC;IAC5C,OAAO,CAAC,UAAU,CAAsB;IACxC,OAAO,CAAC,MAAM,CAAgB;IAE9B,YAAY,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,CAAC,EAAE,eAAe,CAAA;KAAE,EASzG;IAEK,WAAW,IAAI,OAAO,CAAC,eAAe,CAAC,CAE5C;IAEK,SAAS,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAExC;IAEK,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAKpD;IAEK,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAErC;IAEK,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAKxD;IAEK,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAEhE;IAEK,WAAW,CAAC,KAAK,SAAS,gBAAgB,CAAC,MAAM,CAAC,EACvD,IAAI,EAAE,KAAK,GACT,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,gBAAgB,EAAE;QAAE,IAAI,EAAE,KAAK,CAAA;KAAE,CAAC,CAAC,CAAC,CAE5D;IAEK,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAEtD;IAEK,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAStE;IAEK,UAAU,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAE9C;CACD"}
@@ -1,85 +0,0 @@
1
- import { randomUUID } from "node:crypto";
2
- import { v7 as uuidv7 } from "uuid";
3
- function updateLabelCache(labelsById, entry) {
4
- if (entry.type !== "label")
5
- return;
6
- const label = entry.label?.trim();
7
- if (label) {
8
- labelsById.set(entry.targetId, label);
9
- }
10
- else {
11
- labelsById.delete(entry.targetId);
12
- }
13
- }
14
- function buildLabelsById(entries) {
15
- const labelsById = new Map();
16
- for (const entry of entries) {
17
- updateLabelCache(labelsById, entry);
18
- }
19
- return labelsById;
20
- }
21
- function generateEntryId(byId) {
22
- for (let i = 0; i < 100; i++) {
23
- const id = randomUUID().slice(0, 8);
24
- if (!byId.has(id))
25
- return id;
26
- }
27
- return randomUUID();
28
- }
29
- export class InMemorySessionStorage {
30
- constructor(options) {
31
- this.entries = options?.entries ? [...options.entries] : [];
32
- this.byId = new Map(this.entries.map((entry) => [entry.id, entry]));
33
- this.labelsById = buildLabelsById(this.entries);
34
- this.leafId = options?.leafId ?? this.entries[this.entries.length - 1]?.id ?? null;
35
- if (this.leafId !== null && !this.byId.has(this.leafId)) {
36
- throw new Error(`Entry ${this.leafId} not found`);
37
- }
38
- this.metadata = options?.metadata ?? { id: uuidv7(), createdAt: new Date().toISOString() };
39
- }
40
- async getMetadata() {
41
- return this.metadata;
42
- }
43
- async getLeafId() {
44
- return this.leafId;
45
- }
46
- async setLeafId(leafId) {
47
- if (leafId !== null && !this.byId.has(leafId)) {
48
- throw new Error(`Entry ${leafId} not found`);
49
- }
50
- this.leafId = leafId;
51
- }
52
- async createEntryId() {
53
- return generateEntryId(this.byId);
54
- }
55
- async appendEntry(entry) {
56
- this.entries.push(entry);
57
- this.byId.set(entry.id, entry);
58
- updateLabelCache(this.labelsById, entry);
59
- this.leafId = entry.id;
60
- }
61
- async getEntry(id) {
62
- return this.byId.get(id);
63
- }
64
- async findEntries(type) {
65
- return this.entries.filter((entry) => entry.type === type);
66
- }
67
- async getLabel(id) {
68
- return this.labelsById.get(id);
69
- }
70
- async getPathToRoot(leafId) {
71
- if (leafId === null)
72
- return [];
73
- const path = [];
74
- let current = this.byId.get(leafId);
75
- while (current) {
76
- path.unshift(current);
77
- current = current.parentId ? this.byId.get(current.parentId) : undefined;
78
- }
79
- return path;
80
- }
81
- async getEntries() {
82
- return [...this.entries];
83
- }
84
- }
85
- //# sourceMappingURL=memory.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../../../src/harness/session/storage/memory.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { v7 as uuidv7 } from \"uuid\";\nimport type { SessionMetadata, SessionStorage, SessionTreeEntry } from \"../../types.js\";\n\nfunction updateLabelCache(labelsById: Map<string, string>, entry: SessionTreeEntry): void {\n\tif (entry.type !== \"label\") return;\n\tconst label = entry.label?.trim();\n\tif (label) {\n\t\tlabelsById.set(entry.targetId, label);\n\t} else {\n\t\tlabelsById.delete(entry.targetId);\n\t}\n}\n\nfunction buildLabelsById(entries: SessionTreeEntry[]): Map<string, string> {\n\tconst labelsById = new Map<string, string>();\n\tfor (const entry of entries) {\n\t\tupdateLabelCache(labelsById, entry);\n\t}\n\treturn labelsById;\n}\n\nfunction generateEntryId(byId: { has(id: string): boolean }): string {\n\tfor (let i = 0; i < 100; i++) {\n\t\tconst id = randomUUID().slice(0, 8);\n\t\tif (!byId.has(id)) return id;\n\t}\n\treturn randomUUID();\n}\n\nexport class InMemorySessionStorage implements SessionStorage {\n\tprivate readonly metadata: SessionMetadata;\n\tprivate entries: SessionTreeEntry[];\n\tprivate byId: Map<string, SessionTreeEntry>;\n\tprivate labelsById: Map<string, string>;\n\tprivate leafId: string | null;\n\n\tconstructor(options?: { entries?: SessionTreeEntry[]; leafId?: string | null; metadata?: SessionMetadata }) {\n\t\tthis.entries = options?.entries ? [...options.entries] : [];\n\t\tthis.byId = new Map(this.entries.map((entry) => [entry.id, entry]));\n\t\tthis.labelsById = buildLabelsById(this.entries);\n\t\tthis.leafId = options?.leafId ?? this.entries[this.entries.length - 1]?.id ?? null;\n\t\tif (this.leafId !== null && !this.byId.has(this.leafId)) {\n\t\t\tthrow new Error(`Entry ${this.leafId} not found`);\n\t\t}\n\t\tthis.metadata = options?.metadata ?? { id: uuidv7(), createdAt: new Date().toISOString() };\n\t}\n\n\tasync getMetadata(): Promise<SessionMetadata> {\n\t\treturn this.metadata;\n\t}\n\n\tasync getLeafId(): Promise<string | null> {\n\t\treturn this.leafId;\n\t}\n\n\tasync setLeafId(leafId: string | null): Promise<void> {\n\t\tif (leafId !== null && !this.byId.has(leafId)) {\n\t\t\tthrow new Error(`Entry ${leafId} not found`);\n\t\t}\n\t\tthis.leafId = leafId;\n\t}\n\n\tasync createEntryId(): Promise<string> {\n\t\treturn generateEntryId(this.byId);\n\t}\n\n\tasync appendEntry(entry: SessionTreeEntry): Promise<void> {\n\t\tthis.entries.push(entry);\n\t\tthis.byId.set(entry.id, entry);\n\t\tupdateLabelCache(this.labelsById, entry);\n\t\tthis.leafId = entry.id;\n\t}\n\n\tasync getEntry(id: string): Promise<SessionTreeEntry | undefined> {\n\t\treturn this.byId.get(id);\n\t}\n\n\tasync findEntries<TType extends SessionTreeEntry[\"type\"]>(\n\t\ttype: TType,\n\t): Promise<Array<Extract<SessionTreeEntry, { type: TType }>>> {\n\t\treturn this.entries.filter((entry): entry is Extract<SessionTreeEntry, { type: TType }> => entry.type === type);\n\t}\n\n\tasync getLabel(id: string): Promise<string | undefined> {\n\t\treturn this.labelsById.get(id);\n\t}\n\n\tasync getPathToRoot(leafId: string | null): Promise<SessionTreeEntry[]> {\n\t\tif (leafId === null) return [];\n\t\tconst path: SessionTreeEntry[] = [];\n\t\tlet current = this.byId.get(leafId);\n\t\twhile (current) {\n\t\t\tpath.unshift(current);\n\t\t\tcurrent = current.parentId ? this.byId.get(current.parentId) : undefined;\n\t\t}\n\t\treturn path;\n\t}\n\n\tasync getEntries(): Promise<SessionTreeEntry[]> {\n\t\treturn [...this.entries];\n\t}\n}\n"]}
@@ -1,2 +0,0 @@
1
- export declare function uuidv7(): string;
2
- //# sourceMappingURL=uuid.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"uuid.d.ts","sourceRoot":"","sources":["../../../src/harness/session/uuid.ts"],"names":[],"mappings":"AAcA,wBAAgB,MAAM,IAAI,MAAM,CAkC/B"}
@@ -1,50 +0,0 @@
1
- let lastTimestamp = -Infinity;
2
- let sequence = 0;
3
- function fillRandomBytes(bytes) {
4
- const crypto = globalThis.crypto;
5
- if (crypto?.getRandomValues) {
6
- crypto.getRandomValues(bytes);
7
- return;
8
- }
9
- for (let i = 0; i < bytes.length; i++) {
10
- bytes[i] = Math.floor(Math.random() * 256);
11
- }
12
- }
13
- export function uuidv7() {
14
- const random = new Uint8Array(16);
15
- fillRandomBytes(random);
16
- const timestamp = Date.now();
17
- if (timestamp > lastTimestamp) {
18
- sequence = random[6] * 0x1000000 + random[7] * 0x10000 + random[8] * 0x100 + random[9];
19
- lastTimestamp = timestamp;
20
- }
21
- else {
22
- sequence = (sequence + 1) >>> 0;
23
- if (sequence === 0) {
24
- lastTimestamp++;
25
- }
26
- }
27
- const bytes = new Uint8Array(16);
28
- bytes[0] = (lastTimestamp / 0x10000000000) & 0xff;
29
- bytes[1] = (lastTimestamp / 0x100000000) & 0xff;
30
- bytes[2] = (lastTimestamp / 0x1000000) & 0xff;
31
- bytes[3] = (lastTimestamp / 0x10000) & 0xff;
32
- bytes[4] = (lastTimestamp / 0x100) & 0xff;
33
- bytes[5] = lastTimestamp & 0xff;
34
- bytes[6] = 0x70 | ((sequence >>> 28) & 0x0f);
35
- bytes[7] = (sequence >>> 20) & 0xff;
36
- bytes[8] = 0x80 | ((sequence >>> 14) & 0x3f);
37
- bytes[9] = (sequence >>> 6) & 0xff;
38
- bytes[10] = ((sequence & 0x3f) << 2) | (random[10] & 0x03);
39
- bytes[11] = random[11];
40
- bytes[12] = random[12];
41
- bytes[13] = random[13];
42
- bytes[14] = random[14];
43
- bytes[15] = random[15];
44
- return formatUuid(bytes);
45
- }
46
- function formatUuid(bytes) {
47
- const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0"));
48
- return `${hex.slice(0, 4).join("")}-${hex.slice(4, 6).join("")}-${hex.slice(6, 8).join("")}-${hex.slice(8, 10).join("")}-${hex.slice(10, 16).join("")}`;
49
- }
50
- //# sourceMappingURL=uuid.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"uuid.js","sourceRoot":"","sources":["../../../src/harness/session/uuid.ts"],"names":[],"mappings":"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","sourcesContent":["let lastTimestamp = -Infinity;\nlet sequence = 0;\n\nfunction fillRandomBytes(bytes: Uint8Array<ArrayBuffer>): void {\n\tconst crypto = globalThis.crypto;\n\tif (crypto?.getRandomValues) {\n\t\tcrypto.getRandomValues(bytes);\n\t\treturn;\n\t}\n\tfor (let i = 0; i < bytes.length; i++) {\n\t\tbytes[i] = Math.floor(Math.random() * 256);\n\t}\n}\n\nexport function uuidv7(): string {\n\tconst random = new Uint8Array(16);\n\tfillRandomBytes(random);\n\tconst timestamp = Date.now();\n\n\tif (timestamp > lastTimestamp) {\n\t\tsequence = random[6] * 0x1000000 + random[7] * 0x10000 + random[8] * 0x100 + random[9];\n\t\tlastTimestamp = timestamp;\n\t} else {\n\t\tsequence = (sequence + 1) >>> 0;\n\t\tif (sequence === 0) {\n\t\t\tlastTimestamp++;\n\t\t}\n\t}\n\n\tconst bytes = new Uint8Array(16);\n\tbytes[0] = (lastTimestamp / 0x10000000000) & 0xff;\n\tbytes[1] = (lastTimestamp / 0x100000000) & 0xff;\n\tbytes[2] = (lastTimestamp / 0x1000000) & 0xff;\n\tbytes[3] = (lastTimestamp / 0x10000) & 0xff;\n\tbytes[4] = (lastTimestamp / 0x100) & 0xff;\n\tbytes[5] = lastTimestamp & 0xff;\n\tbytes[6] = 0x70 | ((sequence >>> 28) & 0x0f);\n\tbytes[7] = (sequence >>> 20) & 0xff;\n\tbytes[8] = 0x80 | ((sequence >>> 14) & 0x3f);\n\tbytes[9] = (sequence >>> 6) & 0xff;\n\tbytes[10] = ((sequence & 0x3f) << 2) | (random[10] & 0x03);\n\tbytes[11] = random[11];\n\tbytes[12] = random[12];\n\tbytes[13] = random[13];\n\tbytes[14] = random[14];\n\tbytes[15] = random[15];\n\n\treturn formatUuid(bytes);\n}\n\nfunction formatUuid(bytes: Uint8Array): string {\n\tconst hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, \"0\"));\n\treturn `${hex.slice(0, 4).join(\"\")}-${hex.slice(4, 6).join(\"\")}-${hex.slice(6, 8).join(\"\")}-${hex.slice(8, 10).join(\"\")}-${hex.slice(10, 16).join(\"\")}`;\n}\n"]}