@pasko70/pibo 1.9.13 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) 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 +10 -0
  10. package/dist/apps/chat/data/project-service.js +168 -168
  11. package/dist/apps/chat/data/read-state-service.js +18 -18
  12. package/dist/apps/chat/data/session-query-service.js +25 -25
  13. package/dist/apps/chat/data/timeline-query-service.js +19 -19
  14. package/dist/apps/chat/loop-api.js +176 -0
  15. package/dist/apps/chat/static-assets.js +854 -854
  16. package/dist/apps/chat/web-app.js +6 -6
  17. package/dist/apps/chat/workflow-manual-trigger-runtime.js +149 -46
  18. package/dist/apps/chat/workflow-persistence.js +255 -255
  19. package/dist/apps/chat-ui/assets/{dist-yCYNNb5d.js → dist-BwKObYnX.js} +1 -1
  20. package/dist/apps/chat-ui/assets/{dist-BCB6zezO.js → dist-CKtT8YGm.js} +1 -1
  21. package/dist/apps/chat-ui/assets/{dist-CnVsqwSG.js → dist-CS7wdk0Z.js} +1 -1
  22. package/dist/apps/chat-ui/assets/{dist-HqTN67dc.js → dist-D-cxLQO1.js} +1 -1
  23. package/dist/apps/chat-ui/assets/{dist-BNMu92bb.js → dist-DUlaXAk7.js} +1 -1
  24. package/dist/apps/chat-ui/assets/{dist-CzE6k3F3.js → dist-DlATLa-U.js} +1 -1
  25. package/dist/apps/chat-ui/assets/{dist-Dq4GxJi3.js → dist-GdEM8UW1.js} +1 -1
  26. package/dist/apps/chat-ui/assets/{dist-BZ2eTC4f.js → dist-LHRs1Nhr.js} +1 -1
  27. package/dist/apps/chat-ui/assets/{dist-D811wJeV.js → dist-Y-AA2omI.js} +1 -1
  28. package/dist/apps/chat-ui/assets/{dist-WyXdYl-w.js → dist-nOLTkZrJ.js} +1 -1
  29. package/dist/apps/chat-ui/assets/{dist-BHa-kcGl.js → dist-wE9nop9V.js} +1 -1
  30. package/dist/apps/chat-ui/assets/{index-DwHJfmiF.js → index-8W_yMHQI.js} +6 -6
  31. package/dist/apps/chat-ui/index.html +17 -17
  32. package/dist/apps/chat-ui/manifest.webmanifest +25 -25
  33. package/dist/apps/chat-ui/sw.js +47 -47
  34. package/dist/apps/chat-vscode-web/index.html +12 -12
  35. package/dist/apps/cli-ui/cliSessionsCommand.js +23 -23
  36. package/dist/apps/context-files-ui/index.html +11 -11
  37. package/dist/cli.js +61 -44
  38. package/dist/compute/cli.js +54 -54
  39. package/dist/core/routed-session.js +30 -1
  40. package/dist/core/runtime.js +6 -1
  41. package/dist/core/session-router.js +4 -2
  42. package/dist/cron/cli.js +15 -15
  43. package/dist/cron/store.js +49 -49
  44. package/dist/data/cli.js +23 -23
  45. package/dist/data/event-log.js +23 -23
  46. package/dist/data/message-store.js +27 -27
  47. package/dist/data/navigation-store.js +9 -9
  48. package/dist/data/observation-store.js +4 -4
  49. package/dist/data/payload-store.js +17 -17
  50. package/dist/data/schema.js +433 -433
  51. package/dist/data/session-store.js +4 -4
  52. package/dist/data/telemetry-queries.js +54 -54
  53. package/dist/data/telemetry.js +197 -197
  54. package/dist/debug/events.js +12 -12
  55. package/dist/debug/failures.js +6 -6
  56. package/dist/debug/index.js +227 -227
  57. package/dist/debug/messages.js +6 -6
  58. package/dist/debug/pty.js +124 -124
  59. package/dist/debug/session.js +29 -29
  60. package/dist/debug/tools.js +5 -5
  61. package/dist/debug/web-snapshot-browser-scripts.js +294 -294
  62. package/dist/debug/web-streaming-browser-library.js +925 -925
  63. package/dist/debug/web-streaming-browser-scripts.js +232 -232
  64. package/dist/debug/web-streaming-provider-telemetry.js +4 -4
  65. package/dist/debug/web.js +93 -93
  66. package/dist/gateway/cli.js +19 -19
  67. package/dist/gateway/server.js +4 -2
  68. package/dist/gateway/web.js +2 -2
  69. package/dist/loops/channel.js +8 -0
  70. package/dist/loops/cli.js +208 -0
  71. package/dist/loops/plugin.js +16 -0
  72. package/dist/loops/prompts.js +83 -0
  73. package/dist/loops/service.js +357 -0
  74. package/dist/loops/stopping.js +170 -0
  75. package/dist/loops/store.js +531 -0
  76. package/dist/loops/templates.js +232 -0
  77. package/dist/loops/tools.js +167 -0
  78. package/dist/loops/types.js +1 -0
  79. package/dist/mcp/config-command.js +53 -53
  80. package/dist/mcp/index.js +21 -21
  81. package/dist/mcp/registry.js +11 -11
  82. package/dist/pi-packages/cli.js +11 -11
  83. package/dist/plugins/builtin.js +8 -0
  84. package/dist/plugins/context-files-store.js +110 -110
  85. package/dist/plugins/context-files.js +4 -4
  86. package/dist/plugins/registry.js +23 -12
  87. package/dist/ralph/cli.js +18 -18
  88. package/dist/ralph/templates.js +140 -140
  89. package/dist/reliability/store.js +226 -226
  90. package/dist/sessions/pibo-data-store.js +16 -16
  91. package/dist/sessions/sqlite-store.js +53 -53
  92. package/dist/setup/cli.js +58 -58
  93. package/dist/tools/agent-browser-wrapper.js +80 -80
  94. package/dist/tools/browser-use-cdp.js +12 -12
  95. package/dist/tools/browser-use-wrapper.js +762 -762
  96. package/dist/tools/guides.js +589 -538
  97. package/dist/tools/index.js +122 -99
  98. package/dist/tools/registry.js +21 -3
  99. package/dist/tools/runtime/node-worker-source.js +205 -205
  100. package/dist/tools/runtime/python-worker-source.js +177 -177
  101. package/dist/vscode/cli.js +9 -9
  102. package/dist/web-annotations/cdp.js +900 -900
  103. package/dist/web-annotations/store.js +96 -96
  104. package/docs/README.md +23 -23
  105. package/docs/ops/install-developer-host.md +112 -112
  106. package/docs/ops/install-user-host.md +96 -96
  107. package/docs/ops/upgrade-user-to-developer-host.md +69 -69
  108. package/docs/ops/vscode-extension-release.md +160 -160
  109. package/package.json +98 -95
  110. package/skills/builtin/graphify/SKILL.md +52 -52
  111. package/skills/builtin/loop/SKILL.md +69 -0
  112. package/skills/builtin/pi-agent-harness/SKILL.md +319 -319
  113. package/skills/builtin/pi-agent-harness/agents/openai.yaml +4 -4
  114. package/skills/builtin/pibo-docker-system/SKILL.md +170 -170
  115. package/skills/builtin/pibo-spec-writing/SKILL.md +330 -330
  116. package/skills/builtin/prd/SKILL.md +143 -143
  117. package/skills/builtin/ralph-loop/SKILL.md +361 -359
  118. package/skills/builtin/ralph-prd-json/SKILL.md +123 -123
  119. package/skills/builtin/skill-creator/LICENSE.txt +201 -201
  120. package/skills/builtin/skill-creator/SKILL.md +513 -513
  121. package/skills/builtin/skill-creator/agents/analyzer.md +274 -274
  122. package/skills/builtin/skill-creator/agents/comparator.md +202 -202
  123. package/skills/builtin/skill-creator/agents/grader.md +223 -223
  124. package/skills/builtin/skill-creator/assets/eval_review.html +146 -146
  125. package/skills/builtin/skill-creator/eval-viewer/generate_review.py +471 -471
  126. package/skills/builtin/skill-creator/eval-viewer/viewer.html +1325 -1325
  127. package/skills/builtin/skill-creator/references/schemas.md +430 -430
  128. package/skills/builtin/skill-creator/scripts/aggregate_benchmark.py +401 -401
  129. package/skills/builtin/skill-creator/scripts/generate_report.py +326 -326
  130. package/skills/builtin/skill-creator/scripts/improve_description.py +247 -247
  131. package/skills/builtin/skill-creator/scripts/package_skill.py +136 -136
  132. package/skills/builtin/skill-creator/scripts/quick_validate.py +102 -102
  133. package/skills/builtin/skill-creator/scripts/run_eval.py +310 -310
  134. package/skills/builtin/skill-creator/scripts/run_loop.py +328 -328
  135. package/skills/builtin/skill-creator/scripts/utils.py +47 -47
  136. package/skills/builtin/web-annotations/SKILL.md +93 -93
  137. package/src/mcp/LICENSE.mcp-cli +21 -21
  138. package/dist/apps/vscode-artifacts/latest.vsix +0 -0
  139. package/dist/apps/vscode-artifacts/pibo-vscode-ext-1.9.13.vsix +0 -0
@@ -29,6 +29,31 @@ function isAssistantMessage(message) {
29
29
  function numberValue(value) {
30
30
  return typeof value === "number" && Number.isFinite(value) ? value : undefined;
31
31
  }
32
+ export function normalizeAssistantUsageEvent(piboSessionId, message) {
33
+ const assistant = message;
34
+ if (!assistant?.usage || typeof assistant.usage !== "object")
35
+ return undefined;
36
+ const usage = assistant.usage;
37
+ const inputTokens = numberValue(usage.inputTokens) ?? numberValue(usage.input);
38
+ const outputTokens = numberValue(usage.outputTokens) ?? numberValue(usage.output);
39
+ const cacheReadTokens = numberValue(usage.cacheRead);
40
+ const cacheWriteTokens = numberValue(usage.cacheWrite);
41
+ const reportedTotal = numberValue(usage.totalTokens);
42
+ const normalizedTotal = reportedTotal ?? [inputTokens, outputTokens, cacheReadTokens, cacheWriteTokens]
43
+ .filter((value) => value !== undefined)
44
+ .reduce((sum, value) => sum + value, 0);
45
+ if (normalizedTotal <= 0 && inputTokens === undefined && outputTokens === undefined && cacheReadTokens === undefined && cacheWriteTokens === undefined)
46
+ return undefined;
47
+ return {
48
+ type: "assistant_usage",
49
+ piboSessionId,
50
+ ...(inputTokens !== undefined ? { inputTokens } : {}),
51
+ ...(outputTokens !== undefined ? { outputTokens } : {}),
52
+ ...(cacheReadTokens !== undefined ? { cacheReadTokens } : {}),
53
+ ...(cacheWriteTokens !== undefined ? { cacheWriteTokens } : {}),
54
+ totalTokens: Math.max(0, normalizedTotal),
55
+ };
56
+ }
32
57
  function stringValue(value) {
33
58
  return typeof value === "string" && value.length > 0 ? value : undefined;
34
59
  }
@@ -511,6 +536,9 @@ export class RoutedSession {
511
536
  const normalized = normalizePiEvent(this.piboSessionId, event, { contextWindow: numberValue(model?.contextWindow) });
512
537
  const candidate = event && typeof event === "object" ? event : undefined;
513
538
  const assistantMessageEnded = candidate?.type === "message_end" && isAssistantMessage(candidate.message);
539
+ const usageEvent = assistantMessageEnded ? normalizeAssistantUsageEvent(this.piboSessionId, candidate?.message) : undefined;
540
+ if (usageEvent)
541
+ this.emit(this.withActiveMessage(usageEvent));
514
542
  // Pi gets the first chance to recover through its short retry/compaction loop.
515
543
  // Keep the final error pending so the routed turn can continue durable recovery.
516
544
  if (assistantMessageEnded && normalized?.type === "session_error") {
@@ -1150,7 +1178,8 @@ export class RoutedSession {
1150
1178
  return output;
1151
1179
  }
1152
1180
  if (this.activeMessage?.id &&
1153
- (event.type === "tool_call" ||
1181
+ (event.type === "assistant_usage" ||
1182
+ event.type === "tool_call" ||
1154
1183
  event.type === "tool_execution_started" ||
1155
1184
  event.type === "tool_execution_updated" ||
1156
1185
  event.type === "tool_execution_finished" ||
@@ -17,6 +17,7 @@ import { createPiboCompactionPromptExtension } from "./compaction-prompt.js";
17
17
  import { cancelPiboAssistantContextGuardRecovery, createPiboAssistantContextGuardExtension, createPiboAssistantContextGuardRecovery, isPiboAssistantContextGuardRecoveryPending, registerPiboAssistantContextGuardRecovery, } from "./context-guard.js";
18
18
  import { getPiPackageRuntimeOptions } from "../pi-packages/runtime.js";
19
19
  import { getDefaultPiboWorkspace } from "./workspace.js";
20
+ import { createPiboGoalToolDefinitions, PIBO_GOAL_TOOL_NAMES } from "../loops/tools.js";
20
21
  import { DEFAULT_USER_TIMEZONE } from "./user-settings.js";
21
22
  import { registerMiniMaxProvider } from "../providers/minimax.js";
22
23
  import { registerGlmProvider } from "../providers/glm.js";
@@ -109,6 +110,8 @@ function getEnabledToolDefinitions(profile, options, subagentRunner, runToolCont
109
110
  const profileToolDefinitions = profileTools.map((tool) => getToolDefinition(tool, options.toolContext));
110
111
  const codexCompatEnabled = profile.toolPackages.codexCompat === true;
111
112
  const runControlEnabled = profile.toolPackages.runControl === true;
113
+ const goalControlEnabled = profile.toolPackages.goalControl !== false;
114
+ const goalTools = goalControlEnabled ? createPiboGoalToolDefinitions(options.toolContext ?? {}) : [];
112
115
  const runControlBashTool = runControlEnabled && runToolController
113
116
  ? createBashToolDefinition(options.runtimeCwd, {
114
117
  commandPrefix: options.shellCommandPrefix,
@@ -137,6 +140,7 @@ function getEnabledToolDefinitions(profile, options, subagentRunner, runToolCont
137
140
  ...(runtimeTool ? [runtimeTool] : []),
138
141
  ...subagentTools,
139
142
  ...codexCompatTools,
143
+ ...goalTools,
140
144
  ...runTools,
141
145
  ];
142
146
  }
@@ -155,7 +159,7 @@ function isEnabledRuntimeTool(tool) {
155
159
  return tool.enabled !== false && isRuntimeTool(tool);
156
160
  }
157
161
  function isGeneratedPiboTool(name) {
158
- return name === "runtime" || name.startsWith("pibo_subagent_") || name.startsWith("pibo_run_");
162
+ return name === "runtime" || name.startsWith("pibo_subagent_") || name.startsWith("pibo_run_") || PIBO_GOAL_TOOL_NAMES.includes(name);
159
163
  }
160
164
  function getBuiltinToolAllowlist(profile, customTools) {
161
165
  if (profile.builtinTools === "disabled")
@@ -282,6 +286,7 @@ export async function createPiboRuntime(options = {}) {
282
286
  toolContext: {
283
287
  piboSessionId: options.sessionContext?.piboSessionId ?? profile.sessionId,
284
288
  piboRoomId: options.sessionContext?.piboRoomId,
289
+ profileName: profile.profileName,
285
290
  },
286
291
  }, options.subagentRunner, options.runToolController, runtimeToolController);
287
292
  const modelDefaults = options.modelDefaults ?? loadPiboModelDefaults(runtimeCwd);
@@ -22,13 +22,15 @@ import { createPiboProviderTelemetryExtension } from "./provider-telemetry.js";
22
22
  import { AsyncTelemetryWriter } from "../data/telemetry-writer.js";
23
23
  const DEFAULT_SUBAGENT_REPLY_TIMEOUT_MS = 10 * 60 * 1000;
24
24
  const DEFAULT_ROUTED_SESSION_IDLE_TIMEOUT_MS = 30 * 60 * 1000;
25
- export const RALPH_RUNTIME_RETRY_DEFAULTS = {
25
+ export const LOOP_RUNTIME_RETRY_DEFAULTS = {
26
26
  enabled: true,
27
27
  maxRetries: 7,
28
28
  baseDelayMs: 2_000,
29
29
  };
30
+ /** @deprecated Use LOOP_RUNTIME_RETRY_DEFAULTS. */
31
+ export const RALPH_RUNTIME_RETRY_DEFAULTS = LOOP_RUNTIME_RETRY_DEFAULTS;
30
32
  export function resolvePiboSessionRetryDefaults(kind, configured) {
31
- return configured ?? (kind === "ralph" ? RALPH_RUNTIME_RETRY_DEFAULTS : undefined);
33
+ return configured ?? (kind === "loop" || kind === "ralph" ? LOOP_RUNTIME_RETRY_DEFAULTS : undefined);
32
34
  }
33
35
  export function resolvePiboSessionInitialThinkingLevel(session) {
34
36
  const value = session.metadata?.initialThinkingLevel;
package/dist/cron/cli.js CHANGED
@@ -2,21 +2,21 @@ import { Command } from "commander";
2
2
  import { parseFriendlySchedule } from "./schedule.js";
3
3
  import { createDefaultPiboCronStore } from "./store.js";
4
4
  function printDiscovery() {
5
- console.log(`pibo cron
6
-
7
- Manage scheduled Pibo agent jobs.
8
-
9
- Commands:
10
- status Show scheduler store status
11
- list List cron jobs
12
- add Create a cron job
13
- edit Update a cron job
14
- pause Disable a cron job
15
- resume Enable a cron job and recompute next run
16
- remove Delete a cron job
17
- runs List cron runs
18
-
19
- Next: pibo cron add --help
5
+ console.log(`pibo cron
6
+
7
+ Manage scheduled Pibo agent jobs.
8
+
9
+ Commands:
10
+ status Show scheduler store status
11
+ list List cron jobs
12
+ add Create a cron job
13
+ edit Update a cron job
14
+ pause Disable a cron job
15
+ resume Enable a cron job and recompute next run
16
+ remove Delete a cron job
17
+ runs List cron runs
18
+
19
+ Next: pibo cron add --help
20
20
  pibo cron edit --help`);
21
21
  }
22
22
  function printJson(value) {
@@ -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);
@@ -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)
@@ -39,13 +39,13 @@ export class MessageStore {
39
39
  return rows.map(messageFromRow);
40
40
  }
41
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'
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
49
  `).run(input.completedAt, input.status ?? "complete", input.sessionId, input.turnId);
50
50
  return Number(result.changes ?? 0);
51
51
  }
@@ -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)