@askexenow/exe-os 0.9.70 → 0.9.72

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 (69) hide show
  1. package/dist/bin/agentic-ontology-backfill.js +27 -0
  2. package/dist/bin/agentic-reflection-backfill.js +27 -0
  3. package/dist/bin/agentic-semantic-label.js +27 -0
  4. package/dist/bin/backfill-conversations.js +27 -0
  5. package/dist/bin/backfill-responses.js +27 -0
  6. package/dist/bin/backfill-vectors.js +27 -0
  7. package/dist/bin/bulk-sync-postgres.js +27 -0
  8. package/dist/bin/cleanup-stale-review-tasks.js +27 -0
  9. package/dist/bin/cli.js +27 -0
  10. package/dist/bin/exe-assign.js +27 -0
  11. package/dist/bin/exe-boot.js +27 -0
  12. package/dist/bin/exe-cloud.js +27 -0
  13. package/dist/bin/exe-dispatch.js +27 -0
  14. package/dist/bin/exe-doctor.js +27 -0
  15. package/dist/bin/exe-export-behaviors.js +27 -0
  16. package/dist/bin/exe-forget.js +27 -0
  17. package/dist/bin/exe-gateway.js +27 -0
  18. package/dist/bin/exe-heartbeat.js +27 -0
  19. package/dist/bin/exe-kill.js +27 -0
  20. package/dist/bin/exe-launch-agent.js +27 -0
  21. package/dist/bin/exe-pending-messages.js +27 -0
  22. package/dist/bin/exe-pending-notifications.js +27 -0
  23. package/dist/bin/exe-pending-reviews.js +27 -0
  24. package/dist/bin/exe-rename.js +27 -0
  25. package/dist/bin/exe-review.js +27 -0
  26. package/dist/bin/exe-search.js +27 -0
  27. package/dist/bin/exe-session-cleanup.js +27 -0
  28. package/dist/bin/exe-start-codex.js +27 -0
  29. package/dist/bin/exe-start-opencode.js +27 -0
  30. package/dist/bin/exe-status.js +27 -0
  31. package/dist/bin/exe-team.js +27 -0
  32. package/dist/bin/git-sweep.js +27 -0
  33. package/dist/bin/graph-backfill.js +27 -0
  34. package/dist/bin/graph-export.js +27 -0
  35. package/dist/bin/intercom-check.js +27 -0
  36. package/dist/bin/scan-tasks.js +27 -0
  37. package/dist/bin/setup.js +27 -0
  38. package/dist/bin/shard-migrate.js +27 -0
  39. package/dist/gateway/index.js +27 -0
  40. package/dist/hooks/bug-report-worker.js +27 -0
  41. package/dist/hooks/codex-stop-task-finalizer.js +27 -0
  42. package/dist/hooks/commit-complete.js +27 -0
  43. package/dist/hooks/error-recall.js +27 -0
  44. package/dist/hooks/ingest.js +27 -0
  45. package/dist/hooks/instructions-loaded.js +27 -0
  46. package/dist/hooks/notification.js +27 -0
  47. package/dist/hooks/post-compact.js +27 -0
  48. package/dist/hooks/post-tool-combined.js +692 -17
  49. package/dist/hooks/pre-compact.js +27 -0
  50. package/dist/hooks/pre-tool-use.js +27 -0
  51. package/dist/hooks/prompt-submit.js +308 -0
  52. package/dist/hooks/session-end.js +27 -0
  53. package/dist/hooks/session-start.js +27 -0
  54. package/dist/hooks/stop.js +273 -12
  55. package/dist/hooks/subagent-stop.js +27 -0
  56. package/dist/hooks/summary-worker.js +27 -0
  57. package/dist/index.js +27 -0
  58. package/dist/lib/cloud-sync.js +27 -0
  59. package/dist/lib/database.js +27 -0
  60. package/dist/lib/db.js +27 -0
  61. package/dist/lib/device-registry.js +27 -0
  62. package/dist/lib/exe-daemon.js +260 -28
  63. package/dist/lib/hybrid-search.js +27 -0
  64. package/dist/lib/schedules.js +27 -0
  65. package/dist/lib/store.js +27 -0
  66. package/dist/mcp/server.js +246 -25
  67. package/dist/runtime/index.js +27 -0
  68. package/dist/tui/App.js +27 -0
  69. package/package.json +5 -5
@@ -1386,8 +1386,8 @@ function findPackageRoot() {
1386
1386
  function getAvailableMemoryGB() {
1387
1387
  if (process.platform === "darwin") {
1388
1388
  try {
1389
- const { execSync: execSync6 } = __require("child_process");
1390
- const vmstat = execSync6("vm_stat", { encoding: "utf8" });
1389
+ const { execSync: execSync7 } = __require("child_process");
1390
+ const vmstat = execSync7("vm_stat", { encoding: "utf8" });
1391
1391
  const pageSize = 16384;
1392
1392
  const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
1393
1393
  const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
@@ -2769,6 +2769,33 @@ async function ensureSchema() {
2769
2769
  CREATE INDEX IF NOT EXISTS idx_chat_history_session
2770
2770
  ON chat_history(session_id, id);
2771
2771
  `);
2772
+ await client.executeMultiple(`
2773
+ CREATE TABLE IF NOT EXISTS session_events (
2774
+ id TEXT PRIMARY KEY,
2775
+ agent_id TEXT NOT NULL,
2776
+ agent_role TEXT NOT NULL,
2777
+ session_id TEXT NOT NULL,
2778
+ session_scope TEXT,
2779
+ project_name TEXT NOT NULL,
2780
+ event_index INTEGER NOT NULL,
2781
+ event_type TEXT NOT NULL,
2782
+ tool_name TEXT,
2783
+ tool_use_id TEXT,
2784
+ content TEXT NOT NULL,
2785
+ payload_json TEXT,
2786
+ has_error INTEGER NOT NULL DEFAULT 0,
2787
+ created_at TEXT NOT NULL
2788
+ );
2789
+
2790
+ CREATE INDEX IF NOT EXISTS idx_session_events_agent_time
2791
+ ON session_events(agent_id, created_at DESC);
2792
+
2793
+ CREATE INDEX IF NOT EXISTS idx_session_events_session_index
2794
+ ON session_events(session_id, event_index);
2795
+
2796
+ CREATE INDEX IF NOT EXISTS idx_session_events_scope_agent_time
2797
+ ON session_events(session_scope, agent_id, created_at DESC);
2798
+ `);
2772
2799
  await client.executeMultiple(`
2773
2800
  CREATE TABLE IF NOT EXISTS workspaces (
2774
2801
  id TEXT PRIMARY KEY,
@@ -3519,6 +3546,15 @@ function sessionScopeFilter(sessionScope, tableAlias) {
3519
3546
  args: [scope]
3520
3547
  };
3521
3548
  }
3549
+ function strictSessionScopeFilter(sessionScope, tableAlias) {
3550
+ const scope = sessionScope !== void 0 ? sessionScope : getCurrentSessionScope();
3551
+ if (!scope) return { sql: "", args: [] };
3552
+ const col = tableAlias ? `${tableAlias}.session_scope` : "session_scope";
3553
+ return {
3554
+ sql: ` AND ${col} = ?`,
3555
+ args: [scope]
3556
+ };
3557
+ }
3522
3558
  var init_task_scope = __esm({
3523
3559
  "src/lib/task-scope.ts"() {
3524
3560
  "use strict";
@@ -5892,9 +5928,179 @@ var init_fast_db_init = __esm({
5892
5928
  }
5893
5929
  });
5894
5930
 
5931
+ // src/lib/project-name.ts
5932
+ import { execSync as execSync6 } from "child_process";
5933
+ import path16 from "path";
5934
+ function getProjectName(cwd) {
5935
+ const dir = cwd ?? process.cwd();
5936
+ if (_cached2 && _cachedCwd === dir) return _cached2;
5937
+ try {
5938
+ let repoRoot;
5939
+ try {
5940
+ const gitCommonDir = execSync6("git rev-parse --path-format=absolute --git-common-dir", {
5941
+ cwd: dir,
5942
+ encoding: "utf8",
5943
+ timeout: 2e3,
5944
+ stdio: ["pipe", "pipe", "pipe"]
5945
+ }).trim();
5946
+ repoRoot = path16.dirname(gitCommonDir);
5947
+ } catch {
5948
+ repoRoot = execSync6("git rev-parse --show-toplevel", {
5949
+ cwd: dir,
5950
+ encoding: "utf8",
5951
+ timeout: 2e3,
5952
+ stdio: ["pipe", "pipe", "pipe"]
5953
+ }).trim();
5954
+ }
5955
+ _cached2 = path16.basename(repoRoot);
5956
+ _cachedCwd = dir;
5957
+ return _cached2;
5958
+ } catch {
5959
+ _cached2 = path16.basename(dir);
5960
+ _cachedCwd = dir;
5961
+ return _cached2;
5962
+ }
5963
+ }
5964
+ var _cached2, _cachedCwd;
5965
+ var init_project_name = __esm({
5966
+ "src/lib/project-name.ts"() {
5967
+ "use strict";
5968
+ _cached2 = null;
5969
+ _cachedCwd = null;
5970
+ }
5971
+ });
5972
+
5973
+ // src/lib/session-events.ts
5974
+ var session_events_exports = {};
5975
+ __export(session_events_exports, {
5976
+ ensureSessionEventsTable: () => ensureSessionEventsTable,
5977
+ listRecentSessionEvents: () => listRecentSessionEvents,
5978
+ recordSessionEvent: () => recordSessionEvent
5979
+ });
5980
+ import { randomUUID as randomUUID4 } from "crypto";
5981
+ async function ensureSessionEventsTable(client) {
5982
+ await client.execute(`
5983
+ CREATE TABLE IF NOT EXISTS session_events (
5984
+ id TEXT PRIMARY KEY,
5985
+ agent_id TEXT NOT NULL,
5986
+ agent_role TEXT NOT NULL,
5987
+ session_id TEXT NOT NULL,
5988
+ session_scope TEXT,
5989
+ project_name TEXT NOT NULL,
5990
+ event_index INTEGER NOT NULL,
5991
+ event_type TEXT NOT NULL,
5992
+ tool_name TEXT,
5993
+ tool_use_id TEXT,
5994
+ content TEXT NOT NULL,
5995
+ payload_json TEXT,
5996
+ has_error INTEGER NOT NULL DEFAULT 0,
5997
+ created_at TEXT NOT NULL
5998
+ )
5999
+ `);
6000
+ await client.execute(`
6001
+ CREATE INDEX IF NOT EXISTS idx_session_events_agent_time
6002
+ ON session_events(agent_id, created_at DESC)
6003
+ `);
6004
+ await client.execute(`
6005
+ CREATE INDEX IF NOT EXISTS idx_session_events_session_index
6006
+ ON session_events(session_id, event_index)
6007
+ `);
6008
+ await client.execute(`
6009
+ CREATE INDEX IF NOT EXISTS idx_session_events_scope_agent_time
6010
+ ON session_events(session_scope, agent_id, created_at DESC)
6011
+ `);
6012
+ }
6013
+ async function recordSessionEvent(client, input2) {
6014
+ if (!input2.content || input2.content.trim().length === 0) return;
6015
+ await ensureSessionEventsTable(client);
6016
+ const maxResult = await client.execute({
6017
+ sql: "SELECT COALESCE(MAX(event_index), 0) AS max_index FROM session_events WHERE session_id = ?",
6018
+ args: [input2.sessionId]
6019
+ });
6020
+ const currentMax = Number(maxResult.rows[0]?.max_index ?? 0);
6021
+ const eventIndex = Number.isFinite(currentMax) ? currentMax + 1 : 1;
6022
+ await client.execute({
6023
+ sql: `INSERT INTO session_events (
6024
+ id, agent_id, agent_role, session_id, session_scope, project_name,
6025
+ event_index, event_type, tool_name, tool_use_id, content,
6026
+ payload_json, has_error, created_at
6027
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
6028
+ args: [
6029
+ randomUUID4(),
6030
+ input2.agentId,
6031
+ input2.agentRole,
6032
+ input2.sessionId,
6033
+ input2.sessionScope ?? getCurrentSessionScope(),
6034
+ input2.projectName ?? getProjectName(input2.cwd),
6035
+ eventIndex,
6036
+ input2.eventType,
6037
+ input2.toolName ?? null,
6038
+ input2.toolUseId ?? null,
6039
+ input2.content,
6040
+ input2.payloadJson ?? null,
6041
+ input2.hasError ? 1 : 0,
6042
+ input2.timestamp ?? (/* @__PURE__ */ new Date()).toISOString()
6043
+ ]
6044
+ });
6045
+ }
6046
+ async function listRecentSessionEvents(client, options) {
6047
+ await ensureSessionEventsTable(client);
6048
+ const conditions = ["agent_id = ?"];
6049
+ const args = [options.agentId];
6050
+ if (options.sessionId) {
6051
+ conditions.push("session_id = ?");
6052
+ args.push(options.sessionId);
6053
+ }
6054
+ if (options.eventType) {
6055
+ conditions.push("event_type = ?");
6056
+ args.push(options.eventType);
6057
+ }
6058
+ if (options.projectName && options.projectName !== "all") {
6059
+ conditions.push("project_name = ?");
6060
+ args.push(options.projectName);
6061
+ }
6062
+ const scope = strictSessionScopeFilter(options.sessionScope);
6063
+ const where = `WHERE ${conditions.join(" AND ")}${scope.sql}`;
6064
+ args.push(...scope.args);
6065
+ args.push(Math.min(Math.max(options.limit ?? 20, 1), 100));
6066
+ const result = await client.execute({
6067
+ sql: `SELECT id, agent_id, agent_role, session_id, session_scope,
6068
+ project_name, event_index, event_type, tool_name, tool_use_id,
6069
+ content, payload_json, has_error, created_at
6070
+ FROM session_events
6071
+ ${where}
6072
+ ORDER BY created_at DESC, event_index DESC
6073
+ LIMIT ?`,
6074
+ args
6075
+ });
6076
+ return result.rows.map((row) => ({
6077
+ id: String(row.id),
6078
+ agentId: String(row.agent_id),
6079
+ agentRole: String(row.agent_role),
6080
+ sessionId: String(row.session_id),
6081
+ sessionScope: row.session_scope == null ? null : String(row.session_scope),
6082
+ projectName: String(row.project_name),
6083
+ eventIndex: Number(row.event_index),
6084
+ eventType: String(row.event_type),
6085
+ toolName: row.tool_name == null ? null : String(row.tool_name),
6086
+ toolUseId: row.tool_use_id == null ? null : String(row.tool_use_id),
6087
+ content: String(row.content),
6088
+ payloadJson: row.payload_json == null ? null : String(row.payload_json),
6089
+ hasError: Number(row.has_error) === 1,
6090
+ createdAt: String(row.created_at)
6091
+ }));
6092
+ }
6093
+ var init_session_events = __esm({
6094
+ "src/lib/session-events.ts"() {
6095
+ "use strict";
6096
+ init_task_scope();
6097
+ init_project_name();
6098
+ }
6099
+ });
6100
+
5895
6101
  // src/lib/memory-queue.ts
5896
6102
  import { appendFileSync as appendFileSync2, readFileSync as readFileSync11, renameSync as renameSync5, unlinkSync as unlinkSync4, existsSync as existsSync14, statSync as statSync4 } from "fs";
5897
- import path16 from "path";
6103
+ import path17 from "path";
5898
6104
  function enqueueMemory(entry) {
5899
6105
  appendFileSync2(QUEUE_PATH2, JSON.stringify(entry) + "\n");
5900
6106
  }
@@ -5903,7 +6109,7 @@ var init_memory_queue = __esm({
5903
6109
  "src/lib/memory-queue.ts"() {
5904
6110
  "use strict";
5905
6111
  init_config();
5906
- QUEUE_PATH2 = path16.join(EXE_AI_DIR, "memory-queue.jsonl");
6112
+ QUEUE_PATH2 = path17.join(EXE_AI_DIR, "memory-queue.jsonl");
5907
6113
  PROCESSING_PATH = QUEUE_PATH2 + ".processing";
5908
6114
  TTL_MS2 = 24 * 60 * 60 * 1e3;
5909
6115
  }
@@ -5969,7 +6175,7 @@ init_config();
5969
6175
  init_config();
5970
6176
  import { spawn as spawn2 } from "child_process";
5971
6177
  import { existsSync as existsSync15, openSync as openSync2, closeSync as closeSync2 } from "fs";
5972
- import path17 from "path";
6178
+ import path18 from "path";
5973
6179
  import { fileURLToPath as fileURLToPath3 } from "url";
5974
6180
 
5975
6181
  // src/lib/active-agent.ts
@@ -6090,7 +6296,7 @@ if (!process.env.AGENT_ID) {
6090
6296
  if (!loadConfigSync().autoIngestion) {
6091
6297
  process.exit(0);
6092
6298
  }
6093
- var WORKER_LOG_PATH = path17.join(EXE_AI_DIR, "workers.log");
6299
+ var WORKER_LOG_PATH = path18.join(EXE_AI_DIR, "workers.log");
6094
6300
  function openWorkerLog() {
6095
6301
  try {
6096
6302
  return openSync2(WORKER_LOG_PATH, "a");
@@ -6128,13 +6334,13 @@ process.stdin.setEncoding("utf8");
6128
6334
  process.stdin.on("data", (chunk) => {
6129
6335
  if (input.length < MAX_INPUT_SIZE) input += chunk;
6130
6336
  });
6131
- process.stdin.on("end", () => {
6337
+ process.stdin.on("end", async () => {
6132
6338
  try {
6133
6339
  if (process.env.EXE_DEBUG_HOOKS || process.env.EXE_RUNTIME === "codex") {
6134
6340
  try {
6135
- const debugPath = path17.join(EXE_AI_DIR, "logs", "hook-stdin-stop.log");
6341
+ const debugPath = path18.join(EXE_AI_DIR, "logs", "hook-stdin-stop.log");
6136
6342
  const { mkdirSync: mkdirSync8, writeFileSync: writeFileSync8 } = __require("fs");
6137
- mkdirSync8(path17.dirname(debugPath), { recursive: true });
6343
+ mkdirSync8(path18.dirname(debugPath), { recursive: true });
6138
6344
  const ts = (/* @__PURE__ */ new Date()).toISOString();
6139
6345
  const snippet = input.length > 500 ? input.slice(0, 500) + "...[truncated]" : input;
6140
6346
  writeFileSync8(debugPath, `[${ts}] len=${input.length} ${snippet}
@@ -6144,11 +6350,11 @@ process.stdin.on("end", () => {
6144
6350
  }
6145
6351
  const data = JSON.parse(input);
6146
6352
  const agent = getActiveAgent();
6147
- const message = data.last_assistant_message ?? "";
6353
+ const message = data.last_assistant_message || readLastAssistantMessageFromTranscript(data.transcript_path) || "";
6148
6354
  const cwd = data.cwd ?? process.cwd();
6149
6355
  if (process.env.EXE_RUNTIME === "codex" && !canCoordinate(agent.agentId, agent.agentRole)) {
6150
- const codexFinalizerPath = path17.resolve(
6151
- path17.dirname(fileURLToPath3(import.meta.url)),
6356
+ const codexFinalizerPath = path18.resolve(
6357
+ path18.dirname(fileURLToPath3(import.meta.url)),
6152
6358
  "codex-stop-task-finalizer.js"
6153
6359
  );
6154
6360
  spawnDetachedWorker(codexFinalizerPath, {
@@ -6162,6 +6368,21 @@ process.stdin.on("end", () => {
6162
6368
  if (!message || message.length < MIN_LENGTH) {
6163
6369
  process.exit(0);
6164
6370
  }
6371
+ try {
6372
+ const { fastDbInit: fastDbInit2 } = await Promise.resolve().then(() => (init_fast_db_init(), fast_db_init_exports));
6373
+ const { recordSessionEvent: recordSessionEvent2 } = await Promise.resolve().then(() => (init_session_events(), session_events_exports));
6374
+ const client = await fastDbInit2();
6375
+ await recordSessionEvent2(client, {
6376
+ agentId: agent.agentId,
6377
+ agentRole: agent.agentRole,
6378
+ sessionId: data.session_id,
6379
+ eventType: "assistant_response",
6380
+ content: message.slice(0, 2e4),
6381
+ cwd,
6382
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
6383
+ });
6384
+ } catch {
6385
+ }
6165
6386
  const CAPACITY_SIGNALS = /context[- ]?full|hit capacity|conversation is too long|maximum context length|context window.*(?:limit|exceed|full)/i;
6166
6387
  if (!canCoordinate(agent.agentId, agent.agentRole) && CAPACITY_SIGNALS.test(message)) {
6167
6388
  Promise.resolve().then(() => (init_fast_db_init(), fast_db_init_exports)).then(({ fastDbInit: fastDbInit2 }) => fastDbInit2()).then(async (client) => {
@@ -6235,3 +6456,43 @@ process.stdin.on("end", () => {
6235
6456
  }
6236
6457
  process.exit(0);
6237
6458
  });
6459
+ function readLastAssistantMessageFromTranscript(transcriptPath) {
6460
+ if (!transcriptPath) return null;
6461
+ try {
6462
+ const { readFileSync: readFileSync12 } = __require("fs");
6463
+ const text = readFileSync12(transcriptPath, "utf8");
6464
+ const lines = text.trim().split("\n").reverse();
6465
+ for (const line of lines) {
6466
+ try {
6467
+ const event = JSON.parse(line);
6468
+ const message = extractAssistantText(event);
6469
+ if (message) return message;
6470
+ } catch {
6471
+ }
6472
+ }
6473
+ } catch {
6474
+ return null;
6475
+ }
6476
+ return null;
6477
+ }
6478
+ function extractAssistantText(event) {
6479
+ const obj = event;
6480
+ if (obj.type !== "assistant" && obj.role !== "assistant") return null;
6481
+ const message = obj.message ?? obj;
6482
+ const content = message.content;
6483
+ if (typeof content === "string") return content.trim() || null;
6484
+ if (Array.isArray(content)) {
6485
+ const parts = content.map((part) => {
6486
+ if (typeof part === "string") return part;
6487
+ if (part && typeof part === "object") {
6488
+ const p = part;
6489
+ if (typeof p.text === "string") return p.text;
6490
+ if (typeof p.content === "string") return p.content;
6491
+ }
6492
+ return "";
6493
+ }).filter(Boolean);
6494
+ const joined = parts.join("\n").trim();
6495
+ return joined || null;
6496
+ }
6497
+ return null;
6498
+ }
@@ -2741,6 +2741,33 @@ async function ensureSchema() {
2741
2741
  CREATE INDEX IF NOT EXISTS idx_chat_history_session
2742
2742
  ON chat_history(session_id, id);
2743
2743
  `);
2744
+ await client.executeMultiple(`
2745
+ CREATE TABLE IF NOT EXISTS session_events (
2746
+ id TEXT PRIMARY KEY,
2747
+ agent_id TEXT NOT NULL,
2748
+ agent_role TEXT NOT NULL,
2749
+ session_id TEXT NOT NULL,
2750
+ session_scope TEXT,
2751
+ project_name TEXT NOT NULL,
2752
+ event_index INTEGER NOT NULL,
2753
+ event_type TEXT NOT NULL,
2754
+ tool_name TEXT,
2755
+ tool_use_id TEXT,
2756
+ content TEXT NOT NULL,
2757
+ payload_json TEXT,
2758
+ has_error INTEGER NOT NULL DEFAULT 0,
2759
+ created_at TEXT NOT NULL
2760
+ );
2761
+
2762
+ CREATE INDEX IF NOT EXISTS idx_session_events_agent_time
2763
+ ON session_events(agent_id, created_at DESC);
2764
+
2765
+ CREATE INDEX IF NOT EXISTS idx_session_events_session_index
2766
+ ON session_events(session_id, event_index);
2767
+
2768
+ CREATE INDEX IF NOT EXISTS idx_session_events_scope_agent_time
2769
+ ON session_events(session_scope, agent_id, created_at DESC);
2770
+ `);
2744
2771
  await client.executeMultiple(`
2745
2772
  CREATE TABLE IF NOT EXISTS workspaces (
2746
2773
  id TEXT PRIMARY KEY,
@@ -2508,6 +2508,33 @@ async function ensureSchema() {
2508
2508
  CREATE INDEX IF NOT EXISTS idx_chat_history_session
2509
2509
  ON chat_history(session_id, id);
2510
2510
  `);
2511
+ await client.executeMultiple(`
2512
+ CREATE TABLE IF NOT EXISTS session_events (
2513
+ id TEXT PRIMARY KEY,
2514
+ agent_id TEXT NOT NULL,
2515
+ agent_role TEXT NOT NULL,
2516
+ session_id TEXT NOT NULL,
2517
+ session_scope TEXT,
2518
+ project_name TEXT NOT NULL,
2519
+ event_index INTEGER NOT NULL,
2520
+ event_type TEXT NOT NULL,
2521
+ tool_name TEXT,
2522
+ tool_use_id TEXT,
2523
+ content TEXT NOT NULL,
2524
+ payload_json TEXT,
2525
+ has_error INTEGER NOT NULL DEFAULT 0,
2526
+ created_at TEXT NOT NULL
2527
+ );
2528
+
2529
+ CREATE INDEX IF NOT EXISTS idx_session_events_agent_time
2530
+ ON session_events(agent_id, created_at DESC);
2531
+
2532
+ CREATE INDEX IF NOT EXISTS idx_session_events_session_index
2533
+ ON session_events(session_id, event_index);
2534
+
2535
+ CREATE INDEX IF NOT EXISTS idx_session_events_scope_agent_time
2536
+ ON session_events(session_scope, agent_id, created_at DESC);
2537
+ `);
2511
2538
  await client.executeMultiple(`
2512
2539
  CREATE TABLE IF NOT EXISTS workspaces (
2513
2540
  id TEXT PRIMARY KEY,
package/dist/index.js CHANGED
@@ -3246,6 +3246,33 @@ async function ensureSchema() {
3246
3246
  CREATE INDEX IF NOT EXISTS idx_chat_history_session
3247
3247
  ON chat_history(session_id, id);
3248
3248
  `);
3249
+ await client.executeMultiple(`
3250
+ CREATE TABLE IF NOT EXISTS session_events (
3251
+ id TEXT PRIMARY KEY,
3252
+ agent_id TEXT NOT NULL,
3253
+ agent_role TEXT NOT NULL,
3254
+ session_id TEXT NOT NULL,
3255
+ session_scope TEXT,
3256
+ project_name TEXT NOT NULL,
3257
+ event_index INTEGER NOT NULL,
3258
+ event_type TEXT NOT NULL,
3259
+ tool_name TEXT,
3260
+ tool_use_id TEXT,
3261
+ content TEXT NOT NULL,
3262
+ payload_json TEXT,
3263
+ has_error INTEGER NOT NULL DEFAULT 0,
3264
+ created_at TEXT NOT NULL
3265
+ );
3266
+
3267
+ CREATE INDEX IF NOT EXISTS idx_session_events_agent_time
3268
+ ON session_events(agent_id, created_at DESC);
3269
+
3270
+ CREATE INDEX IF NOT EXISTS idx_session_events_session_index
3271
+ ON session_events(session_id, event_index);
3272
+
3273
+ CREATE INDEX IF NOT EXISTS idx_session_events_scope_agent_time
3274
+ ON session_events(session_scope, agent_id, created_at DESC);
3275
+ `);
3249
3276
  await client.executeMultiple(`
3250
3277
  CREATE TABLE IF NOT EXISTS workspaces (
3251
3278
  id TEXT PRIMARY KEY,
@@ -2160,6 +2160,33 @@ async function ensureSchema() {
2160
2160
  CREATE INDEX IF NOT EXISTS idx_chat_history_session
2161
2161
  ON chat_history(session_id, id);
2162
2162
  `);
2163
+ await client.executeMultiple(`
2164
+ CREATE TABLE IF NOT EXISTS session_events (
2165
+ id TEXT PRIMARY KEY,
2166
+ agent_id TEXT NOT NULL,
2167
+ agent_role TEXT NOT NULL,
2168
+ session_id TEXT NOT NULL,
2169
+ session_scope TEXT,
2170
+ project_name TEXT NOT NULL,
2171
+ event_index INTEGER NOT NULL,
2172
+ event_type TEXT NOT NULL,
2173
+ tool_name TEXT,
2174
+ tool_use_id TEXT,
2175
+ content TEXT NOT NULL,
2176
+ payload_json TEXT,
2177
+ has_error INTEGER NOT NULL DEFAULT 0,
2178
+ created_at TEXT NOT NULL
2179
+ );
2180
+
2181
+ CREATE INDEX IF NOT EXISTS idx_session_events_agent_time
2182
+ ON session_events(agent_id, created_at DESC);
2183
+
2184
+ CREATE INDEX IF NOT EXISTS idx_session_events_session_index
2185
+ ON session_events(session_id, event_index);
2186
+
2187
+ CREATE INDEX IF NOT EXISTS idx_session_events_scope_agent_time
2188
+ ON session_events(session_scope, agent_id, created_at DESC);
2189
+ `);
2163
2190
  await client.executeMultiple(`
2164
2191
  CREATE TABLE IF NOT EXISTS workspaces (
2165
2192
  id TEXT PRIMARY KEY,
@@ -2076,6 +2076,33 @@ async function ensureSchema() {
2076
2076
  CREATE INDEX IF NOT EXISTS idx_chat_history_session
2077
2077
  ON chat_history(session_id, id);
2078
2078
  `);
2079
+ await client.executeMultiple(`
2080
+ CREATE TABLE IF NOT EXISTS session_events (
2081
+ id TEXT PRIMARY KEY,
2082
+ agent_id TEXT NOT NULL,
2083
+ agent_role TEXT NOT NULL,
2084
+ session_id TEXT NOT NULL,
2085
+ session_scope TEXT,
2086
+ project_name TEXT NOT NULL,
2087
+ event_index INTEGER NOT NULL,
2088
+ event_type TEXT NOT NULL,
2089
+ tool_name TEXT,
2090
+ tool_use_id TEXT,
2091
+ content TEXT NOT NULL,
2092
+ payload_json TEXT,
2093
+ has_error INTEGER NOT NULL DEFAULT 0,
2094
+ created_at TEXT NOT NULL
2095
+ );
2096
+
2097
+ CREATE INDEX IF NOT EXISTS idx_session_events_agent_time
2098
+ ON session_events(agent_id, created_at DESC);
2099
+
2100
+ CREATE INDEX IF NOT EXISTS idx_session_events_session_index
2101
+ ON session_events(session_id, event_index);
2102
+
2103
+ CREATE INDEX IF NOT EXISTS idx_session_events_scope_agent_time
2104
+ ON session_events(session_scope, agent_id, created_at DESC);
2105
+ `);
2079
2106
  await client.executeMultiple(`
2080
2107
  CREATE TABLE IF NOT EXISTS workspaces (
2081
2108
  id TEXT PRIMARY KEY,
package/dist/lib/db.js CHANGED
@@ -2076,6 +2076,33 @@ async function ensureSchema() {
2076
2076
  CREATE INDEX IF NOT EXISTS idx_chat_history_session
2077
2077
  ON chat_history(session_id, id);
2078
2078
  `);
2079
+ await client.executeMultiple(`
2080
+ CREATE TABLE IF NOT EXISTS session_events (
2081
+ id TEXT PRIMARY KEY,
2082
+ agent_id TEXT NOT NULL,
2083
+ agent_role TEXT NOT NULL,
2084
+ session_id TEXT NOT NULL,
2085
+ session_scope TEXT,
2086
+ project_name TEXT NOT NULL,
2087
+ event_index INTEGER NOT NULL,
2088
+ event_type TEXT NOT NULL,
2089
+ tool_name TEXT,
2090
+ tool_use_id TEXT,
2091
+ content TEXT NOT NULL,
2092
+ payload_json TEXT,
2093
+ has_error INTEGER NOT NULL DEFAULT 0,
2094
+ created_at TEXT NOT NULL
2095
+ );
2096
+
2097
+ CREATE INDEX IF NOT EXISTS idx_session_events_agent_time
2098
+ ON session_events(agent_id, created_at DESC);
2099
+
2100
+ CREATE INDEX IF NOT EXISTS idx_session_events_session_index
2101
+ ON session_events(session_id, event_index);
2102
+
2103
+ CREATE INDEX IF NOT EXISTS idx_session_events_scope_agent_time
2104
+ ON session_events(session_scope, agent_id, created_at DESC);
2105
+ `);
2079
2106
  await client.executeMultiple(`
2080
2107
  CREATE TABLE IF NOT EXISTS workspaces (
2081
2108
  id TEXT PRIMARY KEY,
@@ -2105,6 +2105,33 @@ async function ensureSchema() {
2105
2105
  CREATE INDEX IF NOT EXISTS idx_chat_history_session
2106
2106
  ON chat_history(session_id, id);
2107
2107
  `);
2108
+ await client.executeMultiple(`
2109
+ CREATE TABLE IF NOT EXISTS session_events (
2110
+ id TEXT PRIMARY KEY,
2111
+ agent_id TEXT NOT NULL,
2112
+ agent_role TEXT NOT NULL,
2113
+ session_id TEXT NOT NULL,
2114
+ session_scope TEXT,
2115
+ project_name TEXT NOT NULL,
2116
+ event_index INTEGER NOT NULL,
2117
+ event_type TEXT NOT NULL,
2118
+ tool_name TEXT,
2119
+ tool_use_id TEXT,
2120
+ content TEXT NOT NULL,
2121
+ payload_json TEXT,
2122
+ has_error INTEGER NOT NULL DEFAULT 0,
2123
+ created_at TEXT NOT NULL
2124
+ );
2125
+
2126
+ CREATE INDEX IF NOT EXISTS idx_session_events_agent_time
2127
+ ON session_events(agent_id, created_at DESC);
2128
+
2129
+ CREATE INDEX IF NOT EXISTS idx_session_events_session_index
2130
+ ON session_events(session_id, event_index);
2131
+
2132
+ CREATE INDEX IF NOT EXISTS idx_session_events_scope_agent_time
2133
+ ON session_events(session_scope, agent_id, created_at DESC);
2134
+ `);
2108
2135
  await client.executeMultiple(`
2109
2136
  CREATE TABLE IF NOT EXISTS workspaces (
2110
2137
  id TEXT PRIMARY KEY,