@askexenow/exe-os 0.9.93 → 0.9.94

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 (88) hide show
  1. package/deploy/compose/docker-compose.yml +1 -0
  2. package/dist/bin/agentic-ontology-backfill.js +65 -8
  3. package/dist/bin/agentic-reflection-backfill.js +54 -3
  4. package/dist/bin/agentic-semantic-label.js +54 -3
  5. package/dist/bin/backfill-conversations.js +69 -9
  6. package/dist/bin/backfill-responses.js +69 -9
  7. package/dist/bin/backfill-vectors.js +54 -3
  8. package/dist/bin/bulk-sync-postgres.js +66 -8
  9. package/dist/bin/cleanup-stale-review-tasks.js +118 -13
  10. package/dist/bin/cli.js +1558 -466
  11. package/dist/bin/customer-readiness.js +51 -0
  12. package/dist/bin/exe-agent.js +17 -3
  13. package/dist/bin/exe-assign.js +75 -9
  14. package/dist/bin/exe-boot.js +111 -12
  15. package/dist/bin/exe-call.js +17 -3
  16. package/dist/bin/exe-cloud.js +76 -10
  17. package/dist/bin/exe-dispatch.js +133 -18
  18. package/dist/bin/exe-doctor.js +75 -9
  19. package/dist/bin/exe-export-behaviors.js +75 -9
  20. package/dist/bin/exe-forget.js +94 -9
  21. package/dist/bin/exe-gateway.js +132 -18
  22. package/dist/bin/exe-heartbeat.js +118 -13
  23. package/dist/bin/exe-kill.js +75 -9
  24. package/dist/bin/exe-launch-agent.js +75 -9
  25. package/dist/bin/exe-new-employee.js +18 -4
  26. package/dist/bin/exe-pending-messages.js +118 -13
  27. package/dist/bin/exe-pending-notifications.js +118 -13
  28. package/dist/bin/exe-pending-reviews.js +118 -13
  29. package/dist/bin/exe-rename.js +75 -9
  30. package/dist/bin/exe-review.js +75 -9
  31. package/dist/bin/exe-search.js +100 -9
  32. package/dist/bin/exe-session-cleanup.js +133 -18
  33. package/dist/bin/exe-settings.js +1 -0
  34. package/dist/bin/exe-start-codex.js +65 -8
  35. package/dist/bin/exe-start-opencode.js +65 -8
  36. package/dist/bin/exe-status.js +118 -13
  37. package/dist/bin/exe-support.js +1 -0
  38. package/dist/bin/exe-team.js +75 -9
  39. package/dist/bin/git-sweep.js +133 -18
  40. package/dist/bin/graph-backfill.js +65 -8
  41. package/dist/bin/graph-export.js +75 -9
  42. package/dist/bin/intercom-check.js +133 -18
  43. package/dist/bin/scan-tasks.js +133 -18
  44. package/dist/bin/setup.js +55 -4
  45. package/dist/bin/shard-migrate.js +65 -8
  46. package/dist/bin/stack-update.js +5 -6
  47. package/dist/bin/update.js +1 -1
  48. package/dist/gateway/index.js +133 -18
  49. package/dist/hooks/bug-report-worker.js +133 -18
  50. package/dist/hooks/codex-stop-task-finalizer.js +123 -14
  51. package/dist/hooks/commit-complete.js +133 -18
  52. package/dist/hooks/error-recall.js +100 -9
  53. package/dist/hooks/ingest.js +75 -9
  54. package/dist/hooks/instructions-loaded.js +75 -9
  55. package/dist/hooks/notification.js +75 -9
  56. package/dist/hooks/post-compact.js +310 -50
  57. package/dist/hooks/post-tool-combined.js +433 -13
  58. package/dist/hooks/pre-compact.js +133 -18
  59. package/dist/hooks/pre-tool-use.js +118 -13
  60. package/dist/hooks/prompt-submit.js +191 -19
  61. package/dist/hooks/session-end.js +133 -18
  62. package/dist/hooks/session-start.js +143 -13
  63. package/dist/hooks/stop.js +118 -13
  64. package/dist/hooks/subagent-stop.js +118 -13
  65. package/dist/hooks/summary-worker.js +96 -7
  66. package/dist/index.js +133 -18
  67. package/dist/lib/cloud-sync.js +38 -0
  68. package/dist/lib/consolidation.js +3 -1
  69. package/dist/lib/database.js +37 -0
  70. package/dist/lib/db.js +37 -0
  71. package/dist/lib/device-registry.js +37 -0
  72. package/dist/lib/employee-templates.js +17 -3
  73. package/dist/lib/exe-daemon.js +913 -42
  74. package/dist/lib/hybrid-search.js +100 -9
  75. package/dist/lib/license.js +1 -1
  76. package/dist/lib/messaging.js +40 -4
  77. package/dist/lib/schedules.js +54 -3
  78. package/dist/lib/store.js +75 -9
  79. package/dist/lib/tasks.js +58 -9
  80. package/dist/lib/tmux-routing.js +58 -9
  81. package/dist/mcp/server.js +875 -42
  82. package/dist/mcp/tools/create-task.js +67 -12
  83. package/dist/mcp/tools/list-tasks.js +46 -5
  84. package/dist/mcp/tools/send-message.js +40 -4
  85. package/dist/mcp/tools/update-task.js +58 -9
  86. package/dist/runtime/index.js +133 -18
  87. package/dist/tui/App.js +132 -18
  88. package/package.json +1 -1
@@ -2690,6 +2690,20 @@ async function ensureSchema() {
2690
2690
  });
2691
2691
  } catch {
2692
2692
  }
2693
+ try {
2694
+ await client.execute({
2695
+ sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
2696
+ args: []
2697
+ });
2698
+ } catch {
2699
+ }
2700
+ try {
2701
+ await client.execute({
2702
+ sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
2703
+ args: []
2704
+ });
2705
+ } catch {
2706
+ }
2693
2707
  await client.executeMultiple(`
2694
2708
  CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
2695
2709
  content_text,
@@ -2941,6 +2955,22 @@ async function ensureSchema() {
2941
2955
  );
2942
2956
  } catch {
2943
2957
  }
2958
+ for (const col of [
2959
+ "ALTER TABLE memories ADD COLUMN valid_from TEXT",
2960
+ "ALTER TABLE memories ADD COLUMN invalid_at TEXT"
2961
+ ]) {
2962
+ try {
2963
+ await client.execute(col);
2964
+ } catch {
2965
+ }
2966
+ }
2967
+ try {
2968
+ await client.execute({
2969
+ sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
2970
+ args: []
2971
+ });
2972
+ } catch {
2973
+ }
2944
2974
  try {
2945
2975
  await client.execute({
2946
2976
  sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
@@ -2983,6 +3013,13 @@ async function ensureSchema() {
2983
3013
  } catch {
2984
3014
  }
2985
3015
  }
3016
+ try {
3017
+ await client.execute({
3018
+ sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
3019
+ args: []
3020
+ });
3021
+ } catch {
3022
+ }
2986
3023
  try {
2987
3024
  await client.execute({
2988
3025
  sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
@@ -3564,6 +3601,20 @@ var init_platform_procedures = __esm({
3564
3601
  priority: "p1",
3565
3602
  content: "Once per session (COO boot only, never repeat), call list_my_feature_requests to check if any previously filed feature requests have been shipped by AskExe. If any request has status 'shipped' with a shipped_version, surface it to the founder immediately: '\u{1F680} N feature(s) shipped \u2014 run exe-os update to get version X.Y.Z'. This is a one-time check at boot, not a recurring poll. If no requests exist or none are shipped, skip silently. If the MCP tool is unavailable or the network call fails, skip silently \u2014 this is informational, not blocking."
3566
3603
  },
3604
+ // --- Tool guidance ---
3605
+ {
3606
+ title: "How to use company_actions \u2014 execute business actions through gateway connectors",
3607
+ domain: "tools",
3608
+ priority: "p2",
3609
+ content: "The company_actions tool executes business actions through gateway connectors (e.g. send WhatsApp, trigger workflows, update CRM). It routes through the exe-gateway on the VPS. Actions are defined by the customer's gateway configuration \u2014 each connector (WhatsApp, Shopify, email, etc.) exposes specific actions. Use query_company_brain to find available data first, then company_actions to act on it. Requires gateway auth token. Read-only founders should NOT use this \u2014 it mutates external state."
3610
+ },
3611
+ // --- Release awareness ---
3612
+ {
3613
+ title: "What's New check \u2014 surface new features after update",
3614
+ domain: "support",
3615
+ priority: "p1",
3616
+ content: "Once per session (COO boot only, never repeat), check if the installed exe-os version is newer than the last session. If it is, read the bundled release-notes.json (at the package root) and surface a brief summary to the founder: 'Updated to exe-os vX.Y.Z \u2014 N new features, M fixes.' List the top 3 features by name. This helps the founder know what they got from the update. If release-notes.json doesn't exist or the version hasn't changed, skip silently. Never repeat this check in the same session."
3617
+ },
3567
3618
  // --- Platform vs Customer ownership ---
3568
3619
  {
3569
3620
  title: "What the platform provides vs what you customize",
@@ -3652,13 +3703,13 @@ var init_platform_procedures = __esm({
3652
3703
  title: "MCP tools \u2014 memory, decision, and search",
3653
3704
  domain: "tool-use",
3654
3705
  priority: "p1",
3655
- content: `memory(action="recall") / recall_my_memory: search your own memories (semantic + FTS). memory(action="ask_team") / ask_team_memory: search a colleague's memories by agent name. memory(action="store") / store_memory: persist a memory. memory(action="commit") / commit_memory: high-importance memory that survives consolidation. Requires summary. memory(action="search") / search_everything: unified search across memories, tasks, entities, conversations. memory(action="session_context") / get_session_context: temporal memory window. Requires session_id + target_timestamp. memory(action="consolidate") / consolidate_memories: merge duplicate/related memories. memory(action="cardinality") / get_memory_cardinality: count memories per agent. decision(action="store") / store_decision: record an architectural decision (domain, decision, rationale). decision(action="get") / get_decision: retrieve a past decision by domain or query.`
3706
+ content: `memory(action="recall") / recall_my_memory: search your own memories (semantic + FTS). Supports as_of param for bi-temporal queries (what did I know at time X?), kind param to filter by memory type (decision, procedure, observation, raw, conversation, behavior). memory(action="ask_team") / ask_team_memory: search a colleague's memories by agent name. memory(action="store") / store_memory: persist a memory. Supports kind param and procedure_for domain tag for procedure-type memories. memory(action="commit") / commit_memory: high-importance memory that survives consolidation. Requires summary. memory(action="search") / search_everything: unified search across memories, tasks, entities, conversations. memory(action="session_context") / get_session_context: temporal memory window. Requires session_id + target_timestamp. memory(action="consolidate") / consolidate_memories: merge duplicate/related memories. memory(action="cardinality") / get_memory_cardinality: count memories per agent. memory(action="supersede") / supersede: replace an old memory with a new version (old_id + new text). decision(action="store") / store_decision: record an architectural decision (domain, decision, rationale). decision(action="get") / get_decision: retrieve a past decision by domain or query.`
3656
3707
  },
3657
3708
  {
3658
3709
  title: "MCP tools \u2014 task orchestration",
3659
3710
  domain: "tool-use",
3660
3711
  priority: "p1",
3661
- content: 'task(action="create") / create_task: dispatch work (title, assigned_to, context). The ONLY dispatch path. Auto-spawns session. task(action="list") / list_tasks: query tasks by status, assignee, project. task(action="get") / get_task: fetch full task details by task_id. task(action="update") / update_task: change status (in_progress, done, blocked, cancelled) + result summary. task(action="close") / close_task: finalize a reviewed task (COO only). task(action="checkpoint") / checkpoint_task: save progress state for crash recovery. task(action="resume") / resume_employee: re-spawn an employee session for an existing task.'
3712
+ content: `task(action="create") / create_task: dispatch work (title, assigned_to, context). The ONLY dispatch path. Auto-spawns session. Supports spawn_runtime and spawn_model params to override the agent's default runtime/model for a specific task. task(action="list") / list_tasks: query tasks by status, assignee, project. task(action="get") / get_task: fetch full task details by task_id. task(action="update") / update_task: change status (in_progress, done, blocked, cancelled) + result summary. task(action="close") / close_task: finalize a reviewed task (COO only). task(action="checkpoint") / checkpoint_task: save progress state for crash recovery. task(action="resume") / resume_employee: re-spawn an employee session for an existing task.`
3662
3713
  },
3663
3714
  {
3664
3715
  title: "MCP tools \u2014 knowledge graph (GraphRAG)",
@@ -3688,7 +3739,7 @@ var init_platform_procedures = __esm({
3688
3739
  title: "MCP tools \u2014 admin, config, and operations",
3689
3740
  domain: "tool-use",
3690
3741
  priority: "p1",
3691
- content: 'config(action="list_employees"): view roster. config(action="agent_spend"): token usage per agent. config(action="daemon_health"): check exed status. config(action="license_status"): check license. config(action="cloud_sync"): force sync. config(action="memory_audit"): health check (dupes, null vectors). config(action="run_consolidation"): trigger memory consolidation. config(action="company_procedure", subaction="store|list|deactivate"): manage company procedures. config(action="global_procedure"): list all procedures (platform + company). config(action="create_trigger|list_triggers"): scheduled agent jobs. config(action="export_orchestration|import_orchestration"): portable org state. diagnostics(action="healthcheck|doctor|status_brief|check_update|cloud_status"): system diagnostics. mcp_ping(): daemon health + license status + tool usage stats.'
3742
+ content: 'config(action="list_employees"): view roster. config(action="agent_spend"): token usage per agent. config(action="daemon_health"): check exed status. config(action="license_status"): check license. config(action="cloud_sync"): force sync. config(action="memory_audit"): health check (dupes, null vectors). config(action="run_consolidation"): trigger memory consolidation. config(action="company_procedure", subaction="store|list|deactivate"): manage company procedures. config(action="global_procedure"): list all procedures (platform + company). config(action="create_trigger|list_triggers"): scheduled agent jobs. config(action="export_orchestration|import_orchestration"): portable org state. diagnostics(action="healthcheck|doctor|status_brief|check_update|cloud_status"): system diagnostics. diagnostics(action="tool_search"): semantic tool discovery \u2014 find relevant MCP tools by natural language query. Returns top-K tools ranked by relevance. diagnostics(action="drift"): identity drift detection \u2014 score how far an agent has drifted from its role identity. Returns drift score + recommendations. mcp_ping(): daemon health + license status + tool usage stats.'
3692
3743
  }
3693
3744
  ];
3694
3745
  PLATFORM_PROCEDURE_TITLES = new Set(
@@ -4917,6 +4968,8 @@ async function writeMemory(record) {
4917
4968
  source_type: record.source_type ?? null,
4918
4969
  tier: record.tier ?? classifyTier(record),
4919
4970
  supersedes_id: record.supersedes_id ?? null,
4971
+ valid_from: record.valid_from ?? record.timestamp,
4972
+ invalid_at: record.invalid_at ?? null,
4920
4973
  draft: record.draft ? 1 : 0,
4921
4974
  memory_type: memoryType,
4922
4975
  trajectory: record.trajectory ? JSON.stringify(record.trajectory) : null,
@@ -4935,7 +4988,8 @@ async function writeMemory(record) {
4935
4988
  token_cost: record.token_cost ?? null,
4936
4989
  audience: record.audience ?? null,
4937
4990
  language_type: record.language_type ?? inferLanguageType(record),
4938
- parent_memory_id: record.parent_memory_id ?? null
4991
+ parent_memory_id: record.parent_memory_id ?? null,
4992
+ procedure_for: record.procedure_for ?? null
4939
4993
  };
4940
4994
  _pendingRecords.push(dbRow);
4941
4995
  orgBus.emit({
@@ -4990,6 +5044,8 @@ async function flushBatch() {
4990
5044
  const sourceType = row.source_type ?? null;
4991
5045
  const tier = row.tier ?? 3;
4992
5046
  const supersedesId = row.supersedes_id ?? null;
5047
+ const validFrom = row.valid_from ?? row.timestamp;
5048
+ const invalidAt = row.invalid_at ?? null;
4993
5049
  const draft = row.draft ? 1 : 0;
4994
5050
  const memoryType = row.memory_type ?? "raw";
4995
5051
  const trajectory = row.trajectory ?? null;
@@ -5009,15 +5065,16 @@ async function flushBatch() {
5009
5065
  const audience = row.audience ?? null;
5010
5066
  const languageType = row.language_type ?? null;
5011
5067
  const parentMemoryId = row.parent_memory_id ?? null;
5068
+ const procedureFor = row.procedure_for ?? null;
5012
5069
  const cols = `id, agent_id, agent_role, session_id, timestamp,
5013
5070
  tool_name, project_name,
5014
5071
  has_error, raw_text, vector, version, task_id, importance, status,
5015
5072
  confidence, last_accessed,
5016
5073
  workspace_id, document_id, user_id, char_offset, page_number,
5017
- source_path, source_type, tier, supersedes_id, draft, memory_type, trajectory, content_hash,
5074
+ source_path, source_type, tier, supersedes_id, valid_from, invalid_at, draft, memory_type, trajectory, content_hash,
5018
5075
  intent, outcome, domain, referenced_entities, retrieval_count,
5019
5076
  chain_position, review_status, context_window_pct, file_paths, commit_hash,
5020
- duration_ms, token_cost, audience, language_type, parent_memory_id`;
5077
+ duration_ms, token_cost, audience, language_type, parent_memory_id, procedure_for`;
5021
5078
  const metaArgs = [
5022
5079
  intent,
5023
5080
  outcome,
@@ -5033,7 +5090,8 @@ async function flushBatch() {
5033
5090
  tokenCost,
5034
5091
  audience,
5035
5092
  languageType,
5036
- parentMemoryId
5093
+ parentMemoryId,
5094
+ procedureFor
5037
5095
  ];
5038
5096
  const baseArgs = [
5039
5097
  row.id,
@@ -5062,6 +5120,8 @@ async function flushBatch() {
5062
5120
  sourceType,
5063
5121
  tier,
5064
5122
  supersedesId,
5123
+ validFrom,
5124
+ invalidAt,
5065
5125
  draft,
5066
5126
  memoryType,
5067
5127
  trajectory,
@@ -5069,8 +5129,8 @@ async function flushBatch() {
5069
5129
  ];
5070
5130
  return {
5071
5131
  sql: hasVector ? `INSERT OR IGNORE INTO memories (${cols})
5072
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
5073
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
5132
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
5133
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
5074
5134
  args: hasVector ? [...baseArgs, vectorToBlob(row.vector), ...sharedArgs, ...metaArgs] : [...baseArgs, ...sharedArgs, ...metaArgs]
5075
5135
  };
5076
5136
  };
@@ -2686,6 +2686,20 @@ async function ensureSchema() {
2686
2686
  });
2687
2687
  } catch {
2688
2688
  }
2689
+ try {
2690
+ await client.execute({
2691
+ sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
2692
+ args: []
2693
+ });
2694
+ } catch {
2695
+ }
2696
+ try {
2697
+ await client.execute({
2698
+ sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
2699
+ args: []
2700
+ });
2701
+ } catch {
2702
+ }
2689
2703
  await client.executeMultiple(`
2690
2704
  CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
2691
2705
  content_text,
@@ -2937,6 +2951,22 @@ async function ensureSchema() {
2937
2951
  );
2938
2952
  } catch {
2939
2953
  }
2954
+ for (const col of [
2955
+ "ALTER TABLE memories ADD COLUMN valid_from TEXT",
2956
+ "ALTER TABLE memories ADD COLUMN invalid_at TEXT"
2957
+ ]) {
2958
+ try {
2959
+ await client.execute(col);
2960
+ } catch {
2961
+ }
2962
+ }
2963
+ try {
2964
+ await client.execute({
2965
+ sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
2966
+ args: []
2967
+ });
2968
+ } catch {
2969
+ }
2940
2970
  try {
2941
2971
  await client.execute({
2942
2972
  sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
@@ -2979,6 +3009,13 @@ async function ensureSchema() {
2979
3009
  } catch {
2980
3010
  }
2981
3011
  }
3012
+ try {
3013
+ await client.execute({
3014
+ sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
3015
+ args: []
3016
+ });
3017
+ } catch {
3018
+ }
2982
3019
  try {
2983
3020
  await client.execute({
2984
3021
  sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
@@ -3560,6 +3597,20 @@ var init_platform_procedures = __esm({
3560
3597
  priority: "p1",
3561
3598
  content: "Once per session (COO boot only, never repeat), call list_my_feature_requests to check if any previously filed feature requests have been shipped by AskExe. If any request has status 'shipped' with a shipped_version, surface it to the founder immediately: '\u{1F680} N feature(s) shipped \u2014 run exe-os update to get version X.Y.Z'. This is a one-time check at boot, not a recurring poll. If no requests exist or none are shipped, skip silently. If the MCP tool is unavailable or the network call fails, skip silently \u2014 this is informational, not blocking."
3562
3599
  },
3600
+ // --- Tool guidance ---
3601
+ {
3602
+ title: "How to use company_actions \u2014 execute business actions through gateway connectors",
3603
+ domain: "tools",
3604
+ priority: "p2",
3605
+ content: "The company_actions tool executes business actions through gateway connectors (e.g. send WhatsApp, trigger workflows, update CRM). It routes through the exe-gateway on the VPS. Actions are defined by the customer's gateway configuration \u2014 each connector (WhatsApp, Shopify, email, etc.) exposes specific actions. Use query_company_brain to find available data first, then company_actions to act on it. Requires gateway auth token. Read-only founders should NOT use this \u2014 it mutates external state."
3606
+ },
3607
+ // --- Release awareness ---
3608
+ {
3609
+ title: "What's New check \u2014 surface new features after update",
3610
+ domain: "support",
3611
+ priority: "p1",
3612
+ content: "Once per session (COO boot only, never repeat), check if the installed exe-os version is newer than the last session. If it is, read the bundled release-notes.json (at the package root) and surface a brief summary to the founder: 'Updated to exe-os vX.Y.Z \u2014 N new features, M fixes.' List the top 3 features by name. This helps the founder know what they got from the update. If release-notes.json doesn't exist or the version hasn't changed, skip silently. Never repeat this check in the same session."
3613
+ },
3563
3614
  // --- Platform vs Customer ownership ---
3564
3615
  {
3565
3616
  title: "What the platform provides vs what you customize",
@@ -3648,13 +3699,13 @@ var init_platform_procedures = __esm({
3648
3699
  title: "MCP tools \u2014 memory, decision, and search",
3649
3700
  domain: "tool-use",
3650
3701
  priority: "p1",
3651
- content: `memory(action="recall") / recall_my_memory: search your own memories (semantic + FTS). memory(action="ask_team") / ask_team_memory: search a colleague's memories by agent name. memory(action="store") / store_memory: persist a memory. memory(action="commit") / commit_memory: high-importance memory that survives consolidation. Requires summary. memory(action="search") / search_everything: unified search across memories, tasks, entities, conversations. memory(action="session_context") / get_session_context: temporal memory window. Requires session_id + target_timestamp. memory(action="consolidate") / consolidate_memories: merge duplicate/related memories. memory(action="cardinality") / get_memory_cardinality: count memories per agent. decision(action="store") / store_decision: record an architectural decision (domain, decision, rationale). decision(action="get") / get_decision: retrieve a past decision by domain or query.`
3702
+ content: `memory(action="recall") / recall_my_memory: search your own memories (semantic + FTS). Supports as_of param for bi-temporal queries (what did I know at time X?), kind param to filter by memory type (decision, procedure, observation, raw, conversation, behavior). memory(action="ask_team") / ask_team_memory: search a colleague's memories by agent name. memory(action="store") / store_memory: persist a memory. Supports kind param and procedure_for domain tag for procedure-type memories. memory(action="commit") / commit_memory: high-importance memory that survives consolidation. Requires summary. memory(action="search") / search_everything: unified search across memories, tasks, entities, conversations. memory(action="session_context") / get_session_context: temporal memory window. Requires session_id + target_timestamp. memory(action="consolidate") / consolidate_memories: merge duplicate/related memories. memory(action="cardinality") / get_memory_cardinality: count memories per agent. memory(action="supersede") / supersede: replace an old memory with a new version (old_id + new text). decision(action="store") / store_decision: record an architectural decision (domain, decision, rationale). decision(action="get") / get_decision: retrieve a past decision by domain or query.`
3652
3703
  },
3653
3704
  {
3654
3705
  title: "MCP tools \u2014 task orchestration",
3655
3706
  domain: "tool-use",
3656
3707
  priority: "p1",
3657
- content: 'task(action="create") / create_task: dispatch work (title, assigned_to, context). The ONLY dispatch path. Auto-spawns session. task(action="list") / list_tasks: query tasks by status, assignee, project. task(action="get") / get_task: fetch full task details by task_id. task(action="update") / update_task: change status (in_progress, done, blocked, cancelled) + result summary. task(action="close") / close_task: finalize a reviewed task (COO only). task(action="checkpoint") / checkpoint_task: save progress state for crash recovery. task(action="resume") / resume_employee: re-spawn an employee session for an existing task.'
3708
+ content: `task(action="create") / create_task: dispatch work (title, assigned_to, context). The ONLY dispatch path. Auto-spawns session. Supports spawn_runtime and spawn_model params to override the agent's default runtime/model for a specific task. task(action="list") / list_tasks: query tasks by status, assignee, project. task(action="get") / get_task: fetch full task details by task_id. task(action="update") / update_task: change status (in_progress, done, blocked, cancelled) + result summary. task(action="close") / close_task: finalize a reviewed task (COO only). task(action="checkpoint") / checkpoint_task: save progress state for crash recovery. task(action="resume") / resume_employee: re-spawn an employee session for an existing task.`
3658
3709
  },
3659
3710
  {
3660
3711
  title: "MCP tools \u2014 knowledge graph (GraphRAG)",
@@ -3684,7 +3735,7 @@ var init_platform_procedures = __esm({
3684
3735
  title: "MCP tools \u2014 admin, config, and operations",
3685
3736
  domain: "tool-use",
3686
3737
  priority: "p1",
3687
- content: 'config(action="list_employees"): view roster. config(action="agent_spend"): token usage per agent. config(action="daemon_health"): check exed status. config(action="license_status"): check license. config(action="cloud_sync"): force sync. config(action="memory_audit"): health check (dupes, null vectors). config(action="run_consolidation"): trigger memory consolidation. config(action="company_procedure", subaction="store|list|deactivate"): manage company procedures. config(action="global_procedure"): list all procedures (platform + company). config(action="create_trigger|list_triggers"): scheduled agent jobs. config(action="export_orchestration|import_orchestration"): portable org state. diagnostics(action="healthcheck|doctor|status_brief|check_update|cloud_status"): system diagnostics. mcp_ping(): daemon health + license status + tool usage stats.'
3738
+ content: 'config(action="list_employees"): view roster. config(action="agent_spend"): token usage per agent. config(action="daemon_health"): check exed status. config(action="license_status"): check license. config(action="cloud_sync"): force sync. config(action="memory_audit"): health check (dupes, null vectors). config(action="run_consolidation"): trigger memory consolidation. config(action="company_procedure", subaction="store|list|deactivate"): manage company procedures. config(action="global_procedure"): list all procedures (platform + company). config(action="create_trigger|list_triggers"): scheduled agent jobs. config(action="export_orchestration|import_orchestration"): portable org state. diagnostics(action="healthcheck|doctor|status_brief|check_update|cloud_status"): system diagnostics. diagnostics(action="tool_search"): semantic tool discovery \u2014 find relevant MCP tools by natural language query. Returns top-K tools ranked by relevance. diagnostics(action="drift"): identity drift detection \u2014 score how far an agent has drifted from its role identity. Returns drift score + recommendations. mcp_ping(): daemon health + license status + tool usage stats.'
3688
3739
  }
3689
3740
  ];
3690
3741
  PLATFORM_PROCEDURE_TITLES = new Set(
@@ -2550,6 +2550,20 @@ async function ensureSchema() {
2550
2550
  });
2551
2551
  } catch {
2552
2552
  }
2553
+ try {
2554
+ await client.execute({
2555
+ sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
2556
+ args: []
2557
+ });
2558
+ } catch {
2559
+ }
2560
+ try {
2561
+ await client.execute({
2562
+ sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
2563
+ args: []
2564
+ });
2565
+ } catch {
2566
+ }
2553
2567
  await client.executeMultiple(`
2554
2568
  CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
2555
2569
  content_text,
@@ -2801,6 +2815,22 @@ async function ensureSchema() {
2801
2815
  );
2802
2816
  } catch {
2803
2817
  }
2818
+ for (const col of [
2819
+ "ALTER TABLE memories ADD COLUMN valid_from TEXT",
2820
+ "ALTER TABLE memories ADD COLUMN invalid_at TEXT"
2821
+ ]) {
2822
+ try {
2823
+ await client.execute(col);
2824
+ } catch {
2825
+ }
2826
+ }
2827
+ try {
2828
+ await client.execute({
2829
+ sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
2830
+ args: []
2831
+ });
2832
+ } catch {
2833
+ }
2804
2834
  try {
2805
2835
  await client.execute({
2806
2836
  sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
@@ -2843,6 +2873,13 @@ async function ensureSchema() {
2843
2873
  } catch {
2844
2874
  }
2845
2875
  }
2876
+ try {
2877
+ await client.execute({
2878
+ sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
2879
+ args: []
2880
+ });
2881
+ } catch {
2882
+ }
2846
2883
  try {
2847
2884
  await client.execute({
2848
2885
  sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
@@ -3732,6 +3769,20 @@ var init_platform_procedures = __esm({
3732
3769
  priority: "p1",
3733
3770
  content: "Once per session (COO boot only, never repeat), call list_my_feature_requests to check if any previously filed feature requests have been shipped by AskExe. If any request has status 'shipped' with a shipped_version, surface it to the founder immediately: '\u{1F680} N feature(s) shipped \u2014 run exe-os update to get version X.Y.Z'. This is a one-time check at boot, not a recurring poll. If no requests exist or none are shipped, skip silently. If the MCP tool is unavailable or the network call fails, skip silently \u2014 this is informational, not blocking."
3734
3771
  },
3772
+ // --- Tool guidance ---
3773
+ {
3774
+ title: "How to use company_actions \u2014 execute business actions through gateway connectors",
3775
+ domain: "tools",
3776
+ priority: "p2",
3777
+ content: "The company_actions tool executes business actions through gateway connectors (e.g. send WhatsApp, trigger workflows, update CRM). It routes through the exe-gateway on the VPS. Actions are defined by the customer's gateway configuration \u2014 each connector (WhatsApp, Shopify, email, etc.) exposes specific actions. Use query_company_brain to find available data first, then company_actions to act on it. Requires gateway auth token. Read-only founders should NOT use this \u2014 it mutates external state."
3778
+ },
3779
+ // --- Release awareness ---
3780
+ {
3781
+ title: "What's New check \u2014 surface new features after update",
3782
+ domain: "support",
3783
+ priority: "p1",
3784
+ content: "Once per session (COO boot only, never repeat), check if the installed exe-os version is newer than the last session. If it is, read the bundled release-notes.json (at the package root) and surface a brief summary to the founder: 'Updated to exe-os vX.Y.Z \u2014 N new features, M fixes.' List the top 3 features by name. This helps the founder know what they got from the update. If release-notes.json doesn't exist or the version hasn't changed, skip silently. Never repeat this check in the same session."
3785
+ },
3735
3786
  // --- Platform vs Customer ownership ---
3736
3787
  {
3737
3788
  title: "What the platform provides vs what you customize",
@@ -3820,13 +3871,13 @@ var init_platform_procedures = __esm({
3820
3871
  title: "MCP tools \u2014 memory, decision, and search",
3821
3872
  domain: "tool-use",
3822
3873
  priority: "p1",
3823
- content: `memory(action="recall") / recall_my_memory: search your own memories (semantic + FTS). memory(action="ask_team") / ask_team_memory: search a colleague's memories by agent name. memory(action="store") / store_memory: persist a memory. memory(action="commit") / commit_memory: high-importance memory that survives consolidation. Requires summary. memory(action="search") / search_everything: unified search across memories, tasks, entities, conversations. memory(action="session_context") / get_session_context: temporal memory window. Requires session_id + target_timestamp. memory(action="consolidate") / consolidate_memories: merge duplicate/related memories. memory(action="cardinality") / get_memory_cardinality: count memories per agent. decision(action="store") / store_decision: record an architectural decision (domain, decision, rationale). decision(action="get") / get_decision: retrieve a past decision by domain or query.`
3874
+ content: `memory(action="recall") / recall_my_memory: search your own memories (semantic + FTS). Supports as_of param for bi-temporal queries (what did I know at time X?), kind param to filter by memory type (decision, procedure, observation, raw, conversation, behavior). memory(action="ask_team") / ask_team_memory: search a colleague's memories by agent name. memory(action="store") / store_memory: persist a memory. Supports kind param and procedure_for domain tag for procedure-type memories. memory(action="commit") / commit_memory: high-importance memory that survives consolidation. Requires summary. memory(action="search") / search_everything: unified search across memories, tasks, entities, conversations. memory(action="session_context") / get_session_context: temporal memory window. Requires session_id + target_timestamp. memory(action="consolidate") / consolidate_memories: merge duplicate/related memories. memory(action="cardinality") / get_memory_cardinality: count memories per agent. memory(action="supersede") / supersede: replace an old memory with a new version (old_id + new text). decision(action="store") / store_decision: record an architectural decision (domain, decision, rationale). decision(action="get") / get_decision: retrieve a past decision by domain or query.`
3824
3875
  },
3825
3876
  {
3826
3877
  title: "MCP tools \u2014 task orchestration",
3827
3878
  domain: "tool-use",
3828
3879
  priority: "p1",
3829
- content: 'task(action="create") / create_task: dispatch work (title, assigned_to, context). The ONLY dispatch path. Auto-spawns session. task(action="list") / list_tasks: query tasks by status, assignee, project. task(action="get") / get_task: fetch full task details by task_id. task(action="update") / update_task: change status (in_progress, done, blocked, cancelled) + result summary. task(action="close") / close_task: finalize a reviewed task (COO only). task(action="checkpoint") / checkpoint_task: save progress state for crash recovery. task(action="resume") / resume_employee: re-spawn an employee session for an existing task.'
3880
+ content: `task(action="create") / create_task: dispatch work (title, assigned_to, context). The ONLY dispatch path. Auto-spawns session. Supports spawn_runtime and spawn_model params to override the agent's default runtime/model for a specific task. task(action="list") / list_tasks: query tasks by status, assignee, project. task(action="get") / get_task: fetch full task details by task_id. task(action="update") / update_task: change status (in_progress, done, blocked, cancelled) + result summary. task(action="close") / close_task: finalize a reviewed task (COO only). task(action="checkpoint") / checkpoint_task: save progress state for crash recovery. task(action="resume") / resume_employee: re-spawn an employee session for an existing task.`
3830
3881
  },
3831
3882
  {
3832
3883
  title: "MCP tools \u2014 knowledge graph (GraphRAG)",
@@ -3856,7 +3907,7 @@ var init_platform_procedures = __esm({
3856
3907
  title: "MCP tools \u2014 admin, config, and operations",
3857
3908
  domain: "tool-use",
3858
3909
  priority: "p1",
3859
- content: 'config(action="list_employees"): view roster. config(action="agent_spend"): token usage per agent. config(action="daemon_health"): check exed status. config(action="license_status"): check license. config(action="cloud_sync"): force sync. config(action="memory_audit"): health check (dupes, null vectors). config(action="run_consolidation"): trigger memory consolidation. config(action="company_procedure", subaction="store|list|deactivate"): manage company procedures. config(action="global_procedure"): list all procedures (platform + company). config(action="create_trigger|list_triggers"): scheduled agent jobs. config(action="export_orchestration|import_orchestration"): portable org state. diagnostics(action="healthcheck|doctor|status_brief|check_update|cloud_status"): system diagnostics. mcp_ping(): daemon health + license status + tool usage stats.'
3910
+ content: 'config(action="list_employees"): view roster. config(action="agent_spend"): token usage per agent. config(action="daemon_health"): check exed status. config(action="license_status"): check license. config(action="cloud_sync"): force sync. config(action="memory_audit"): health check (dupes, null vectors). config(action="run_consolidation"): trigger memory consolidation. config(action="company_procedure", subaction="store|list|deactivate"): manage company procedures. config(action="global_procedure"): list all procedures (platform + company). config(action="create_trigger|list_triggers"): scheduled agent jobs. config(action="export_orchestration|import_orchestration"): portable org state. diagnostics(action="healthcheck|doctor|status_brief|check_update|cloud_status"): system diagnostics. diagnostics(action="tool_search"): semantic tool discovery \u2014 find relevant MCP tools by natural language query. Returns top-K tools ranked by relevance. diagnostics(action="drift"): identity drift detection \u2014 score how far an agent has drifted from its role identity. Returns drift score + recommendations. mcp_ping(): daemon health + license status + tool usage stats.'
3860
3911
  }
3861
3912
  ];
3862
3913
  PLATFORM_PROCEDURE_TITLES = new Set(
@@ -4639,6 +4690,8 @@ async function flushBatch() {
4639
4690
  const sourceType = row.source_type ?? null;
4640
4691
  const tier = row.tier ?? 3;
4641
4692
  const supersedesId = row.supersedes_id ?? null;
4693
+ const validFrom = row.valid_from ?? row.timestamp;
4694
+ const invalidAt = row.invalid_at ?? null;
4642
4695
  const draft = row.draft ? 1 : 0;
4643
4696
  const memoryType = row.memory_type ?? "raw";
4644
4697
  const trajectory = row.trajectory ?? null;
@@ -4658,15 +4711,16 @@ async function flushBatch() {
4658
4711
  const audience = row.audience ?? null;
4659
4712
  const languageType = row.language_type ?? null;
4660
4713
  const parentMemoryId = row.parent_memory_id ?? null;
4714
+ const procedureFor = row.procedure_for ?? null;
4661
4715
  const cols = `id, agent_id, agent_role, session_id, timestamp,
4662
4716
  tool_name, project_name,
4663
4717
  has_error, raw_text, vector, version, task_id, importance, status,
4664
4718
  confidence, last_accessed,
4665
4719
  workspace_id, document_id, user_id, char_offset, page_number,
4666
- source_path, source_type, tier, supersedes_id, draft, memory_type, trajectory, content_hash,
4720
+ source_path, source_type, tier, supersedes_id, valid_from, invalid_at, draft, memory_type, trajectory, content_hash,
4667
4721
  intent, outcome, domain, referenced_entities, retrieval_count,
4668
4722
  chain_position, review_status, context_window_pct, file_paths, commit_hash,
4669
- duration_ms, token_cost, audience, language_type, parent_memory_id`;
4723
+ duration_ms, token_cost, audience, language_type, parent_memory_id, procedure_for`;
4670
4724
  const metaArgs = [
4671
4725
  intent,
4672
4726
  outcome,
@@ -4682,7 +4736,8 @@ async function flushBatch() {
4682
4736
  tokenCost,
4683
4737
  audience,
4684
4738
  languageType,
4685
- parentMemoryId
4739
+ parentMemoryId,
4740
+ procedureFor
4686
4741
  ];
4687
4742
  const baseArgs = [
4688
4743
  row.id,
@@ -4711,6 +4766,8 @@ async function flushBatch() {
4711
4766
  sourceType,
4712
4767
  tier,
4713
4768
  supersedesId,
4769
+ validFrom,
4770
+ invalidAt,
4714
4771
  draft,
4715
4772
  memoryType,
4716
4773
  trajectory,
@@ -4718,8 +4775,8 @@ async function flushBatch() {
4718
4775
  ];
4719
4776
  return {
4720
4777
  sql: hasVector ? `INSERT OR IGNORE INTO memories (${cols})
4721
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
4722
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
4778
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
4779
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
4723
4780
  args: hasVector ? [...baseArgs, vectorToBlob(row.vector), ...sharedArgs, ...metaArgs] : [...baseArgs, ...sharedArgs, ...metaArgs]
4724
4781
  };
4725
4782
  };
@@ -4825,6 +4882,7 @@ import { jwtVerify, importSPKI } from "jose";
4825
4882
  var LICENSE_PATH = path8.join(EXE_AI_DIR, "license.key");
4826
4883
  var CACHE_PATH = path8.join(EXE_AI_DIR, "license-cache.json");
4827
4884
  var DEVICE_ID_PATH = path8.join(EXE_AI_DIR, "device-id");
4885
+ var API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://askexe.com/cloud";
4828
4886
 
4829
4887
  // src/lib/cloud-sync.ts
4830
4888
  init_config();