@pasko70/pibo 1.9.13 → 1.10.1

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 (163) 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-profiles.js +2 -2
  8. package/dist/apps/chat/agent-store.js +263 -250
  9. package/dist/apps/chat/chat-request-normalizers.js +17 -0
  10. package/dist/apps/chat/data/chat-data-mappers.js +2 -0
  11. package/dist/apps/chat/data/project-service.js +168 -168
  12. package/dist/apps/chat/data/read-state-service.js +18 -18
  13. package/dist/apps/chat/data/session-query-service.js +25 -25
  14. package/dist/apps/chat/data/timeline-query-service.js +19 -19
  15. package/dist/apps/chat/loop-api.js +181 -0
  16. package/dist/apps/chat/static-assets.js +854 -854
  17. package/dist/apps/chat/web-app.js +36 -16
  18. package/dist/apps/chat/workflow-manual-trigger-runtime.js +149 -46
  19. package/dist/apps/chat/workflow-persistence.js +255 -255
  20. package/dist/apps/chat-ui/assets/{dist-BZ2eTC4f.js → dist-3Sts0Afa.js} +1 -1
  21. package/dist/apps/chat-ui/assets/{dist-BHa-kcGl.js → dist-4NlLjLs7.js} +1 -1
  22. package/dist/apps/chat-ui/assets/{dist-yCYNNb5d.js → dist-BA6mhAec.js} +1 -1
  23. package/dist/apps/chat-ui/assets/{dist-D811wJeV.js → dist-BPl-fzRB.js} +1 -1
  24. package/dist/apps/chat-ui/assets/{dist-Dq4GxJi3.js → dist-BPnn9e2B.js} +1 -1
  25. package/dist/apps/chat-ui/assets/{dist-CzE6k3F3.js → dist-BpfBSMzK.js} +1 -1
  26. package/dist/apps/chat-ui/assets/{dist-CnVsqwSG.js → dist-Cvx5M97R.js} +1 -1
  27. package/dist/apps/chat-ui/assets/{dist-WyXdYl-w.js → dist-DnXWNQRm.js} +1 -1
  28. package/dist/apps/chat-ui/assets/{dist-BNMu92bb.js → dist-hU-2oAb6.js} +1 -1
  29. package/dist/apps/chat-ui/assets/{dist-BCB6zezO.js → dist-r31x5Fcc.js} +1 -1
  30. package/dist/apps/chat-ui/assets/{dist-HqTN67dc.js → dist-uF6UXzI7.js} +1 -1
  31. package/dist/apps/chat-ui/assets/index-CaTGYBOS.js +173 -0
  32. package/dist/apps/chat-ui/assets/{index-C0x9nEcf.css → index-al8DeEjA.css} +1 -1
  33. package/dist/apps/chat-ui/index.html +18 -18
  34. package/dist/apps/chat-ui/manifest.webmanifest +25 -25
  35. package/dist/apps/chat-ui/sw.js +47 -47
  36. package/dist/apps/chat-vscode-web/assets/index-CK4SMZuu.js +41 -0
  37. package/dist/apps/chat-vscode-web/index.html +13 -13
  38. package/dist/apps/cli-ui/cliSessionsCommand.js +23 -23
  39. package/dist/apps/context-files-ui/index.html +11 -11
  40. package/dist/cli-session/localSessionSource.js +34 -12
  41. package/dist/cli.js +61 -44
  42. package/dist/compute/cli.js +54 -54
  43. package/dist/compute/resource-health.js +35 -2
  44. package/dist/core/events.js +6 -1
  45. package/dist/core/routed-session.js +97 -5
  46. package/dist/core/runtime.js +6 -1
  47. package/dist/core/session-router.js +27 -8
  48. package/dist/cron/cli.js +15 -15
  49. package/dist/cron/store.js +49 -49
  50. package/dist/data/cli.js +23 -23
  51. package/dist/data/event-log.js +23 -23
  52. package/dist/data/ingest-service.js +3 -1
  53. package/dist/data/message-store.js +27 -27
  54. package/dist/data/navigation-store.js +9 -9
  55. package/dist/data/observation-store.js +4 -4
  56. package/dist/data/payload-store.js +17 -17
  57. package/dist/data/schema.js +433 -433
  58. package/dist/data/session-store.js +4 -4
  59. package/dist/data/telemetry-queries.js +54 -54
  60. package/dist/data/telemetry.js +197 -197
  61. package/dist/debug/events.js +12 -12
  62. package/dist/debug/failures.js +6 -6
  63. package/dist/debug/index.js +231 -227
  64. package/dist/debug/messages.js +6 -6
  65. package/dist/debug/pty.js +124 -124
  66. package/dist/debug/session.js +29 -29
  67. package/dist/debug/tools.js +5 -5
  68. package/dist/debug/trace.js +42 -7
  69. package/dist/debug/web-snapshot-browser-scripts.js +294 -294
  70. package/dist/debug/web-streaming-browser-library.js +925 -925
  71. package/dist/debug/web-streaming-browser-scripts.js +232 -232
  72. package/dist/debug/web-streaming-provider-telemetry.js +4 -4
  73. package/dist/debug/web.js +93 -93
  74. package/dist/gateway/cli.js +19 -19
  75. package/dist/gateway/server.js +4 -2
  76. package/dist/gateway/web.js +2 -2
  77. package/dist/index.js +1 -0
  78. package/dist/loops/accounting.js +19 -0
  79. package/dist/loops/channel.js +8 -0
  80. package/dist/loops/cli.js +224 -0
  81. package/dist/loops/plugin.js +16 -0
  82. package/dist/loops/prompts.js +86 -0
  83. package/dist/loops/service.js +446 -0
  84. package/dist/loops/stopping.js +170 -0
  85. package/dist/loops/store.js +642 -0
  86. package/dist/loops/templates.js +232 -0
  87. package/dist/loops/tools.js +184 -0
  88. package/dist/loops/types.js +1 -0
  89. package/dist/mcp/config-command.js +53 -53
  90. package/dist/mcp/index.js +21 -21
  91. package/dist/mcp/registry.js +11 -11
  92. package/dist/pi-packages/cli.js +11 -11
  93. package/dist/plugins/builtin.js +8 -0
  94. package/dist/plugins/context-files-store.js +110 -110
  95. package/dist/plugins/context-files.js +4 -4
  96. package/dist/plugins/registry.js +23 -12
  97. package/dist/ralph/cli.js +18 -18
  98. package/dist/ralph/templates.js +140 -140
  99. package/dist/reliability/store.js +256 -229
  100. package/dist/runs/lifecycle.js +59 -0
  101. package/dist/runs/registry.js +47 -1
  102. package/dist/runs/tools.js +31 -13
  103. package/dist/session-ui/terminalRows.js +66 -2
  104. package/dist/sessions/pibo-data-store.js +16 -16
  105. package/dist/sessions/sqlite-store.js +53 -53
  106. package/dist/setup/cli.js +58 -58
  107. package/dist/shared/trace-async-agent-runs.js +4 -4
  108. package/dist/shared/trace-event-projection.js +59 -19
  109. package/dist/shared/trace-nodes.js +5 -0
  110. package/dist/shared/trace-page-merge.js +15 -0
  111. package/dist/shared/trace-run-notifications.js +3 -1
  112. package/dist/signals/projector.js +6 -2
  113. package/dist/tools/agent-browser-wrapper.js +80 -80
  114. package/dist/tools/browser-pool.js +50 -0
  115. package/dist/tools/browser-use-cdp.js +12 -12
  116. package/dist/tools/browser-use-leases.js +12 -8
  117. package/dist/tools/browser-use-wrapper.js +762 -762
  118. package/dist/tools/guides.js +596 -538
  119. package/dist/tools/index.js +123 -99
  120. package/dist/tools/registry.js +21 -3
  121. package/dist/tools/runtime/node-worker-source.js +205 -205
  122. package/dist/tools/runtime/python-worker-source.js +177 -177
  123. package/dist/vscode/cli.js +9 -9
  124. package/dist/web-annotations/cdp.js +900 -900
  125. package/dist/web-annotations/store.js +96 -96
  126. package/docs/README.md +23 -23
  127. package/docs/ops/install-developer-host.md +112 -112
  128. package/docs/ops/install-user-host.md +96 -96
  129. package/docs/ops/upgrade-user-to-developer-host.md +69 -69
  130. package/docs/ops/vscode-extension-release.md +160 -160
  131. package/package.json +99 -95
  132. package/skills/builtin/graphify/SKILL.md +52 -52
  133. package/skills/builtin/loop/SKILL.md +78 -0
  134. package/skills/builtin/pi-agent-harness/SKILL.md +319 -319
  135. package/skills/builtin/pi-agent-harness/agents/openai.yaml +4 -4
  136. package/skills/builtin/pibo-docker-system/SKILL.md +170 -170
  137. package/skills/builtin/pibo-spec-writing/SKILL.md +330 -330
  138. package/skills/builtin/prd/SKILL.md +143 -143
  139. package/skills/builtin/ralph-loop/SKILL.md +361 -359
  140. package/skills/builtin/ralph-prd-json/SKILL.md +123 -123
  141. package/skills/builtin/skill-creator/LICENSE.txt +201 -201
  142. package/skills/builtin/skill-creator/SKILL.md +513 -513
  143. package/skills/builtin/skill-creator/agents/analyzer.md +274 -274
  144. package/skills/builtin/skill-creator/agents/comparator.md +202 -202
  145. package/skills/builtin/skill-creator/agents/grader.md +223 -223
  146. package/skills/builtin/skill-creator/assets/eval_review.html +146 -146
  147. package/skills/builtin/skill-creator/eval-viewer/generate_review.py +471 -471
  148. package/skills/builtin/skill-creator/eval-viewer/viewer.html +1325 -1325
  149. package/skills/builtin/skill-creator/references/schemas.md +430 -430
  150. package/skills/builtin/skill-creator/scripts/aggregate_benchmark.py +401 -401
  151. package/skills/builtin/skill-creator/scripts/generate_report.py +326 -326
  152. package/skills/builtin/skill-creator/scripts/improve_description.py +247 -247
  153. package/skills/builtin/skill-creator/scripts/package_skill.py +136 -136
  154. package/skills/builtin/skill-creator/scripts/quick_validate.py +102 -102
  155. package/skills/builtin/skill-creator/scripts/run_eval.py +310 -310
  156. package/skills/builtin/skill-creator/scripts/run_loop.py +328 -328
  157. package/skills/builtin/skill-creator/scripts/utils.py +47 -47
  158. package/skills/builtin/web-annotations/SKILL.md +93 -93
  159. package/src/mcp/LICENSE.mcp-cli +21 -21
  160. package/dist/apps/chat-ui/assets/index-DwHJfmiF.js +0 -173
  161. package/dist/apps/chat-vscode-web/assets/index-BAMxIaI_.js +0 -41
  162. package/dist/apps/vscode-artifacts/latest.vsix +0 -0
  163. package/dist/apps/vscode-artifacts/pibo-vscode-ext-1.9.13.vsix +0 -0
@@ -26,8 +26,8 @@ export class ChatProjectService {
26
26
  const folder = resolve(input.projectFolder ?? piboHomePath("projects/workspace"));
27
27
  mkdirSync(folder, { recursive: true });
28
28
  const now = new Date().toISOString();
29
- const legacy = this.db.prepare(`SELECT * FROM projects
30
- WHERE project_folder = ?
29
+ const legacy = this.db.prepare(`SELECT * FROM projects
30
+ WHERE project_folder = ?
31
31
  AND (id LIKE 'personal_%' OR json_extract(metadata_json, '$.personal') IS 1 OR json_extract(metadata_json, '$.default') IS 1)`)
32
32
  .get(folder);
33
33
  if (legacy) {
@@ -49,7 +49,7 @@ export class ChatProjectService {
49
49
  }
50
50
  return this.requireProject(id);
51
51
  }
52
- this.db.prepare(`INSERT INTO projects (id, name, description, project_folder, configuration_status, metadata_json, created_at, updated_at)
52
+ this.db.prepare(`INSERT INTO projects (id, name, description, project_folder, configuration_status, metadata_json, created_at, updated_at)
53
53
  VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(id, "Project Manager", null, folder, "configured", JSON.stringify({ default: true }), now, now);
54
54
  return this.requireProject(id);
55
55
  }
@@ -75,7 +75,7 @@ export class ChatProjectService {
75
75
  this.ensureProjectFolderUsable(projectFolder);
76
76
  const now = new Date().toISOString();
77
77
  const id = `prj_${randomUUID()}`;
78
- this.db.prepare(`INSERT INTO projects (id, name, description, project_folder, configuration_status, metadata_json, created_at, updated_at)
78
+ this.db.prepare(`INSERT INTO projects (id, name, description, project_folder, configuration_status, metadata_json, created_at, updated_at)
79
79
  VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(id, name, normalizeOptionalString(input.description) ?? null, projectFolder, "configured", "{}", now, now);
80
80
  return this.requireProject(id);
81
81
  }
@@ -133,8 +133,8 @@ export class ChatProjectService {
133
133
  configuration,
134
134
  });
135
135
  }
136
- this.db.prepare(`INSERT INTO project_sessions (project_id, pibo_session_id, kind, workflow_id, workflow_version, workflow_run_id, parent_main_session_id, title, state, configuration_json, archived, created_at, updated_at)
137
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, ?, ?)
136
+ this.db.prepare(`INSERT INTO project_sessions (project_id, pibo_session_id, kind, workflow_id, workflow_version, workflow_run_id, parent_main_session_id, title, state, configuration_json, archived, created_at, updated_at)
137
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, ?, ?)
138
138
  ON CONFLICT(pibo_session_id) DO UPDATE SET project_id = excluded.project_id, kind = excluded.kind, workflow_id = excluded.workflow_id, workflow_version = excluded.workflow_version, workflow_run_id = excluded.workflow_run_id, parent_main_session_id = excluded.parent_main_session_id, title = excluded.title, state = excluded.state, configuration_json = excluded.configuration_json, updated_at = excluded.updated_at`)
139
139
  .run(input.projectId, input.piboSessionId, kind, workflowId, workflowVersion ?? null, workflowRunId ?? null, parentMainSessionId ?? null, title ?? null, state, serializeProjectSessionConfiguration(configuration), now, now);
140
140
  if (kind === "main") {
@@ -166,7 +166,7 @@ export class ChatProjectService {
166
166
  const existingForSession = this.getWorkflowSessionSnapshotForSession(snapshot.piboSessionId);
167
167
  if (existingForSession)
168
168
  throw new Error(`Project workflow session '${snapshot.piboSessionId}' already has a configuration snapshot`);
169
- this.db.prepare(`INSERT INTO project_workflow_session_snapshots (id, schema_version, project_id, pibo_session_id, workflow_id, workflow_version, base_definition_hash, effective_definition_hash, snapshot_json, created_at)
169
+ this.db.prepare(`INSERT INTO project_workflow_session_snapshots (id, schema_version, project_id, pibo_session_id, workflow_id, workflow_version, base_definition_hash, effective_definition_hash, snapshot_json, created_at)
170
170
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(snapshot.id, snapshot.schemaVersion, snapshot.projectId, snapshot.piboSessionId, snapshot.workflow.id, snapshot.workflow.version, snapshot.workflow.baseDefinitionHash, snapshot.workflow.effectiveDefinitionHash, JSON.stringify(snapshot), snapshot.createdAt);
171
171
  return this.getWorkflowSessionSnapshot(snapshot.id);
172
172
  }
@@ -203,36 +203,36 @@ export class ChatProjectService {
203
203
  return rows.map(projectWorkflowRunFromRow);
204
204
  }
205
205
  saveProjectWorkflowWaitToken(token) {
206
- this.db.prepare(`INSERT INTO project_workflow_wait_tokens (
207
- id,
208
- project_id,
209
- pibo_session_id,
210
- workflow_run_id,
211
- node_attempt_id,
212
- human_node_id,
213
- actions_json,
214
- prompt,
215
- schema_json,
216
- status,
217
- resume_payload_json,
218
- resume_payload_present,
219
- expires_at,
220
- created_at,
221
- resolved_at
222
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
223
- ON CONFLICT(id) DO UPDATE SET
224
- project_id = excluded.project_id,
225
- pibo_session_id = excluded.pibo_session_id,
226
- workflow_run_id = excluded.workflow_run_id,
227
- node_attempt_id = excluded.node_attempt_id,
228
- human_node_id = excluded.human_node_id,
229
- actions_json = excluded.actions_json,
230
- prompt = excluded.prompt,
231
- schema_json = excluded.schema_json,
232
- status = excluded.status,
233
- resume_payload_json = excluded.resume_payload_json,
234
- resume_payload_present = excluded.resume_payload_present,
235
- expires_at = excluded.expires_at,
206
+ this.db.prepare(`INSERT INTO project_workflow_wait_tokens (
207
+ id,
208
+ project_id,
209
+ pibo_session_id,
210
+ workflow_run_id,
211
+ node_attempt_id,
212
+ human_node_id,
213
+ actions_json,
214
+ prompt,
215
+ schema_json,
216
+ status,
217
+ resume_payload_json,
218
+ resume_payload_present,
219
+ expires_at,
220
+ created_at,
221
+ resolved_at
222
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
223
+ ON CONFLICT(id) DO UPDATE SET
224
+ project_id = excluded.project_id,
225
+ pibo_session_id = excluded.pibo_session_id,
226
+ workflow_run_id = excluded.workflow_run_id,
227
+ node_attempt_id = excluded.node_attempt_id,
228
+ human_node_id = excluded.human_node_id,
229
+ actions_json = excluded.actions_json,
230
+ prompt = excluded.prompt,
231
+ schema_json = excluded.schema_json,
232
+ status = excluded.status,
233
+ resume_payload_json = excluded.resume_payload_json,
234
+ resume_payload_present = excluded.resume_payload_present,
235
+ expires_at = excluded.expires_at,
236
236
  resolved_at = excluded.resolved_at`).run(token.id, token.projectId, token.piboSessionId, token.workflowRunId, token.nodeAttemptId ?? null, token.humanNodeId ?? null, JSON.stringify(token.actions), token.prompt, token.schema ? JSON.stringify(token.schema) : null, token.status, token.resumePayload === undefined ? null : JSON.stringify(token.resumePayload), token.resumePayload === undefined ? 0 : 1, token.expiresAt ?? null, token.createdAt, token.resolvedAt ?? null);
237
237
  if (token.status === "pending") {
238
238
  const now = new Date().toISOString();
@@ -331,18 +331,18 @@ export class ChatProjectService {
331
331
  ...(input.payload !== undefined ? { payload: input.payload } : {}),
332
332
  createdAt: actedAt,
333
333
  };
334
- this.db.prepare(`INSERT INTO project_workflow_human_actions (
335
- id,
336
- project_id,
337
- pibo_session_id,
338
- workflow_run_id,
339
- wait_token_id,
340
- action_id,
341
- kind,
342
- actor_json,
343
- payload_json,
344
- payload_present,
345
- created_at
334
+ this.db.prepare(`INSERT INTO project_workflow_human_actions (
335
+ id,
336
+ project_id,
337
+ pibo_session_id,
338
+ workflow_run_id,
339
+ wait_token_id,
340
+ action_id,
341
+ kind,
342
+ actor_json,
343
+ payload_json,
344
+ payload_present,
345
+ created_at
346
346
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
347
347
  .run(action.id, action.projectId, action.piboSessionId, action.workflowRunId, action.waitTokenId, action.actionId ?? null, action.kind, action.actor ? JSON.stringify(action.actor) : null, action.payload === undefined ? null : JSON.stringify(action.payload), action.payload === undefined ? 0 : 1, action.createdAt);
348
348
  this.db.prepare("UPDATE project_workflow_wait_tokens SET status = ?, resume_payload_json = ?, resume_payload_present = ?, resolved_at = ? WHERE id = ?")
@@ -451,128 +451,128 @@ export class ChatProjectService {
451
451
  return run;
452
452
  }
453
453
  insertProjectWorkflowRun(run) {
454
- this.db.prepare(`INSERT INTO project_workflow_runs (
455
- id,
456
- project_id,
457
- pibo_session_id,
458
- workflow_id,
459
- workflow_version,
460
- snapshot_id,
461
- effective_definition_hash,
462
- status,
463
- current_json,
464
- input_json,
465
- validation_json,
466
- created_at,
467
- updated_at,
468
- completed_at,
469
- failed_at,
470
- cancelled_at
454
+ this.db.prepare(`INSERT INTO project_workflow_runs (
455
+ id,
456
+ project_id,
457
+ pibo_session_id,
458
+ workflow_id,
459
+ workflow_version,
460
+ snapshot_id,
461
+ effective_definition_hash,
462
+ status,
463
+ current_json,
464
+ input_json,
465
+ validation_json,
466
+ created_at,
467
+ updated_at,
468
+ completed_at,
469
+ failed_at,
470
+ cancelled_at
471
471
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(run.id, run.projectId, run.piboSessionId, run.workflowId, run.workflowVersion, run.snapshotId, run.effectiveDefinitionHash, run.status, JSON.stringify(run.current), JSON.stringify(run.inputValues), run.validation ? JSON.stringify(run.validation) : null, run.createdAt, run.updatedAt, run.completedAt ?? null, run.failedAt ?? null, run.cancelledAt ?? null);
472
472
  }
473
473
  applySchema() {
474
- this.db.exec(`
475
- CREATE TABLE IF NOT EXISTS projects (
476
- id TEXT PRIMARY KEY,
477
- name TEXT NOT NULL,
478
- description TEXT,
479
- project_folder TEXT NOT NULL,
480
- configuration_status TEXT NOT NULL DEFAULT 'configured',
481
- current_main_session_id TEXT,
482
- archived_at TEXT,
483
- metadata_json TEXT NOT NULL DEFAULT '{}',
484
- created_at TEXT NOT NULL,
485
- updated_at TEXT NOT NULL
486
- );
487
- CREATE UNIQUE INDEX IF NOT EXISTS projects_name_unique ON projects (lower(name));
488
- CREATE UNIQUE INDEX IF NOT EXISTS projects_folder_unique ON projects (project_folder);
489
- CREATE TABLE IF NOT EXISTS project_sessions (
490
- project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
491
- pibo_session_id TEXT PRIMARY KEY,
492
- kind TEXT NOT NULL DEFAULT 'main',
493
- workflow_id TEXT NOT NULL DEFAULT 'simple-chat',
494
- workflow_version TEXT,
495
- workflow_run_id TEXT,
496
- parent_main_session_id TEXT,
497
- title TEXT,
498
- state TEXT,
499
- configuration_json TEXT,
500
- retry_count INTEGER,
501
- max_retries INTEGER,
502
- archived INTEGER NOT NULL DEFAULT 0,
503
- created_at TEXT NOT NULL,
504
- updated_at TEXT NOT NULL
505
- );
506
- CREATE INDEX IF NOT EXISTS project_sessions_project_id_idx ON project_sessions(project_id, archived, created_at);
507
- CREATE TABLE IF NOT EXISTS project_workflow_session_snapshots (
508
- id TEXT PRIMARY KEY,
509
- schema_version INTEGER NOT NULL,
510
- project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
511
- pibo_session_id TEXT NOT NULL REFERENCES project_sessions(pibo_session_id) ON DELETE CASCADE,
512
- workflow_id TEXT NOT NULL,
513
- workflow_version TEXT NOT NULL,
514
- base_definition_hash TEXT NOT NULL,
515
- effective_definition_hash TEXT NOT NULL,
516
- snapshot_json TEXT NOT NULL,
517
- created_at TEXT NOT NULL,
518
- UNIQUE(pibo_session_id)
519
- );
520
- CREATE INDEX IF NOT EXISTS project_workflow_session_snapshots_project_idx ON project_workflow_session_snapshots(project_id, created_at);
521
- CREATE TABLE IF NOT EXISTS project_workflow_runs (
522
- id TEXT PRIMARY KEY,
523
- project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
524
- pibo_session_id TEXT NOT NULL REFERENCES project_sessions(pibo_session_id) ON DELETE CASCADE,
525
- workflow_id TEXT NOT NULL,
526
- workflow_version TEXT NOT NULL,
527
- snapshot_id TEXT NOT NULL REFERENCES project_workflow_session_snapshots(id) ON DELETE RESTRICT,
528
- effective_definition_hash TEXT NOT NULL,
529
- status TEXT NOT NULL,
530
- current_json TEXT NOT NULL,
531
- input_json TEXT NOT NULL,
532
- validation_json TEXT,
533
- created_at TEXT NOT NULL,
534
- updated_at TEXT NOT NULL,
535
- completed_at TEXT,
536
- failed_at TEXT,
537
- cancelled_at TEXT,
538
- UNIQUE(pibo_session_id)
539
- );
540
- CREATE INDEX IF NOT EXISTS project_workflow_runs_project_idx ON project_workflow_runs(project_id, created_at);
541
- CREATE INDEX IF NOT EXISTS project_workflow_runs_session_idx ON project_workflow_runs(pibo_session_id);
542
- CREATE TABLE IF NOT EXISTS project_workflow_wait_tokens (
543
- id TEXT PRIMARY KEY,
544
- project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
545
- pibo_session_id TEXT NOT NULL REFERENCES project_sessions(pibo_session_id) ON DELETE CASCADE,
546
- workflow_run_id TEXT NOT NULL REFERENCES project_workflow_runs(id) ON DELETE CASCADE,
547
- node_attempt_id TEXT,
548
- human_node_id TEXT,
549
- actions_json TEXT NOT NULL,
550
- prompt TEXT NOT NULL,
551
- schema_json TEXT,
552
- status TEXT NOT NULL,
553
- resume_payload_json TEXT,
554
- resume_payload_present INTEGER NOT NULL DEFAULT 0,
555
- expires_at TEXT,
556
- created_at TEXT NOT NULL,
557
- resolved_at TEXT
558
- );
559
- CREATE INDEX IF NOT EXISTS project_workflow_wait_tokens_run_idx ON project_workflow_wait_tokens(workflow_run_id, status, created_at);
560
- CREATE INDEX IF NOT EXISTS project_workflow_wait_tokens_session_idx ON project_workflow_wait_tokens(project_id, pibo_session_id, status, created_at);
561
- CREATE TABLE IF NOT EXISTS project_workflow_human_actions (
562
- id TEXT PRIMARY KEY,
563
- project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
564
- pibo_session_id TEXT NOT NULL REFERENCES project_sessions(pibo_session_id) ON DELETE CASCADE,
565
- workflow_run_id TEXT NOT NULL REFERENCES project_workflow_runs(id) ON DELETE CASCADE,
566
- wait_token_id TEXT NOT NULL REFERENCES project_workflow_wait_tokens(id) ON DELETE CASCADE,
567
- action_id TEXT,
568
- kind TEXT NOT NULL,
569
- actor_json TEXT,
570
- payload_json TEXT,
571
- payload_present INTEGER NOT NULL DEFAULT 0,
572
- created_at TEXT NOT NULL
573
- );
574
- CREATE INDEX IF NOT EXISTS project_workflow_human_actions_run_idx ON project_workflow_human_actions(workflow_run_id, created_at);
575
- CREATE INDEX IF NOT EXISTS project_workflow_human_actions_wait_token_idx ON project_workflow_human_actions(wait_token_id, created_at);
474
+ this.db.exec(`
475
+ CREATE TABLE IF NOT EXISTS projects (
476
+ id TEXT PRIMARY KEY,
477
+ name TEXT NOT NULL,
478
+ description TEXT,
479
+ project_folder TEXT NOT NULL,
480
+ configuration_status TEXT NOT NULL DEFAULT 'configured',
481
+ current_main_session_id TEXT,
482
+ archived_at TEXT,
483
+ metadata_json TEXT NOT NULL DEFAULT '{}',
484
+ created_at TEXT NOT NULL,
485
+ updated_at TEXT NOT NULL
486
+ );
487
+ CREATE UNIQUE INDEX IF NOT EXISTS projects_name_unique ON projects (lower(name));
488
+ CREATE UNIQUE INDEX IF NOT EXISTS projects_folder_unique ON projects (project_folder);
489
+ CREATE TABLE IF NOT EXISTS project_sessions (
490
+ project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
491
+ pibo_session_id TEXT PRIMARY KEY,
492
+ kind TEXT NOT NULL DEFAULT 'main',
493
+ workflow_id TEXT NOT NULL DEFAULT 'simple-chat',
494
+ workflow_version TEXT,
495
+ workflow_run_id TEXT,
496
+ parent_main_session_id TEXT,
497
+ title TEXT,
498
+ state TEXT,
499
+ configuration_json TEXT,
500
+ retry_count INTEGER,
501
+ max_retries INTEGER,
502
+ archived INTEGER NOT NULL DEFAULT 0,
503
+ created_at TEXT NOT NULL,
504
+ updated_at TEXT NOT NULL
505
+ );
506
+ CREATE INDEX IF NOT EXISTS project_sessions_project_id_idx ON project_sessions(project_id, archived, created_at);
507
+ CREATE TABLE IF NOT EXISTS project_workflow_session_snapshots (
508
+ id TEXT PRIMARY KEY,
509
+ schema_version INTEGER NOT NULL,
510
+ project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
511
+ pibo_session_id TEXT NOT NULL REFERENCES project_sessions(pibo_session_id) ON DELETE CASCADE,
512
+ workflow_id TEXT NOT NULL,
513
+ workflow_version TEXT NOT NULL,
514
+ base_definition_hash TEXT NOT NULL,
515
+ effective_definition_hash TEXT NOT NULL,
516
+ snapshot_json TEXT NOT NULL,
517
+ created_at TEXT NOT NULL,
518
+ UNIQUE(pibo_session_id)
519
+ );
520
+ CREATE INDEX IF NOT EXISTS project_workflow_session_snapshots_project_idx ON project_workflow_session_snapshots(project_id, created_at);
521
+ CREATE TABLE IF NOT EXISTS project_workflow_runs (
522
+ id TEXT PRIMARY KEY,
523
+ project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
524
+ pibo_session_id TEXT NOT NULL REFERENCES project_sessions(pibo_session_id) ON DELETE CASCADE,
525
+ workflow_id TEXT NOT NULL,
526
+ workflow_version TEXT NOT NULL,
527
+ snapshot_id TEXT NOT NULL REFERENCES project_workflow_session_snapshots(id) ON DELETE RESTRICT,
528
+ effective_definition_hash TEXT NOT NULL,
529
+ status TEXT NOT NULL,
530
+ current_json TEXT NOT NULL,
531
+ input_json TEXT NOT NULL,
532
+ validation_json TEXT,
533
+ created_at TEXT NOT NULL,
534
+ updated_at TEXT NOT NULL,
535
+ completed_at TEXT,
536
+ failed_at TEXT,
537
+ cancelled_at TEXT,
538
+ UNIQUE(pibo_session_id)
539
+ );
540
+ CREATE INDEX IF NOT EXISTS project_workflow_runs_project_idx ON project_workflow_runs(project_id, created_at);
541
+ CREATE INDEX IF NOT EXISTS project_workflow_runs_session_idx ON project_workflow_runs(pibo_session_id);
542
+ CREATE TABLE IF NOT EXISTS project_workflow_wait_tokens (
543
+ id TEXT PRIMARY KEY,
544
+ project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
545
+ pibo_session_id TEXT NOT NULL REFERENCES project_sessions(pibo_session_id) ON DELETE CASCADE,
546
+ workflow_run_id TEXT NOT NULL REFERENCES project_workflow_runs(id) ON DELETE CASCADE,
547
+ node_attempt_id TEXT,
548
+ human_node_id TEXT,
549
+ actions_json TEXT NOT NULL,
550
+ prompt TEXT NOT NULL,
551
+ schema_json TEXT,
552
+ status TEXT NOT NULL,
553
+ resume_payload_json TEXT,
554
+ resume_payload_present INTEGER NOT NULL DEFAULT 0,
555
+ expires_at TEXT,
556
+ created_at TEXT NOT NULL,
557
+ resolved_at TEXT
558
+ );
559
+ CREATE INDEX IF NOT EXISTS project_workflow_wait_tokens_run_idx ON project_workflow_wait_tokens(workflow_run_id, status, created_at);
560
+ CREATE INDEX IF NOT EXISTS project_workflow_wait_tokens_session_idx ON project_workflow_wait_tokens(project_id, pibo_session_id, status, created_at);
561
+ CREATE TABLE IF NOT EXISTS project_workflow_human_actions (
562
+ id TEXT PRIMARY KEY,
563
+ project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
564
+ pibo_session_id TEXT NOT NULL REFERENCES project_sessions(pibo_session_id) ON DELETE CASCADE,
565
+ workflow_run_id TEXT NOT NULL REFERENCES project_workflow_runs(id) ON DELETE CASCADE,
566
+ wait_token_id TEXT NOT NULL REFERENCES project_workflow_wait_tokens(id) ON DELETE CASCADE,
567
+ action_id TEXT,
568
+ kind TEXT NOT NULL,
569
+ actor_json TEXT,
570
+ payload_json TEXT,
571
+ payload_present INTEGER NOT NULL DEFAULT 0,
572
+ created_at TEXT NOT NULL
573
+ );
574
+ CREATE INDEX IF NOT EXISTS project_workflow_human_actions_run_idx ON project_workflow_human_actions(workflow_run_id, created_at);
575
+ CREATE INDEX IF NOT EXISTS project_workflow_human_actions_wait_token_idx ON project_workflow_human_actions(wait_token_id, created_at);
576
576
  `);
577
577
  this.ensureProjectSessionWorkflowVersionColumn();
578
578
  this.ensureProjectSessionConfigurationColumn();
@@ -5,13 +5,13 @@ export class ChatReadStateService {
5
5
  }
6
6
  markSessionRead(piboSessionId, lastReadStreamId) {
7
7
  const now = new Date().toISOString();
8
- this.store.db.prepare(`
9
- INSERT INTO app_session_read_state (session_id, last_read_stream_id, last_read_at, updated_at)
10
- VALUES (?, ?, ?, ?)
11
- ON CONFLICT(session_id) DO UPDATE SET
12
- last_read_stream_id = MAX(app_session_read_state.last_read_stream_id, excluded.last_read_stream_id),
13
- last_read_at = excluded.last_read_at,
14
- updated_at = excluded.updated_at
8
+ this.store.db.prepare(`
9
+ INSERT INTO app_session_read_state (session_id, last_read_stream_id, last_read_at, updated_at)
10
+ VALUES (?, ?, ?, ?)
11
+ ON CONFLICT(session_id) DO UPDATE SET
12
+ last_read_stream_id = MAX(app_session_read_state.last_read_stream_id, excluded.last_read_stream_id),
13
+ last_read_at = excluded.last_read_at,
14
+ updated_at = excluded.updated_at
15
15
  `).run(piboSessionId, lastReadStreamId, now, now);
16
16
  }
17
17
  countUnreadMessagesBySession(input) {
@@ -21,17 +21,17 @@ export class ChatReadStateService {
21
21
  for (let offset = 0; offset < input.piboSessionIds.length; offset += 400) {
22
22
  const ids = [...new Set(input.piboSessionIds)].slice(offset, offset + 400);
23
23
  const placeholders = ids.map(() => "?").join(", ");
24
- const rows = this.store.db.prepare(`
25
- SELECT e.session_id, COUNT(*) AS count
26
- FROM event_log e
27
- LEFT JOIN app_session_read_state reads ON reads.session_id = e.session_id
28
- WHERE e.session_id IN (${placeholders})
29
- AND e.stream_id > COALESCE(reads.last_read_stream_id, 0)
30
- AND (
31
- (e.retention_class = 'chat_message' AND e.type IN ('user.message.accepted', 'assistant_message'))
32
- OR e.type = 'session_error'
33
- )
34
- GROUP BY e.session_id
24
+ const rows = this.store.db.prepare(`
25
+ SELECT e.session_id, COUNT(*) AS count
26
+ FROM event_log e
27
+ LEFT JOIN app_session_read_state reads ON reads.session_id = e.session_id
28
+ WHERE e.session_id IN (${placeholders})
29
+ AND e.stream_id > COALESCE(reads.last_read_stream_id, 0)
30
+ AND (
31
+ (e.retention_class = 'chat_message' AND e.type IN ('user.message.accepted', 'assistant_message'))
32
+ OR e.type = 'session_error'
33
+ )
34
+ GROUP BY e.session_id
35
35
  `).all(...ids);
36
36
  for (const row of rows)
37
37
  if (Number(row.count) > 0)
@@ -58,31 +58,31 @@ export class ChatSessionQueryService {
58
58
  const title = session.title || "Untitled Session";
59
59
  const metadataJson = JSON.stringify(session.metadata ?? {});
60
60
  const activeModelJson = session.activeModel ? JSON.stringify(session.activeModel) : null;
61
- const row = this.store.db.prepare(`
62
- SELECT
63
- s.pi_session_id,
64
- s.room_id,
65
- s.root_session_id,
66
- s.parent_id,
67
- s.origin_id,
68
- s.channel,
69
- s.kind,
70
- s.profile,
71
- s.active_model_json,
72
- s.workspace,
73
- s.title,
74
- s.status,
75
- s.metadata_json,
76
- s.created_at,
77
- s.updated_at,
78
- s.last_activity_at,
79
- n.status AS navigation_status,
80
- n.title AS navigation_title,
81
- n.sort_key AS navigation_sort_key,
82
- n.updated_at AS navigation_updated_at
83
- FROM sessions s
84
- LEFT JOIN session_navigation n ON n.session_id = s.id
85
- WHERE s.id = ? AND s.deleted_at IS NULL
61
+ const row = this.store.db.prepare(`
62
+ SELECT
63
+ s.pi_session_id,
64
+ s.room_id,
65
+ s.root_session_id,
66
+ s.parent_id,
67
+ s.origin_id,
68
+ s.channel,
69
+ s.kind,
70
+ s.profile,
71
+ s.active_model_json,
72
+ s.workspace,
73
+ s.title,
74
+ s.status,
75
+ s.metadata_json,
76
+ s.created_at,
77
+ s.updated_at,
78
+ s.last_activity_at,
79
+ n.status AS navigation_status,
80
+ n.title AS navigation_title,
81
+ n.sort_key AS navigation_sort_key,
82
+ n.updated_at AS navigation_updated_at
83
+ FROM sessions s
84
+ LEFT JOIN session_navigation n ON n.session_id = s.id
85
+ WHERE s.id = ? AND s.deleted_at IS NULL
86
86
  `).get(session.id);
87
87
  if (!row)
88
88
  return false;
@@ -32,11 +32,11 @@ export class ChatTimelineQueryService {
32
32
  return this.listTraceEvents({ piboSessionId, limit: 10000, includeLive: true });
33
33
  }
34
34
  listMessageTurnTimings(piboSessionId) {
35
- const rows = this.store.db.prepare(`
36
- SELECT * FROM event_log
37
- WHERE session_id = ?
38
- AND type IN ('message_started', 'message_finished')
39
- ORDER BY session_sequence ASC, stream_id ASC
35
+ const rows = this.store.db.prepare(`
36
+ SELECT * FROM event_log
37
+ WHERE session_id = ?
38
+ AND type IN ('message_started', 'message_finished')
39
+ ORDER BY session_sequence ASC, stream_id ASC
40
40
  `).all(piboSessionId);
41
41
  const events = rows.map(storedPiboEventFromV2Row).filter((event) => event !== undefined);
42
42
  return messageTurnTimingsFromEvents(events);
@@ -59,14 +59,14 @@ export class ChatTimelineQueryService {
59
59
  clauses.push("session_sequence <= ?");
60
60
  values.push(beforeOrAtSequence);
61
61
  }
62
- const rows = this.store.db.prepare(`
63
- SELECT * FROM (
64
- SELECT * FROM event_log
65
- WHERE ${clauses.join(" AND ")}
66
- ORDER BY session_sequence DESC, stream_id DESC
67
- LIMIT ?
68
- )
69
- ORDER BY session_sequence ASC, stream_id ASC
62
+ const rows = this.store.db.prepare(`
63
+ SELECT * FROM (
64
+ SELECT * FROM event_log
65
+ WHERE ${clauses.join(" AND ")}
66
+ ORDER BY session_sequence DESC, stream_id DESC
67
+ LIMIT ?
68
+ )
69
+ ORDER BY session_sequence ASC, stream_id ASC
70
70
  `).all(...values, limit);
71
71
  return rows.map(storedPiboEventFromV2Row).filter((event) => event !== undefined);
72
72
  }
@@ -86,12 +86,12 @@ export class ChatTimelineQueryService {
86
86
  return rows.map((row) => ({ eventType: row.type, count: Number(row.count) }));
87
87
  }
88
88
  getLatestEventSequence(piboSessionId) {
89
- const row = this.store.db.prepare(`
90
- SELECT session_sequence AS latest_sequence
91
- FROM event_log
92
- WHERE session_id = ?
93
- ORDER BY session_sequence DESC, stream_id DESC
94
- LIMIT 1
89
+ const row = this.store.db.prepare(`
90
+ SELECT session_sequence AS latest_sequence
91
+ FROM event_log
92
+ WHERE session_id = ?
93
+ ORDER BY session_sequence DESC, stream_id DESC
94
+ LIMIT 1
95
95
  `).get(piboSessionId);
96
96
  return row?.latest_sequence ?? 0;
97
97
  }