@pasko70/pibo 1.9.11 → 1.9.13

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 (111) hide show
  1. package/README.md +183 -183
  2. package/context/codex-base-prompt.md +148 -148
  3. package/context/compute-worker.md +23 -23
  4. package/context/pibo-compaction-prompt.md +100 -100
  5. package/context/pibo-native-tooling.md +18 -18
  6. package/context/pibo-system-prompt.md +77 -77
  7. package/dist/apps/chat/agent-store.js +248 -248
  8. package/dist/apps/chat/data/project-service.js +168 -168
  9. package/dist/apps/chat/data/read-state-service.js +18 -18
  10. package/dist/apps/chat/data/session-query-service.js +25 -25
  11. package/dist/apps/chat/data/timeline-query-service.js +25 -14
  12. package/dist/apps/chat/static-assets.js +854 -854
  13. package/dist/apps/chat/trace.js +2 -0
  14. package/dist/apps/chat/web-app.js +7 -0
  15. package/dist/apps/chat/workflow-persistence.js +255 -255
  16. package/dist/apps/chat-ui/index.html +16 -16
  17. package/dist/apps/chat-ui/manifest.webmanifest +25 -25
  18. package/dist/apps/chat-ui/sw.js +47 -47
  19. package/dist/apps/chat-vscode-web/index.html +12 -12
  20. package/dist/apps/cli-ui/cliSessionsCommand.js +23 -23
  21. package/dist/apps/context-files-ui/index.html +11 -11
  22. package/dist/apps/vscode-artifacts/latest.vsix +0 -0
  23. package/dist/apps/vscode-artifacts/pibo-vscode-ext-1.9.13.vsix +0 -0
  24. package/dist/cli.js +39 -39
  25. package/dist/compute/cli.js +54 -54
  26. package/dist/cron/cli.js +15 -15
  27. package/dist/cron/store.js +49 -49
  28. package/dist/data/cli.js +23 -23
  29. package/dist/data/event-log.js +23 -23
  30. package/dist/data/ingest-service.js +7 -0
  31. package/dist/data/message-store.js +31 -20
  32. package/dist/data/navigation-store.js +9 -9
  33. package/dist/data/observation-store.js +4 -4
  34. package/dist/data/payload-store.js +17 -17
  35. package/dist/data/schema.js +433 -431
  36. package/dist/data/session-store.js +4 -4
  37. package/dist/data/telemetry-queries.js +54 -54
  38. package/dist/data/telemetry.js +197 -197
  39. package/dist/debug/events.js +12 -12
  40. package/dist/debug/failures.js +6 -6
  41. package/dist/debug/index.js +227 -227
  42. package/dist/debug/messages.js +6 -6
  43. package/dist/debug/pty.js +124 -124
  44. package/dist/debug/session.js +29 -29
  45. package/dist/debug/tools.js +5 -5
  46. package/dist/debug/web-snapshot-browser-scripts.js +294 -294
  47. package/dist/debug/web-streaming-browser-library.js +925 -925
  48. package/dist/debug/web-streaming-browser-scripts.js +232 -232
  49. package/dist/debug/web-streaming-provider-telemetry.js +4 -4
  50. package/dist/debug/web.js +93 -93
  51. package/dist/gateway/cli.js +19 -19
  52. package/dist/mcp/config-command.js +53 -53
  53. package/dist/mcp/index.js +21 -21
  54. package/dist/mcp/registry.js +11 -11
  55. package/dist/pi-packages/cli.js +11 -11
  56. package/dist/plugins/context-files-store.js +110 -110
  57. package/dist/plugins/context-files.js +4 -4
  58. package/dist/ralph/cli.js +18 -18
  59. package/dist/ralph/templates.js +140 -140
  60. package/dist/reliability/store.js +226 -226
  61. package/dist/resources/lifecycle.js +4 -6
  62. package/dist/resources/reaper-state.js +30 -3
  63. package/dist/resources/reaper.js +43 -15
  64. package/dist/sessions/pibo-data-store.js +16 -16
  65. package/dist/sessions/sqlite-store.js +53 -53
  66. package/dist/setup/cli.js +58 -58
  67. package/dist/shared/trace-engine.js +3 -2
  68. package/dist/shared/trace-event-projection.js +26 -0
  69. package/dist/tools/agent-browser-wrapper.js +80 -80
  70. package/dist/tools/browser-use-cdp.js +12 -12
  71. package/dist/tools/browser-use-wrapper.js +762 -762
  72. package/dist/tools/guides.js +538 -538
  73. package/dist/tools/index.js +99 -99
  74. package/dist/tools/runtime/node-worker-source.js +205 -205
  75. package/dist/tools/runtime/python-worker-source.js +177 -177
  76. package/dist/vscode/cli.js +9 -9
  77. package/dist/web-annotations/cdp.js +900 -900
  78. package/dist/web-annotations/store.js +96 -96
  79. package/docs/README.md +23 -23
  80. package/docs/ops/install-developer-host.md +112 -112
  81. package/docs/ops/install-user-host.md +96 -96
  82. package/docs/ops/upgrade-user-to-developer-host.md +69 -69
  83. package/docs/ops/vscode-extension-release.md +160 -160
  84. package/package.json +95 -95
  85. package/skills/builtin/graphify/SKILL.md +52 -52
  86. package/skills/builtin/pi-agent-harness/SKILL.md +319 -319
  87. package/skills/builtin/pi-agent-harness/agents/openai.yaml +4 -4
  88. package/skills/builtin/pibo-docker-system/SKILL.md +170 -170
  89. package/skills/builtin/pibo-spec-writing/SKILL.md +330 -330
  90. package/skills/builtin/prd/SKILL.md +143 -143
  91. package/skills/builtin/ralph-loop/SKILL.md +359 -359
  92. package/skills/builtin/ralph-prd-json/SKILL.md +123 -123
  93. package/skills/builtin/skill-creator/LICENSE.txt +201 -201
  94. package/skills/builtin/skill-creator/SKILL.md +513 -513
  95. package/skills/builtin/skill-creator/agents/analyzer.md +274 -274
  96. package/skills/builtin/skill-creator/agents/comparator.md +202 -202
  97. package/skills/builtin/skill-creator/agents/grader.md +223 -223
  98. package/skills/builtin/skill-creator/assets/eval_review.html +146 -146
  99. package/skills/builtin/skill-creator/eval-viewer/generate_review.py +471 -471
  100. package/skills/builtin/skill-creator/eval-viewer/viewer.html +1325 -1325
  101. package/skills/builtin/skill-creator/references/schemas.md +430 -430
  102. package/skills/builtin/skill-creator/scripts/aggregate_benchmark.py +401 -401
  103. package/skills/builtin/skill-creator/scripts/generate_report.py +326 -326
  104. package/skills/builtin/skill-creator/scripts/improve_description.py +247 -247
  105. package/skills/builtin/skill-creator/scripts/package_skill.py +136 -136
  106. package/skills/builtin/skill-creator/scripts/quick_validate.py +102 -102
  107. package/skills/builtin/skill-creator/scripts/run_eval.py +310 -310
  108. package/skills/builtin/skill-creator/scripts/run_loop.py +328 -328
  109. package/skills/builtin/skill-creator/scripts/utils.py +47 -47
  110. package/skills/builtin/web-annotations/SKILL.md +93 -93
  111. package/src/mcp/LICENSE.mcp-cli +21 -21
@@ -172,10 +172,10 @@ export class PiboCronStore {
172
172
  const result = [];
173
173
  this.db.exec("BEGIN IMMEDIATE");
174
174
  try {
175
- const rows = this.db.prepare(`
176
- SELECT * FROM pibo_cron_jobs
177
- WHERE enabled = 1
178
- ORDER BY updated_at ASC
175
+ const rows = this.db.prepare(`
176
+ SELECT * FROM pibo_cron_jobs
177
+ WHERE enabled = 1
178
+ ORDER BY updated_at ASC
179
179
  `).all();
180
180
  for (const row of rows) {
181
181
  if (result.length >= limit)
@@ -242,10 +242,10 @@ export class PiboCronStore {
242
242
  lastPiboSessionId: input.piboSessionId ?? job.state.lastPiboSessionId,
243
243
  consecutiveErrors: input.status === "error" ? (job.state.consecutiveErrors ?? 0) + 1 : 0,
244
244
  };
245
- this.db.prepare(`
246
- UPDATE pibo_cron_runs
247
- SET status = ?, pibo_session_id = ?, reason = ?, error = ?, completed_at = ?, updated_at = ?
248
- WHERE id = ?
245
+ this.db.prepare(`
246
+ UPDATE pibo_cron_runs
247
+ SET status = ?, pibo_session_id = ?, reason = ?, error = ?, completed_at = ?, updated_at = ?
248
+ WHERE id = ?
249
249
  `).run(input.status, input.piboSessionId ?? null, input.reason ?? null, input.error ?? null, timestamp, timestamp, input.runId);
250
250
  this.db.prepare(`UPDATE pibo_cron_jobs SET enabled = ?, state_json = ?, updated_at = ? WHERE id = ?`).run(enabled ? 1 : 0, JSON.stringify(state), timestamp, job.id);
251
251
  if (job.deleteAfterRun && job.schedule.kind === "at" && input.status === "ok") {
@@ -286,50 +286,50 @@ export class PiboCronStore {
286
286
  this.createFreshSchema();
287
287
  }
288
288
  createFreshSchema() {
289
- this.db.exec(`
290
- CREATE TABLE IF NOT EXISTS pibo_cron_jobs (
291
- id TEXT PRIMARY KEY,
292
- name TEXT NOT NULL,
293
- description TEXT,
294
- enabled INTEGER NOT NULL,
295
- target_json TEXT NOT NULL,
296
- profile TEXT NOT NULL,
297
- prompt TEXT NOT NULL,
298
- schedule_json TEXT NOT NULL,
299
- schedule_ui_json TEXT,
300
- delete_after_run INTEGER NOT NULL DEFAULT 0,
301
- state_json TEXT NOT NULL,
302
- created_at TEXT NOT NULL,
303
- updated_at TEXT NOT NULL
304
- );
305
- CREATE INDEX IF NOT EXISTS idx_pibo_cron_jobs_enabled ON pibo_cron_jobs(enabled, updated_at DESC);
306
-
307
- CREATE TABLE IF NOT EXISTS pibo_cron_runs (
308
- id TEXT PRIMARY KEY,
309
- job_id TEXT NOT NULL,
310
- pibo_session_id TEXT,
311
- status TEXT NOT NULL,
312
- reason TEXT,
313
- error TEXT,
314
- started_at TEXT,
315
- completed_at TEXT,
316
- created_at TEXT NOT NULL,
317
- updated_at TEXT NOT NULL
318
- );
319
- CREATE INDEX IF NOT EXISTS idx_pibo_cron_runs_job_created ON pibo_cron_runs(job_id, created_at DESC);
289
+ this.db.exec(`
290
+ CREATE TABLE IF NOT EXISTS pibo_cron_jobs (
291
+ id TEXT PRIMARY KEY,
292
+ name TEXT NOT NULL,
293
+ description TEXT,
294
+ enabled INTEGER NOT NULL,
295
+ target_json TEXT NOT NULL,
296
+ profile TEXT NOT NULL,
297
+ prompt TEXT NOT NULL,
298
+ schedule_json TEXT NOT NULL,
299
+ schedule_ui_json TEXT,
300
+ delete_after_run INTEGER NOT NULL DEFAULT 0,
301
+ state_json TEXT NOT NULL,
302
+ created_at TEXT NOT NULL,
303
+ updated_at TEXT NOT NULL
304
+ );
305
+ CREATE INDEX IF NOT EXISTS idx_pibo_cron_jobs_enabled ON pibo_cron_jobs(enabled, updated_at DESC);
306
+
307
+ CREATE TABLE IF NOT EXISTS pibo_cron_runs (
308
+ id TEXT PRIMARY KEY,
309
+ job_id TEXT NOT NULL,
310
+ pibo_session_id TEXT,
311
+ status TEXT NOT NULL,
312
+ reason TEXT,
313
+ error TEXT,
314
+ started_at TEXT,
315
+ completed_at TEXT,
316
+ created_at TEXT NOT NULL,
317
+ updated_at TEXT NOT NULL
318
+ );
319
+ CREATE INDEX IF NOT EXISTS idx_pibo_cron_runs_job_created ON pibo_cron_runs(job_id, created_at DESC);
320
320
  `);
321
321
  }
322
322
  insertJob(job) {
323
- this.db.prepare(`
324
- INSERT INTO pibo_cron_jobs (id, name, description, enabled, target_json, profile, prompt, schedule_json, schedule_ui_json, delete_after_run, state_json, created_at, updated_at)
325
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
323
+ this.db.prepare(`
324
+ INSERT INTO pibo_cron_jobs (id, name, description, enabled, target_json, profile, prompt, schedule_json, schedule_ui_json, delete_after_run, state_json, created_at, updated_at)
325
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
326
326
  `).run(job.id, job.name, job.description ?? null, job.enabled ? 1 : 0, targetJson(job.target), job.profile, job.prompt, JSON.stringify(job.schedule), job.scheduleUi ? JSON.stringify(job.scheduleUi) : null, job.deleteAfterRun ? 1 : 0, JSON.stringify(job.state), job.createdAt, job.updatedAt);
327
327
  }
328
328
  writeJob(job) {
329
- this.db.prepare(`
330
- UPDATE pibo_cron_jobs
331
- SET name = ?, description = ?, enabled = ?, target_json = ?, profile = ?, prompt = ?, schedule_json = ?, schedule_ui_json = ?, delete_after_run = ?, state_json = ?, updated_at = ?
332
- WHERE id = ?
329
+ this.db.prepare(`
330
+ UPDATE pibo_cron_jobs
331
+ SET name = ?, description = ?, enabled = ?, target_json = ?, profile = ?, prompt = ?, schedule_json = ?, schedule_ui_json = ?, delete_after_run = ?, state_json = ?, updated_at = ?
332
+ WHERE id = ?
333
333
  `).run(job.name, job.description ?? null, job.enabled ? 1 : 0, targetJson(job.target), job.profile, job.prompt, JSON.stringify(job.schedule), job.scheduleUi ? JSON.stringify(job.scheduleUi) : null, job.deleteAfterRun ? 1 : 0, JSON.stringify(job.state), job.updatedAt, job.id);
334
334
  }
335
335
  updateJobStateLocked(id, state, updatedAt) {
@@ -337,9 +337,9 @@ export class PiboCronStore {
337
337
  }
338
338
  createRunLocked(job, timestamp, status, reason) {
339
339
  const run = { id: `crun_${randomUUID()}`, jobId: job.id, status, reason, startedAt: timestamp, createdAt: timestamp, updatedAt: timestamp };
340
- this.db.prepare(`
341
- INSERT INTO pibo_cron_runs (id, job_id, pibo_session_id, status, reason, error, started_at, completed_at, created_at, updated_at)
342
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
340
+ this.db.prepare(`
341
+ INSERT INTO pibo_cron_runs (id, job_id, pibo_session_id, status, reason, error, started_at, completed_at, created_at, updated_at)
342
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
343
343
  `).run(run.id, run.jobId, null, run.status, run.reason ?? null, null, run.startedAt ?? null, null, run.createdAt, run.updatedAt);
344
344
  return run;
345
345
  }
package/dist/data/cli.js CHANGED
@@ -102,19 +102,19 @@ function migrateSessionsToV2(input) {
102
102
  "channel", "kind", "profile", "active_model_json", "workspace", "title", "status",
103
103
  "metadata_json", "created_at", "updated_at", "last_activity_at",
104
104
  ];
105
- target.db.prepare(`
106
- INSERT INTO sessions (${columns.join(", ")})
107
- VALUES (${columns.map(() => "?").join(", ")})
105
+ target.db.prepare(`
106
+ INSERT INTO sessions (${columns.join(", ")})
107
+ VALUES (${columns.map(() => "?").join(", ")})
108
108
  `).run(row.id, row.pi_session_id, typeof metadata.chatRoomId === "string" ? metadata.chatRoomId : null, rootSessionId, row.parent_id, row.origin_id, row.channel, row.kind, row.profile, row.active_model_json, row.workspace, row.title ?? "Untitled Session", "idle", JSON.stringify(metadata), row.created_at, row.updated_at, row.updated_at);
109
109
  report.inserted++;
110
110
  }
111
111
  else if (row.updated_at > existing.updated_at) {
112
- target.db.prepare(`
113
- UPDATE sessions SET
114
- pi_session_id = ?, root_session_id = ?, parent_id = ?, origin_id = ?,
115
- channel = ?, kind = ?, profile = ?, active_model_json = ?, workspace = ?, title = ?,
116
- metadata_json = ?, updated_at = ?, last_activity_at = MAX(last_activity_at, ?)
117
- WHERE id = ?
112
+ target.db.prepare(`
113
+ UPDATE sessions SET
114
+ pi_session_id = ?, root_session_id = ?, parent_id = ?, origin_id = ?,
115
+ channel = ?, kind = ?, profile = ?, active_model_json = ?, workspace = ?, title = ?,
116
+ metadata_json = ?, updated_at = ?, last_activity_at = MAX(last_activity_at, ?)
117
+ WHERE id = ?
118
118
  `).run(row.pi_session_id, rootSessionId, row.parent_id, row.origin_id, row.channel, row.kind, row.profile, row.active_model_json, row.workspace, row.title ?? "Untitled Session", JSON.stringify(metadata), row.updated_at, row.updated_at, row.id);
119
119
  report.updated++;
120
120
  }
@@ -166,19 +166,19 @@ function printInventory(stores) {
166
166
  }
167
167
  }
168
168
  function printDataHelp() {
169
- console.log(`pibo data - inspect and maintain Pibo data stores
170
-
171
- Commands:
172
- inventory Read-only row counts, sizes, WAL sizes, and integrity checks; legacy-* rows are archived stores
173
- migrate sessions-to-v2 Import an explicit legacy pibo-sessions.sqlite into pibo.sqlite idempotently
174
-
175
- Options:
176
- --json Print machine-readable JSON
177
- --root DIR Inspect a specific Pibo home directory instead of ~/.pibo
178
- --to FILE Target pibo.sqlite path for migration or repair
179
-
180
- Next:
181
- pibo data inventory --json
182
- pibo data migrate sessions-to-v2 --from /path/to/pibo-sessions.sqlite --json
169
+ console.log(`pibo data - inspect and maintain Pibo data stores
170
+
171
+ Commands:
172
+ inventory Read-only row counts, sizes, WAL sizes, and integrity checks; legacy-* rows are archived stores
173
+ migrate sessions-to-v2 Import an explicit legacy pibo-sessions.sqlite into pibo.sqlite idempotently
174
+
175
+ Options:
176
+ --json Print machine-readable JSON
177
+ --root DIR Inspect a specific Pibo home directory instead of ~/.pibo
178
+ --to FILE Target pibo.sqlite path for migration or repair
179
+
180
+ Next:
181
+ pibo data inventory --json
182
+ pibo data migrate sessions-to-v2 --from /path/to/pibo-sessions.sqlite --json
183
183
  `);
184
184
  }
@@ -12,29 +12,29 @@ export class PiboEventLogStore {
12
12
  }
13
13
  const createdAt = input.createdAt ?? new Date().toISOString();
14
14
  const eventId = input.eventId ?? `evt_${randomUUID()}`;
15
- const result = this.db.prepare(`
16
- INSERT OR IGNORE INTO event_log (
17
- session_id,
18
- session_sequence,
19
- room_id,
20
- topic,
21
- type,
22
- source,
23
- actor_type,
24
- actor_id,
25
- turn_id,
26
- event_id,
27
- tool_call_id,
28
- run_id,
29
- workflow_run_id,
30
- idempotency_key,
31
- retention_class,
32
- payload_ref,
33
- preview_text,
34
- attributes_json,
35
- created_at,
36
- indexed_at
37
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
15
+ const result = this.db.prepare(`
16
+ INSERT OR IGNORE INTO event_log (
17
+ session_id,
18
+ session_sequence,
19
+ room_id,
20
+ topic,
21
+ type,
22
+ source,
23
+ actor_type,
24
+ actor_id,
25
+ turn_id,
26
+ event_id,
27
+ tool_call_id,
28
+ run_id,
29
+ workflow_run_id,
30
+ idempotency_key,
31
+ retention_class,
32
+ payload_ref,
33
+ preview_text,
34
+ attributes_json,
35
+ created_at,
36
+ indexed_at
37
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
38
38
  `).run(input.sessionId ?? null, input.sessionSequence ?? null, input.roomId ?? null, input.topic, input.type, input.source, input.actorType ?? null, input.actorId ?? null, input.turnId ?? null, eventId, input.toolCallId ?? null, input.runId ?? null, input.workflowRunId ?? null, input.idempotencyKey ?? null, input.retentionClass, input.payloadRef ?? null, input.previewText ?? null, JSON.stringify(input.attributes ?? {}), createdAt, input.indexedAt ?? null);
39
39
  if (input.idempotencyKey) {
40
40
  const existing = this.findByIdempotencyKey(input.idempotencyKey);
@@ -120,6 +120,13 @@ export class ChatDataIngestService {
120
120
  indexedAt: now,
121
121
  });
122
122
  let messageId;
123
+ if (event.type === "message_finished" && event.eventId) {
124
+ this.store.messages.completeAssistantMessagesForTurn({
125
+ sessionId: input.session.id,
126
+ turnId: event.eventId,
127
+ completedAt: now,
128
+ });
129
+ }
123
130
  if (event.type === "assistant_message") {
124
131
  messageId = messageIdForOutputEvent(event);
125
132
  if (messageId && !this.store.messages.getMessage(messageId)) {
@@ -4,26 +4,26 @@ export class MessageStore {
4
4
  this.db = db;
5
5
  }
6
6
  insertMessage(input) {
7
- this.db.prepare(`
8
- INSERT INTO chat_messages (
9
- id,
10
- session_id,
11
- room_id,
12
- sequence,
13
- turn_id,
14
- role,
15
- actor_id,
16
- status,
17
- created_at,
18
- completed_at,
19
- content_preview,
20
- content_payload_ref,
21
- source_stream_id,
22
- input_tokens,
23
- output_tokens,
24
- cost_usd,
25
- attributes_json
26
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
7
+ this.db.prepare(`
8
+ INSERT INTO chat_messages (
9
+ id,
10
+ session_id,
11
+ room_id,
12
+ sequence,
13
+ turn_id,
14
+ role,
15
+ actor_id,
16
+ status,
17
+ created_at,
18
+ completed_at,
19
+ content_preview,
20
+ content_payload_ref,
21
+ source_stream_id,
22
+ input_tokens,
23
+ output_tokens,
24
+ cost_usd,
25
+ attributes_json
26
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
27
27
  `).run(input.id, input.sessionId, input.roomId ?? null, input.sequence, input.turnId ?? null, input.role, input.actorId ?? null, input.status, input.createdAt, input.completedAt ?? null, input.contentPreview ?? null, input.contentPayloadRef ?? null, input.sourceStreamId ?? null, input.inputTokens ?? null, input.outputTokens ?? null, input.costUsd ?? null, JSON.stringify(input.attributes ?? {}));
28
28
  const stored = this.getMessage(input.id);
29
29
  if (!stored)
@@ -38,6 +38,17 @@ export class MessageStore {
38
38
  const rows = this.db.prepare("SELECT * FROM chat_messages WHERE session_id = ? ORDER BY sequence ASC").all(sessionId);
39
39
  return rows.map(messageFromRow);
40
40
  }
41
+ completeAssistantMessagesForTurn(input) {
42
+ const result = this.db.prepare(`
43
+ UPDATE chat_messages
44
+ SET completed_at = ?,
45
+ status = ?
46
+ WHERE session_id = ?
47
+ AND turn_id = ?
48
+ AND role = 'assistant'
49
+ `).run(input.completedAt, input.status ?? "complete", input.sessionId, input.turnId);
50
+ return Number(result.changes ?? 0);
51
+ }
41
52
  }
42
53
  function messageFromRow(row) {
43
54
  return {
@@ -22,10 +22,10 @@ export class NavigationStore {
22
22
  "sort_key = excluded.sort_key",
23
23
  "updated_at = excluded.updated_at",
24
24
  ];
25
- this.db.prepare(`
26
- INSERT INTO session_navigation (${insertColumns.join(", ")})
27
- VALUES (${insertColumns.map(() => "?").join(", ")})
28
- ON CONFLICT(session_id) DO UPDATE SET ${assignments.join(", ")}
25
+ this.db.prepare(`
26
+ INSERT INTO session_navigation (${insertColumns.join(", ")})
27
+ VALUES (${insertColumns.map(() => "?").join(", ")})
28
+ ON CONFLICT(session_id) DO UPDATE SET ${assignments.join(", ")}
29
29
  `).run(input.roomId ?? null, input.sessionId, input.rootSessionId ?? null, input.parentId ?? null, input.originId ?? null, input.title, input.profile, input.status, input.archivedAt ?? null, input.lastActivityAt, input.lastMessagePreview ?? null, input.childCount ?? 0, input.sortKey, input.updatedAt);
30
30
  const stored = this.getSession(input.sessionId);
31
31
  if (!stored)
@@ -46,11 +46,11 @@ export class NavigationStore {
46
46
  if (!input.includeArchived)
47
47
  clauses.push("archived_at IS NULL");
48
48
  const limit = Math.max(1, Math.min(input.limit ?? 100, 1000));
49
- const rows = this.db.prepare(`
50
- SELECT * FROM session_navigation
51
- ${clauses.length ? `WHERE ${clauses.join(" AND ")}` : ""}
52
- ORDER BY sort_key DESC, updated_at DESC
53
- LIMIT ?
49
+ const rows = this.db.prepare(`
50
+ SELECT * FROM session_navigation
51
+ ${clauses.length ? `WHERE ${clauses.join(" AND ")}` : ""}
52
+ ORDER BY sort_key DESC, updated_at DESC
53
+ LIMIT ?
54
54
  `).all(...values, limit);
55
55
  return rows.map(sessionNavigationFromRow);
56
56
  }
@@ -8,10 +8,10 @@ export class ObservationStore {
8
8
  const sequence = input.sequence ?? this.nextSequence(input.sessionId);
9
9
  const startedAt = input.startedAt ?? new Date().toISOString();
10
10
  const id = input.id ?? `obs_${randomUUID()}`;
11
- this.db.prepare(`INSERT OR IGNORE INTO observations (
12
- id, session_id, sequence, trace_id, span_id, parent_span_id, parent_observation_id, turn_id, event_stream_id,
13
- kind, role, name, status, started_at, ended_at, latency_ms, model_provider, model_id, input_tokens, output_tokens,
14
- cost_usd, preview_text, payload_ref, attributes_json
11
+ this.db.prepare(`INSERT OR IGNORE INTO observations (
12
+ id, session_id, sequence, trace_id, span_id, parent_span_id, parent_observation_id, turn_id, event_stream_id,
13
+ kind, role, name, status, started_at, ended_at, latency_ms, model_provider, model_id, input_tokens, output_tokens,
14
+ cost_usd, preview_text, payload_ref, attributes_json
15
15
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, input.sessionId, sequence, input.traceId ?? null, input.spanId ?? null, input.parentSpanId ?? null, input.parentObservationId ?? null, input.turnId ?? null, input.eventStreamId ?? null, input.kind, input.role ?? null, input.name ?? null, input.status ?? "completed", startedAt, input.endedAt ?? null, input.latencyMs ?? null, input.modelProvider ?? null, input.modelId ?? null, input.inputTokens ?? null, input.outputTokens ?? null, input.costUsd ?? null, input.previewText ?? null, input.payloadRef ?? null, JSON.stringify(input.attributes ?? {}));
16
16
  return this.getObservation(id) ?? this.listObservations(input.sessionId).find((row) => row.sequence === sequence);
17
17
  }
@@ -31,23 +31,23 @@ export class PayloadStore {
31
31
  const absolutePath = this.rootDir === ":memory:" ? relativePath : join(this.rootDir, relativePath);
32
32
  writePayloadFile(absolutePath, bytesToStore);
33
33
  const id = input.id ?? `payload_${randomUUID()}`;
34
- this.db.prepare(`
35
- INSERT INTO payloads (
36
- id,
37
- sha256,
38
- storage_kind,
39
- storage_path,
40
- content_type,
41
- encoding,
42
- byte_size,
43
- compressed_byte_size,
44
- preview_text,
45
- retention_class,
46
- ref_count,
47
- status,
48
- created_at,
49
- last_verified_at
50
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
34
+ this.db.prepare(`
35
+ INSERT INTO payloads (
36
+ id,
37
+ sha256,
38
+ storage_kind,
39
+ storage_path,
40
+ content_type,
41
+ encoding,
42
+ byte_size,
43
+ compressed_byte_size,
44
+ preview_text,
45
+ retention_class,
46
+ ref_count,
47
+ status,
48
+ created_at,
49
+ last_verified_at
50
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
51
51
  `).run(id, sha256, "file", relativePath, contentType, encoding, bytes.byteLength, compressedByteSize, previewTextFromValue(input.value) ?? null, input.retentionClass, 1, "committed", createdAt, createdAt);
52
52
  const stored = this.getPayload(id);
53
53
  if (!stored)