@earendil-works/pi-durable 0.99.2 → 1.0.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 (129) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +196 -74
  3. package/dist/env/index.d.ts +5 -0
  4. package/dist/env/index.d.ts.map +1 -1
  5. package/dist/env/index.js.map +1 -1
  6. package/dist/env/node.d.ts +2 -0
  7. package/dist/env/node.d.ts.map +1 -1
  8. package/dist/env/node.js +2 -0
  9. package/dist/env/node.js.map +1 -1
  10. package/dist/harness/agent.d.ts +31 -0
  11. package/dist/harness/agent.d.ts.map +1 -0
  12. package/dist/harness/agent.js +209 -0
  13. package/dist/harness/agent.js.map +1 -0
  14. package/dist/harness/compaction.d.ts.map +1 -1
  15. package/dist/harness/compaction.js +8 -11
  16. package/dist/harness/compaction.js.map +1 -1
  17. package/dist/harness/define.d.ts +18 -0
  18. package/dist/harness/define.d.ts.map +1 -0
  19. package/dist/harness/define.js +25 -0
  20. package/dist/harness/define.js.map +1 -0
  21. package/dist/harness/events.d.ts +5 -5
  22. package/dist/harness/events.d.ts.map +1 -1
  23. package/dist/harness/events.js +6 -6
  24. package/dist/harness/events.js.map +1 -1
  25. package/dist/harness/generation.d.ts +2 -4
  26. package/dist/harness/generation.d.ts.map +1 -1
  27. package/dist/harness/generation.js +39 -43
  28. package/dist/harness/generation.js.map +1 -1
  29. package/dist/harness/harness.d.ts.map +1 -1
  30. package/dist/harness/harness.js +68 -154
  31. package/dist/harness/harness.js.map +1 -1
  32. package/dist/harness/inbox.d.ts +4 -2
  33. package/dist/harness/inbox.d.ts.map +1 -1
  34. package/dist/harness/inbox.js +3 -5
  35. package/dist/harness/inbox.js.map +1 -1
  36. package/dist/harness/prompt.d.ts +1 -3
  37. package/dist/harness/prompt.d.ts.map +1 -1
  38. package/dist/harness/prompt.js +1 -11
  39. package/dist/harness/prompt.js.map +1 -1
  40. package/dist/harness/registry.d.ts +2 -3
  41. package/dist/harness/registry.d.ts.map +1 -1
  42. package/dist/harness/registry.js +66 -283
  43. package/dist/harness/registry.js.map +1 -1
  44. package/dist/harness/scheduler.d.ts +7 -2
  45. package/dist/harness/scheduler.d.ts.map +1 -1
  46. package/dist/harness/scheduler.js +41 -27
  47. package/dist/harness/scheduler.js.map +1 -1
  48. package/dist/harness/submissions.d.ts +4 -4
  49. package/dist/harness/submissions.d.ts.map +1 -1
  50. package/dist/harness/submissions.js +7 -4
  51. package/dist/harness/submissions.js.map +1 -1
  52. package/dist/harness/task-graph.d.ts +49 -0
  53. package/dist/harness/task-graph.d.ts.map +1 -0
  54. package/dist/harness/task-graph.js +163 -0
  55. package/dist/harness/task-graph.js.map +1 -0
  56. package/dist/harness/tool.d.ts +1 -1
  57. package/dist/harness/tool.d.ts.map +1 -1
  58. package/dist/harness/tool.js +9 -6
  59. package/dist/harness/tool.js.map +1 -1
  60. package/dist/harness/types.d.ts +171 -140
  61. package/dist/harness/types.d.ts.map +1 -1
  62. package/dist/harness/types.js.map +1 -1
  63. package/dist/harness/view.d.ts +1 -1
  64. package/dist/harness/view.d.ts.map +1 -1
  65. package/dist/harness/view.js +2 -7
  66. package/dist/harness/view.js.map +1 -1
  67. package/dist/index.d.ts +4 -2
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +2 -1
  70. package/dist/index.js.map +1 -1
  71. package/dist/session/session.d.ts.map +1 -1
  72. package/dist/session/session.js +5 -1
  73. package/dist/session/session.js.map +1 -1
  74. package/dist/session/transaction.d.ts +2 -2
  75. package/dist/session/transaction.d.ts.map +1 -1
  76. package/dist/session/transaction.js +7 -4
  77. package/dist/session/transaction.js.map +1 -1
  78. package/dist/storage/sqlite/database.d.ts +26 -19
  79. package/dist/storage/sqlite/database.d.ts.map +1 -1
  80. package/dist/storage/sqlite/database.js.map +1 -1
  81. package/dist/storage/sqlite/index.d.ts +1 -1
  82. package/dist/storage/sqlite/index.d.ts.map +1 -1
  83. package/dist/storage/sqlite/index.js.map +1 -1
  84. package/dist/storage/sqlite/migrations.js +6 -6
  85. package/dist/storage/sqlite/migrations.js.map +1 -1
  86. package/dist/storage/sqlite/node.d.ts +23 -7
  87. package/dist/storage/sqlite/node.d.ts.map +1 -1
  88. package/dist/storage/sqlite/node.js +129 -47
  89. package/dist/storage/sqlite/node.js.map +1 -1
  90. package/dist/storage/sqlite/storage.d.ts +12 -0
  91. package/dist/storage/sqlite/storage.d.ts.map +1 -1
  92. package/dist/storage/sqlite/storage.js +121 -129
  93. package/dist/storage/sqlite/storage.js.map +1 -1
  94. package/dist/tools/bash.d.ts +1 -1
  95. package/dist/tools/bash.d.ts.map +1 -1
  96. package/dist/tools/bash.js +3 -2
  97. package/dist/tools/bash.js.map +1 -1
  98. package/dist/tools/edit.d.ts +3 -3
  99. package/dist/tools/edit.d.ts.map +1 -1
  100. package/dist/tools/edit.js +5 -4
  101. package/dist/tools/edit.js.map +1 -1
  102. package/dist/tools/file-mutation-queue.d.ts +5 -1
  103. package/dist/tools/file-mutation-queue.d.ts.map +1 -1
  104. package/dist/tools/file-mutation-queue.js +39 -33
  105. package/dist/tools/file-mutation-queue.js.map +1 -1
  106. package/dist/tools/index.d.ts +18 -0
  107. package/dist/tools/index.d.ts.map +1 -1
  108. package/dist/tools/index.js +10 -0
  109. package/dist/tools/index.js.map +1 -1
  110. package/dist/tools/read.d.ts +3 -3
  111. package/dist/tools/read.d.ts.map +1 -1
  112. package/dist/tools/read.js +4 -3
  113. package/dist/tools/read.js.map +1 -1
  114. package/dist/tools/write.d.ts +1 -1
  115. package/dist/tools/write.d.ts.map +1 -1
  116. package/dist/tools/write.js +3 -2
  117. package/dist/tools/write.js.map +1 -1
  118. package/dist/types.d.ts +15 -4
  119. package/dist/types.d.ts.map +1 -1
  120. package/dist/types.js.map +1 -1
  121. package/package.json +25 -15
  122. package/dist/harness/config.d.ts +0 -29
  123. package/dist/harness/config.d.ts.map +0 -1
  124. package/dist/harness/config.js +0 -24
  125. package/dist/harness/config.js.map +0 -1
  126. package/docs/chord-delta-findings.md +0 -358
  127. package/docs/pico-v5-chord-usage.md +0 -373
  128. package/docs/pico-v5-handoff.md +0 -861
  129. package/docs/pico-v5.md +0 -4174
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/storage/sqlite/storage.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context, JsonValue } from \"@earendil-works/chord\";\nimport { apply, type Op } from \"@earendil-works/chord/delta\";\nimport { StorageRejected } from \"../../errors.ts\";\nimport { idFromNumber, seqFromNumber } from \"../../ids.ts\";\nimport type {\n\tConversationId,\n\tConversationQuery,\n\tConversationRecord,\n\tCursor,\n\tDocumentAddress,\n\tDocumentContent,\n\tDocumentCreate,\n\tDocumentId,\n\tDocumentPoint,\n\tDocumentQuery,\n\tDocumentRecord,\n\tEntryId,\n\tEntryQuery,\n\tEntryRecord,\n\tId,\n\tJsonObject,\n\tPage,\n\tSeq,\n\tStorage,\n\tStorageWrite,\n\tStoredDocument,\n\tSubmissionId,\n\tSubmissionQuery,\n\tSubmissionRecord,\n\tTaskId,\n\tTaskQuery,\n\tTaskRecord,\n} from \"../../types.ts\";\nimport type { SqliteDatabase, SqliteStatement, SqliteValue } from \"./database.ts\";\nimport { applySqliteMigrations } from \"./migrations.ts\";\n\ntype StoredTask = TaskRecord<JsonValue, JsonValue, JsonValue>;\ntype TableName = \"conversation\" | \"entry\" | \"task\" | \"submission\" | \"document\";\ntype RecordIdRow = { readonly record_type: TableName };\ntype JsonRow = { readonly record: string };\ntype EntryJsonRow = { readonly record: string; readonly commit_seq: number };\ntype RevisionRow = {\n\treadonly seq: number;\n\treadonly kind: DocumentContent[\"kind\"];\n\treadonly version: number;\n\treadonly content: string;\n};\ntype IdRow = { readonly id: number };\ntype MetadataRow = { readonly next_id: string; readonly next_seq: number };\ntype DocumentAction = {\n\tcreate?: DocumentCreate;\n\tcopy?: Extract<StorageWrite, { readonly type: \"document.copy\" }>[\"source\"];\n\tcontent?: DocumentContent;\n\tretire: boolean;\n};\ntype ScopeColumns = {\n\treadonly scopeKind: DocumentRecord[\"scope\"][\"kind\"];\n\treadonly ownerId: number;\n};\n\nconst parseJson = <T>(value: string): T => JSON.parse(value) as T;\nconst encodeJson = (value: unknown): string => JSON.stringify(value) as string;\n// Some SQLite bindings replace lone UTF-16 surrogates. JSON encoding keeps indexed identities lossless.\nconst encodeIndexedString = (value: string): string => JSON.stringify(value);\n\nconst getRow = <T extends object>(statement: SqliteStatement, ...params: SqliteValue[]): T | undefined =>\n\tstatement.get<T>(...params);\n\nconst allRows = <T extends object>(statement: SqliteStatement, ...params: SqliteValue[]): T[] =>\n\tstatement.all<T>(...params);\n\nconst cursorId = <I extends Id<string>>(cursor: Cursor | undefined): I | undefined => {\n\tconst after = cursor?.after;\n\tif (after === undefined) return undefined;\n\tif (typeof after !== \"number\" || !Number.isSafeInteger(after)) throw new TypeError(\"Invalid storage cursor\");\n\treturn idFromNumber<I>(after);\n};\n\nconst page = <T extends { readonly id: Id<string> }>(values: readonly T[], limit: number): Page<T, Cursor> => {\n\tconst items = values.slice(0, limit);\n\tif (values.length <= limit) return { items };\n\treturn { items, next: { after: items.at(-1)!.id } };\n};\n\nconst scopeColumns = (scope: DocumentRecord[\"scope\"]): ScopeColumns => {\n\tswitch (scope.kind) {\n\t\tcase \"session\":\n\t\t\treturn { scopeKind: \"session\", ownerId: 0 };\n\t\tcase \"conversation\":\n\t\t\treturn { scopeKind: \"conversation\", ownerId: scope.conversationId };\n\t\tcase \"task\":\n\t\t\treturn { scopeKind: \"task\", ownerId: scope.taskId };\n\t}\n};\n\nconst addressParts = (address: DocumentAddress | DocumentCreate | DocumentRecord) => {\n\tconst scope = scopeColumns(address.scope);\n\treturn {\n\t\tkind: encodeIndexedString(address.kind),\n\t\t...scope,\n\t\tfamily: address.key === undefined ? 0 : 1,\n\t\tkeyValue: encodeIndexedString(address.key ?? \"\"),\n\t};\n};\n\nconst addressKey = (address: DocumentAddress | DocumentCreate | DocumentRecord): string => {\n\tconst parts = addressParts(address);\n\treturn JSON.stringify([parts.kind, parts.scopeKind, parts.ownerId, parts.family, parts.keyValue]);\n};\n\nconst isAliveAt = (record: DocumentRecord, at: DocumentPoint): boolean => {\n\tif (at === \"current\") return record.retiredAt === undefined;\n\treturn record.createdAt <= at && (record.retiredAt === undefined || at < record.retiredAt);\n};\n\nconst isCurrentOnly = (record: DocumentRecord): boolean =>\n\trecord.scope.kind !== \"conversation\" || record.history === \"latest\";\n\nconst writeId = (write: StorageWrite): Id<string> | undefined => {\n\tswitch (write.type) {\n\t\tcase \"conversation\":\n\t\tcase \"entry\":\n\t\tcase \"task\":\n\t\tcase \"submission\":\n\t\t\treturn write.value.id;\n\t\tcase \"document.create\":\n\t\tcase \"document.copy\":\n\t\t\treturn write.record.id;\n\t\tcase \"document.change\":\n\t\tcase \"document.retire\":\n\t\t\treturn undefined;\n\t}\n};\n\nclass StatementCachingDatabase implements SqliteDatabase {\n\tprivate readonly database: SqliteDatabase;\n\tprivate readonly statements = new Map<string, SqliteStatement>();\n\n\tconstructor(database: SqliteDatabase) {\n\t\tthis.database = database;\n\t}\n\n\texec(sql: string): void {\n\t\tthis.database.exec(sql);\n\t}\n\n\tprepare(sql: string): SqliteStatement {\n\t\tlet statement = this.statements.get(sql);\n\t\tif (statement === undefined) {\n\t\t\tstatement = this.database.prepare(sql);\n\t\t\tthis.statements.set(sql, statement);\n\t\t}\n\t\treturn statement;\n\t}\n\n\ttransaction<T>(callback: () => T): T | Promise<T> {\n\t\treturn this.database.transaction(callback);\n\t}\n\n\tclose(): void | Promise<void> {\n\t\tthis.statements.clear();\n\t\treturn this.database.close();\n\t}\n}\n\n/** Portable SQLite implementation of the Pico storage contract. */\nexport class SqliteStorage implements Storage {\n\tprivate readonly db: SqliteDatabase;\n\tprivate nextId: number;\n\tprivate closed = false;\n\n\tprivate constructor(db: SqliteDatabase, nextId: number) {\n\t\tthis.db = new StatementCachingDatabase(db);\n\t\tthis.nextId = nextId;\n\t}\n\n\t/** Initialize storage over an owned SQLite database facade. */\n\tstatic async open(db: SqliteDatabase): Promise<SqliteStorage> {\n\t\ttry {\n\t\t\tawait applySqliteMigrations(db);\n\t\t\tconst metadata = getRow<MetadataRow>(\n\t\t\t\tdb.prepare(\"SELECT next_id, next_seq FROM durable_metadata WHERE singleton = 1\"),\n\t\t\t);\n\t\t\tif (metadata === undefined) throw new Error(\"Durable SQLite metadata is missing\");\n\t\t\treturn new SqliteStorage(db, Number(metadata.next_id));\n\t\t} catch (error) {\n\t\t\ttry {\n\t\t\t\tawait db.close();\n\t\t\t} catch {\n\t\t\t\t// Preserve the initialization failure.\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync commit(writes: readonly StorageWrite[], _context: Context): Promise<Seq> {\n\t\tthis.assertOpen();\n\t\tconst documentActions = this.prepareDocumentActions(writes);\n\t\tconst candidateNextId = this.candidateNextId(writes);\n\t\tconst seq = await this.db.transaction(() => {\n\t\t\tconst metadata = getRow<MetadataRow>(\n\t\t\t\tthis.db.prepare(\"SELECT next_id, next_seq FROM durable_metadata WHERE singleton = 1\"),\n\t\t\t);\n\t\t\tif (metadata === undefined) throw new Error(\"Durable SQLite metadata is missing\");\n\t\t\tconst committedSeq = seqFromNumber(metadata.next_seq);\n\t\t\tthis.checkGlobalIds(writes);\n\t\t\tthis.checkDocumentActions(documentActions);\n\t\t\tfor (const write of writes) this.applyTableWrite(write, committedSeq);\n\t\t\tthis.applyDocumentActions(documentActions, committedSeq);\n\t\t\tthis.db\n\t\t\t\t.prepare(\"UPDATE durable_metadata SET next_id = ?, next_seq = ? WHERE singleton = 1\")\n\t\t\t\t.run(String(Math.max(Number(metadata.next_id), candidateNextId)), committedSeq + 1);\n\t\t\treturn committedSeq;\n\t\t});\n\t\tthis.nextId = Math.max(this.nextId, candidateNextId);\n\t\treturn seq;\n\t}\n\n\tasync mintId<I extends Id<string>>(): Promise<I> {\n\t\tthis.assertOpen();\n\t\tif (!Number.isSafeInteger(this.nextId)) throw new Error(\"ID space is exhausted\");\n\t\treturn idFromNumber<I>(this.nextId++);\n\t}\n\n\tasync conversation(id: ConversationId, _context: Context): Promise<ConversationRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst row = getRow<JsonRow>(this.db.prepare(\"SELECT record FROM conversations WHERE id = ?\"), id);\n\t\treturn row === undefined ? undefined : parseJson<ConversationRecord>(row.record);\n\t}\n\n\tasync scanConversations(\n\t\tquery: ConversationQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<ConversationRecord, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst clauses = [\"id > ?\"];\n\t\tconst params: SqliteValue[] = [cursorId(cursor) ?? -1];\n\t\tif (query.ownerConversationId !== undefined) {\n\t\t\tclauses.push(\"owner_conversation_id = ?\");\n\t\t\tparams.push(query.ownerConversationId);\n\t\t}\n\t\tif (query.ownerTaskId !== undefined) {\n\t\t\tclauses.push(\"owner_task_id = ?\");\n\t\t\tparams.push(query.ownerTaskId);\n\t\t}\n\t\tparams.push(limit + 1);\n\t\tconst rows = allRows<JsonRow>(\n\t\t\tthis.db.prepare(`SELECT record FROM conversations WHERE ${clauses.join(\" AND \")} ORDER BY id LIMIT ?`),\n\t\t\t...params,\n\t\t);\n\t\treturn page(\n\t\t\trows.map((row) => parseJson<ConversationRecord>(row.record)),\n\t\t\tlimit,\n\t\t);\n\t}\n\n\tentry(id: EntryId, context: Context): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined>;\n\tentry(\n\t\tconversationId: ConversationId,\n\t\tid: EntryId,\n\t\tcontext: Context,\n\t): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined>;\n\tasync entry(\n\t\tidOrConversationId: EntryId | ConversationId,\n\t\tidOrContext: EntryId | Context,\n\t\tcontext?: Context,\n\t): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined> {\n\t\tthis.assertOpen();\n\t\tconst id =\n\t\t\tcontext === undefined\n\t\t\t\t? idFromNumber<EntryId>(idOrConversationId)\n\t\t\t\t: typeof idOrContext === \"number\"\n\t\t\t\t\t? idFromNumber<EntryId>(idOrContext)\n\t\t\t\t\t: undefined;\n\t\tif (id === undefined) throw new TypeError(\"Storage.entry() requires an entry ID\");\n\t\tlet conversation: ConversationRecord | undefined;\n\t\tif (context !== undefined) {\n\t\t\tconst conversationId = idFromNumber<ConversationId>(idOrConversationId);\n\t\t\tconversation = this.readConversation(conversationId);\n\t\t\tif (conversation === undefined) throw new Error(`Unknown conversation: ${conversationId}`);\n\t\t}\n\t\tconst row = getRow<EntryJsonRow>(this.db.prepare(\"SELECT record, commit_seq FROM entries WHERE id = ?\"), id);\n\t\tif (row === undefined) return undefined;\n\t\tconst entry = parseJson<EntryRecord>(row.record);\n\t\tif (conversation !== undefined) {\n\t\t\tlet upperEntryId = Number.POSITIVE_INFINITY;\n\t\t\twhile (conversation.id !== entry.conversationId) {\n\t\t\t\tif (conversation.parent === undefined) return undefined;\n\t\t\t\tupperEntryId = Math.min(upperEntryId, conversation.parent.at);\n\t\t\t\tconversation = this.readConversation(conversation.parent.conversationId)!;\n\t\t\t}\n\t\t\tif (entry.id > upperEntryId) return undefined;\n\t\t}\n\t\treturn { entry, commitSeq: seqFromNumber(row.commit_seq) };\n\t}\n\n\tasync findLatestHeadMarker(\n\t\tconversationId: ConversationId,\n\t\tatOrBeforeEntryId: EntryId | undefined,\n\t\t_context: Context,\n\t): Promise<(EntryRecord & { readonly head: EntryId }) | undefined> {\n\t\tthis.assertOpen();\n\t\tlet conversation = this.readConversation(conversationId);\n\t\tif (conversation === undefined) throw new Error(`Unknown conversation: ${conversationId}`);\n\t\tlet upper: number | undefined = atOrBeforeEntryId;\n\t\twhile (true) {\n\t\t\tconst row =\n\t\t\t\tupper === undefined\n\t\t\t\t\t? getRow<JsonRow>(\n\t\t\t\t\t\t\tthis.db.prepare(\n\t\t\t\t\t\t\t\t\"SELECT record FROM entries WHERE conversation_id = ? AND head IS NOT NULL ORDER BY id DESC LIMIT 1\",\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tconversation.id,\n\t\t\t\t\t\t)\n\t\t\t\t\t: getRow<JsonRow>(\n\t\t\t\t\t\t\tthis.db.prepare(\n\t\t\t\t\t\t\t\t\"SELECT record FROM entries WHERE conversation_id = ? AND head IS NOT NULL AND id <= ? ORDER BY id DESC LIMIT 1\",\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tconversation.id,\n\t\t\t\t\t\t\tupper,\n\t\t\t\t\t\t);\n\t\t\tif (row !== undefined) return parseJson<EntryRecord & { readonly head: EntryId }>(row.record);\n\t\t\tif (conversation.parent === undefined) return undefined;\n\t\t\tupper = upper === undefined ? conversation.parent.at : Math.min(upper, conversation.parent.at);\n\t\t\tconversation = this.readConversation(conversation.parent.conversationId)!;\n\t\t}\n\t}\n\n\tasync scanEntries(\n\t\tquery: EntryQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<EntryRecord, Cursor>> {\n\t\tthis.assertOpen();\n\t\tlet conversation = this.readConversation(query.conversationId);\n\t\tif (conversation === undefined) throw new Error(`Unknown conversation: ${query.conversationId}`);\n\t\tconst after = cursorId(cursor);\n\t\tlet upper: number | undefined = query.maxEntryId;\n\t\tif (after !== undefined) upper = Math.min(upper ?? Number.MAX_SAFE_INTEGER, after - 1);\n\t\tconst values: EntryRecord[] = [];\n\t\twhile (true) {\n\t\t\tconst clauses = [\"conversation_id = ?\"];\n\t\t\tconst params: SqliteValue[] = [conversation.id];\n\t\t\tif (query.minEntryId !== undefined) {\n\t\t\t\tclauses.push(\"id >= ?\");\n\t\t\t\tparams.push(query.minEntryId);\n\t\t\t}\n\t\t\tif (upper !== undefined) {\n\t\t\t\tclauses.push(\"id <= ?\");\n\t\t\t\tparams.push(upper);\n\t\t\t}\n\t\t\tparams.push(limit + 1 - values.length);\n\t\t\tconst rows = allRows<JsonRow>(\n\t\t\t\tthis.db.prepare(`SELECT record FROM entries WHERE ${clauses.join(\" AND \")} ORDER BY id DESC LIMIT ?`),\n\t\t\t\t...params,\n\t\t\t);\n\t\t\tvalues.push(...rows.map((row) => parseJson<EntryRecord>(row.record)));\n\t\t\tif (values.length > limit || conversation.parent === undefined) break;\n\t\t\tupper = upper === undefined ? conversation.parent.at : Math.min(upper, conversation.parent.at);\n\t\t\tif (query.minEntryId !== undefined && upper < query.minEntryId) break;\n\t\t\tconversation = this.readConversation(conversation.parent.conversationId)!;\n\t\t}\n\t\treturn page(values, limit);\n\t}\n\n\tasync task(id: TaskId, _context: Context): Promise<StoredTask | undefined> {\n\t\tthis.assertOpen();\n\t\tconst row = getRow<JsonRow>(this.db.prepare(\"SELECT record FROM tasks WHERE id = ?\"), id);\n\t\treturn row === undefined ? undefined : parseJson<StoredTask>(row.record);\n\t}\n\n\tasync scanTasks(\n\t\tquery: TaskQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<StoredTask, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst clauses = [\"id > ?\"];\n\t\tconst params: SqliteValue[] = [cursorId(cursor) ?? -1];\n\t\tif (query.conversationId !== undefined) {\n\t\t\tclauses.push(\"conversation_id = ?\");\n\t\t\tparams.push(query.conversationId);\n\t\t}\n\t\tif (query.kind !== undefined) {\n\t\t\tclauses.push(\"kind = ?\");\n\t\t\tparams.push(encodeIndexedString(query.kind));\n\t\t}\n\t\tif (query.status !== undefined) {\n\t\t\tclauses.push(\"status = ?\");\n\t\t\tparams.push(query.status);\n\t\t}\n\t\tif (query.abortRequested !== undefined) {\n\t\t\tclauses.push(\"abort_requested = ?\");\n\t\t\tparams.push(query.abortRequested ? 1 : 0);\n\t\t}\n\t\tif (query.background !== undefined) {\n\t\t\tclauses.push(\"background = ?\");\n\t\t\tparams.push(query.background ? 1 : 0);\n\t\t}\n\t\tparams.push(limit + 1);\n\t\tconst rows = allRows<JsonRow>(\n\t\t\tthis.db.prepare(`SELECT record FROM tasks WHERE ${clauses.join(\" AND \")} ORDER BY id LIMIT ?`),\n\t\t\t...params,\n\t\t);\n\t\treturn page(\n\t\t\trows.map((row) => parseJson<StoredTask>(row.record)),\n\t\t\tlimit,\n\t\t);\n\t}\n\n\tasync submission(id: SubmissionId, _context: Context): Promise<SubmissionRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst row = getRow<JsonRow>(this.db.prepare(\"SELECT record FROM submissions WHERE id = ?\"), id);\n\t\treturn row === undefined ? undefined : parseJson<SubmissionRecord>(row.record);\n\t}\n\n\tasync scanSubmissions(\n\t\tquery: SubmissionQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<SubmissionRecord, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst clauses = [\"id > ?\"];\n\t\tconst params: SqliteValue[] = [cursorId(cursor) ?? -1];\n\t\tif (query.conversationId !== undefined) {\n\t\t\tclauses.push(\"conversation_id = ?\");\n\t\t\tparams.push(query.conversationId);\n\t\t}\n\t\tif (query.status !== undefined) {\n\t\t\tclauses.push(\"status = ?\");\n\t\t\tparams.push(query.status);\n\t\t}\n\t\tparams.push(limit + 1);\n\t\tconst rows = allRows<JsonRow>(\n\t\t\tthis.db.prepare(`SELECT record FROM submissions WHERE ${clauses.join(\" AND \")} ORDER BY id LIMIT ?`),\n\t\t\t...params,\n\t\t);\n\t\treturn page(\n\t\t\trows.map((row) => parseJson<SubmissionRecord>(row.record)),\n\t\t\tlimit,\n\t\t);\n\t}\n\n\tasync submissionByRequest(\n\t\tconversationId: ConversationId,\n\t\trequestId: string,\n\t\t_context: Context,\n\t): Promise<SubmissionRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst row = getRow<JsonRow>(\n\t\t\tthis.db.prepare(\"SELECT record FROM submissions WHERE conversation_id = ? AND request_id = ?\"),\n\t\t\tconversationId,\n\t\t\tencodeIndexedString(requestId),\n\t\t);\n\t\treturn row === undefined ? undefined : parseJson<SubmissionRecord>(row.record);\n\t}\n\n\tasync findDocument(\n\t\taddress: DocumentAddress,\n\t\tat: DocumentPoint,\n\t\t_context: Context,\n\t): Promise<DocumentRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst parts = addressParts(address);\n\t\tconst statement =\n\t\t\tat === \"current\"\n\t\t\t\t? this.db.prepare(`SELECT record FROM documents\n\t\t\t\t\tWHERE kind = ? AND scope_kind = ? AND owner_id = ? AND family = ? AND key_value = ?\n\t\t\t\t\tAND retired_at IS NULL ORDER BY created_at DESC LIMIT 1`)\n\t\t\t\t: this.db.prepare(`SELECT record FROM documents\n\t\t\t\t\tWHERE kind = ? AND scope_kind = ? AND owner_id = ? AND family = ? AND key_value = ?\n\t\t\t\t\tAND created_at <= ? AND (retired_at IS NULL OR retired_at > ?)\n\t\t\t\t\tORDER BY created_at DESC LIMIT 1`);\n\t\tconst params: SqliteValue[] = [parts.kind, parts.scopeKind, parts.ownerId, parts.family, parts.keyValue];\n\t\tif (at !== \"current\") params.push(at, at);\n\t\tconst row = getRow<JsonRow>(statement, ...params);\n\t\treturn row === undefined ? undefined : parseJson<DocumentRecord>(row.record);\n\t}\n\n\tasync document(id: DocumentId, at: DocumentPoint, _context: Context): Promise<StoredDocument | undefined> {\n\t\tthis.assertOpen();\n\t\treturn this.materializeDocument(id, at);\n\t}\n\n\tasync scanDocuments(\n\t\tquery: DocumentQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<DocumentRecord, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst scope = scopeColumns(query.scope);\n\t\tconst clauses = [\"scope_kind = ?\", \"owner_id = ?\", \"id > ?\"];\n\t\tconst params: SqliteValue[] = [scope.scopeKind, scope.ownerId, cursorId(cursor) ?? -1];\n\t\tif (query.kind !== undefined) {\n\t\t\tclauses.push(\"kind = ?\");\n\t\t\tparams.push(encodeIndexedString(query.kind));\n\t\t}\n\t\tif (query.at === \"current\") {\n\t\t\tclauses.push(\"retired_at IS NULL\");\n\t\t} else {\n\t\t\tclauses.push(\"created_at <= ?\", \"(retired_at IS NULL OR retired_at > ?)\");\n\t\t\tparams.push(query.at, query.at);\n\t\t}\n\t\tparams.push(limit + 1);\n\t\tconst rows = allRows<JsonRow>(\n\t\t\tthis.db.prepare(`SELECT record FROM documents WHERE ${clauses.join(\" AND \")} ORDER BY id LIMIT ?`),\n\t\t\t...params,\n\t\t);\n\t\treturn page(\n\t\t\trows.map((row) => parseJson<DocumentRecord>(row.record)),\n\t\t\tlimit,\n\t\t);\n\t}\n\n\tasync close(_context: Context): Promise<void> {\n\t\tif (this.closed) return;\n\t\tthis.closed = true;\n\t\tawait this.db.close();\n\t}\n\n\tprivate readConversation(id: ConversationId): ConversationRecord | undefined {\n\t\tconst row = getRow<JsonRow>(this.db.prepare(\"SELECT record FROM conversations WHERE id = ?\"), id);\n\t\treturn row === undefined ? undefined : parseJson<ConversationRecord>(row.record);\n\t}\n\n\tprivate materializeDocument(id: DocumentId, at: DocumentPoint): StoredDocument | undefined {\n\t\tconst row = getRow<JsonRow>(this.db.prepare(\"SELECT record FROM documents WHERE id = ?\"), id);\n\t\tif (row === undefined) return undefined;\n\t\tconst record = parseJson<DocumentRecord>(row.record);\n\t\tif (at !== \"current\" && isCurrentOnly(record)) {\n\t\t\tthrow new Error(`Document ${id} does not retain historical content`);\n\t\t}\n\t\tif (!isAliveAt(record, at)) return undefined;\n\t\tconst upper = at === \"current\" ? Number.MAX_SAFE_INTEGER : at;\n\t\tconst base = getRow<RevisionRow>(\n\t\t\tthis.db.prepare(`SELECT seq, kind, version, content FROM document_revisions\n\t\t\t\tWHERE document_id = ? AND kind = 'base' AND seq <= ? ORDER BY seq DESC LIMIT 1`),\n\t\t\tid,\n\t\t\tupper,\n\t\t);\n\t\tif (base === undefined) throw new Error(`Document ${id} is missing a required base`);\n\t\tlet value = parseJson<JsonObject>(base.content);\n\t\tconst tail = allRows<RevisionRow>(\n\t\t\tthis.db.prepare(`SELECT seq, kind, version, content FROM document_revisions\n\t\t\t\tWHERE document_id = ? AND seq > ? AND seq <= ? ORDER BY seq`),\n\t\t\tid,\n\t\t\tbase.seq,\n\t\t\tupper,\n\t\t);\n\t\tfor (const revision of tail) {\n\t\t\tif (revision.kind !== \"delta\" || revision.version !== base.version) {\n\t\t\t\tthrow new Error(`Document ${id} crosses a stored version boundary without a base`);\n\t\t\t}\n\t\t\tvalue = apply(value, parseJson<readonly Op[]>(revision.content)) as JsonObject;\n\t\t}\n\t\treturn { record, version: base.version, value, deltasSinceBase: tail.length };\n\t}\n\n\tprivate candidateNextId(writes: readonly StorageWrite[]): number {\n\t\tlet nextId = this.nextId;\n\t\tfor (const write of writes) {\n\t\t\tconst id = writeId(write);\n\t\t\tif (id !== undefined) nextId = Math.max(nextId, id + 1);\n\t\t}\n\t\treturn nextId;\n\t}\n\n\tprivate checkGlobalIds(writes: readonly StorageWrite[]): void {\n\t\tconst claimed = new Map<Id<string>, TableName>();\n\t\tconst lookup = this.db.prepare(\"SELECT record_type FROM record_ids WHERE id = ?\");\n\t\tfor (const write of writes) {\n\t\t\tif (write.type === \"document.change\" || write.type === \"document.retire\") continue;\n\t\t\tconst document = write.type === \"document.create\" || write.type === \"document.copy\";\n\t\t\tconst table: TableName = document ? \"document\" : write.type;\n\t\t\tconst id = document ? write.record.id : write.value.id;\n\t\t\tconst existing = getRow<RecordIdRow>(lookup, id)?.record_type;\n\t\t\tconst earlier = claimed.get(id);\n\t\t\tif (table === \"conversation\" || table === \"entry\" || table === \"document\") {\n\t\t\t\tif (existing !== undefined) throw new Error(`ID ${id} already belongs to ${existing}`);\n\t\t\t\tif (earlier !== undefined) throw new Error(`ID ${id} is written more than once`);\n\t\t\t} else {\n\t\t\t\tif (existing !== undefined && existing !== table)\n\t\t\t\t\tthrow new Error(`ID ${id} already belongs to ${existing}`);\n\t\t\t\tif (earlier !== undefined && earlier !== table) throw new Error(`ID ${id} is written as two record types`);\n\t\t\t}\n\t\t\tclaimed.set(id, table);\n\t\t}\n\t}\n\n\tprivate prepareDocumentActions(writes: readonly StorageWrite[]): Map<DocumentId, DocumentAction> {\n\t\tconst actions = new Map<DocumentId, DocumentAction>();\n\t\tfor (const write of writes) {\n\t\t\tif (\n\t\t\t\twrite.type !== \"document.create\" &&\n\t\t\t\twrite.type !== \"document.copy\" &&\n\t\t\t\twrite.type !== \"document.change\" &&\n\t\t\t\twrite.type !== \"document.retire\"\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst id = write.type === \"document.create\" || write.type === \"document.copy\" ? write.record.id : write.id;\n\t\t\tlet action = actions.get(id);\n\t\t\tif (action === undefined) {\n\t\t\t\taction = { retire: false };\n\t\t\t\tactions.set(id, action);\n\t\t\t}\n\t\t\tswitch (write.type) {\n\t\t\t\tcase \"document.create\":\n\t\t\t\t\tif (action.create !== undefined || action.content !== undefined || action.copy !== undefined) {\n\t\t\t\t\t\tthrow new Error(`Document ${id} has more than one content command`);\n\t\t\t\t\t}\n\t\t\t\t\taction.create = write.record;\n\t\t\t\t\taction.content = write.content;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"document.copy\":\n\t\t\t\t\tif (action.create !== undefined || action.content !== undefined || action.copy !== undefined) {\n\t\t\t\t\t\tthrow new Error(`Document ${id} has more than one content command`);\n\t\t\t\t\t}\n\t\t\t\t\taction.create = write.record;\n\t\t\t\t\taction.copy = write.source;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"document.change\":\n\t\t\t\t\tif (action.content !== undefined || action.copy !== undefined) {\n\t\t\t\t\t\tthrow new Error(`Document ${id} has more than one content command`);\n\t\t\t\t\t}\n\t\t\t\t\taction.content = write.content;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"document.retire\":\n\t\t\t\t\tif (action.retire) throw new Error(`Document ${id} is retired more than once`);\n\t\t\t\t\taction.retire = true;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn actions;\n\t}\n\n\tprivate checkDocumentActions(actions: ReadonlyMap<DocumentId, DocumentAction>): void {\n\t\tconst liveCounts = new Map<string, number>();\n\t\tfor (const [id, action] of actions) {\n\t\t\tif (action.copy !== undefined && actions.has(action.copy.id)) {\n\t\t\t\tthrow new StorageRejected(`Document copy ${id} source is changed in the copy batch`);\n\t\t\t}\n\t\t\tconst row = getRow<JsonRow>(this.db.prepare(\"SELECT record FROM documents WHERE id = ?\"), id);\n\t\t\tconst existing = row === undefined ? undefined : parseJson<DocumentRecord>(row.record);\n\t\t\tif (action.create === undefined && existing === undefined) throw new Error(`Unknown document: ${id}`);\n\t\t\tif (action.create !== undefined && existing !== undefined) throw new Error(`Document ${id} already exists`);\n\t\t\tif (existing?.retiredAt !== undefined) throw new Error(`Document ${id} is retired`);\n\t\t\tif (action.content?.kind === \"delta\") {\n\t\t\t\tconst previous = getRow<{ readonly version: number }>(\n\t\t\t\t\tthis.db.prepare(\n\t\t\t\t\t\t\"SELECT version FROM document_revisions WHERE document_id = ? ORDER BY seq DESC LIMIT 1\",\n\t\t\t\t\t),\n\t\t\t\t\tid,\n\t\t\t\t);\n\t\t\t\tif (previous === undefined) throw new Error(`Document ${id} delta has no base`);\n\t\t\t\tif (previous.version !== action.content.version) {\n\t\t\t\t\tthrow new Error(`Document ${id} version transition requires a base`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst record = action.create ?? existing!;\n\t\t\tconst key = addressKey(record);\n\t\t\tlet live = liveCounts.get(key);\n\t\t\tif (live === undefined) live = this.currentDocumentId(record) === undefined ? 0 : 1;\n\t\t\tif (action.retire && existing !== undefined) live--;\n\t\t\tif (action.create !== undefined && !action.retire) live++;\n\t\t\tliveCounts.set(key, live);\n\t\t}\n\t\tfor (const live of liveCounts.values()) {\n\t\t\tif (live > 1) throw new Error(\"Document address already has a current incarnation\");\n\t\t}\n\t}\n\n\tprivate currentDocumentId(address: DocumentAddress | DocumentCreate | DocumentRecord): DocumentId | undefined {\n\t\tconst parts = addressParts(address);\n\t\tconst id = getRow<IdRow>(\n\t\t\tthis.db.prepare(`SELECT id FROM documents\n\t\t\t\tWHERE kind = ? AND scope_kind = ? AND owner_id = ? AND family = ? AND key_value = ? AND retired_at IS NULL\n\t\t\t\tLIMIT 1`),\n\t\t\tparts.kind,\n\t\t\tparts.scopeKind,\n\t\t\tparts.ownerId,\n\t\t\tparts.family,\n\t\t\tparts.keyValue,\n\t\t)?.id;\n\t\treturn id === undefined ? undefined : idFromNumber<DocumentId>(id);\n\t}\n\n\tprivate applyTableWrite(write: StorageWrite, seq: Seq): void {\n\t\tswitch (write.type) {\n\t\t\tcase \"conversation\":\n\t\t\t\tthis.claimId(write.value.id, \"conversation\");\n\t\t\t\tthis.db\n\t\t\t\t\t.prepare(\n\t\t\t\t\t\t\"INSERT INTO conversations (id, owner_conversation_id, owner_task_id, record) VALUES (?, ?, ?, ?)\",\n\t\t\t\t\t)\n\t\t\t\t\t.run(\n\t\t\t\t\t\twrite.value.id,\n\t\t\t\t\t\twrite.value.owner?.conversationId ?? null,\n\t\t\t\t\t\twrite.value.owner?.taskId ?? null,\n\t\t\t\t\t\tencodeJson(write.value),\n\t\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"entry\":\n\t\t\t\tthis.claimId(write.value.id, \"entry\");\n\t\t\t\tthis.db\n\t\t\t\t\t.prepare(\"INSERT INTO entries (id, conversation_id, head, commit_seq, record) VALUES (?, ?, ?, ?, ?)\")\n\t\t\t\t\t.run(write.value.id, write.value.conversationId, write.value.head ?? null, seq, encodeJson(write.value));\n\t\t\t\tbreak;\n\t\t\tcase \"task\":\n\t\t\t\tthis.claimId(write.value.id, \"task\");\n\t\t\t\tthis.db\n\t\t\t\t\t.prepare(`INSERT INTO tasks (id, conversation_id, kind, status, abort_requested, background, record)\n\t\t\t\t\t\tVALUES (?, ?, ?, ?, ?, ?, ?)\n\t\t\t\t\t\tON CONFLICT(id) DO UPDATE SET conversation_id = excluded.conversation_id, kind = excluded.kind,\n\t\t\t\t\t\tstatus = excluded.status, abort_requested = excluded.abort_requested,\n\t\t\t\t\t\tbackground = excluded.background, record = excluded.record`)\n\t\t\t\t\t.run(\n\t\t\t\t\t\twrite.value.id,\n\t\t\t\t\t\twrite.value.conversationId,\n\t\t\t\t\t\tencodeIndexedString(write.value.kind),\n\t\t\t\t\t\twrite.value.state.status,\n\t\t\t\t\t\twrite.value.abortRequested ? 1 : 0,\n\t\t\t\t\t\twrite.value.background ? 1 : 0,\n\t\t\t\t\t\tencodeJson(write.value),\n\t\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"submission\":\n\t\t\t\tthis.claimId(write.value.id, \"submission\");\n\t\t\t\tthis.db\n\t\t\t\t\t.prepare(`INSERT INTO submissions (id, conversation_id, request_id, status, record) VALUES (?, ?, ?, ?, ?)\n\t\t\t\t\t\tON CONFLICT(id) DO UPDATE SET conversation_id = excluded.conversation_id,\n\t\t\t\t\t\trequest_id = excluded.request_id, status = excluded.status, record = excluded.record`)\n\t\t\t\t\t.run(\n\t\t\t\t\t\twrite.value.id,\n\t\t\t\t\t\twrite.value.conversationId,\n\t\t\t\t\t\twrite.value.requestId === undefined ? null : encodeIndexedString(write.value.requestId),\n\t\t\t\t\t\twrite.value.status,\n\t\t\t\t\t\tencodeJson(write.value),\n\t\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"document.create\":\n\t\t\tcase \"document.copy\":\n\t\t\tcase \"document.change\":\n\t\t\tcase \"document.retire\":\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate claimId(id: Id<string>, table: TableName): void {\n\t\tthis.db.prepare(\"INSERT OR IGNORE INTO record_ids (id, record_type) VALUES (?, ?)\").run(id, table);\n\t}\n\n\tprivate applyDocumentActions(actions: ReadonlyMap<DocumentId, DocumentAction>, seq: Seq): void {\n\t\tfor (const [id, action] of actions) {\n\t\t\tlet content = action.content;\n\t\t\tif (action.copy !== undefined) {\n\t\t\t\ttry {\n\t\t\t\t\tconst stored = this.materializeDocument(action.copy.id, action.copy.at);\n\t\t\t\t\tif (stored === undefined) throw new Error(`Fork source document ${action.copy.id} cannot be read`);\n\t\t\t\t\tconst create = action.create!;\n\t\t\t\t\tif (\n\t\t\t\t\t\tstored.record.scope.kind !== \"conversation\" ||\n\t\t\t\t\t\tcreate.scope.kind !== \"conversation\" ||\n\t\t\t\t\t\tstored.record.kind !== create.kind ||\n\t\t\t\t\t\tstored.record.key !== create.key ||\n\t\t\t\t\t\tstored.record.history !== create.history ||\n\t\t\t\t\t\tstored.record.fork !== create.fork\n\t\t\t\t\t) {\n\t\t\t\t\t\tthrow new Error(`Fork source document ${action.copy.id} does not match the copied record`);\n\t\t\t\t\t}\n\t\t\t\t\tcontent = { kind: \"base\", version: stored.version, value: stored.value };\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (error instanceof StorageRejected) throw error;\n\t\t\t\t\tthrow new StorageRejected(`Document copy ${id} was rejected`, { cause: error });\n\t\t\t\t}\n\t\t\t}\n\t\t\tlet record: DocumentRecord;\n\t\t\tif (action.create !== undefined) {\n\t\t\t\trecord = {\n\t\t\t\t\t...action.create,\n\t\t\t\t\tcreatedAt: seq,\n\t\t\t\t\t...(action.retire ? { retiredAt: seq } : {}),\n\t\t\t\t};\n\t\t\t\tconst parts = addressParts(record);\n\t\t\t\tthis.claimId(id, \"document\");\n\t\t\t\tthis.db\n\t\t\t\t\t.prepare(`INSERT INTO documents\n\t\t\t\t\t\t(id, kind, family, key_value, scope_kind, owner_id, created_at, retired_at, record)\n\t\t\t\t\t\tVALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`)\n\t\t\t\t\t.run(\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tparts.kind,\n\t\t\t\t\t\tparts.family,\n\t\t\t\t\t\tparts.keyValue,\n\t\t\t\t\t\tparts.scopeKind,\n\t\t\t\t\t\tparts.ownerId,\n\t\t\t\t\t\tseq,\n\t\t\t\t\t\taction.retire ? seq : null,\n\t\t\t\t\t\tencodeJson(record),\n\t\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tconst row = getRow<JsonRow>(this.db.prepare(\"SELECT record FROM documents WHERE id = ?\"), id)!;\n\t\t\t\trecord = parseJson<DocumentRecord>(row.record);\n\t\t\t}\n\n\t\t\tif (content !== undefined) {\n\t\t\t\tif (content.kind === \"base\" && isCurrentOnly(record)) {\n\t\t\t\t\tthis.db.prepare(\"DELETE FROM document_revisions WHERE document_id = ?\").run(id);\n\t\t\t\t}\n\t\t\t\tconst encodedContent = content.kind === \"base\" ? encodeJson(content.value) : encodeJson(content.ops);\n\t\t\t\tthis.db\n\t\t\t\t\t.prepare(\n\t\t\t\t\t\t\"INSERT INTO document_revisions (document_id, seq, kind, version, content) VALUES (?, ?, ?, ?, ?)\",\n\t\t\t\t\t)\n\t\t\t\t\t.run(id, seq, content.kind, content.version, encodedContent);\n\t\t\t}\n\n\t\t\tif (action.retire) {\n\t\t\t\tif (action.create === undefined) {\n\t\t\t\t\trecord = { ...record, retiredAt: seq };\n\t\t\t\t\tthis.db\n\t\t\t\t\t\t.prepare(\"UPDATE documents SET retired_at = ?, record = ? WHERE id = ?\")\n\t\t\t\t\t\t.run(seq, encodeJson(record), id);\n\t\t\t\t}\n\t\t\t\tif (isCurrentOnly(record)) this.db.prepare(\"DELETE FROM document_revisions WHERE document_id = ?\").run(id);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate assertOpen(): void {\n\t\tif (this.closed) throw new Error(\"SqliteStorage is closed\");\n\t}\n}\n"]}
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/storage/sqlite/storage.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context, JsonValue } from \"@earendil-works/chord\";\nimport { apply, type Op } from \"@earendil-works/chord/delta\";\nimport { StorageRejected } from \"../../errors.ts\";\nimport { idFromNumber, seqFromNumber } from \"../../ids.ts\";\nimport type {\n\tConversationId,\n\tConversationQuery,\n\tConversationRecord,\n\tCursor,\n\tDocumentAddress,\n\tDocumentContent,\n\tDocumentCreate,\n\tDocumentId,\n\tDocumentPoint,\n\tDocumentQuery,\n\tDocumentRecord,\n\tEntryId,\n\tEntryQuery,\n\tEntryRecord,\n\tId,\n\tJsonObject,\n\tPage,\n\tSeq,\n\tStorage,\n\tStorageWrite,\n\tStoredDocument,\n\tSubmissionId,\n\tSubmissionQuery,\n\tSubmissionRecord,\n\tTaskId,\n\tTaskQuery,\n\tTaskRecord,\n} from \"../../types.ts\";\nimport type { SqliteDatabase, SqliteExecutor, SqliteValue } from \"./database.ts\";\nimport { applySqliteMigrations } from \"./migrations.ts\";\n\ntype StoredTask = TaskRecord<JsonValue, JsonValue, JsonValue>;\ntype TableName = \"conversation\" | \"entry\" | \"task\" | \"submission\" | \"document\";\ntype RecordIdRow = { readonly record_type: TableName };\ntype JsonRow = { readonly record: string };\ntype EntryJsonRow = { readonly record: string; readonly commit_seq: number };\ntype RevisionRow = {\n\treadonly seq: number;\n\treadonly kind: DocumentContent[\"kind\"];\n\treadonly version: number;\n\treadonly content: string;\n};\ntype IdRow = { readonly id: number };\ntype MetadataRow = { readonly next_id: string; readonly next_seq: number };\ntype DocumentAction = {\n\tcreate?: DocumentCreate;\n\tcopy?: Extract<StorageWrite, { readonly type: \"document.copy\" }>[\"source\"];\n\tcontent?: DocumentContent;\n\tretire: boolean;\n};\ntype ScopeColumns = {\n\treadonly scopeKind: DocumentRecord[\"scope\"][\"kind\"];\n\treadonly ownerId: number;\n};\n\nconst parseJson = <T>(value: string): T => JSON.parse(value) as T;\nconst encodeJson = (value: unknown): string => JSON.stringify(value) as string;\n// Some SQLite bindings replace lone UTF-16 surrogates. JSON encoding keeps indexed identities lossless.\nconst encodeIndexedString = (value: string): string => JSON.stringify(value);\n\nconst cursorId = <I extends Id<string>>(cursor: Cursor | undefined): I | undefined => {\n\tconst after = cursor?.after;\n\tif (after === undefined) return undefined;\n\tif (typeof after !== \"number\" || !Number.isSafeInteger(after)) throw new TypeError(\"Invalid storage cursor\");\n\treturn idFromNumber<I>(after);\n};\n\nconst page = <T extends { readonly id: Id<string> }>(values: readonly T[], limit: number): Page<T, Cursor> => {\n\tconst items = values.slice(0, limit);\n\tif (values.length <= limit) return { items };\n\treturn { items, next: { after: items.at(-1)!.id } };\n};\n\nconst scopeColumns = (scope: DocumentRecord[\"scope\"]): ScopeColumns => {\n\tswitch (scope.kind) {\n\t\tcase \"session\":\n\t\t\treturn { scopeKind: \"session\", ownerId: 0 };\n\t\tcase \"conversation\":\n\t\t\treturn { scopeKind: \"conversation\", ownerId: scope.conversationId };\n\t\tcase \"task\":\n\t\t\treturn { scopeKind: \"task\", ownerId: scope.taskId };\n\t}\n};\n\nconst addressParts = (address: DocumentAddress | DocumentCreate | DocumentRecord) => {\n\tconst scope = scopeColumns(address.scope);\n\treturn {\n\t\tkind: encodeIndexedString(address.kind),\n\t\t...scope,\n\t\tfamily: address.key === undefined ? 0 : 1,\n\t\tkeyValue: encodeIndexedString(address.key ?? \"\"),\n\t};\n};\n\nconst addressKey = (address: DocumentAddress | DocumentCreate | DocumentRecord): string => {\n\tconst parts = addressParts(address);\n\treturn JSON.stringify([parts.kind, parts.scopeKind, parts.ownerId, parts.family, parts.keyValue]);\n};\n\nconst isAliveAt = (record: DocumentRecord, at: DocumentPoint): boolean => {\n\tif (at === \"current\") return record.retiredAt === undefined;\n\treturn record.createdAt <= at && (record.retiredAt === undefined || at < record.retiredAt);\n};\n\nconst isCurrentOnly = (record: DocumentRecord): boolean =>\n\trecord.scope.kind !== \"conversation\" || record.history === \"latest\";\n\nconst writeId = (write: StorageWrite): Id<string> | undefined => {\n\tswitch (write.type) {\n\t\tcase \"conversation\":\n\t\tcase \"entry\":\n\t\tcase \"task\":\n\t\tcase \"submission\":\n\t\t\treturn write.value.id;\n\t\tcase \"document.create\":\n\t\tcase \"document.copy\":\n\t\t\treturn write.record.id;\n\t\tcase \"document.change\":\n\t\tcase \"document.retire\":\n\t\t\treturn undefined;\n\t}\n};\n\n/** Portable SQLite implementation of the Pico storage contract. */\nexport class SqliteStorage implements Storage {\n\tprivate readonly db: SqliteDatabase;\n\tprivate nextId: number;\n\tprivate closed = false;\n\tprivate closing: Promise<void> | undefined;\n\tprivate admittedReads = 0;\n\tprivate readsDrained: (() => void) | undefined;\n\n\tprivate constructor(db: SqliteDatabase, nextId: number) {\n\t\tthis.db = db;\n\t\tthis.nextId = nextId;\n\t}\n\n\t/** Initialize storage over an owned SQLite database facade. */\n\tstatic async open(db: SqliteDatabase): Promise<SqliteStorage> {\n\t\ttry {\n\t\t\tawait applySqliteMigrations(db);\n\t\t\tconst metadata = await db.get<MetadataRow>(\n\t\t\t\t\"SELECT next_id, next_seq FROM durable_metadata WHERE singleton = 1\",\n\t\t\t);\n\t\t\tif (metadata === undefined) throw new Error(\"Durable SQLite metadata is missing\");\n\t\t\treturn new SqliteStorage(db, Number(metadata.next_id));\n\t\t} catch (error) {\n\t\t\ttry {\n\t\t\t\tawait db.close();\n\t\t\t} catch {\n\t\t\t\t// Preserve the initialization failure.\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync commit(writes: readonly StorageWrite[], _context: Context): Promise<Seq> {\n\t\tthis.assertOpen();\n\t\tconst documentActions = this.prepareDocumentActions(writes);\n\t\tconst candidateNextId = this.candidateNextId(writes);\n\t\tconst seq = await this.db.transaction(async (transaction) => {\n\t\t\tconst metadata = await transaction.get<MetadataRow>(\n\t\t\t\t\"SELECT next_id, next_seq FROM durable_metadata WHERE singleton = 1\",\n\t\t\t);\n\t\t\tif (metadata === undefined) throw new Error(\"Durable SQLite metadata is missing\");\n\t\t\tconst committedSeq = seqFromNumber(metadata.next_seq);\n\t\t\tawait this.checkGlobalIds(transaction, writes);\n\t\t\tawait this.checkDocumentActions(transaction, documentActions);\n\t\t\tfor (const write of writes) await this.applyTableWrite(transaction, write, committedSeq);\n\t\t\tawait this.applyDocumentActions(transaction, documentActions, committedSeq);\n\t\t\tawait transaction.run(\n\t\t\t\t\"UPDATE durable_metadata SET next_id = ?, next_seq = ? WHERE singleton = 1\",\n\t\t\t\tString(Math.max(Number(metadata.next_id), candidateNextId)),\n\t\t\t\tcommittedSeq + 1,\n\t\t\t);\n\t\t\treturn committedSeq;\n\t\t});\n\t\tthis.nextId = Math.max(this.nextId, candidateNextId);\n\t\treturn seq;\n\t}\n\n\tasync mintId<I extends Id<string>>(): Promise<I> {\n\t\tthis.assertOpen();\n\t\tif (!Number.isSafeInteger(this.nextId)) throw new Error(\"ID space is exhausted\");\n\t\treturn idFromNumber<I>(this.nextId++);\n\t}\n\n\tasync conversation(id: ConversationId, _context: Context): Promise<ConversationRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst row = await this.db.get<JsonRow>(\"SELECT record FROM conversations WHERE id = ?\", id);\n\t\treturn row === undefined ? undefined : parseJson<ConversationRecord>(row.record);\n\t}\n\n\tasync scanConversations(\n\t\tquery: ConversationQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<ConversationRecord, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst clauses = [\"id > ?\"];\n\t\tconst params: SqliteValue[] = [cursorId(cursor) ?? -1];\n\t\tif (query.ownerConversationId !== undefined) {\n\t\t\tclauses.push(\"owner_conversation_id = ?\");\n\t\t\tparams.push(query.ownerConversationId);\n\t\t}\n\t\tif (query.ownerTaskId !== undefined) {\n\t\t\tclauses.push(\"owner_task_id = ?\");\n\t\t\tparams.push(query.ownerTaskId);\n\t\t}\n\t\tparams.push(limit + 1);\n\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t`SELECT record FROM conversations WHERE ${clauses.join(\" AND \")} ORDER BY id LIMIT ?`,\n\t\t\t...params,\n\t\t);\n\t\treturn page(\n\t\t\trows.map((row) => parseJson<ConversationRecord>(row.record)),\n\t\t\tlimit,\n\t\t);\n\t}\n\n\tentry(id: EntryId, context: Context): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined>;\n\tentry(\n\t\tconversationId: ConversationId,\n\t\tid: EntryId,\n\t\tcontext: Context,\n\t): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined>;\n\tentry(\n\t\tidOrConversationId: EntryId | ConversationId,\n\t\tidOrContext: EntryId | Context,\n\t\tcontext?: Context,\n\t): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined> {\n\t\treturn this.admitRead(() => this.readEntry(idOrConversationId, idOrContext, context));\n\t}\n\n\tfindLatestHeadMarker(\n\t\tconversationId: ConversationId,\n\t\tatOrBeforeEntryId: EntryId | undefined,\n\t\t_context: Context,\n\t): Promise<(EntryRecord & { readonly head: EntryId }) | undefined> {\n\t\treturn this.admitRead(() => this.readLatestHeadMarker(conversationId, atOrBeforeEntryId));\n\t}\n\n\tscanEntries(\n\t\tquery: EntryQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<EntryRecord, Cursor>> {\n\t\treturn this.admitRead(() => this.readEntries(query, limit, cursor));\n\t}\n\n\tprivate async readEntry(\n\t\tidOrConversationId: EntryId | ConversationId,\n\t\tidOrContext: EntryId | Context,\n\t\tcontext?: Context,\n\t): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined> {\n\t\tconst id =\n\t\t\tcontext === undefined\n\t\t\t\t? idFromNumber<EntryId>(idOrConversationId)\n\t\t\t\t: typeof idOrContext === \"number\"\n\t\t\t\t\t? idFromNumber<EntryId>(idOrContext)\n\t\t\t\t\t: undefined;\n\t\tif (id === undefined) throw new TypeError(\"Storage.entry() requires an entry ID\");\n\t\tlet conversation: ConversationRecord | undefined;\n\t\tif (context !== undefined) {\n\t\t\tconst conversationId = idFromNumber<ConversationId>(idOrConversationId);\n\t\t\tconversation = await this.readConversation(conversationId);\n\t\t\tif (conversation === undefined) throw new Error(`Unknown conversation: ${conversationId}`);\n\t\t}\n\t\tconst row = await this.db.get<EntryJsonRow>(\"SELECT record, commit_seq FROM entries WHERE id = ?\", id);\n\t\tif (row === undefined) return undefined;\n\t\tconst entry = parseJson<EntryRecord>(row.record);\n\t\tif (conversation !== undefined) {\n\t\t\tlet upperEntryId = Number.POSITIVE_INFINITY;\n\t\t\twhile (conversation.id !== entry.conversationId) {\n\t\t\t\tif (conversation.parent === undefined) return undefined;\n\t\t\t\tupperEntryId = Math.min(upperEntryId, conversation.parent.at);\n\t\t\t\tconversation = (await this.readConversation(conversation.parent.conversationId))!;\n\t\t\t}\n\t\t\tif (entry.id > upperEntryId) return undefined;\n\t\t}\n\t\treturn { entry, commitSeq: seqFromNumber(row.commit_seq) };\n\t}\n\n\tprivate async readLatestHeadMarker(\n\t\tconversationId: ConversationId,\n\t\tatOrBeforeEntryId: EntryId | undefined,\n\t): Promise<(EntryRecord & { readonly head: EntryId }) | undefined> {\n\t\tlet conversation = await this.readConversation(conversationId);\n\t\tif (conversation === undefined) throw new Error(`Unknown conversation: ${conversationId}`);\n\t\tlet upper: number | undefined = atOrBeforeEntryId;\n\t\twhile (true) {\n\t\t\tconst row =\n\t\t\t\tupper === undefined\n\t\t\t\t\t? await this.db.get<JsonRow>(\n\t\t\t\t\t\t\t\"SELECT record FROM entries WHERE conversation_id = ? AND head IS NOT NULL ORDER BY id DESC LIMIT 1\",\n\t\t\t\t\t\t\tconversation.id,\n\t\t\t\t\t\t)\n\t\t\t\t\t: await this.db.get<JsonRow>(\n\t\t\t\t\t\t\t\"SELECT record FROM entries WHERE conversation_id = ? AND head IS NOT NULL AND id <= ? ORDER BY id DESC LIMIT 1\",\n\t\t\t\t\t\t\tconversation.id,\n\t\t\t\t\t\t\tupper,\n\t\t\t\t\t\t);\n\t\t\tif (row !== undefined) return parseJson<EntryRecord & { readonly head: EntryId }>(row.record);\n\t\t\tif (conversation.parent === undefined) return undefined;\n\t\t\tupper = upper === undefined ? conversation.parent.at : Math.min(upper, conversation.parent.at);\n\t\t\tconversation = (await this.readConversation(conversation.parent.conversationId))!;\n\t\t}\n\t}\n\n\tprivate async readEntries(\n\t\tquery: EntryQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t): Promise<Page<EntryRecord, Cursor>> {\n\t\tlet conversation = await this.readConversation(query.conversationId);\n\t\tif (conversation === undefined) throw new Error(`Unknown conversation: ${query.conversationId}`);\n\t\tconst after = cursorId(cursor);\n\t\tlet upper: number | undefined = query.maxEntryId;\n\t\tif (after !== undefined) upper = Math.min(upper ?? Number.MAX_SAFE_INTEGER, after - 1);\n\t\tconst values: EntryRecord[] = [];\n\t\twhile (true) {\n\t\t\tconst clauses = [\"conversation_id = ?\"];\n\t\t\tconst params: SqliteValue[] = [conversation.id];\n\t\t\tif (query.minEntryId !== undefined) {\n\t\t\t\tclauses.push(\"id >= ?\");\n\t\t\t\tparams.push(query.minEntryId);\n\t\t\t}\n\t\t\tif (upper !== undefined) {\n\t\t\t\tclauses.push(\"id <= ?\");\n\t\t\t\tparams.push(upper);\n\t\t\t}\n\t\t\tparams.push(limit + 1 - values.length);\n\t\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t\t`SELECT record FROM entries WHERE ${clauses.join(\" AND \")} ORDER BY id DESC LIMIT ?`,\n\t\t\t\t...params,\n\t\t\t);\n\t\t\tvalues.push(...rows.map((row) => parseJson<EntryRecord>(row.record)));\n\t\t\tif (values.length > limit || conversation.parent === undefined) break;\n\t\t\tupper = upper === undefined ? conversation.parent.at : Math.min(upper, conversation.parent.at);\n\t\t\tif (query.minEntryId !== undefined && upper < query.minEntryId) break;\n\t\t\tconversation = (await this.readConversation(conversation.parent.conversationId))!;\n\t\t}\n\t\treturn page(values, limit);\n\t}\n\n\tasync task(id: TaskId, _context: Context): Promise<StoredTask | undefined> {\n\t\tthis.assertOpen();\n\t\tconst row = await this.db.get<JsonRow>(\"SELECT record FROM tasks WHERE id = ?\", id);\n\t\treturn row === undefined ? undefined : parseJson<StoredTask>(row.record);\n\t}\n\n\tasync scanTasks(\n\t\tquery: TaskQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<StoredTask, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst clauses = [\"id > ?\"];\n\t\tconst params: SqliteValue[] = [cursorId(cursor) ?? -1];\n\t\tif (query.conversationId !== undefined) {\n\t\t\tclauses.push(\"conversation_id = ?\");\n\t\t\tparams.push(query.conversationId);\n\t\t}\n\t\tif (query.kind !== undefined) {\n\t\t\tclauses.push(\"kind = ?\");\n\t\t\tparams.push(encodeIndexedString(query.kind));\n\t\t}\n\t\tif (query.status !== undefined) {\n\t\t\tclauses.push(\"status = ?\");\n\t\t\tparams.push(query.status);\n\t\t}\n\t\tif (query.abortRequested !== undefined) {\n\t\t\tclauses.push(\"abort_requested = ?\");\n\t\t\tparams.push(query.abortRequested ? 1 : 0);\n\t\t}\n\t\tif (query.background !== undefined) {\n\t\t\tclauses.push(\"background = ?\");\n\t\t\tparams.push(query.background ? 1 : 0);\n\t\t}\n\t\tparams.push(limit + 1);\n\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t`SELECT record FROM tasks WHERE ${clauses.join(\" AND \")} ORDER BY id LIMIT ?`,\n\t\t\t...params,\n\t\t);\n\t\treturn page(\n\t\t\trows.map((row) => parseJson<StoredTask>(row.record)),\n\t\t\tlimit,\n\t\t);\n\t}\n\n\tasync submission(id: SubmissionId, _context: Context): Promise<SubmissionRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst row = await this.db.get<JsonRow>(\"SELECT record FROM submissions WHERE id = ?\", id);\n\t\treturn row === undefined ? undefined : parseJson<SubmissionRecord>(row.record);\n\t}\n\n\tasync scanSubmissions(\n\t\tquery: SubmissionQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<SubmissionRecord, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst clauses = [\"id > ?\"];\n\t\tconst params: SqliteValue[] = [cursorId(cursor) ?? -1];\n\t\tif (query.conversationId !== undefined) {\n\t\t\tclauses.push(\"conversation_id = ?\");\n\t\t\tparams.push(query.conversationId);\n\t\t}\n\t\tif (query.status !== undefined) {\n\t\t\tclauses.push(\"status = ?\");\n\t\t\tparams.push(query.status);\n\t\t}\n\t\tparams.push(limit + 1);\n\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t`SELECT record FROM submissions WHERE ${clauses.join(\" AND \")} ORDER BY id LIMIT ?`,\n\t\t\t...params,\n\t\t);\n\t\treturn page(\n\t\t\trows.map((row) => parseJson<SubmissionRecord>(row.record)),\n\t\t\tlimit,\n\t\t);\n\t}\n\n\tasync submissionByRequest(\n\t\tconversationId: ConversationId,\n\t\trequestId: string,\n\t\t_context: Context,\n\t): Promise<SubmissionRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst row = await this.db.get<JsonRow>(\n\t\t\t\"SELECT record FROM submissions WHERE conversation_id = ? AND request_id = ?\",\n\t\t\tconversationId,\n\t\t\tencodeIndexedString(requestId),\n\t\t);\n\t\treturn row === undefined ? undefined : parseJson<SubmissionRecord>(row.record);\n\t}\n\n\tasync findDocument(\n\t\taddress: DocumentAddress,\n\t\tat: DocumentPoint,\n\t\t_context: Context,\n\t): Promise<DocumentRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst parts = addressParts(address);\n\t\tconst sql =\n\t\t\tat === \"current\"\n\t\t\t\t? `SELECT record FROM documents\n\t\t\t\t\tWHERE kind = ? AND scope_kind = ? AND owner_id = ? AND family = ? AND key_value = ?\n\t\t\t\t\tAND retired_at IS NULL ORDER BY created_at DESC LIMIT 1`\n\t\t\t\t: `SELECT record FROM documents\n\t\t\t\t\tWHERE kind = ? AND scope_kind = ? AND owner_id = ? AND family = ? AND key_value = ?\n\t\t\t\t\tAND created_at <= ? AND (retired_at IS NULL OR retired_at > ?)\n\t\t\t\t\tORDER BY created_at DESC LIMIT 1`;\n\t\tconst params: SqliteValue[] = [parts.kind, parts.scopeKind, parts.ownerId, parts.family, parts.keyValue];\n\t\tif (at !== \"current\") params.push(at, at);\n\t\tconst row = await this.db.get<JsonRow>(sql, ...params);\n\t\treturn row === undefined ? undefined : parseJson<DocumentRecord>(row.record);\n\t}\n\n\tasync document(id: DocumentId, at: DocumentPoint, _context: Context): Promise<StoredDocument | undefined> {\n\t\tthis.assertOpen();\n\t\t// The record and revision queries must observe one committed state; a commit between them can replace the base.\n\t\treturn this.db.transaction((transaction) => this.materializeDocument(transaction, id, at));\n\t}\n\n\tasync scanDocuments(\n\t\tquery: DocumentQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<DocumentRecord, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst scope = scopeColumns(query.scope);\n\t\tconst clauses = [\"scope_kind = ?\", \"owner_id = ?\", \"id > ?\"];\n\t\tconst params: SqliteValue[] = [scope.scopeKind, scope.ownerId, cursorId(cursor) ?? -1];\n\t\tif (query.kind !== undefined) {\n\t\t\tclauses.push(\"kind = ?\");\n\t\t\tparams.push(encodeIndexedString(query.kind));\n\t\t}\n\t\tif (query.at === \"current\") {\n\t\t\tclauses.push(\"retired_at IS NULL\");\n\t\t} else {\n\t\t\tclauses.push(\"created_at <= ?\", \"(retired_at IS NULL OR retired_at > ?)\");\n\t\t\tparams.push(query.at, query.at);\n\t\t}\n\t\tparams.push(limit + 1);\n\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t`SELECT record FROM documents WHERE ${clauses.join(\" AND \")} ORDER BY id LIMIT ?`,\n\t\t\t...params,\n\t\t);\n\t\treturn page(\n\t\t\trows.map((row) => parseJson<DocumentRecord>(row.record)),\n\t\t\tlimit,\n\t\t);\n\t}\n\n\tclose(_context: Context): Promise<void> {\n\t\tif (this.closing === undefined) {\n\t\t\tthis.closed = true;\n\t\t\tthis.closing = this.closeDatabase();\n\t\t}\n\t\treturn this.closing;\n\t}\n\n\tprivate async closeDatabase(): Promise<void> {\n\t\tif (this.admittedReads > 0) {\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tthis.readsDrained = resolve;\n\t\t\t});\n\t\t}\n\t\tawait this.db.close();\n\t}\n\n\t/**\n\t * Run a read that issues several queries. Close waits for admitted reads, so their later queries never reach a\n\t * closed database. Single-query reads and transactions are already ordered before close by the database.\n\t */\n\tprivate async admitRead<T>(read: () => Promise<T>): Promise<T> {\n\t\tthis.assertOpen();\n\t\tthis.admittedReads++;\n\t\ttry {\n\t\t\treturn await read();\n\t\t} finally {\n\t\t\tif (--this.admittedReads === 0) this.readsDrained?.();\n\t\t}\n\t}\n\n\tprivate async readConversation(id: ConversationId): Promise<ConversationRecord | undefined> {\n\t\tconst row = await this.db.get<JsonRow>(\"SELECT record FROM conversations WHERE id = ?\", id);\n\t\treturn row === undefined ? undefined : parseJson<ConversationRecord>(row.record);\n\t}\n\n\tprivate async materializeDocument(\n\t\texecutor: SqliteExecutor,\n\t\tid: DocumentId,\n\t\tat: DocumentPoint,\n\t): Promise<StoredDocument | undefined> {\n\t\tconst row = await executor.get<JsonRow>(\"SELECT record FROM documents WHERE id = ?\", id);\n\t\tif (row === undefined) return undefined;\n\t\tconst record = parseJson<DocumentRecord>(row.record);\n\t\tif (at !== \"current\" && isCurrentOnly(record)) {\n\t\t\tthrow new Error(`Document ${id} does not retain historical content`);\n\t\t}\n\t\tif (!isAliveAt(record, at)) return undefined;\n\t\tconst upper = at === \"current\" ? Number.MAX_SAFE_INTEGER : at;\n\t\tconst base = await executor.get<RevisionRow>(\n\t\t\t`SELECT seq, kind, version, content FROM document_revisions\n\t\t\t\tWHERE document_id = ? AND kind = 'base' AND seq <= ? ORDER BY seq DESC LIMIT 1`,\n\t\t\tid,\n\t\t\tupper,\n\t\t);\n\t\tif (base === undefined) throw new Error(`Document ${id} is missing a required base`);\n\t\tlet value = parseJson<JsonObject>(base.content);\n\t\tconst tail = await executor.all<RevisionRow>(\n\t\t\t`SELECT seq, kind, version, content FROM document_revisions\n\t\t\t\tWHERE document_id = ? AND seq > ? AND seq <= ? ORDER BY seq`,\n\t\t\tid,\n\t\t\tbase.seq,\n\t\t\tupper,\n\t\t);\n\t\tfor (const revision of tail) {\n\t\t\tif (revision.kind !== \"delta\" || revision.version !== base.version) {\n\t\t\t\tthrow new Error(`Document ${id} crosses a stored version boundary without a base`);\n\t\t\t}\n\t\t\tvalue = apply(value, parseJson<readonly Op[]>(revision.content)) as JsonObject;\n\t\t}\n\t\treturn { record, version: base.version, value, deltasSinceBase: tail.length };\n\t}\n\n\tprivate candidateNextId(writes: readonly StorageWrite[]): number {\n\t\tlet nextId = this.nextId;\n\t\tfor (const write of writes) {\n\t\t\tconst id = writeId(write);\n\t\t\tif (id !== undefined) nextId = Math.max(nextId, id + 1);\n\t\t}\n\t\treturn nextId;\n\t}\n\n\tprivate async checkGlobalIds(executor: SqliteExecutor, writes: readonly StorageWrite[]): Promise<void> {\n\t\tconst claimed = new Map<Id<string>, TableName>();\n\t\tfor (const write of writes) {\n\t\t\tif (write.type === \"document.change\" || write.type === \"document.retire\") continue;\n\t\t\tconst document = write.type === \"document.create\" || write.type === \"document.copy\";\n\t\t\tconst table: TableName = document ? \"document\" : write.type;\n\t\t\tconst id = document ? write.record.id : write.value.id;\n\t\t\tconst existing = (await executor.get<RecordIdRow>(\"SELECT record_type FROM record_ids WHERE id = ?\", id))\n\t\t\t\t?.record_type;\n\t\t\tconst earlier = claimed.get(id);\n\t\t\tif (table === \"conversation\" || table === \"entry\" || table === \"document\") {\n\t\t\t\tif (existing !== undefined) throw new Error(`ID ${id} already belongs to ${existing}`);\n\t\t\t\tif (earlier !== undefined) throw new Error(`ID ${id} is written more than once`);\n\t\t\t} else {\n\t\t\t\tif (existing !== undefined && existing !== table)\n\t\t\t\t\tthrow new Error(`ID ${id} already belongs to ${existing}`);\n\t\t\t\tif (earlier !== undefined && earlier !== table) throw new Error(`ID ${id} is written as two record types`);\n\t\t\t}\n\t\t\tclaimed.set(id, table);\n\t\t}\n\t}\n\n\tprivate prepareDocumentActions(writes: readonly StorageWrite[]): Map<DocumentId, DocumentAction> {\n\t\tconst actions = new Map<DocumentId, DocumentAction>();\n\t\tfor (const write of writes) {\n\t\t\tif (\n\t\t\t\twrite.type !== \"document.create\" &&\n\t\t\t\twrite.type !== \"document.copy\" &&\n\t\t\t\twrite.type !== \"document.change\" &&\n\t\t\t\twrite.type !== \"document.retire\"\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst id = write.type === \"document.create\" || write.type === \"document.copy\" ? write.record.id : write.id;\n\t\t\tlet action = actions.get(id);\n\t\t\tif (action === undefined) {\n\t\t\t\taction = { retire: false };\n\t\t\t\tactions.set(id, action);\n\t\t\t}\n\t\t\tswitch (write.type) {\n\t\t\t\tcase \"document.create\":\n\t\t\t\t\tif (action.create !== undefined || action.content !== undefined || action.copy !== undefined) {\n\t\t\t\t\t\tthrow new Error(`Document ${id} has more than one content command`);\n\t\t\t\t\t}\n\t\t\t\t\taction.create = write.record;\n\t\t\t\t\taction.content = write.content;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"document.copy\":\n\t\t\t\t\tif (action.create !== undefined || action.content !== undefined || action.copy !== undefined) {\n\t\t\t\t\t\tthrow new Error(`Document ${id} has more than one content command`);\n\t\t\t\t\t}\n\t\t\t\t\taction.create = write.record;\n\t\t\t\t\taction.copy = write.source;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"document.change\":\n\t\t\t\t\tif (action.content !== undefined || action.copy !== undefined) {\n\t\t\t\t\t\tthrow new Error(`Document ${id} has more than one content command`);\n\t\t\t\t\t}\n\t\t\t\t\taction.content = write.content;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"document.retire\":\n\t\t\t\t\tif (action.retire) throw new Error(`Document ${id} is retired more than once`);\n\t\t\t\t\taction.retire = true;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn actions;\n\t}\n\n\tprivate async checkDocumentActions(\n\t\texecutor: SqliteExecutor,\n\t\tactions: ReadonlyMap<DocumentId, DocumentAction>,\n\t): Promise<void> {\n\t\tconst liveCounts = new Map<string, number>();\n\t\tfor (const [id, action] of actions) {\n\t\t\tif (action.copy !== undefined && actions.has(action.copy.id)) {\n\t\t\t\tthrow new StorageRejected(`Document copy ${id} source is changed in the copy batch`);\n\t\t\t}\n\t\t\tconst row = await executor.get<JsonRow>(\"SELECT record FROM documents WHERE id = ?\", id);\n\t\t\tconst existing = row === undefined ? undefined : parseJson<DocumentRecord>(row.record);\n\t\t\tif (action.create === undefined && existing === undefined) throw new Error(`Unknown document: ${id}`);\n\t\t\tif (action.create !== undefined && existing !== undefined) throw new Error(`Document ${id} already exists`);\n\t\t\tif (existing?.retiredAt !== undefined) throw new Error(`Document ${id} is retired`);\n\t\t\tif (action.content?.kind === \"delta\") {\n\t\t\t\tconst previous = await executor.get<{ readonly version: number }>(\n\t\t\t\t\t\"SELECT version FROM document_revisions WHERE document_id = ? ORDER BY seq DESC LIMIT 1\",\n\t\t\t\t\tid,\n\t\t\t\t);\n\t\t\t\tif (previous === undefined) throw new Error(`Document ${id} delta has no base`);\n\t\t\t\tif (previous.version !== action.content.version) {\n\t\t\t\t\tthrow new Error(`Document ${id} version transition requires a base`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst record = action.create ?? existing!;\n\t\t\tconst key = addressKey(record);\n\t\t\tlet live = liveCounts.get(key);\n\t\t\tif (live === undefined) live = (await this.currentDocumentId(executor, record)) === undefined ? 0 : 1;\n\t\t\tif (action.retire && existing !== undefined) live--;\n\t\t\tif (action.create !== undefined && !action.retire) live++;\n\t\t\tliveCounts.set(key, live);\n\t\t}\n\t\tfor (const live of liveCounts.values()) {\n\t\t\tif (live > 1) throw new Error(\"Document address already has a current incarnation\");\n\t\t}\n\t}\n\n\tprivate async currentDocumentId(\n\t\texecutor: SqliteExecutor,\n\t\taddress: DocumentAddress | DocumentCreate | DocumentRecord,\n\t): Promise<DocumentId | undefined> {\n\t\tconst parts = addressParts(address);\n\t\tconst id = (\n\t\t\tawait executor.get<IdRow>(\n\t\t\t\t`SELECT id FROM documents\n\t\t\t\tWHERE kind = ? AND scope_kind = ? AND owner_id = ? AND family = ? AND key_value = ? AND retired_at IS NULL\n\t\t\t\tLIMIT 1`,\n\t\t\t\tparts.kind,\n\t\t\t\tparts.scopeKind,\n\t\t\t\tparts.ownerId,\n\t\t\t\tparts.family,\n\t\t\t\tparts.keyValue,\n\t\t\t)\n\t\t)?.id;\n\t\treturn id === undefined ? undefined : idFromNumber<DocumentId>(id);\n\t}\n\n\tprivate async applyTableWrite(executor: SqliteExecutor, write: StorageWrite, seq: Seq): Promise<void> {\n\t\tswitch (write.type) {\n\t\t\tcase \"conversation\":\n\t\t\t\tawait this.claimId(executor, write.value.id, \"conversation\");\n\t\t\t\tawait executor.run(\n\t\t\t\t\t\"INSERT INTO conversations (id, owner_conversation_id, owner_task_id, record) VALUES (?, ?, ?, ?)\",\n\t\t\t\t\twrite.value.id,\n\t\t\t\t\twrite.value.owner?.conversationId ?? null,\n\t\t\t\t\twrite.value.owner?.taskId ?? null,\n\t\t\t\t\tencodeJson(write.value),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"entry\":\n\t\t\t\tawait this.claimId(executor, write.value.id, \"entry\");\n\t\t\t\tawait executor.run(\n\t\t\t\t\t\"INSERT INTO entries (id, conversation_id, head, commit_seq, record) VALUES (?, ?, ?, ?, ?)\",\n\t\t\t\t\twrite.value.id,\n\t\t\t\t\twrite.value.conversationId,\n\t\t\t\t\twrite.value.head ?? null,\n\t\t\t\t\tseq,\n\t\t\t\t\tencodeJson(write.value),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"task\":\n\t\t\t\tawait this.claimId(executor, write.value.id, \"task\");\n\t\t\t\tawait executor.run(\n\t\t\t\t\t`INSERT INTO tasks (id, conversation_id, kind, status, abort_requested, background, record)\n\t\t\t\t\t\tVALUES (?, ?, ?, ?, ?, ?, ?)\n\t\t\t\t\t\tON CONFLICT(id) DO UPDATE SET conversation_id = excluded.conversation_id, kind = excluded.kind,\n\t\t\t\t\t\tstatus = excluded.status, abort_requested = excluded.abort_requested,\n\t\t\t\t\t\tbackground = excluded.background, record = excluded.record`,\n\t\t\t\t\twrite.value.id,\n\t\t\t\t\twrite.value.conversationId,\n\t\t\t\t\tencodeIndexedString(write.value.kind),\n\t\t\t\t\twrite.value.state.status,\n\t\t\t\t\twrite.value.abortRequested ? 1 : 0,\n\t\t\t\t\twrite.value.background ? 1 : 0,\n\t\t\t\t\tencodeJson(write.value),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"submission\":\n\t\t\t\tawait this.claimId(executor, write.value.id, \"submission\");\n\t\t\t\tawait executor.run(\n\t\t\t\t\t`INSERT INTO submissions (id, conversation_id, request_id, status, record) VALUES (?, ?, ?, ?, ?)\n\t\t\t\t\t\tON CONFLICT(id) DO UPDATE SET conversation_id = excluded.conversation_id,\n\t\t\t\t\t\trequest_id = excluded.request_id, status = excluded.status, record = excluded.record`,\n\t\t\t\t\twrite.value.id,\n\t\t\t\t\twrite.value.conversationId,\n\t\t\t\t\twrite.value.requestId === undefined ? null : encodeIndexedString(write.value.requestId),\n\t\t\t\t\twrite.value.status,\n\t\t\t\t\tencodeJson(write.value),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"document.create\":\n\t\t\tcase \"document.copy\":\n\t\t\tcase \"document.change\":\n\t\t\tcase \"document.retire\":\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate async claimId(executor: SqliteExecutor, id: Id<string>, table: TableName): Promise<void> {\n\t\tawait executor.run(\"INSERT OR IGNORE INTO record_ids (id, record_type) VALUES (?, ?)\", id, table);\n\t}\n\n\tprivate async applyDocumentActions(\n\t\texecutor: SqliteExecutor,\n\t\tactions: ReadonlyMap<DocumentId, DocumentAction>,\n\t\tseq: Seq,\n\t): Promise<void> {\n\t\tfor (const [id, action] of actions) {\n\t\t\tlet content = action.content;\n\t\t\tif (action.copy !== undefined) {\n\t\t\t\ttry {\n\t\t\t\t\tconst stored = await this.materializeDocument(executor, action.copy.id, action.copy.at);\n\t\t\t\t\tif (stored === undefined) throw new Error(`Fork source document ${action.copy.id} cannot be read`);\n\t\t\t\t\tconst create = action.create!;\n\t\t\t\t\tif (\n\t\t\t\t\t\tstored.record.scope.kind !== \"conversation\" ||\n\t\t\t\t\t\tcreate.scope.kind !== \"conversation\" ||\n\t\t\t\t\t\tstored.record.kind !== create.kind ||\n\t\t\t\t\t\tstored.record.key !== create.key ||\n\t\t\t\t\t\tstored.record.history !== create.history ||\n\t\t\t\t\t\tstored.record.fork !== create.fork\n\t\t\t\t\t) {\n\t\t\t\t\t\tthrow new Error(`Fork source document ${action.copy.id} does not match the copied record`);\n\t\t\t\t\t}\n\t\t\t\t\tcontent = { kind: \"base\", version: stored.version, value: stored.value };\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (error instanceof StorageRejected) throw error;\n\t\t\t\t\tthrow new StorageRejected(`Document copy ${id} was rejected`, { cause: error });\n\t\t\t\t}\n\t\t\t}\n\t\t\tlet record: DocumentRecord;\n\t\t\tif (action.create !== undefined) {\n\t\t\t\trecord = {\n\t\t\t\t\t...action.create,\n\t\t\t\t\tcreatedAt: seq,\n\t\t\t\t\t...(action.retire ? { retiredAt: seq } : {}),\n\t\t\t\t};\n\t\t\t\tconst parts = addressParts(record);\n\t\t\t\tawait this.claimId(executor, id, \"document\");\n\t\t\t\tawait executor.run(\n\t\t\t\t\t`INSERT INTO documents\n\t\t\t\t\t\t(id, kind, family, key_value, scope_kind, owner_id, created_at, retired_at, record)\n\t\t\t\t\t\tVALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n\t\t\t\t\tid,\n\t\t\t\t\tparts.kind,\n\t\t\t\t\tparts.family,\n\t\t\t\t\tparts.keyValue,\n\t\t\t\t\tparts.scopeKind,\n\t\t\t\t\tparts.ownerId,\n\t\t\t\t\tseq,\n\t\t\t\t\taction.retire ? seq : null,\n\t\t\t\t\tencodeJson(record),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tconst row = (await executor.get<JsonRow>(\"SELECT record FROM documents WHERE id = ?\", id))!;\n\t\t\t\trecord = parseJson<DocumentRecord>(row.record);\n\t\t\t}\n\n\t\t\tif (content !== undefined) {\n\t\t\t\tif (content.kind === \"base\" && isCurrentOnly(record)) {\n\t\t\t\t\tawait executor.run(\"DELETE FROM document_revisions WHERE document_id = ?\", id);\n\t\t\t\t}\n\t\t\t\tconst encodedContent = content.kind === \"base\" ? encodeJson(content.value) : encodeJson(content.ops);\n\t\t\t\tawait executor.run(\n\t\t\t\t\t\"INSERT INTO document_revisions (document_id, seq, kind, version, content) VALUES (?, ?, ?, ?, ?)\",\n\t\t\t\t\tid,\n\t\t\t\t\tseq,\n\t\t\t\t\tcontent.kind,\n\t\t\t\t\tcontent.version,\n\t\t\t\t\tencodedContent,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (action.retire) {\n\t\t\t\tif (action.create === undefined) {\n\t\t\t\t\trecord = { ...record, retiredAt: seq };\n\t\t\t\t\tawait executor.run(\n\t\t\t\t\t\t\"UPDATE documents SET retired_at = ?, record = ? WHERE id = ?\",\n\t\t\t\t\t\tseq,\n\t\t\t\t\t\tencodeJson(record),\n\t\t\t\t\t\tid,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (isCurrentOnly(record)) {\n\t\t\t\t\tawait executor.run(\"DELETE FROM document_revisions WHERE document_id = ?\", id);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate assertOpen(): void {\n\t\tif (this.closed) throw new Error(\"SqliteStorage is closed\");\n\t}\n}\n"]}
@@ -23,6 +23,6 @@ export interface BashToolOptions {
23
23
  * file whose path is reported as a diagnostic. A nonzero exit or timeout throws, which makes an error result that still
24
24
  * carries the output and diagnostics.
25
25
  */
26
- export declare function createBashTool(options?: BashToolOptions): ToolRegistration;
26
+ export declare function createBashTool(options?: BashToolOptions): ToolRegistration<typeof bashSchema>;
27
27
  export {};
28
28
  //# sourceMappingURL=bash.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAM9E,QAAA,MAAM,UAAU;;;EAGd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAEtD,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,UAAU,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,MAAM,WAAW,GAAG,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,gBAAgB,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEtH,MAAM,WAAW,eAAe;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,WAAW,CAAC;CACtB;AAYD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,gBAAgB,CA2C1E"}
1
+ {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAM9E,QAAA,MAAM,UAAU;;;EAGd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAEtD,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,UAAU,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,MAAM,WAAW,GAAG,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,gBAAgB,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEtH,MAAM,WAAW,eAAe;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,WAAW,CAAC;CACtB;AAYD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,gBAAgB,CAAC,OAAO,UAAU,CAAC,CA2C7F"}
@@ -1,4 +1,5 @@
1
1
  import { Type } from "typebox";
2
+ import { defineTool } from "../harness/define.js";
2
3
  import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES } from "../truncate.js";
3
4
  import { requireEnv } from "./env.js";
4
5
  const MAX_TIMEOUT_SECONDS = 2_147_483_647 / 1000;
@@ -23,7 +24,7 @@ function validateTimeout(timeout) {
23
24
  * carries the output and diagnostics.
24
25
  */
25
26
  export function createBashTool(options) {
26
- return {
27
+ return defineTool({
27
28
  name: "bash",
28
29
  description: `Execute a bash command in the current working directory. Returns combined stdout and stderr. Output is truncated to last ${DEFAULT_MAX_LINES} lines or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). If truncated, full output is saved to a temp file. Optionally provide a timeout in seconds.`,
29
30
  parameters: bashSchema,
@@ -64,6 +65,6 @@ export function createBashTool(options) {
64
65
  throw new Error(`Command exited with code ${result.value.exitCode}`);
65
66
  return {};
66
67
  },
67
- };
68
+ });
68
69
  }
69
70
  //# sourceMappingURL=bash.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bash.js","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context } from \"@earendil-works/chord\";\nimport { type Static, Type } from \"typebox\";\nimport type { ToolExecutionApi, ToolRegistration } from \"../harness/types.ts\";\nimport { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES } from \"../truncate.ts\";\nimport { requireEnv } from \"./env.ts\";\n\nconst MAX_TIMEOUT_SECONDS = 2_147_483_647 / 1000;\n\nconst bashSchema = Type.Object({\n\tcommand: Type.String({ description: \"Bash command to execute\" }),\n\ttimeout: Type.Optional(Type.Number({ description: \"Timeout in seconds (optional, no default timeout)\" })),\n});\n\nexport type BashToolInput = Static<typeof bashSchema>;\n\nexport interface BashExecution {\n\tcommand: string;\n\tcwd: string;\n\tenv: Record<string, string>;\n\tinheritEnv: boolean;\n}\n\nexport type BashPrepare = (execution: BashExecution, api: ToolExecutionApi, context: Context) => void | Promise<void>;\n\nexport interface BashToolOptions {\n\tcommandPrefix?: string;\n\tprepare?: BashPrepare;\n}\n\nfunction validateTimeout(timeout: number | undefined): void {\n\tif (timeout === undefined) return;\n\tif (!Number.isFinite(timeout) || timeout <= 0) {\n\t\tthrow new Error(\"Invalid timeout: must be a finite number of seconds\");\n\t}\n\tif (timeout > MAX_TIMEOUT_SECONDS) {\n\t\tthrow new Error(`Invalid timeout: maximum is ${MAX_TIMEOUT_SECONDS} seconds`);\n\t}\n}\n\n/**\n * Runs a command through the environment's shell. Its output streams to `api.output()`, where the Harness keeps the\n * tail within the default limits; the result content is that retained output. Output beyond the limits is spilled to a\n * file whose path is reported as a diagnostic. A nonzero exit or timeout throws, which makes an error result that still\n * carries the output and diagnostics.\n */\nexport function createBashTool(options?: BashToolOptions): ToolRegistration {\n\treturn {\n\t\tname: \"bash\",\n\t\tdescription: `Execute a bash command in the current working directory. Returns combined stdout and stderr. Output is truncated to last ${DEFAULT_MAX_LINES} lines or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). If truncated, full output is saved to a temp file. Optionally provide a timeout in seconds.`,\n\t\tparameters: bashSchema,\n\t\toutputLimits: { retain: \"tail\" },\n\t\tasync execute(args, api, context) {\n\t\t\tconst { command, timeout } = args as BashToolInput;\n\t\t\tvalidateTimeout(timeout);\n\t\t\tconst env = requireEnv(api);\n\t\t\tconst execution: BashExecution = {\n\t\t\t\tcommand: options?.commandPrefix ? `${options.commandPrefix}\\n${command}` : command,\n\t\t\t\tcwd: env.cwd,\n\t\t\t\tenv: {},\n\t\t\t\tinheritEnv: true,\n\t\t\t};\n\t\t\tawait options?.prepare?.(execution, api, context);\n\t\t\tconst result = await env.exec(\n\t\t\t\texecution.command,\n\t\t\t\t{\n\t\t\t\t\tcwd: execution.cwd,\n\t\t\t\t\tenv: execution.env,\n\t\t\t\t\tinheritEnv: execution.inheritEnv,\n\t\t\t\t\t...(timeout === undefined ? {} : { timeout }),\n\t\t\t\t\tonOutput: (text) => api.output(text),\n\t\t\t\t\tspill: { afterBytes: DEFAULT_MAX_BYTES, afterLines: DEFAULT_MAX_LINES },\n\t\t\t\t},\n\t\t\t\tcontext,\n\t\t\t);\n\t\t\tconst spillPath = result.ok ? result.value.spillPath : result.error.spillPath;\n\t\t\tif (spillPath !== undefined) {\n\t\t\t\tapi.diagnostic({ severity: \"info\", code: \"full_output\", message: `Full output: ${spillPath}` });\n\t\t\t}\n\t\t\tif (!result.ok) {\n\t\t\t\tif (result.error.code === \"aborted\" && context.abortSignal?.aborted) throw result.error;\n\t\t\t\tif (result.error.code === \"timeout\") throw new Error(`Command timed out after ${timeout} seconds`);\n\t\t\t\tif (result.error.code === \"aborted\") throw new Error(\"Command aborted\");\n\t\t\t\tthrow result.error;\n\t\t\t}\n\t\t\tif (result.value.exitCode !== 0) throw new Error(`Command exited with code ${result.value.exitCode}`);\n\t\t\treturn {};\n\t\t},\n\t};\n}\n"]}
1
+ {"version":3,"file":"bash.js","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context } from \"@earendil-works/chord\";\nimport { type Static, Type } from \"typebox\";\nimport { defineTool } from \"../harness/define.ts\";\nimport type { ToolExecutionApi, ToolRegistration } from \"../harness/types.ts\";\nimport { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES } from \"../truncate.ts\";\nimport { requireEnv } from \"./env.ts\";\n\nconst MAX_TIMEOUT_SECONDS = 2_147_483_647 / 1000;\n\nconst bashSchema = Type.Object({\n\tcommand: Type.String({ description: \"Bash command to execute\" }),\n\ttimeout: Type.Optional(Type.Number({ description: \"Timeout in seconds (optional, no default timeout)\" })),\n});\n\nexport type BashToolInput = Static<typeof bashSchema>;\n\nexport interface BashExecution {\n\tcommand: string;\n\tcwd: string;\n\tenv: Record<string, string>;\n\tinheritEnv: boolean;\n}\n\nexport type BashPrepare = (execution: BashExecution, api: ToolExecutionApi, context: Context) => void | Promise<void>;\n\nexport interface BashToolOptions {\n\tcommandPrefix?: string;\n\tprepare?: BashPrepare;\n}\n\nfunction validateTimeout(timeout: number | undefined): void {\n\tif (timeout === undefined) return;\n\tif (!Number.isFinite(timeout) || timeout <= 0) {\n\t\tthrow new Error(\"Invalid timeout: must be a finite number of seconds\");\n\t}\n\tif (timeout > MAX_TIMEOUT_SECONDS) {\n\t\tthrow new Error(`Invalid timeout: maximum is ${MAX_TIMEOUT_SECONDS} seconds`);\n\t}\n}\n\n/**\n * Runs a command through the environment's shell. Its output streams to `api.output()`, where the Harness keeps the\n * tail within the default limits; the result content is that retained output. Output beyond the limits is spilled to a\n * file whose path is reported as a diagnostic. A nonzero exit or timeout throws, which makes an error result that still\n * carries the output and diagnostics.\n */\nexport function createBashTool(options?: BashToolOptions): ToolRegistration<typeof bashSchema> {\n\treturn defineTool({\n\t\tname: \"bash\",\n\t\tdescription: `Execute a bash command in the current working directory. Returns combined stdout and stderr. Output is truncated to last ${DEFAULT_MAX_LINES} lines or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). If truncated, full output is saved to a temp file. Optionally provide a timeout in seconds.`,\n\t\tparameters: bashSchema,\n\t\toutputLimits: { retain: \"tail\" },\n\t\tasync execute(args, api, context) {\n\t\t\tconst { command, timeout } = args;\n\t\t\tvalidateTimeout(timeout);\n\t\t\tconst env = requireEnv(api);\n\t\t\tconst execution: BashExecution = {\n\t\t\t\tcommand: options?.commandPrefix ? `${options.commandPrefix}\\n${command}` : command,\n\t\t\t\tcwd: env.cwd,\n\t\t\t\tenv: {},\n\t\t\t\tinheritEnv: true,\n\t\t\t};\n\t\t\tawait options?.prepare?.(execution, api, context);\n\t\t\tconst result = await env.exec(\n\t\t\t\texecution.command,\n\t\t\t\t{\n\t\t\t\t\tcwd: execution.cwd,\n\t\t\t\t\tenv: execution.env,\n\t\t\t\t\tinheritEnv: execution.inheritEnv,\n\t\t\t\t\t...(timeout === undefined ? {} : { timeout }),\n\t\t\t\t\tonOutput: (text) => api.output(text),\n\t\t\t\t\tspill: { afterBytes: DEFAULT_MAX_BYTES, afterLines: DEFAULT_MAX_LINES },\n\t\t\t\t},\n\t\t\t\tcontext,\n\t\t\t);\n\t\t\tconst spillPath = result.ok ? result.value.spillPath : result.error.spillPath;\n\t\t\tif (spillPath !== undefined) {\n\t\t\t\tapi.diagnostic({ severity: \"info\", code: \"full_output\", message: `Full output: ${spillPath}` });\n\t\t\t}\n\t\t\tif (!result.ok) {\n\t\t\t\tif (result.error.code === \"aborted\" && context.abortSignal?.aborted) throw result.error;\n\t\t\t\tif (result.error.code === \"timeout\") throw new Error(`Command timed out after ${timeout} seconds`);\n\t\t\t\tif (result.error.code === \"aborted\") throw new Error(\"Command aborted\");\n\t\t\t\tthrow result.error;\n\t\t\t}\n\t\t\tif (result.value.exitCode !== 0) throw new Error(`Command exited with code ${result.value.exitCode}`);\n\t\t\treturn {};\n\t\t},\n\t});\n}\n"]}
@@ -8,11 +8,11 @@ declare const editSchema: Type.TObject<{
8
8
  }>>;
9
9
  }>;
10
10
  export type EditToolInput = Static<typeof editSchema>;
11
- export interface EditToolDetails {
11
+ export type EditToolDetails = {
12
12
  diff: string;
13
13
  patch: string;
14
14
  firstChangedLine?: number;
15
- }
16
- export declare function createEditTool(): ToolRegistration;
15
+ };
16
+ export declare function createEditTool(): ToolRegistration<typeof editSchema, EditToolDetails>;
17
17
  export {};
18
18
  //# sourceMappingURL=edit.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../src/tools/edit.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAuB5D,QAAA,MAAM,UAAU;;;;;;EAMd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAsCtD,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AAaD,wBAAgB,cAAc,IAAI,gBAAgB,CAsDjD"}
1
+ {"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../src/tools/edit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAuB5D,QAAA,MAAM,UAAU;;;;;;EAMd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAsCtD,MAAM,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAaF,wBAAgB,cAAc,IAAI,gBAAgB,CAAC,OAAO,UAAU,EAAE,eAAe,CAAC,CAsDrF"}
@@ -1,4 +1,5 @@
1
1
  import { Type } from "typebox";
2
+ import { defineTool } from "../harness/define.js";
2
3
  import { applyEditsToNormalizedContent, detectLineEnding, generateDiffString, generateUnifiedPatch, normalizeToLF, restoreLineEndings, stripBom, } from "./edit-diff.js";
3
4
  import { requireEnv } from "./env.js";
4
5
  import { withFileMutationQueue } from "./file-mutation-queue.js";
@@ -46,7 +47,7 @@ function prepareEditArguments(input) {
46
47
  }
47
48
  const legacy = args;
48
49
  if (typeof legacy.oldText !== "string" || typeof legacy.newText !== "string")
49
- return args;
50
+ return legacy;
50
51
  const edits = Array.isArray(legacy.edits) ? [...legacy.edits] : [];
51
52
  edits.push({ oldText: legacy.oldText, newText: legacy.newText });
52
53
  const { oldText: _oldText, newText: _newText, ...rest } = legacy;
@@ -62,7 +63,7 @@ function editAccessError(path, error) {
62
63
  return new Error(`Could not edit file: ${path}. Error code: ${error.code}.`, { cause: error });
63
64
  }
64
65
  export function createEditTool() {
65
- return {
66
+ return defineTool({
66
67
  name: "edit",
67
68
  description: "Edit a single file using exact text replacement. Every edits[].oldText must match a unique, non-overlapping region of the original file. If two changes affect the same block or nearby lines, merge them into one edit instead of emitting overlapping edits. Do not include large unchanged regions just to connect distant changes.",
68
69
  parameters: editSchema,
@@ -107,10 +108,10 @@ export function createEditTool() {
107
108
  };
108
109
  return {
109
110
  content: [{ type: "text", text: `Successfully replaced ${edits.length} block(s) in ${path}.` }],
110
- details: details,
111
+ details,
111
112
  };
112
113
  }, context);
113
114
  },
114
- };
115
+ });
115
116
  }
116
117
  //# sourceMappingURL=edit.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"edit.js","sourceRoot":"","sources":["../../src/tools/edit.ts"],"names":[],"mappings":"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","sourcesContent":["import type { JsonValue } from \"@earendil-works/chord\";\nimport { type Static, Type } from \"typebox\";\nimport type { FileError } from \"../env/index.ts\";\nimport type { ToolRegistration } from \"../harness/types.ts\";\nimport {\n\tapplyEditsToNormalizedContent,\n\tdetectLineEnding,\n\ttype Edit,\n\tgenerateDiffString,\n\tgenerateUnifiedPatch,\n\tnormalizeToLF,\n\trestoreLineEndings,\n\tstripBom,\n} from \"./edit-diff.ts\";\nimport { requireEnv } from \"./env.ts\";\nimport { withFileMutationQueue } from \"./file-mutation-queue.ts\";\nimport { resolveToolPath } from \"./path-utils.ts\";\n\nconst replaceEditSchema = Type.Object({\n\toldText: Type.String({\n\t\tdescription:\n\t\t\t\"Exact text for one targeted replacement. It must be unique in the original file and must not overlap with any other edits[].oldText in the same call.\",\n\t}),\n\tnewText: Type.String({ description: \"Replacement text for this targeted edit.\" }),\n});\n\nconst editSchema = Type.Object({\n\tpath: Type.String({ description: \"Path to the file to edit (relative or absolute)\" }),\n\tedits: Type.Array(replaceEditSchema, {\n\t\tdescription:\n\t\t\t\"One or more targeted replacements. Each edit is matched against the original file, not incrementally. Do not include overlapping or nested edits. If two changes touch the same block or nearby lines, merge them into one edit instead.\",\n\t}),\n});\n\nexport type EditToolInput = Static<typeof editSchema>;\ntype LegacyEditToolInput = EditToolInput & { oldText?: unknown; newText?: unknown };\ntype SingleEditInput = { oldText: string; newText: string };\n\nfunction isSingleEditInput(value: unknown): value is SingleEditInput {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tconst edit = value as Record<string, unknown>;\n\treturn typeof edit.oldText === \"string\" && typeof edit.newText === \"string\";\n}\n\n/**\n * Repair shapes models commonly send: `edits` as a JSON string or as a single edit object, and a top-level\n * `oldText`/`newText` pair. Works on a copy; the call's arguments stay unchanged.\n */\nfunction prepareEditArguments(input: JsonValue): JsonValue {\n\tif (!input || typeof input !== \"object\" || Array.isArray(input)) return input;\n\tconst args: Record<string, unknown> = { ...input };\n\tif (typeof args.edits === \"string\") {\n\t\ttry {\n\t\t\tconst parsed: unknown = JSON.parse(args.edits);\n\t\t\tif (Array.isArray(parsed)) {\n\t\t\t\targs.edits = parsed;\n\t\t\t} else if (isSingleEditInput(parsed)) {\n\t\t\t\targs.edits = [parsed];\n\t\t\t}\n\t\t} catch {}\n\t} else if (isSingleEditInput(args.edits)) {\n\t\targs.edits = [args.edits];\n\t}\n\n\tconst legacy = args as LegacyEditToolInput;\n\tif (typeof legacy.oldText !== \"string\" || typeof legacy.newText !== \"string\") return args as JsonValue;\n\tconst edits = Array.isArray(legacy.edits) ? [...legacy.edits] : [];\n\tedits.push({ oldText: legacy.oldText, newText: legacy.newText });\n\tconst { oldText: _oldText, newText: _newText, ...rest } = legacy;\n\treturn { ...rest, edits } as JsonValue;\n}\n\nexport interface EditToolDetails {\n\tdiff: string;\n\tpatch: string;\n\tfirstChangedLine?: number;\n}\n\nfunction validateEditInput(input: EditToolInput): { path: string; edits: Edit[] } {\n\tif (!Array.isArray(input.edits) || input.edits.length === 0) {\n\t\tthrow new Error(\"Edit tool input is invalid. edits must contain at least one replacement.\");\n\t}\n\treturn { path: input.path, edits: input.edits };\n}\n\nfunction editAccessError(path: string, error: FileError): Error {\n\treturn new Error(`Could not edit file: ${path}. Error code: ${error.code}.`, { cause: error });\n}\n\nexport function createEditTool(): ToolRegistration {\n\treturn {\n\t\tname: \"edit\",\n\t\tdescription:\n\t\t\t\"Edit a single file using exact text replacement. Every edits[].oldText must match a unique, non-overlapping region of the original file. If two changes affect the same block or nearby lines, merge them into one edit instead of emitting overlapping edits. Do not include large unchanged regions just to connect distant changes.\",\n\t\tparameters: editSchema,\n\t\tprepareArguments: prepareEditArguments,\n\t\tasync execute(args, api, context) {\n\t\t\tconst { path, edits } = validateEditInput(args as EditToolInput);\n\t\t\tconst env = requireEnv(api);\n\t\t\tconst absolutePath = await resolveToolPath(env, path, context);\n\t\t\treturn withFileMutationQueue(\n\t\t\t\tenv,\n\t\t\t\tabsolutePath,\n\t\t\t\tasync () => {\n\t\t\t\t\tif (context.abortSignal?.aborted) throw new Error(\"Operation aborted\");\n\t\t\t\t\tconst info = await env.fileInfo(absolutePath, context);\n\t\t\t\t\tif (!info.ok) throw editAccessError(path, info.error);\n\t\t\t\t\tif (info.value.kind !== \"file\" && info.value.kind !== \"symlink\") {\n\t\t\t\t\t\tthrow new Error(`Could not edit file: ${path}. Path is not a file.`);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst readResult = await env.readTextFile(absolutePath, context);\n\t\t\t\t\tif (!readResult.ok) throw editAccessError(path, readResult.error);\n\t\t\t\t\tif (context.abortSignal?.aborted) throw new Error(\"Operation aborted\");\n\n\t\t\t\t\tconst { bom, text: content } = stripBom(readResult.value);\n\t\t\t\t\tconst originalEnding = detectLineEnding(content);\n\t\t\t\t\tconst normalizedContent = normalizeToLF(content);\n\t\t\t\t\tconst { baseContent, newContent } = applyEditsToNormalizedContent(normalizedContent, edits, path);\n\t\t\t\t\tif (context.abortSignal?.aborted) throw new Error(\"Operation aborted\");\n\n\t\t\t\t\tconst finalContent = bom + restoreLineEndings(newContent, originalEnding);\n\t\t\t\t\tconst writeResult = await env.writeFile(absolutePath, finalContent, context);\n\t\t\t\t\tif (!writeResult.ok) throw editAccessError(path, writeResult.error);\n\t\t\t\t\tif (context.abortSignal?.aborted) throw new Error(\"Operation aborted\");\n\n\t\t\t\t\tconst diffResult = generateDiffString(baseContent, newContent);\n\t\t\t\t\tconst details: EditToolDetails = {\n\t\t\t\t\t\tdiff: diffResult.diff,\n\t\t\t\t\t\tpatch: generateUnifiedPatch(path, baseContent, newContent),\n\t\t\t\t\t\t...(diffResult.firstChangedLine === undefined\n\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t: { firstChangedLine: diffResult.firstChangedLine }),\n\t\t\t\t\t};\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: `Successfully replaced ${edits.length} block(s) in ${path}.` }],\n\t\t\t\t\t\tdetails: details as unknown as JsonValue,\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t\tcontext,\n\t\t\t);\n\t\t},\n\t};\n}\n"]}
1
+ {"version":3,"file":"edit.js","sourceRoot":"","sources":["../../src/tools/edit.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Static, Type } from \"typebox\";\nimport type { FileError } from \"../env/index.ts\";\nimport { defineTool } from \"../harness/define.ts\";\nimport type { ToolRegistration } from \"../harness/types.ts\";\nimport {\n\tapplyEditsToNormalizedContent,\n\tdetectLineEnding,\n\ttype Edit,\n\tgenerateDiffString,\n\tgenerateUnifiedPatch,\n\tnormalizeToLF,\n\trestoreLineEndings,\n\tstripBom,\n} from \"./edit-diff.ts\";\nimport { requireEnv } from \"./env.ts\";\nimport { withFileMutationQueue } from \"./file-mutation-queue.ts\";\nimport { resolveToolPath } from \"./path-utils.ts\";\n\nconst replaceEditSchema = Type.Object({\n\toldText: Type.String({\n\t\tdescription:\n\t\t\t\"Exact text for one targeted replacement. It must be unique in the original file and must not overlap with any other edits[].oldText in the same call.\",\n\t}),\n\tnewText: Type.String({ description: \"Replacement text for this targeted edit.\" }),\n});\n\nconst editSchema = Type.Object({\n\tpath: Type.String({ description: \"Path to the file to edit (relative or absolute)\" }),\n\tedits: Type.Array(replaceEditSchema, {\n\t\tdescription:\n\t\t\t\"One or more targeted replacements. Each edit is matched against the original file, not incrementally. Do not include overlapping or nested edits. If two changes touch the same block or nearby lines, merge them into one edit instead.\",\n\t}),\n});\n\nexport type EditToolInput = Static<typeof editSchema>;\ntype LegacyEditToolInput = EditToolInput & { oldText?: unknown; newText?: unknown };\ntype SingleEditInput = { oldText: string; newText: string };\n\nfunction isSingleEditInput(value: unknown): value is SingleEditInput {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tconst edit = value as Record<string, unknown>;\n\treturn typeof edit.oldText === \"string\" && typeof edit.newText === \"string\";\n}\n\n/**\n * Repair shapes models commonly send: `edits` as a JSON string or as a single edit object, and a top-level\n * `oldText`/`newText` pair. Works on a copy; the call's arguments stay unchanged.\n */\nfunction prepareEditArguments(input: unknown): EditToolInput {\n\tif (!input || typeof input !== \"object\" || Array.isArray(input)) return input as EditToolInput;\n\tconst args: Record<string, unknown> = { ...input };\n\tif (typeof args.edits === \"string\") {\n\t\ttry {\n\t\t\tconst parsed: unknown = JSON.parse(args.edits);\n\t\t\tif (Array.isArray(parsed)) {\n\t\t\t\targs.edits = parsed;\n\t\t\t} else if (isSingleEditInput(parsed)) {\n\t\t\t\targs.edits = [parsed];\n\t\t\t}\n\t\t} catch {}\n\t} else if (isSingleEditInput(args.edits)) {\n\t\targs.edits = [args.edits];\n\t}\n\n\tconst legacy = args as LegacyEditToolInput;\n\tif (typeof legacy.oldText !== \"string\" || typeof legacy.newText !== \"string\") return legacy;\n\tconst edits = Array.isArray(legacy.edits) ? [...legacy.edits] : [];\n\tedits.push({ oldText: legacy.oldText, newText: legacy.newText });\n\tconst { oldText: _oldText, newText: _newText, ...rest } = legacy;\n\treturn { ...rest, edits };\n}\n\nexport type EditToolDetails = {\n\tdiff: string;\n\tpatch: string;\n\tfirstChangedLine?: number;\n};\n\nfunction validateEditInput(input: EditToolInput): { path: string; edits: Edit[] } {\n\tif (!Array.isArray(input.edits) || input.edits.length === 0) {\n\t\tthrow new Error(\"Edit tool input is invalid. edits must contain at least one replacement.\");\n\t}\n\treturn { path: input.path, edits: input.edits };\n}\n\nfunction editAccessError(path: string, error: FileError): Error {\n\treturn new Error(`Could not edit file: ${path}. Error code: ${error.code}.`, { cause: error });\n}\n\nexport function createEditTool(): ToolRegistration<typeof editSchema, EditToolDetails> {\n\treturn defineTool({\n\t\tname: \"edit\",\n\t\tdescription:\n\t\t\t\"Edit a single file using exact text replacement. Every edits[].oldText must match a unique, non-overlapping region of the original file. If two changes affect the same block or nearby lines, merge them into one edit instead of emitting overlapping edits. Do not include large unchanged regions just to connect distant changes.\",\n\t\tparameters: editSchema,\n\t\tprepareArguments: prepareEditArguments,\n\t\tasync execute(args, api, context) {\n\t\t\tconst { path, edits } = validateEditInput(args);\n\t\t\tconst env = requireEnv(api);\n\t\t\tconst absolutePath = await resolveToolPath(env, path, context);\n\t\t\treturn withFileMutationQueue(\n\t\t\t\tenv,\n\t\t\t\tabsolutePath,\n\t\t\t\tasync () => {\n\t\t\t\t\tif (context.abortSignal?.aborted) throw new Error(\"Operation aborted\");\n\t\t\t\t\tconst info = await env.fileInfo(absolutePath, context);\n\t\t\t\t\tif (!info.ok) throw editAccessError(path, info.error);\n\t\t\t\t\tif (info.value.kind !== \"file\" && info.value.kind !== \"symlink\") {\n\t\t\t\t\t\tthrow new Error(`Could not edit file: ${path}. Path is not a file.`);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst readResult = await env.readTextFile(absolutePath, context);\n\t\t\t\t\tif (!readResult.ok) throw editAccessError(path, readResult.error);\n\t\t\t\t\tif (context.abortSignal?.aborted) throw new Error(\"Operation aborted\");\n\n\t\t\t\t\tconst { bom, text: content } = stripBom(readResult.value);\n\t\t\t\t\tconst originalEnding = detectLineEnding(content);\n\t\t\t\t\tconst normalizedContent = normalizeToLF(content);\n\t\t\t\t\tconst { baseContent, newContent } = applyEditsToNormalizedContent(normalizedContent, edits, path);\n\t\t\t\t\tif (context.abortSignal?.aborted) throw new Error(\"Operation aborted\");\n\n\t\t\t\t\tconst finalContent = bom + restoreLineEndings(newContent, originalEnding);\n\t\t\t\t\tconst writeResult = await env.writeFile(absolutePath, finalContent, context);\n\t\t\t\t\tif (!writeResult.ok) throw editAccessError(path, writeResult.error);\n\t\t\t\t\tif (context.abortSignal?.aborted) throw new Error(\"Operation aborted\");\n\n\t\t\t\t\tconst diffResult = generateDiffString(baseContent, newContent);\n\t\t\t\t\tconst details: EditToolDetails = {\n\t\t\t\t\t\tdiff: diffResult.diff,\n\t\t\t\t\t\tpatch: generateUnifiedPatch(path, baseContent, newContent),\n\t\t\t\t\t\t...(diffResult.firstChangedLine === undefined\n\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t: { firstChangedLine: diffResult.firstChangedLine }),\n\t\t\t\t\t};\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: `Successfully replaced ${edits.length} block(s) in ${path}.` }],\n\t\t\t\t\t\tdetails,\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t\tcontext,\n\t\t\t);\n\t\t},\n\t});\n}\n"]}
@@ -1,5 +1,9 @@
1
1
  import type { Context } from "@earendil-works/chord";
2
2
  import { type ExecutionEnv } from "../env/index.ts";
3
- /** Serialize file mutations targeting the same environment and canonical path. */
3
+ /**
4
+ * Serialize `edit` and `write` mutations of one file within this process: same file system id and canonical path,
5
+ * whichever environment object the call got. Other files, and other file systems, never wait. Concurrent calls on one
6
+ * file run in the order their keys resolve. Not a lock against `bash` or other processes.
7
+ */
4
8
  export declare function withFileMutationQueue<T>(env: ExecutionEnv, path: string, fn: () => Promise<T>, context: Context): Promise<T>;
5
9
  //# sourceMappingURL=file-mutation-queue.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-mutation-queue.d.ts","sourceRoot":"","sources":["../../src/tools/file-mutation-queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,KAAK,YAAY,EAAc,MAAM,iBAAiB,CAAC;AA0BhE,kFAAkF;AAClF,wBAAsB,qBAAqB,CAAC,CAAC,EAC5C,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,CAAC,CAAC,CA2BZ"}
1
+ {"version":3,"file":"file-mutation-queue.d.ts","sourceRoot":"","sources":["../../src/tools/file-mutation-queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,KAAK,YAAY,EAAc,MAAM,iBAAiB,CAAC;AA0BhE;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,CAAC,EAC5C,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,CAAC,CAAC,CAiBZ"}
@@ -1,46 +1,52 @@
1
1
  import { getOrThrow } from "../env/index.js";
2
- const states = new WeakMap();
3
- function getState(env) {
4
- let state = states.get(env);
5
- if (!state) {
6
- state = { queues: new Map(), registration: Promise.resolve() };
7
- states.set(env, state);
8
- }
9
- return state;
10
- }
11
- async function getMutationQueueKey(env, path, context) {
2
+ /** Tail of the mutation chain of each file, keyed by file system id and canonical path. */
3
+ const queues = new Map();
4
+ async function mutationKey(env, path, context) {
12
5
  const absolutePath = getOrThrow(await env.absolutePath(path, context));
13
- const canonicalPath = await env.canonicalPath(absolutePath, context);
14
- if (canonicalPath.ok)
15
- return canonicalPath.value;
16
- if (canonicalPath.error.code === "not_found" || canonicalPath.error.code === "not_supported")
6
+ return `${env.id}\0${await canonical(env, absolutePath, context)}`;
7
+ }
8
+ /**
9
+ * The canonical path; for a file that does not exist yet, its canonical parent joined with its name, so a `write` that
10
+ * creates a file and a later mutation of it share one key even under a symlinked directory.
11
+ */
12
+ async function canonical(env, absolutePath, context) {
13
+ const result = await env.canonicalPath(absolutePath, context);
14
+ if (result.ok)
15
+ return result.value;
16
+ if (result.error.code === "not_supported")
17
+ return absolutePath;
18
+ if (result.error.code !== "not_found")
19
+ throw result.error;
20
+ // The file system splits the path, so a name may contain characters that are separators elsewhere.
21
+ const parent = getOrThrow(await env.joinPath([absolutePath, ".."], context));
22
+ if (parent === absolutePath || !absolutePath.startsWith(parent))
17
23
  return absolutePath;
18
- throw canonicalPath.error;
24
+ const name = absolutePath.slice(parent.length + (/[/\\]$/.test(parent) ? 0 : 1));
25
+ return getOrThrow(await env.joinPath([await canonical(env, parent, context), name], context));
19
26
  }
20
- /** Serialize file mutations targeting the same environment and canonical path. */
27
+ /**
28
+ * Serialize `edit` and `write` mutations of one file within this process: same file system id and canonical path,
29
+ * whichever environment object the call got. Other files, and other file systems, never wait. Concurrent calls on one
30
+ * file run in the order their keys resolve. Not a lock against `bash` or other processes.
31
+ */
21
32
  export async function withFileMutationQueue(env, path, fn, context) {
22
- const state = getState(env);
23
- const registration = state.registration.then(async () => {
24
- const key = await getMutationQueueKey(env, path, context);
25
- const currentQueue = state.queues.get(key) ?? Promise.resolve();
26
- let releaseNext = () => { };
27
- const nextQueue = new Promise((resolve) => {
28
- releaseNext = resolve;
29
- });
30
- const chainedQueue = currentQueue.then(() => nextQueue);
31
- state.queues.set(key, chainedQueue);
32
- return { key, currentQueue, chainedQueue, releaseNext };
33
+ const key = await mutationKey(env, path, context);
34
+ // Take the slot without awaiting, so no other call can take it in between.
35
+ const previous = queues.get(key) ?? Promise.resolve();
36
+ let release = () => { };
37
+ const done = new Promise((resolve) => {
38
+ release = resolve;
33
39
  });
34
- state.registration = registration.then(() => undefined, () => undefined);
35
- const { key, currentQueue, chainedQueue, releaseNext } = await registration;
36
- await currentQueue;
40
+ const tail = previous.then(() => done);
41
+ queues.set(key, tail);
42
+ await previous;
37
43
  try {
38
44
  return await fn();
39
45
  }
40
46
  finally {
41
- releaseNext();
42
- if (state.queues.get(key) === chainedQueue)
43
- state.queues.delete(key);
47
+ release();
48
+ if (queues.get(key) === tail)
49
+ queues.delete(key);
44
50
  }
45
51
  }
46
52
  //# sourceMappingURL=file-mutation-queue.js.map