@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
@@ -126,6 +126,7 @@ export async function buildTraceView(input) {
126
126
  title: createSessionTitle(input.session, metadata),
127
127
  },
128
128
  events: input.events,
129
+ turnTimings: input.turnTimings,
129
130
  transcriptEntries: allEntries,
130
131
  sessions: input.sessions.map((s) => ({
131
132
  id: s.id,
@@ -175,6 +176,7 @@ export function createTraceViewVersion(input) {
175
176
  const eventTail = input.events.at(-1);
176
177
  return createHash("sha1")
177
178
  .update(JSON.stringify({
179
+ traceProjection: "turn-timing-v2",
178
180
  session: {
179
181
  id: input.session.id,
180
182
  piSessionId: input.session.piSessionId,
@@ -323,6 +323,7 @@ function createFastTraceV2Version(input) {
323
323
  .sort((left, right) => left.id.localeCompare(right.id));
324
324
  return createHash("sha1")
325
325
  .update(JSON.stringify({
326
+ traceProjection: "turn-timing-v2",
326
327
  session: {
327
328
  id: input.session.id,
328
329
  piSessionId: input.session.piSessionId,
@@ -4266,6 +4267,7 @@ export function createChatWebApp(options = {}) {
4266
4267
  let metadataMs = 0;
4267
4268
  const lastEventSequence = state.timelineQuery.getLatestEventSequence(selectedSession.id);
4268
4269
  const latestStreamId = state.timelineQuery.getLatestStreamId({ piboSessionId: selectedSession.id });
4270
+ const turnTimings = state.timelineQuery.listMessageTurnTimings(selectedSession.id);
4269
4271
  const liveSnapshots = timelineCursor.kind === "tail" ? state.outputCompactor.snapshotsForSession(selectedSession.id) : [];
4270
4272
  const metadataStartedAt = performance.now();
4271
4273
  const transcriptMetadata = timelineCursor.kind === "tail" || timelineCursor.kind === "transcript"
@@ -4328,6 +4330,7 @@ export function createChatWebApp(options = {}) {
4328
4330
  metadata: transcriptMetadata ?? {},
4329
4331
  transcriptEntries: history.entries,
4330
4332
  transcriptOrderOffset: history.startByte,
4333
+ turnTimings,
4331
4334
  includeRawEvents: false,
4332
4335
  latestStreamId,
4333
4336
  });
@@ -4360,6 +4363,7 @@ export function createChatWebApp(options = {}) {
4360
4363
  status: indexedSession?.status,
4361
4364
  metadata: transcriptMetadata ?? {},
4362
4365
  transcriptEntries,
4366
+ turnTimings,
4363
4367
  includeRawEvents: false,
4364
4368
  latestStreamId,
4365
4369
  });
@@ -4474,6 +4478,7 @@ export function createChatWebApp(options = {}) {
4474
4478
  const metadataMs = performance.now() - metadataStartedAt;
4475
4479
  const lastEventSequence = state.timelineQuery.getLatestEventSequence(selectedSession.id);
4476
4480
  const latestStreamId = state.timelineQuery.getLatestStreamId({ piboSessionId: selectedSession.id });
4481
+ const turnTimings = state.timelineQuery.listMessageTurnTimings(selectedSession.id);
4477
4482
  const liveSnapshots = beforeSequence === undefined ? state.outputCompactor.snapshotsForSession(selectedSession.id) : [];
4478
4483
  const baseVersion = createTraceViewVersion({
4479
4484
  session: selectedSession,
@@ -4517,6 +4522,7 @@ export function createChatWebApp(options = {}) {
4517
4522
  events,
4518
4523
  status: indexedSession?.status,
4519
4524
  metadata,
4525
+ turnTimings,
4520
4526
  includeRawEvents: false,
4521
4527
  latestStreamId,
4522
4528
  });
@@ -4578,6 +4584,7 @@ export function createChatWebApp(options = {}) {
4578
4584
  sessions: ownedSessions,
4579
4585
  events: state.timelineQuery.listTraceEvents({ piboSessionId, beforeOrAtSequence: eventSequence, limit: DEFAULT_TRACE_EVENTS_PAGE_SIZE }),
4580
4586
  status: indexedSession?.status,
4587
+ turnTimings: state.timelineQuery.listMessageTurnTimings(piboSessionId),
4581
4588
  });
4582
4589
  return responseJson(trace);
4583
4590
  }
@@ -6,31 +6,31 @@ export class ChatWorkflowDraftStore {
6
6
  dataStore;
7
7
  constructor(dataStore) {
8
8
  this.dataStore = dataStore;
9
- this.dataStore.db.exec(`
10
- CREATE TABLE IF NOT EXISTS workflow_ui_drafts (
11
- draft_id TEXT PRIMARY KEY,
12
- workflow_id TEXT NOT NULL,
13
- source TEXT NOT NULL,
14
- status TEXT NOT NULL,
15
- base_workflow_id TEXT,
16
- base_workflow_version TEXT,
17
- base_definition_hash TEXT,
18
- target_workflow_version TEXT,
19
- version_intent TEXT NOT NULL,
20
- definition_json TEXT NOT NULL,
21
- diagnostics_json TEXT NOT NULL,
22
- validation_json TEXT,
23
- validation_state TEXT NOT NULL,
24
- revision INTEGER NOT NULL,
25
- created_at TEXT NOT NULL,
26
- updated_at TEXT NOT NULL
27
- );
28
-
29
- CREATE UNIQUE INDEX IF NOT EXISTS idx_workflow_ui_drafts_one_active
30
- ON workflow_ui_drafts(workflow_id)
31
- WHERE status = 'draft';
32
- CREATE INDEX IF NOT EXISTS idx_workflow_ui_drafts_updated
33
- ON workflow_ui_drafts(updated_at, draft_id);
9
+ this.dataStore.db.exec(`
10
+ CREATE TABLE IF NOT EXISTS workflow_ui_drafts (
11
+ draft_id TEXT PRIMARY KEY,
12
+ workflow_id TEXT NOT NULL,
13
+ source TEXT NOT NULL,
14
+ status TEXT NOT NULL,
15
+ base_workflow_id TEXT,
16
+ base_workflow_version TEXT,
17
+ base_definition_hash TEXT,
18
+ target_workflow_version TEXT,
19
+ version_intent TEXT NOT NULL,
20
+ definition_json TEXT NOT NULL,
21
+ diagnostics_json TEXT NOT NULL,
22
+ validation_json TEXT,
23
+ validation_state TEXT NOT NULL,
24
+ revision INTEGER NOT NULL,
25
+ created_at TEXT NOT NULL,
26
+ updated_at TEXT NOT NULL
27
+ );
28
+
29
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_workflow_ui_drafts_one_active
30
+ ON workflow_ui_drafts(workflow_id)
31
+ WHERE status = 'draft';
32
+ CREATE INDEX IF NOT EXISTS idx_workflow_ui_drafts_updated
33
+ ON workflow_ui_drafts(updated_at, draft_id);
34
34
  `);
35
35
  }
36
36
  getDraft(draftId) {
@@ -61,41 +61,41 @@ export class ChatWorkflowDraftStore {
61
61
  if (conflict) {
62
62
  throw new PiboWebHttpError(`Workflow '${record.workflowId}' already has an active draft '${conflict.draft_id}'`, 409);
63
63
  }
64
- this.dataStore.db.prepare(`
65
- INSERT INTO workflow_ui_drafts (
66
- draft_id,
67
- workflow_id,
68
- source,
69
- status,
70
- base_workflow_id,
71
- base_workflow_version,
72
- base_definition_hash,
73
- target_workflow_version,
74
- version_intent,
75
- definition_json,
76
- diagnostics_json,
77
- validation_json,
78
- validation_state,
79
- revision,
80
- created_at,
81
- updated_at
82
- ) VALUES (${Array.from({ length: 16 }, () => "?").join(", ")})
83
- ON CONFLICT(draft_id) DO UPDATE SET
84
- workflow_id = excluded.workflow_id,
85
- source = excluded.source,
86
- status = excluded.status,
87
- base_workflow_id = excluded.base_workflow_id,
88
- base_workflow_version = excluded.base_workflow_version,
89
- base_definition_hash = excluded.base_definition_hash,
90
- target_workflow_version = excluded.target_workflow_version,
91
- version_intent = excluded.version_intent,
92
- definition_json = excluded.definition_json,
93
- diagnostics_json = excluded.diagnostics_json,
94
- validation_json = excluded.validation_json,
95
- validation_state = excluded.validation_state,
96
- revision = excluded.revision,
97
- created_at = excluded.created_at,
98
- updated_at = excluded.updated_at
64
+ this.dataStore.db.prepare(`
65
+ INSERT INTO workflow_ui_drafts (
66
+ draft_id,
67
+ workflow_id,
68
+ source,
69
+ status,
70
+ base_workflow_id,
71
+ base_workflow_version,
72
+ base_definition_hash,
73
+ target_workflow_version,
74
+ version_intent,
75
+ definition_json,
76
+ diagnostics_json,
77
+ validation_json,
78
+ validation_state,
79
+ revision,
80
+ created_at,
81
+ updated_at
82
+ ) VALUES (${Array.from({ length: 16 }, () => "?").join(", ")})
83
+ ON CONFLICT(draft_id) DO UPDATE SET
84
+ workflow_id = excluded.workflow_id,
85
+ source = excluded.source,
86
+ status = excluded.status,
87
+ base_workflow_id = excluded.base_workflow_id,
88
+ base_workflow_version = excluded.base_workflow_version,
89
+ base_definition_hash = excluded.base_definition_hash,
90
+ target_workflow_version = excluded.target_workflow_version,
91
+ version_intent = excluded.version_intent,
92
+ definition_json = excluded.definition_json,
93
+ diagnostics_json = excluded.diagnostics_json,
94
+ validation_json = excluded.validation_json,
95
+ validation_state = excluded.validation_state,
96
+ revision = excluded.revision,
97
+ created_at = excluded.created_at,
98
+ updated_at = excluded.updated_at
99
99
  `).run(record.draftId, record.workflowId, record.source, record.status, record.baseWorkflowId ?? null, record.baseWorkflowVersion ?? null, record.baseDefinitionHash ?? null, record.targetWorkflowVersion ?? null, record.versionIntent, JSON.stringify(record.definition), JSON.stringify(sanitizeWorkflowDiagnostics(record.diagnostics)), record.validation ? JSON.stringify(record.validation) : null, record.validationState, record.revision, record.createdAt, record.updatedAt);
100
100
  });
101
101
  }
@@ -124,28 +124,28 @@ export class ChatWorkflowPublishedVersionStore {
124
124
  dataStore;
125
125
  constructor(dataStore) {
126
126
  this.dataStore = dataStore;
127
- this.dataStore.db.exec(`
128
- CREATE TABLE IF NOT EXISTS workflow_published_versions (
129
- workflow_id TEXT NOT NULL,
130
- version TEXT NOT NULL,
131
- source TEXT NOT NULL,
132
- status TEXT NOT NULL,
133
- definition_hash TEXT NOT NULL,
134
- definition_json TEXT NOT NULL,
135
- published_from_draft_id TEXT,
136
- published_by TEXT,
137
- published_at TEXT NOT NULL,
138
- created_at TEXT NOT NULL,
139
- PRIMARY KEY (workflow_id, version)
140
- );
141
-
142
- CREATE INDEX IF NOT EXISTS idx_workflow_published_versions_workflow
143
- ON workflow_published_versions(workflow_id, version);
144
- CREATE INDEX IF NOT EXISTS idx_workflow_published_versions_published_at
145
- ON workflow_published_versions(published_at);
146
- CREATE UNIQUE INDEX IF NOT EXISTS idx_workflow_published_versions_draft
147
- ON workflow_published_versions(published_from_draft_id)
148
- WHERE published_from_draft_id IS NOT NULL;
127
+ this.dataStore.db.exec(`
128
+ CREATE TABLE IF NOT EXISTS workflow_published_versions (
129
+ workflow_id TEXT NOT NULL,
130
+ version TEXT NOT NULL,
131
+ source TEXT NOT NULL,
132
+ status TEXT NOT NULL,
133
+ definition_hash TEXT NOT NULL,
134
+ definition_json TEXT NOT NULL,
135
+ published_from_draft_id TEXT,
136
+ published_by TEXT,
137
+ published_at TEXT NOT NULL,
138
+ created_at TEXT NOT NULL,
139
+ PRIMARY KEY (workflow_id, version)
140
+ );
141
+
142
+ CREATE INDEX IF NOT EXISTS idx_workflow_published_versions_workflow
143
+ ON workflow_published_versions(workflow_id, version);
144
+ CREATE INDEX IF NOT EXISTS idx_workflow_published_versions_published_at
145
+ ON workflow_published_versions(published_at);
146
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_workflow_published_versions_draft
147
+ ON workflow_published_versions(published_from_draft_id)
148
+ WHERE published_from_draft_id IS NOT NULL;
149
149
  `);
150
150
  }
151
151
  getPublishedVersionByDraftId(draftId) {
@@ -197,19 +197,19 @@ export class ChatWorkflowPublishedVersionStore {
197
197
  });
198
198
  }
199
199
  insertPublishedVersion(record) {
200
- this.dataStore.db.prepare(`
201
- INSERT INTO workflow_published_versions (
202
- workflow_id,
203
- version,
204
- source,
205
- status,
206
- definition_hash,
207
- definition_json,
208
- published_from_draft_id,
209
- published_by,
210
- published_at,
211
- created_at
212
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
200
+ this.dataStore.db.prepare(`
201
+ INSERT INTO workflow_published_versions (
202
+ workflow_id,
203
+ version,
204
+ source,
205
+ status,
206
+ definition_hash,
207
+ definition_json,
208
+ published_from_draft_id,
209
+ published_by,
210
+ published_at,
211
+ created_at
212
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
213
213
  `).run(record.workflowId, record.version, record.source, record.status, record.definitionHash, canonicalWorkflowDefinitionJson(record.definition), record.publishedFromDraftId ?? null, record.publishedBy ?? null, record.publishedAt, record.createdAt);
214
214
  }
215
215
  }
@@ -231,29 +231,29 @@ export class ChatWorkflowPromptAssetStore {
231
231
  dataStore;
232
232
  constructor(dataStore) {
233
233
  this.dataStore = dataStore;
234
- this.dataStore.db.exec(`
235
- CREATE TABLE IF NOT EXISTS workflow_prompt_assets (
236
- asset_id TEXT PRIMARY KEY,
237
- source TEXT NOT NULL,
238
- display_name TEXT NOT NULL,
239
- description TEXT,
240
- active_revision_id TEXT,
241
- created_at TEXT NOT NULL,
242
- updated_at TEXT NOT NULL
243
- );
244
-
245
- CREATE TABLE IF NOT EXISTS workflow_prompt_asset_revisions (
246
- revision_id TEXT PRIMARY KEY,
247
- asset_id TEXT NOT NULL,
248
- content_hash TEXT NOT NULL,
249
- markdown TEXT NOT NULL,
250
- created_at TEXT NOT NULL,
251
- created_by TEXT,
252
- based_on_revision_id TEXT
253
- );
254
-
255
- CREATE INDEX IF NOT EXISTS idx_workflow_prompt_asset_revisions_asset
256
- ON workflow_prompt_asset_revisions(asset_id, created_at DESC);
234
+ this.dataStore.db.exec(`
235
+ CREATE TABLE IF NOT EXISTS workflow_prompt_assets (
236
+ asset_id TEXT PRIMARY KEY,
237
+ source TEXT NOT NULL,
238
+ display_name TEXT NOT NULL,
239
+ description TEXT,
240
+ active_revision_id TEXT,
241
+ created_at TEXT NOT NULL,
242
+ updated_at TEXT NOT NULL
243
+ );
244
+
245
+ CREATE TABLE IF NOT EXISTS workflow_prompt_asset_revisions (
246
+ revision_id TEXT PRIMARY KEY,
247
+ asset_id TEXT NOT NULL,
248
+ content_hash TEXT NOT NULL,
249
+ markdown TEXT NOT NULL,
250
+ created_at TEXT NOT NULL,
251
+ created_by TEXT,
252
+ based_on_revision_id TEXT
253
+ );
254
+
255
+ CREATE INDEX IF NOT EXISTS idx_workflow_prompt_asset_revisions_asset
256
+ ON workflow_prompt_asset_revisions(asset_id, created_at DESC);
257
257
  `);
258
258
  }
259
259
  listAssets() {
@@ -284,32 +284,32 @@ export class ChatWorkflowPromptAssetStore {
284
284
  const existing = this.getAsset(assetId);
285
285
  const revisionId = `wpar_${randomUUID()}`;
286
286
  const contentHash = hashPromptAssetMarkdown(input.markdown);
287
- this.dataStore.db.prepare(`
288
- INSERT INTO workflow_prompt_assets (
289
- asset_id,
290
- source,
291
- display_name,
292
- description,
293
- active_revision_id,
294
- created_at,
295
- updated_at
296
- ) VALUES (${Array.from({ length: 7 }, () => "?").join(", ")})
297
- ON CONFLICT(asset_id) DO UPDATE SET
298
- display_name = excluded.display_name,
299
- description = excluded.description,
300
- active_revision_id = excluded.active_revision_id,
301
- updated_at = excluded.updated_at
287
+ this.dataStore.db.prepare(`
288
+ INSERT INTO workflow_prompt_assets (
289
+ asset_id,
290
+ source,
291
+ display_name,
292
+ description,
293
+ active_revision_id,
294
+ created_at,
295
+ updated_at
296
+ ) VALUES (${Array.from({ length: 7 }, () => "?").join(", ")})
297
+ ON CONFLICT(asset_id) DO UPDATE SET
298
+ display_name = excluded.display_name,
299
+ description = excluded.description,
300
+ active_revision_id = excluded.active_revision_id,
301
+ updated_at = excluded.updated_at
302
302
  `).run(assetId, "ui", normalizeWorkflowPromptAssetLabel(input.displayName), input.description?.trim() || null, revisionId, existing?.createdAt ?? now, now);
303
- this.dataStore.db.prepare(`
304
- INSERT INTO workflow_prompt_asset_revisions (
305
- revision_id,
306
- asset_id,
307
- content_hash,
308
- markdown,
309
- created_at,
310
- created_by,
311
- based_on_revision_id
312
- ) VALUES (${Array.from({ length: 7 }, () => "?").join(", ")})
303
+ this.dataStore.db.prepare(`
304
+ INSERT INTO workflow_prompt_asset_revisions (
305
+ revision_id,
306
+ asset_id,
307
+ content_hash,
308
+ markdown,
309
+ created_at,
310
+ created_by,
311
+ based_on_revision_id
312
+ ) VALUES (${Array.from({ length: 7 }, () => "?").join(", ")})
313
313
  `).run(revisionId, assetId, contentHash, input.markdown, now, input.actorId ?? null, existing?.activeRevisionId ?? null);
314
314
  const asset = this.getAsset(assetId);
315
315
  const revision = this.getActiveRevision(assetId);
@@ -359,19 +359,19 @@ export class ChatWorkflowArchiveStore {
359
359
  dataStore;
360
360
  constructor(dataStore) {
361
361
  this.dataStore = dataStore;
362
- this.dataStore.db.exec(`
363
- CREATE TABLE IF NOT EXISTS workflow_archive_states (
364
- workflow_id TEXT PRIMARY KEY,
365
- source TEXT NOT NULL,
366
- archived INTEGER NOT NULL,
367
- archived_at TEXT,
368
- archived_by TEXT,
369
- archive_reason TEXT,
370
- updated_at TEXT NOT NULL
371
- );
372
-
373
- CREATE INDEX IF NOT EXISTS idx_workflow_archive_states_archived
374
- ON workflow_archive_states(archived, updated_at);
362
+ this.dataStore.db.exec(`
363
+ CREATE TABLE IF NOT EXISTS workflow_archive_states (
364
+ workflow_id TEXT PRIMARY KEY,
365
+ source TEXT NOT NULL,
366
+ archived INTEGER NOT NULL,
367
+ archived_at TEXT,
368
+ archived_by TEXT,
369
+ archive_reason TEXT,
370
+ updated_at TEXT NOT NULL
371
+ );
372
+
373
+ CREATE INDEX IF NOT EXISTS idx_workflow_archive_states_archived
374
+ ON workflow_archive_states(archived, updated_at);
375
375
  `);
376
376
  }
377
377
  setWorkflowArchived(input) {
@@ -391,23 +391,23 @@ export class ChatWorkflowArchiveStore {
391
391
  return record;
392
392
  }
393
393
  saveWorkflowArchiveState(record) {
394
- this.dataStore.db.prepare(`
395
- INSERT INTO workflow_archive_states (
396
- workflow_id,
397
- source,
398
- archived,
399
- archived_at,
400
- archived_by,
401
- archive_reason,
402
- updated_at
403
- ) VALUES (?, ?, ?, ?, ?, ?, ?)
404
- ON CONFLICT(workflow_id) DO UPDATE SET
405
- source = excluded.source,
406
- archived = excluded.archived,
407
- archived_at = excluded.archived_at,
408
- archived_by = excluded.archived_by,
409
- archive_reason = excluded.archive_reason,
410
- updated_at = excluded.updated_at
394
+ this.dataStore.db.prepare(`
395
+ INSERT INTO workflow_archive_states (
396
+ workflow_id,
397
+ source,
398
+ archived,
399
+ archived_at,
400
+ archived_by,
401
+ archive_reason,
402
+ updated_at
403
+ ) VALUES (?, ?, ?, ?, ?, ?, ?)
404
+ ON CONFLICT(workflow_id) DO UPDATE SET
405
+ source = excluded.source,
406
+ archived = excluded.archived,
407
+ archived_at = excluded.archived_at,
408
+ archived_by = excluded.archived_by,
409
+ archive_reason = excluded.archive_reason,
410
+ updated_at = excluded.updated_at
411
411
  `).run(record.workflowId, record.source, record.archived ? 1 : 0, record.archivedAt ?? null, record.archivedBy ?? null, record.archiveReason ?? null, record.updatedAt);
412
412
  }
413
413
  getWorkflowArchiveState(workflowId) {
@@ -430,21 +430,21 @@ export class ChatWorkflowTombstoneStore {
430
430
  dataStore;
431
431
  constructor(dataStore) {
432
432
  this.dataStore = dataStore;
433
- this.dataStore.db.exec(`
434
- CREATE TABLE IF NOT EXISTS workflow_delete_tombstones (
435
- workflow_id TEXT PRIMARY KEY,
436
- source TEXT NOT NULL,
437
- deleted INTEGER NOT NULL,
438
- deleted_at TEXT NOT NULL,
439
- deleted_by TEXT NOT NULL,
440
- last_known_title TEXT NOT NULL,
441
- last_known_version TEXT,
442
- last_definition_hash TEXT,
443
- updated_at TEXT NOT NULL
444
- );
445
-
446
- CREATE INDEX IF NOT EXISTS idx_workflow_delete_tombstones_deleted
447
- ON workflow_delete_tombstones(deleted, updated_at);
433
+ this.dataStore.db.exec(`
434
+ CREATE TABLE IF NOT EXISTS workflow_delete_tombstones (
435
+ workflow_id TEXT PRIMARY KEY,
436
+ source TEXT NOT NULL,
437
+ deleted INTEGER NOT NULL,
438
+ deleted_at TEXT NOT NULL,
439
+ deleted_by TEXT NOT NULL,
440
+ last_known_title TEXT NOT NULL,
441
+ last_known_version TEXT,
442
+ last_definition_hash TEXT,
443
+ updated_at TEXT NOT NULL
444
+ );
445
+
446
+ CREATE INDEX IF NOT EXISTS idx_workflow_delete_tombstones_deleted
447
+ ON workflow_delete_tombstones(deleted, updated_at);
448
448
  `);
449
449
  }
450
450
  setWorkflowDeleted(input) {
@@ -469,27 +469,27 @@ export class ChatWorkflowTombstoneStore {
469
469
  return row ? workflowTombstoneFromStoreRow(row) : undefined;
470
470
  }
471
471
  saveWorkflowTombstone(record) {
472
- this.dataStore.db.prepare(`
473
- INSERT INTO workflow_delete_tombstones (
474
- workflow_id,
475
- source,
476
- deleted,
477
- deleted_at,
478
- deleted_by,
479
- last_known_title,
480
- last_known_version,
481
- last_definition_hash,
482
- updated_at
483
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
484
- ON CONFLICT(workflow_id) DO UPDATE SET
485
- source = excluded.source,
486
- deleted = excluded.deleted,
487
- deleted_at = excluded.deleted_at,
488
- deleted_by = excluded.deleted_by,
489
- last_known_title = excluded.last_known_title,
490
- last_known_version = excluded.last_known_version,
491
- last_definition_hash = excluded.last_definition_hash,
492
- updated_at = excluded.updated_at
472
+ this.dataStore.db.prepare(`
473
+ INSERT INTO workflow_delete_tombstones (
474
+ workflow_id,
475
+ source,
476
+ deleted,
477
+ deleted_at,
478
+ deleted_by,
479
+ last_known_title,
480
+ last_known_version,
481
+ last_definition_hash,
482
+ updated_at
483
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
484
+ ON CONFLICT(workflow_id) DO UPDATE SET
485
+ source = excluded.source,
486
+ deleted = excluded.deleted,
487
+ deleted_at = excluded.deleted_at,
488
+ deleted_by = excluded.deleted_by,
489
+ last_known_title = excluded.last_known_title,
490
+ last_known_version = excluded.last_known_version,
491
+ last_definition_hash = excluded.last_definition_hash,
492
+ updated_at = excluded.updated_at
493
493
  `).run(record.workflowId, record.source, record.deleted ? 1 : 0, record.deletedAt, record.deletedBy, record.lastKnownTitle, record.lastKnownVersion ?? null, record.lastDefinitionHash ?? null, record.updatedAt);
494
494
  }
495
495
  }
@@ -510,30 +510,30 @@ export class ChatWorkflowLifecycleEventStore {
510
510
  dataStore;
511
511
  constructor(dataStore) {
512
512
  this.dataStore = dataStore;
513
- this.dataStore.db.exec(`
514
- CREATE TABLE IF NOT EXISTS workflow_lifecycle_events (
515
- id TEXT PRIMARY KEY,
516
- type TEXT NOT NULL,
517
- actor_id TEXT,
518
- workflow_id TEXT,
519
- workflow_version TEXT,
520
- draft_id TEXT,
521
- project_id TEXT,
522
- pibo_session_id TEXT,
523
- workflow_run_id TEXT,
524
- status TEXT,
525
- validation_json TEXT,
526
- diagnostics_json TEXT NOT NULL,
527
- payload_json TEXT,
528
- created_at TEXT NOT NULL
529
- );
530
-
531
- CREATE INDEX IF NOT EXISTS idx_workflow_lifecycle_events_type
532
- ON workflow_lifecycle_events(type, created_at);
533
- CREATE INDEX IF NOT EXISTS idx_workflow_lifecycle_events_workflow
534
- ON workflow_lifecycle_events(workflow_id, workflow_version, created_at);
535
- CREATE INDEX IF NOT EXISTS idx_workflow_lifecycle_events_project_session
536
- ON workflow_lifecycle_events(project_id, pibo_session_id, created_at);
513
+ this.dataStore.db.exec(`
514
+ CREATE TABLE IF NOT EXISTS workflow_lifecycle_events (
515
+ id TEXT PRIMARY KEY,
516
+ type TEXT NOT NULL,
517
+ actor_id TEXT,
518
+ workflow_id TEXT,
519
+ workflow_version TEXT,
520
+ draft_id TEXT,
521
+ project_id TEXT,
522
+ pibo_session_id TEXT,
523
+ workflow_run_id TEXT,
524
+ status TEXT,
525
+ validation_json TEXT,
526
+ diagnostics_json TEXT NOT NULL,
527
+ payload_json TEXT,
528
+ created_at TEXT NOT NULL
529
+ );
530
+
531
+ CREATE INDEX IF NOT EXISTS idx_workflow_lifecycle_events_type
532
+ ON workflow_lifecycle_events(type, created_at);
533
+ CREATE INDEX IF NOT EXISTS idx_workflow_lifecycle_events_workflow
534
+ ON workflow_lifecycle_events(workflow_id, workflow_version, created_at);
535
+ CREATE INDEX IF NOT EXISTS idx_workflow_lifecycle_events_project_session
536
+ ON workflow_lifecycle_events(project_id, pibo_session_id, created_at);
537
537
  `);
538
538
  }
539
539
  record(input) {
@@ -553,23 +553,23 @@ export class ChatWorkflowLifecycleEventStore {
553
553
  ...(input.payload ? { payload: input.payload } : {}),
554
554
  createdAt: input.createdAt ?? new Date().toISOString(),
555
555
  };
556
- this.dataStore.db.prepare(`
557
- INSERT INTO workflow_lifecycle_events (
558
- id,
559
- type,
560
- actor_id,
561
- workflow_id,
562
- workflow_version,
563
- draft_id,
564
- project_id,
565
- pibo_session_id,
566
- workflow_run_id,
567
- status,
568
- validation_json,
569
- diagnostics_json,
570
- payload_json,
571
- created_at
572
- ) VALUES (${Array.from({ length: 14 }, () => "?").join(", ")})
556
+ this.dataStore.db.prepare(`
557
+ INSERT INTO workflow_lifecycle_events (
558
+ id,
559
+ type,
560
+ actor_id,
561
+ workflow_id,
562
+ workflow_version,
563
+ draft_id,
564
+ project_id,
565
+ pibo_session_id,
566
+ workflow_run_id,
567
+ status,
568
+ validation_json,
569
+ diagnostics_json,
570
+ payload_json,
571
+ created_at
572
+ ) VALUES (${Array.from({ length: 14 }, () => "?").join(", ")})
573
573
  `).run(event.id, event.type, event.actorId ?? null, event.workflowId ?? null, event.workflowVersion ?? null, event.draftId ?? null, event.projectId ?? null, event.piboSessionId ?? null, event.workflowRunId ?? null, event.status ?? null, event.validation ? JSON.stringify(event.validation) : null, JSON.stringify(event.diagnostics), event.payload ? JSON.stringify(event.payload) : null, event.createdAt);
574
574
  return event;
575
575
  }
@@ -601,11 +601,11 @@ export class ChatWorkflowLifecycleEventStore {
601
601
  values.push(filter.workflowRunId);
602
602
  }
603
603
  const where = clauses.length ? `WHERE ${clauses.join(" AND ")}` : "";
604
- const rows = this.dataStore.db.prepare(`
605
- SELECT * FROM workflow_lifecycle_events
606
- ${where}
607
- ORDER BY created_at DESC, id DESC
608
- LIMIT ?
604
+ const rows = this.dataStore.db.prepare(`
605
+ SELECT * FROM workflow_lifecycle_events
606
+ ${where}
607
+ ORDER BY created_at DESC, id DESC
608
+ LIMIT ?
609
609
  `).all(...values, filter.limit ?? 100);
610
610
  return rows.map(workflowLifecycleEventFromStoreRow);
611
611
  }