@askexenow/exe-os 0.9.69 → 0.9.71

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 (79) hide show
  1. package/deploy/stack-manifests/v0.9.json +96 -16
  2. package/dist/bin/agentic-ontology-backfill.js +33 -0
  3. package/dist/bin/agentic-reflection-backfill.js +33 -0
  4. package/dist/bin/agentic-semantic-label.js +33 -0
  5. package/dist/bin/backfill-conversations.js +33 -0
  6. package/dist/bin/backfill-responses.js +33 -0
  7. package/dist/bin/backfill-vectors.js +33 -0
  8. package/dist/bin/bulk-sync-postgres.js +33 -0
  9. package/dist/bin/cleanup-stale-review-tasks.js +33 -0
  10. package/dist/bin/cli.js +1284 -178
  11. package/dist/bin/exe-agent.js +6 -0
  12. package/dist/bin/exe-assign.js +33 -0
  13. package/dist/bin/exe-boot.js +33 -0
  14. package/dist/bin/exe-call.js +6 -0
  15. package/dist/bin/exe-cloud.js +33 -0
  16. package/dist/bin/exe-dispatch.js +33 -0
  17. package/dist/bin/exe-doctor.js +33 -0
  18. package/dist/bin/exe-export-behaviors.js +33 -0
  19. package/dist/bin/exe-forget.js +33 -0
  20. package/dist/bin/exe-gateway.js +178 -110
  21. package/dist/bin/exe-heartbeat.js +33 -0
  22. package/dist/bin/exe-kill.js +33 -0
  23. package/dist/bin/exe-launch-agent.js +33 -0
  24. package/dist/bin/exe-new-employee.js +6 -0
  25. package/dist/bin/exe-pending-messages.js +33 -0
  26. package/dist/bin/exe-pending-notifications.js +33 -0
  27. package/dist/bin/exe-pending-reviews.js +33 -0
  28. package/dist/bin/exe-rename.js +40 -4
  29. package/dist/bin/exe-review.js +33 -0
  30. package/dist/bin/exe-search.js +33 -0
  31. package/dist/bin/exe-session-cleanup.js +33 -0
  32. package/dist/bin/exe-start-codex.js +33 -0
  33. package/dist/bin/exe-start-opencode.js +33 -0
  34. package/dist/bin/exe-status.js +33 -0
  35. package/dist/bin/exe-team.js +33 -0
  36. package/dist/bin/git-sweep.js +33 -0
  37. package/dist/bin/graph-backfill.js +177 -110
  38. package/dist/bin/graph-export.js +33 -0
  39. package/dist/bin/intercom-check.js +33 -0
  40. package/dist/bin/registry-proxy.js +207 -0
  41. package/dist/bin/scan-tasks.js +33 -0
  42. package/dist/bin/setup.js +33 -0
  43. package/dist/bin/shard-migrate.js +33 -0
  44. package/dist/bin/stack-update.js +128 -0
  45. package/dist/gateway/index.js +178 -110
  46. package/dist/hooks/bug-report-worker.js +33 -0
  47. package/dist/hooks/codex-stop-task-finalizer.js +33 -0
  48. package/dist/hooks/commit-complete.js +33 -0
  49. package/dist/hooks/error-recall.js +33 -0
  50. package/dist/hooks/ingest.js +33 -0
  51. package/dist/hooks/instructions-loaded.js +33 -0
  52. package/dist/hooks/notification.js +33 -0
  53. package/dist/hooks/post-compact.js +33 -0
  54. package/dist/hooks/post-tool-combined.js +698 -17
  55. package/dist/hooks/pre-compact.js +33 -0
  56. package/dist/hooks/pre-tool-use.js +33 -0
  57. package/dist/hooks/prompt-submit.js +314 -0
  58. package/dist/hooks/session-end.js +33 -0
  59. package/dist/hooks/session-start.js +33 -0
  60. package/dist/hooks/stop.js +279 -12
  61. package/dist/hooks/subagent-stop.js +33 -0
  62. package/dist/hooks/summary-worker.js +33 -0
  63. package/dist/index.js +178 -110
  64. package/dist/lib/cloud-sync.js +27 -0
  65. package/dist/lib/database.js +27 -0
  66. package/dist/lib/db.js +27 -0
  67. package/dist/lib/device-registry.js +27 -0
  68. package/dist/lib/employee-templates.js +6 -0
  69. package/dist/lib/exe-daemon.js +639 -259
  70. package/dist/lib/hybrid-search.js +33 -0
  71. package/dist/lib/registry-proxy.js +162 -0
  72. package/dist/lib/schedules.js +33 -0
  73. package/dist/lib/store.js +33 -0
  74. package/dist/mcp/server.js +561 -244
  75. package/dist/runtime/index.js +33 -0
  76. package/dist/tui/App.js +33 -0
  77. package/package.json +3 -2
  78. package/stack.release.json +6 -4
  79. package/stack.release.schema.json +89 -18
@@ -3025,6 +3025,33 @@ async function ensureSchema() {
3025
3025
  CREATE INDEX IF NOT EXISTS idx_chat_history_session
3026
3026
  ON chat_history(session_id, id);
3027
3027
  `);
3028
+ await client.executeMultiple(`
3029
+ CREATE TABLE IF NOT EXISTS session_events (
3030
+ id TEXT PRIMARY KEY,
3031
+ agent_id TEXT NOT NULL,
3032
+ agent_role TEXT NOT NULL,
3033
+ session_id TEXT NOT NULL,
3034
+ session_scope TEXT,
3035
+ project_name TEXT NOT NULL,
3036
+ event_index INTEGER NOT NULL,
3037
+ event_type TEXT NOT NULL,
3038
+ tool_name TEXT,
3039
+ tool_use_id TEXT,
3040
+ content TEXT NOT NULL,
3041
+ payload_json TEXT,
3042
+ has_error INTEGER NOT NULL DEFAULT 0,
3043
+ created_at TEXT NOT NULL
3044
+ );
3045
+
3046
+ CREATE INDEX IF NOT EXISTS idx_session_events_agent_time
3047
+ ON session_events(agent_id, created_at DESC);
3048
+
3049
+ CREATE INDEX IF NOT EXISTS idx_session_events_session_index
3050
+ ON session_events(session_id, event_index);
3051
+
3052
+ CREATE INDEX IF NOT EXISTS idx_session_events_scope_agent_time
3053
+ ON session_events(session_scope, agent_id, created_at DESC);
3054
+ `);
3028
3055
  await client.executeMultiple(`
3029
3056
  CREATE TABLE IF NOT EXISTS workspaces (
3030
3057
  id TEXT PRIMARY KEY,
@@ -7890,6 +7917,12 @@ var init_platform_procedures = __esm({
7890
7917
  priority: "p0",
7891
7918
  content: "exe-build-adv is MANDATORY for ALL work touching 3+ files. Run /exe-build-adv --auto BEFORE implementation. Pipeline: Spec \u2192 AC \u2192 Tests \u2192 Evaluate \u2192 Fix. No multi-file feature ships without pipeline artifacts. No exceptions \u2014 managers reject work without them."
7892
7919
  },
7920
+ {
7921
+ title: "Code context first for repository orientation",
7922
+ domain: "workflow",
7923
+ priority: "p1",
7924
+ content: "Before broad repo exploration, symbol tracing, blast-radius review, or codebase Q&A, agents should use the consolidated code_context MCP tool instead of manual grep/read loops. Use action=index or stats to refresh/check the index; action=search with query, limit, offset, languages, paths, refresh_index for fresh multi-language code/doc search; action=trace for symbol imports/dependents; action=blast_radius for impact analysis before edits. CLI parity exists via exe-os code-context init|index|status|stats|search|doctor. Keep code_context separate from durable employee memory: promote only validated decisions, procedures, or lessons into store_memory/commit_memory."
7925
+ },
7893
7926
  {
7894
7927
  title: "Commit discipline \u2014 never leave verified work floating",
7895
7928
  domain: "workflow",
@@ -3021,6 +3021,33 @@ async function ensureSchema() {
3021
3021
  CREATE INDEX IF NOT EXISTS idx_chat_history_session
3022
3022
  ON chat_history(session_id, id);
3023
3023
  `);
3024
+ await client.executeMultiple(`
3025
+ CREATE TABLE IF NOT EXISTS session_events (
3026
+ id TEXT PRIMARY KEY,
3027
+ agent_id TEXT NOT NULL,
3028
+ agent_role TEXT NOT NULL,
3029
+ session_id TEXT NOT NULL,
3030
+ session_scope TEXT,
3031
+ project_name TEXT NOT NULL,
3032
+ event_index INTEGER NOT NULL,
3033
+ event_type TEXT NOT NULL,
3034
+ tool_name TEXT,
3035
+ tool_use_id TEXT,
3036
+ content TEXT NOT NULL,
3037
+ payload_json TEXT,
3038
+ has_error INTEGER NOT NULL DEFAULT 0,
3039
+ created_at TEXT NOT NULL
3040
+ );
3041
+
3042
+ CREATE INDEX IF NOT EXISTS idx_session_events_agent_time
3043
+ ON session_events(agent_id, created_at DESC);
3044
+
3045
+ CREATE INDEX IF NOT EXISTS idx_session_events_session_index
3046
+ ON session_events(session_id, event_index);
3047
+
3048
+ CREATE INDEX IF NOT EXISTS idx_session_events_scope_agent_time
3049
+ ON session_events(session_scope, agent_id, created_at DESC);
3050
+ `);
3024
3051
  await client.executeMultiple(`
3025
3052
  CREATE TABLE IF NOT EXISTS workspaces (
3026
3053
  id TEXT PRIMARY KEY,
@@ -5036,6 +5063,12 @@ var init_platform_procedures = __esm({
5036
5063
  priority: "p0",
5037
5064
  content: "exe-build-adv is MANDATORY for ALL work touching 3+ files. Run /exe-build-adv --auto BEFORE implementation. Pipeline: Spec \u2192 AC \u2192 Tests \u2192 Evaluate \u2192 Fix. No multi-file feature ships without pipeline artifacts. No exceptions \u2014 managers reject work without them."
5038
5065
  },
5066
+ {
5067
+ title: "Code context first for repository orientation",
5068
+ domain: "workflow",
5069
+ priority: "p1",
5070
+ content: "Before broad repo exploration, symbol tracing, blast-radius review, or codebase Q&A, agents should use the consolidated code_context MCP tool instead of manual grep/read loops. Use action=index or stats to refresh/check the index; action=search with query, limit, offset, languages, paths, refresh_index for fresh multi-language code/doc search; action=trace for symbol imports/dependents; action=blast_radius for impact analysis before edits. CLI parity exists via exe-os code-context init|index|status|stats|search|doctor. Keep code_context separate from durable employee memory: promote only validated decisions, procedures, or lessons into store_memory/commit_memory."
5071
+ },
5039
5072
  {
5040
5073
  title: "Commit discipline \u2014 never leave verified work floating",
5041
5074
  domain: "workflow",
@@ -1386,6 +1386,17 @@ var init_daemon_auth = __esm({
1386
1386
  });
1387
1387
 
1388
1388
  // src/lib/exe-daemon-client.ts
1389
+ var exe_daemon_client_exports = {};
1390
+ __export(exe_daemon_client_exports, {
1391
+ connectEmbedDaemon: () => connectEmbedDaemon,
1392
+ disconnectClient: () => disconnectClient,
1393
+ embedBatchViaClient: () => embedBatchViaClient,
1394
+ embedViaClient: () => embedViaClient,
1395
+ isClientConnected: () => isClientConnected,
1396
+ pingDaemon: () => pingDaemon,
1397
+ sendDaemonRequest: () => sendDaemonRequest,
1398
+ sendIngestRequest: () => sendIngestRequest
1399
+ });
1389
1400
  import net from "net";
1390
1401
  import os4 from "os";
1391
1402
  import { spawn } from "child_process";
@@ -1774,6 +1785,15 @@ async function embedViaClient(text, priority = "high") {
1774
1785
  );
1775
1786
  return !result.error && result.vectors?.[0] ? result.vectors[0] : null;
1776
1787
  }
1788
+ async function embedBatchViaClient(texts, priority = "high") {
1789
+ if (!_connected && !await connectEmbedDaemon()) return null;
1790
+ _requestCount++;
1791
+ const result = await retryThenRestart(
1792
+ () => sendRequest(texts, priority),
1793
+ "Batch embed"
1794
+ );
1795
+ return !result.error && result.vectors ? result.vectors : null;
1796
+ }
1777
1797
  function disconnectClient() {
1778
1798
  if (_socket) {
1779
1799
  _socket.destroy();
@@ -1790,6 +1810,17 @@ function disconnectClient() {
1790
1810
  function isClientConnected() {
1791
1811
  return _connected;
1792
1812
  }
1813
+ function sendIngestRequest(payload) {
1814
+ if (!_socket || !_connected) return false;
1815
+ try {
1816
+ const id = randomUUID();
1817
+ const token = process.env[DAEMON_TOKEN_ENV] ?? readDaemonToken();
1818
+ _socket.write(JSON.stringify({ id, token, type: "ingest", ...payload }) + "\n");
1819
+ return true;
1820
+ } catch {
1821
+ return false;
1822
+ }
1823
+ }
1793
1824
  var SOCKET_PATH, PID_PATH, SPAWN_LOCK_PATH, SPAWN_LOCK_STALE_MS, CONNECT_TIMEOUT_MS, REQUEST_TIMEOUT_MS, DAEMON_TOKEN_ENV, _socket, _connected, _buffer, _requestCount, _consecutiveFailures, HEALTH_CHECK_INTERVAL, MAX_RETRIES_BEFORE_RESTART, RETRY_DELAYS_MS, MIN_DAEMON_AGE_MS, _pending, MAX_BUFFER;
1794
1825
  var init_exe_daemon_client = __esm({
1795
1826
  "src/lib/exe-daemon-client.ts"() {
@@ -1818,6 +1849,15 @@ var init_exe_daemon_client = __esm({
1818
1849
  });
1819
1850
 
1820
1851
  // src/lib/daemon-protocol.ts
1852
+ var daemon_protocol_exports = {};
1853
+ __export(daemon_protocol_exports, {
1854
+ deserializeArgs: () => deserializeArgs,
1855
+ deserializeResultSet: () => deserializeResultSet,
1856
+ deserializeValue: () => deserializeValue,
1857
+ serializeArgs: () => serializeArgs,
1858
+ serializeResultSet: () => serializeResultSet,
1859
+ serializeValue: () => serializeValue
1860
+ });
1821
1861
  function serializeValue(v) {
1822
1862
  if (v === null || v === void 0) return null;
1823
1863
  if (typeof v === "bigint") return Number(v);
@@ -1842,6 +1882,32 @@ function deserializeValue(v) {
1842
1882
  }
1843
1883
  return v;
1844
1884
  }
1885
+ function serializeArgs(args) {
1886
+ return args.map(serializeValue);
1887
+ }
1888
+ function deserializeArgs(args) {
1889
+ return args.map(deserializeValue);
1890
+ }
1891
+ function serializeResultSet(rs) {
1892
+ const rows = [];
1893
+ for (const row of rs.rows) {
1894
+ const obj = {};
1895
+ for (let i = 0; i < rs.columns.length; i++) {
1896
+ const col = rs.columns[i];
1897
+ if (col !== void 0) {
1898
+ obj[col] = serializeValue(row[i]);
1899
+ }
1900
+ }
1901
+ rows.push(obj);
1902
+ }
1903
+ return {
1904
+ columns: [...rs.columns],
1905
+ columnTypes: [...rs.columnTypes ?? []],
1906
+ rows,
1907
+ rowsAffected: typeof rs.rowsAffected === "bigint" ? Number(rs.rowsAffected) : rs.rowsAffected ?? 0,
1908
+ lastInsertRowid: rs.lastInsertRowid != null ? typeof rs.lastInsertRowid === "bigint" ? Number(rs.lastInsertRowid) : rs.lastInsertRowid : null
1909
+ };
1910
+ }
1845
1911
  function deserializeResultSet(srs) {
1846
1912
  const rows = srs.rows.map((obj) => {
1847
1913
  const values = srs.columns.map(
@@ -2781,6 +2847,33 @@ async function ensureSchema() {
2781
2847
  CREATE INDEX IF NOT EXISTS idx_chat_history_session
2782
2848
  ON chat_history(session_id, id);
2783
2849
  `);
2850
+ await client.executeMultiple(`
2851
+ CREATE TABLE IF NOT EXISTS session_events (
2852
+ id TEXT PRIMARY KEY,
2853
+ agent_id TEXT NOT NULL,
2854
+ agent_role TEXT NOT NULL,
2855
+ session_id TEXT NOT NULL,
2856
+ session_scope TEXT,
2857
+ project_name TEXT NOT NULL,
2858
+ event_index INTEGER NOT NULL,
2859
+ event_type TEXT NOT NULL,
2860
+ tool_name TEXT,
2861
+ tool_use_id TEXT,
2862
+ content TEXT NOT NULL,
2863
+ payload_json TEXT,
2864
+ has_error INTEGER NOT NULL DEFAULT 0,
2865
+ created_at TEXT NOT NULL
2866
+ );
2867
+
2868
+ CREATE INDEX IF NOT EXISTS idx_session_events_agent_time
2869
+ ON session_events(agent_id, created_at DESC);
2870
+
2871
+ CREATE INDEX IF NOT EXISTS idx_session_events_session_index
2872
+ ON session_events(session_id, event_index);
2873
+
2874
+ CREATE INDEX IF NOT EXISTS idx_session_events_scope_agent_time
2875
+ ON session_events(session_scope, agent_id, created_at DESC);
2876
+ `);
2784
2877
  await client.executeMultiple(`
2785
2878
  CREATE TABLE IF NOT EXISTS workspaces (
2786
2879
  id TEXT PRIMARY KEY,
@@ -4469,6 +4562,12 @@ var init_platform_procedures = __esm({
4469
4562
  priority: "p0",
4470
4563
  content: "exe-build-adv is MANDATORY for ALL work touching 3+ files. Run /exe-build-adv --auto BEFORE implementation. Pipeline: Spec \u2192 AC \u2192 Tests \u2192 Evaluate \u2192 Fix. No multi-file feature ships without pipeline artifacts. No exceptions \u2014 managers reject work without them."
4471
4564
  },
4565
+ {
4566
+ title: "Code context first for repository orientation",
4567
+ domain: "workflow",
4568
+ priority: "p1",
4569
+ content: "Before broad repo exploration, symbol tracing, blast-radius review, or codebase Q&A, agents should use the consolidated code_context MCP tool instead of manual grep/read loops. Use action=index or stats to refresh/check the index; action=search with query, limit, offset, languages, paths, refresh_index for fresh multi-language code/doc search; action=trace for symbol imports/dependents; action=blast_radius for impact analysis before edits. CLI parity exists via exe-os code-context init|index|status|stats|search|doctor. Keep code_context separate from durable employee memory: promote only validated decisions, procedures, or lessons into store_memory/commit_memory."
4570
+ },
4472
4571
  {
4473
4572
  title: "Commit discipline \u2014 never leave verified work floating",
4474
4573
  domain: "workflow",
@@ -10695,6 +10794,206 @@ var init_messaging = __esm({
10695
10794
  }
10696
10795
  });
10697
10796
 
10797
+ // src/bin/fast-db-init.ts
10798
+ var fast_db_init_exports = {};
10799
+ __export(fast_db_init_exports, {
10800
+ fastDbInit: () => fastDbInit
10801
+ });
10802
+ async function fastDbInit() {
10803
+ const { isInitialized: isInitialized2, getClient: getClient2, setExternalClient: setExternalClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
10804
+ if (isInitialized2()) {
10805
+ return getClient2();
10806
+ }
10807
+ try {
10808
+ const { connectEmbedDaemon: connectEmbedDaemon2, sendDaemonRequest: sendDaemonRequest2, isClientConnected: isClientConnected2 } = await Promise.resolve().then(() => (init_exe_daemon_client(), exe_daemon_client_exports));
10809
+ const { deserializeResultSet: deserializeResultSet2 } = await Promise.resolve().then(() => (init_daemon_protocol(), daemon_protocol_exports));
10810
+ await connectEmbedDaemon2();
10811
+ if (isClientConnected2()) {
10812
+ const daemonClient = {
10813
+ async execute(stmt) {
10814
+ const sql = typeof stmt === "string" ? stmt : stmt.sql;
10815
+ const args = typeof stmt === "string" ? [] : Array.isArray(stmt.args) ? stmt.args : [];
10816
+ const resp = await sendDaemonRequest2({ type: "db-execute", sql, args });
10817
+ if (resp.error) throw new Error(String(resp.error));
10818
+ if (resp.db) return deserializeResultSet2(resp.db);
10819
+ throw new Error("Unexpected daemon response");
10820
+ },
10821
+ async batch(stmts, mode) {
10822
+ const statements = stmts.map((s) => {
10823
+ const sql = typeof s === "string" ? s : s.sql;
10824
+ const args = typeof s === "string" ? [] : Array.isArray(s.args) ? s.args : [];
10825
+ return { sql, args };
10826
+ });
10827
+ const resp = await sendDaemonRequest2({ type: "db-batch", statements, mode: mode ?? "deferred" });
10828
+ if (resp.error) throw new Error(String(resp.error));
10829
+ const batchResults = resp["db-batch"];
10830
+ if (batchResults) return batchResults.map(deserializeResultSet2);
10831
+ throw new Error("Unexpected daemon batch response");
10832
+ },
10833
+ async transaction(_mode) {
10834
+ throw new Error("Transactions not supported via daemon socket");
10835
+ },
10836
+ async executeMultiple(_sql) {
10837
+ throw new Error("executeMultiple not supported via daemon socket");
10838
+ },
10839
+ async migrate(_stmts) {
10840
+ throw new Error("migrate not supported via daemon socket");
10841
+ },
10842
+ sync() {
10843
+ return Promise.resolve(void 0);
10844
+ },
10845
+ close() {
10846
+ },
10847
+ get closed() {
10848
+ return false;
10849
+ },
10850
+ get protocol() {
10851
+ return "file";
10852
+ }
10853
+ };
10854
+ setExternalClient2(daemonClient);
10855
+ return daemonClient;
10856
+ }
10857
+ } catch {
10858
+ }
10859
+ const { initStore: initStore2 } = await Promise.resolve().then(() => (init_store(), store_exports));
10860
+ await initStore2({ lightweight: true });
10861
+ return getClient2();
10862
+ }
10863
+ var init_fast_db_init = __esm({
10864
+ "src/bin/fast-db-init.ts"() {
10865
+ "use strict";
10866
+ }
10867
+ });
10868
+
10869
+ // src/lib/session-events.ts
10870
+ var session_events_exports = {};
10871
+ __export(session_events_exports, {
10872
+ ensureSessionEventsTable: () => ensureSessionEventsTable,
10873
+ listRecentSessionEvents: () => listRecentSessionEvents,
10874
+ recordSessionEvent: () => recordSessionEvent
10875
+ });
10876
+ import { randomUUID as randomUUID4 } from "crypto";
10877
+ async function ensureSessionEventsTable(client) {
10878
+ await client.execute(`
10879
+ CREATE TABLE IF NOT EXISTS session_events (
10880
+ id TEXT PRIMARY KEY,
10881
+ agent_id TEXT NOT NULL,
10882
+ agent_role TEXT NOT NULL,
10883
+ session_id TEXT NOT NULL,
10884
+ session_scope TEXT,
10885
+ project_name TEXT NOT NULL,
10886
+ event_index INTEGER NOT NULL,
10887
+ event_type TEXT NOT NULL,
10888
+ tool_name TEXT,
10889
+ tool_use_id TEXT,
10890
+ content TEXT NOT NULL,
10891
+ payload_json TEXT,
10892
+ has_error INTEGER NOT NULL DEFAULT 0,
10893
+ created_at TEXT NOT NULL
10894
+ )
10895
+ `);
10896
+ await client.execute(`
10897
+ CREATE INDEX IF NOT EXISTS idx_session_events_agent_time
10898
+ ON session_events(agent_id, created_at DESC)
10899
+ `);
10900
+ await client.execute(`
10901
+ CREATE INDEX IF NOT EXISTS idx_session_events_session_index
10902
+ ON session_events(session_id, event_index)
10903
+ `);
10904
+ await client.execute(`
10905
+ CREATE INDEX IF NOT EXISTS idx_session_events_scope_agent_time
10906
+ ON session_events(session_scope, agent_id, created_at DESC)
10907
+ `);
10908
+ }
10909
+ async function recordSessionEvent(client, input2) {
10910
+ if (!input2.content || input2.content.trim().length === 0) return;
10911
+ await ensureSessionEventsTable(client);
10912
+ const maxResult = await client.execute({
10913
+ sql: "SELECT COALESCE(MAX(event_index), 0) AS max_index FROM session_events WHERE session_id = ?",
10914
+ args: [input2.sessionId]
10915
+ });
10916
+ const currentMax = Number(maxResult.rows[0]?.max_index ?? 0);
10917
+ const eventIndex = Number.isFinite(currentMax) ? currentMax + 1 : 1;
10918
+ await client.execute({
10919
+ sql: `INSERT INTO session_events (
10920
+ id, agent_id, agent_role, session_id, session_scope, project_name,
10921
+ event_index, event_type, tool_name, tool_use_id, content,
10922
+ payload_json, has_error, created_at
10923
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
10924
+ args: [
10925
+ randomUUID4(),
10926
+ input2.agentId,
10927
+ input2.agentRole,
10928
+ input2.sessionId,
10929
+ input2.sessionScope ?? getCurrentSessionScope(),
10930
+ input2.projectName ?? getProjectName(input2.cwd),
10931
+ eventIndex,
10932
+ input2.eventType,
10933
+ input2.toolName ?? null,
10934
+ input2.toolUseId ?? null,
10935
+ input2.content,
10936
+ input2.payloadJson ?? null,
10937
+ input2.hasError ? 1 : 0,
10938
+ input2.timestamp ?? (/* @__PURE__ */ new Date()).toISOString()
10939
+ ]
10940
+ });
10941
+ }
10942
+ async function listRecentSessionEvents(client, options) {
10943
+ await ensureSessionEventsTable(client);
10944
+ const conditions = ["agent_id = ?"];
10945
+ const args = [options.agentId];
10946
+ if (options.sessionId) {
10947
+ conditions.push("session_id = ?");
10948
+ args.push(options.sessionId);
10949
+ }
10950
+ if (options.eventType) {
10951
+ conditions.push("event_type = ?");
10952
+ args.push(options.eventType);
10953
+ }
10954
+ if (options.projectName && options.projectName !== "all") {
10955
+ conditions.push("project_name = ?");
10956
+ args.push(options.projectName);
10957
+ }
10958
+ const scope = strictSessionScopeFilter(options.sessionScope);
10959
+ const where = `WHERE ${conditions.join(" AND ")}${scope.sql}`;
10960
+ args.push(...scope.args);
10961
+ args.push(Math.min(Math.max(options.limit ?? 20, 1), 100));
10962
+ const result = await client.execute({
10963
+ sql: `SELECT id, agent_id, agent_role, session_id, session_scope,
10964
+ project_name, event_index, event_type, tool_name, tool_use_id,
10965
+ content, payload_json, has_error, created_at
10966
+ FROM session_events
10967
+ ${where}
10968
+ ORDER BY created_at DESC, event_index DESC
10969
+ LIMIT ?`,
10970
+ args
10971
+ });
10972
+ return result.rows.map((row) => ({
10973
+ id: String(row.id),
10974
+ agentId: String(row.agent_id),
10975
+ agentRole: String(row.agent_role),
10976
+ sessionId: String(row.session_id),
10977
+ sessionScope: row.session_scope == null ? null : String(row.session_scope),
10978
+ projectName: String(row.project_name),
10979
+ eventIndex: Number(row.event_index),
10980
+ eventType: String(row.event_type),
10981
+ toolName: row.tool_name == null ? null : String(row.tool_name),
10982
+ toolUseId: row.tool_use_id == null ? null : String(row.tool_use_id),
10983
+ content: String(row.content),
10984
+ payloadJson: row.payload_json == null ? null : String(row.payload_json),
10985
+ hasError: Number(row.has_error) === 1,
10986
+ createdAt: String(row.created_at)
10987
+ }));
10988
+ }
10989
+ var init_session_events = __esm({
10990
+ "src/lib/session-events.ts"() {
10991
+ "use strict";
10992
+ init_task_scope();
10993
+ init_project_name();
10994
+ }
10995
+ });
10996
+
10698
10997
  // src/lib/memory-queue.ts
10699
10998
  import { appendFileSync as appendFileSync2, readFileSync as readFileSync16, renameSync as renameSync5, unlinkSync as unlinkSync9, existsSync as existsSync21, statSync as statSync5 } from "fs";
10700
10999
  import path25 from "path";
@@ -11817,6 +12116,21 @@ IMPORTANT: After completing your current task, you MUST address the pending revi
11817
12116
  });
11818
12117
  async function writePromptMemory(prompt, sessionId, agent) {
11819
12118
  if (!loadConfigSync().autoIngestion) return;
12119
+ try {
12120
+ const { fastDbInit: fastDbInit2 } = await Promise.resolve().then(() => (init_fast_db_init(), fast_db_init_exports));
12121
+ const { recordSessionEvent: recordSessionEvent2 } = await Promise.resolve().then(() => (init_session_events(), session_events_exports));
12122
+ const client = await fastDbInit2();
12123
+ await recordSessionEvent2(client, {
12124
+ agentId: agent.agentId,
12125
+ agentRole: agent.agentRole,
12126
+ sessionId,
12127
+ eventType: "user_prompt",
12128
+ content: prompt.slice(0, 1e4),
12129
+ projectName: getProjectName(),
12130
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
12131
+ });
12132
+ } catch {
12133
+ }
11820
12134
  try {
11821
12135
  const { writeMemoryViaDaemon: writeMemoryViaDaemon2 } = await Promise.resolve().then(() => (init_memory_queue_client(), memory_queue_client_exports));
11822
12136
  await writeMemoryViaDaemon2({
@@ -3028,6 +3028,33 @@ async function ensureSchema() {
3028
3028
  CREATE INDEX IF NOT EXISTS idx_chat_history_session
3029
3029
  ON chat_history(session_id, id);
3030
3030
  `);
3031
+ await client.executeMultiple(`
3032
+ CREATE TABLE IF NOT EXISTS session_events (
3033
+ id TEXT PRIMARY KEY,
3034
+ agent_id TEXT NOT NULL,
3035
+ agent_role TEXT NOT NULL,
3036
+ session_id TEXT NOT NULL,
3037
+ session_scope TEXT,
3038
+ project_name TEXT NOT NULL,
3039
+ event_index INTEGER NOT NULL,
3040
+ event_type TEXT NOT NULL,
3041
+ tool_name TEXT,
3042
+ tool_use_id TEXT,
3043
+ content TEXT NOT NULL,
3044
+ payload_json TEXT,
3045
+ has_error INTEGER NOT NULL DEFAULT 0,
3046
+ created_at TEXT NOT NULL
3047
+ );
3048
+
3049
+ CREATE INDEX IF NOT EXISTS idx_session_events_agent_time
3050
+ ON session_events(agent_id, created_at DESC);
3051
+
3052
+ CREATE INDEX IF NOT EXISTS idx_session_events_session_index
3053
+ ON session_events(session_id, event_index);
3054
+
3055
+ CREATE INDEX IF NOT EXISTS idx_session_events_scope_agent_time
3056
+ ON session_events(session_scope, agent_id, created_at DESC);
3057
+ `);
3031
3058
  await client.executeMultiple(`
3032
3059
  CREATE TABLE IF NOT EXISTS workspaces (
3033
3060
  id TEXT PRIMARY KEY,
@@ -8099,6 +8126,12 @@ var init_platform_procedures = __esm({
8099
8126
  priority: "p0",
8100
8127
  content: "exe-build-adv is MANDATORY for ALL work touching 3+ files. Run /exe-build-adv --auto BEFORE implementation. Pipeline: Spec \u2192 AC \u2192 Tests \u2192 Evaluate \u2192 Fix. No multi-file feature ships without pipeline artifacts. No exceptions \u2014 managers reject work without them."
8101
8128
  },
8129
+ {
8130
+ title: "Code context first for repository orientation",
8131
+ domain: "workflow",
8132
+ priority: "p1",
8133
+ content: "Before broad repo exploration, symbol tracing, blast-radius review, or codebase Q&A, agents should use the consolidated code_context MCP tool instead of manual grep/read loops. Use action=index or stats to refresh/check the index; action=search with query, limit, offset, languages, paths, refresh_index for fresh multi-language code/doc search; action=trace for symbol imports/dependents; action=blast_radius for impact analysis before edits. CLI parity exists via exe-os code-context init|index|status|stats|search|doctor. Keep code_context separate from durable employee memory: promote only validated decisions, procedures, or lessons into store_memory/commit_memory."
8134
+ },
8102
8135
  {
8103
8136
  title: "Commit discipline \u2014 never leave verified work floating",
8104
8137
  domain: "workflow",
@@ -2847,6 +2847,33 @@ async function ensureSchema() {
2847
2847
  CREATE INDEX IF NOT EXISTS idx_chat_history_session
2848
2848
  ON chat_history(session_id, id);
2849
2849
  `);
2850
+ await client.executeMultiple(`
2851
+ CREATE TABLE IF NOT EXISTS session_events (
2852
+ id TEXT PRIMARY KEY,
2853
+ agent_id TEXT NOT NULL,
2854
+ agent_role TEXT NOT NULL,
2855
+ session_id TEXT NOT NULL,
2856
+ session_scope TEXT,
2857
+ project_name TEXT NOT NULL,
2858
+ event_index INTEGER NOT NULL,
2859
+ event_type TEXT NOT NULL,
2860
+ tool_name TEXT,
2861
+ tool_use_id TEXT,
2862
+ content TEXT NOT NULL,
2863
+ payload_json TEXT,
2864
+ has_error INTEGER NOT NULL DEFAULT 0,
2865
+ created_at TEXT NOT NULL
2866
+ );
2867
+
2868
+ CREATE INDEX IF NOT EXISTS idx_session_events_agent_time
2869
+ ON session_events(agent_id, created_at DESC);
2870
+
2871
+ CREATE INDEX IF NOT EXISTS idx_session_events_session_index
2872
+ ON session_events(session_id, event_index);
2873
+
2874
+ CREATE INDEX IF NOT EXISTS idx_session_events_scope_agent_time
2875
+ ON session_events(session_scope, agent_id, created_at DESC);
2876
+ `);
2850
2877
  await client.executeMultiple(`
2851
2878
  CREATE TABLE IF NOT EXISTS workspaces (
2852
2879
  id TEXT PRIMARY KEY,
@@ -4535,6 +4562,12 @@ var init_platform_procedures = __esm({
4535
4562
  priority: "p0",
4536
4563
  content: "exe-build-adv is MANDATORY for ALL work touching 3+ files. Run /exe-build-adv --auto BEFORE implementation. Pipeline: Spec \u2192 AC \u2192 Tests \u2192 Evaluate \u2192 Fix. No multi-file feature ships without pipeline artifacts. No exceptions \u2014 managers reject work without them."
4537
4564
  },
4565
+ {
4566
+ title: "Code context first for repository orientation",
4567
+ domain: "workflow",
4568
+ priority: "p1",
4569
+ content: "Before broad repo exploration, symbol tracing, blast-radius review, or codebase Q&A, agents should use the consolidated code_context MCP tool instead of manual grep/read loops. Use action=index or stats to refresh/check the index; action=search with query, limit, offset, languages, paths, refresh_index for fresh multi-language code/doc search; action=trace for symbol imports/dependents; action=blast_radius for impact analysis before edits. CLI parity exists via exe-os code-context init|index|status|stats|search|doctor. Keep code_context separate from durable employee memory: promote only validated decisions, procedures, or lessons into store_memory/commit_memory."
4570
+ },
4538
4571
  {
4539
4572
  title: "Commit discipline \u2014 never leave verified work floating",
4540
4573
  domain: "workflow",