@askexenow/exe-os 0.9.60 → 0.9.62
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.
- package/deploy/stack-manifests/v0.9.json +62 -13
- package/dist/bin/backfill-conversations.js +282 -7
- package/dist/bin/backfill-responses.js +282 -7
- package/dist/bin/backfill-vectors.js +119 -7
- package/dist/bin/cc-doctor.js +376 -0
- package/dist/bin/cleanup-stale-review-tasks.js +282 -7
- package/dist/bin/cli.js +455 -77
- package/dist/bin/customer-readiness.js +33 -0
- package/dist/bin/exe-agent-config.js +2 -2
- package/dist/bin/exe-agent.js +3 -3
- package/dist/bin/exe-assign.js +282 -7
- package/dist/bin/exe-boot.js +125 -13
- package/dist/bin/exe-call.js +3 -3
- package/dist/bin/exe-cloud.js +2 -2
- package/dist/bin/exe-dispatch.js +282 -7
- package/dist/bin/exe-doctor.js +119 -7
- package/dist/bin/exe-export-behaviors.js +282 -7
- package/dist/bin/exe-forget.js +336 -7
- package/dist/bin/exe-gateway.js +282 -7
- package/dist/bin/exe-heartbeat.js +284 -9
- package/dist/bin/exe-kill.js +282 -7
- package/dist/bin/exe-launch-agent.js +282 -7
- package/dist/bin/exe-link.js +121 -9
- package/dist/bin/exe-new-employee.js +50 -21
- package/dist/bin/exe-pending-messages.js +282 -7
- package/dist/bin/exe-pending-notifications.js +282 -7
- package/dist/bin/exe-pending-reviews.js +282 -7
- package/dist/bin/exe-rename.js +282 -7
- package/dist/bin/exe-review.js +282 -7
- package/dist/bin/exe-search.js +306 -8
- package/dist/bin/exe-session-cleanup.js +282 -7
- package/dist/bin/exe-settings.js +2 -2
- package/dist/bin/exe-start-codex.js +326 -21
- package/dist/bin/exe-start-opencode.js +304 -10
- package/dist/bin/exe-status.js +282 -7
- package/dist/bin/exe-team.js +282 -7
- package/dist/bin/git-sweep.js +282 -7
- package/dist/bin/graph-backfill.js +282 -7
- package/dist/bin/graph-export.js +282 -7
- package/dist/bin/install.js +58 -33
- package/dist/bin/intercom-check.js +282 -7
- package/dist/bin/pre-build-guard.js +98 -0
- package/dist/bin/scan-tasks.js +282 -7
- package/dist/bin/setup.js +122 -10
- package/dist/bin/shard-migrate.js +282 -7
- package/dist/bin/stack-update.js +79 -11
- package/dist/bin/update.js +2 -2
- package/dist/gateway/index.js +288 -13
- package/dist/hooks/bug-report-worker.js +282 -7
- package/dist/hooks/codex-stop-task-finalizer.js +282 -7
- package/dist/hooks/commit-complete.js +282 -7
- package/dist/hooks/error-recall.js +306 -8
- package/dist/hooks/exe-heartbeat-hook.js +2 -2
- package/dist/hooks/ingest-worker.js +2 -2
- package/dist/hooks/ingest.js +282 -7
- package/dist/hooks/instructions-loaded.js +282 -7
- package/dist/hooks/notification.js +282 -7
- package/dist/hooks/post-compact.js +282 -7
- package/dist/hooks/post-tool-combined.js +306 -8
- package/dist/hooks/pre-compact.js +282 -7
- package/dist/hooks/pre-tool-use.js +282 -7
- package/dist/hooks/prompt-submit.js +306 -8
- package/dist/hooks/session-end.js +282 -7
- package/dist/hooks/session-start.js +308 -10
- package/dist/hooks/stop.js +282 -7
- package/dist/hooks/subagent-stop.js +282 -7
- package/dist/hooks/summary-worker.js +125 -13
- package/dist/index.js +288 -13
- package/dist/lib/agent-config.js +2 -2
- package/dist/lib/cloud-sync.js +121 -9
- package/dist/lib/config.js +2 -2
- package/dist/lib/consolidation.js +2 -2
- package/dist/lib/database.js +115 -3
- package/dist/lib/db-daemon-client.js +2 -2
- package/dist/lib/db.js +115 -3
- package/dist/lib/device-registry.js +115 -3
- package/dist/lib/embedder.js +2 -2
- package/dist/lib/employee-templates.js +3 -3
- package/dist/lib/employees.js +2 -2
- package/dist/lib/exe-daemon-client.js +2 -2
- package/dist/lib/exe-daemon.js +339 -31
- package/dist/lib/hybrid-search.js +306 -8
- package/dist/lib/identity.js +2 -2
- package/dist/lib/license.js +2 -2
- package/dist/lib/messaging.js +2 -2
- package/dist/lib/reminders.js +2 -2
- package/dist/lib/schedules.js +119 -7
- package/dist/lib/skill-learning.js +2 -2
- package/dist/lib/store.js +282 -7
- package/dist/lib/task-router.js +2 -2
- package/dist/lib/tasks.js +2 -2
- package/dist/lib/tmux-routing.js +2 -2
- package/dist/lib/token-spend.js +2 -2
- package/dist/mcp/server.js +339 -31
- package/dist/mcp/tools/complete-reminder.js +2 -2
- package/dist/mcp/tools/create-reminder.js +2 -2
- package/dist/mcp/tools/create-task.js +2 -2
- package/dist/mcp/tools/deactivate-behavior.js +2 -2
- package/dist/mcp/tools/list-reminders.js +2 -2
- package/dist/mcp/tools/list-tasks.js +2 -2
- package/dist/mcp/tools/send-message.js +2 -2
- package/dist/mcp/tools/update-task.js +2 -2
- package/dist/runtime/index.js +282 -7
- package/dist/tui/App.js +290 -15
- package/package.json +3 -2
- package/stack.release.json +23 -7
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"latest": "0.9.
|
|
3
|
+
"latest": "0.9.1",
|
|
4
4
|
"stacks": {
|
|
5
5
|
"0.9.0": {
|
|
6
6
|
"version": "0.9.0",
|
|
7
7
|
"releasedAt": "2026-05-10T00:00:00Z",
|
|
8
|
-
"notes": "
|
|
8
|
+
"notes": "Private/customer pilot omnibus stack manifest for self-hosted Exe OS v0.9 VPS deployments. v1.0.0 is the public-beta/stable contract line.",
|
|
9
9
|
"breakingChanges": [
|
|
10
10
|
{
|
|
11
11
|
"id": "whatsapp_relink_required",
|
|
@@ -19,36 +19,85 @@
|
|
|
19
19
|
"services": {
|
|
20
20
|
"crm": {
|
|
21
21
|
"env": "CRM_IMAGE_TAG",
|
|
22
|
-
"image": "ghcr.io/askexe/exe-crm:v0.
|
|
22
|
+
"image": "ghcr.io/askexe/exe-crm:v0.9.0",
|
|
23
23
|
"healthUrl": "http://127.0.0.1:3000/healthz"
|
|
24
24
|
},
|
|
25
25
|
"wiki": {
|
|
26
26
|
"env": "WIKI_IMAGE_TAG",
|
|
27
|
-
"image": "ghcr.io/askexe/exe-wiki:
|
|
27
|
+
"image": "ghcr.io/askexe/exe-wiki:v0.9.0",
|
|
28
28
|
"healthUrl": "http://127.0.0.1:3001/api/ping"
|
|
29
29
|
},
|
|
30
30
|
"exed": {
|
|
31
31
|
"env": "EXED_IMAGE_TAG",
|
|
32
|
-
"image": "ghcr.io/askexe/exed:v0.9.
|
|
32
|
+
"image": "ghcr.io/askexe/exed:v0.9.61",
|
|
33
33
|
"healthUrl": "http://127.0.0.1:8765/health"
|
|
34
34
|
},
|
|
35
35
|
"gateway": {
|
|
36
36
|
"env": "GATEWAY_IMAGE_TAG",
|
|
37
|
-
"image": "ghcr.io/askexe/exe-gateway:v0.
|
|
37
|
+
"image": "ghcr.io/askexe/exe-gateway:v0.9.0",
|
|
38
38
|
"healthUrl": "http://127.0.0.1:3100/health"
|
|
39
39
|
},
|
|
40
40
|
"monitorAgent": {
|
|
41
41
|
"env": "MONITOR_AGENT_IMAGE_TAG",
|
|
42
|
-
"image": "ghcr.io/askexe/exe-monitor-agent:v0.
|
|
42
|
+
"image": "ghcr.io/askexe/exe-monitor-agent:v0.9.0"
|
|
43
43
|
}
|
|
44
44
|
},
|
|
45
45
|
"releaseDescriptors": {
|
|
46
|
-
"exed": "AskExe/exe-os@0.9.
|
|
47
|
-
"crm": "AskExe/exe-crm@0.
|
|
48
|
-
"wiki": "AskExe/exe-wiki@
|
|
49
|
-
"gateway": "AskExe/exe-gateway@0.
|
|
50
|
-
"db": "AskExe/exe-db@0.
|
|
51
|
-
"monitorAgent": "AskExe/exe-monitor@0.
|
|
46
|
+
"exed": "AskExe/exe-os@0.9.61:stack.release.json",
|
|
47
|
+
"crm": "AskExe/exe-crm@0.9.0:stack.release.json",
|
|
48
|
+
"wiki": "AskExe/exe-wiki@0.9.0:stack.release.json",
|
|
49
|
+
"gateway": "AskExe/exe-gateway@0.9.0:stack.release.json",
|
|
50
|
+
"db": "AskExe/exe-db@0.9.0:stack.release.json",
|
|
51
|
+
"monitorAgent": "AskExe/exe-monitor@0.9.0:stack.release.json"
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"0.9.1": {
|
|
55
|
+
"version": "0.9.1",
|
|
56
|
+
"releasedAt": "2026-05-10T00:00:00Z",
|
|
57
|
+
"notes": "High Ghost private/customer pilot stack release. Pins exact tested service images; v1.0.0 remains the public-beta/stable contract line.",
|
|
58
|
+
"breakingChanges": [
|
|
59
|
+
{
|
|
60
|
+
"id": "whatsapp_relink_required",
|
|
61
|
+
"title": "WhatsApp QR re-link required for Baileys v7",
|
|
62
|
+
"description": "exe-gateway uses Baileys v7. Existing WhatsApp 6.x linked-device auth state must be backed up and re-linked once with a new QR code.",
|
|
63
|
+
"requiredAction": "Open https://<gateway-domain>/pair/default?token=<admin-token> and scan from WhatsApp \u2192 Linked Devices after the update.",
|
|
64
|
+
"expectedDowntimeMinutes": "2-5",
|
|
65
|
+
"requiresConfirmation": true
|
|
66
|
+
}
|
|
67
|
+
],
|
|
68
|
+
"services": {
|
|
69
|
+
"crm": {
|
|
70
|
+
"env": "CRM_IMAGE_TAG",
|
|
71
|
+
"image": "ghcr.io/askexe/exe-crm:v0.9.1",
|
|
72
|
+
"healthUrl": "http://127.0.0.1:3000/healthz"
|
|
73
|
+
},
|
|
74
|
+
"wiki": {
|
|
75
|
+
"env": "WIKI_IMAGE_TAG",
|
|
76
|
+
"image": "ghcr.io/askexe/exe-wiki:v0.9.1",
|
|
77
|
+
"healthUrl": "http://127.0.0.1:3001/api/ping"
|
|
78
|
+
},
|
|
79
|
+
"exed": {
|
|
80
|
+
"env": "EXED_IMAGE_TAG",
|
|
81
|
+
"image": "ghcr.io/askexe/exed:v0.9.61",
|
|
82
|
+
"healthUrl": "http://127.0.0.1:8765/health"
|
|
83
|
+
},
|
|
84
|
+
"gateway": {
|
|
85
|
+
"env": "GATEWAY_IMAGE_TAG",
|
|
86
|
+
"image": "ghcr.io/askexe/exe-gateway:v0.9.1",
|
|
87
|
+
"healthUrl": "http://127.0.0.1:3100/health"
|
|
88
|
+
},
|
|
89
|
+
"monitorAgent": {
|
|
90
|
+
"env": "MONITOR_AGENT_IMAGE_TAG",
|
|
91
|
+
"image": "ghcr.io/askexe/exe-monitor-agent:v0.9.1"
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
"releaseDescriptors": {
|
|
95
|
+
"exed": "AskExe/exe-os@0.9.61:stack.release.json",
|
|
96
|
+
"crm": "AskExe/exe-crm@0.9.1:stack.release.json",
|
|
97
|
+
"wiki": "AskExe/exe-wiki@0.9.1:stack.release.json",
|
|
98
|
+
"gateway": "AskExe/exe-gateway@0.9.1:stack.release.json",
|
|
99
|
+
"db": "AskExe/exe-db@0.9.1:stack.release.json",
|
|
100
|
+
"monitorAgent": "AskExe/exe-monitor@0.9.1:stack.release.json"
|
|
52
101
|
}
|
|
53
102
|
}
|
|
54
103
|
}
|
|
@@ -256,8 +256,8 @@ var init_config = __esm({
|
|
|
256
256
|
rerankerAutoTrigger: {
|
|
257
257
|
enabled: true,
|
|
258
258
|
broadQueryMinCardinality: 5e4,
|
|
259
|
-
fetchTopK:
|
|
260
|
-
returnTopK:
|
|
259
|
+
fetchTopK: 200,
|
|
260
|
+
returnTopK: 20
|
|
261
261
|
}
|
|
262
262
|
},
|
|
263
263
|
graphRagEnabled: true,
|
|
@@ -2429,7 +2429,7 @@ async function ensureSchema() {
|
|
|
2429
2429
|
ON session_kills(agent_id);
|
|
2430
2430
|
`);
|
|
2431
2431
|
await client.execute(`
|
|
2432
|
-
CREATE TABLE IF NOT EXISTS
|
|
2432
|
+
CREATE TABLE IF NOT EXISTS company_procedures (
|
|
2433
2433
|
id TEXT PRIMARY KEY,
|
|
2434
2434
|
title TEXT NOT NULL,
|
|
2435
2435
|
content TEXT NOT NULL,
|
|
@@ -2440,6 +2440,73 @@ async function ensureSchema() {
|
|
|
2440
2440
|
updated_at TEXT NOT NULL
|
|
2441
2441
|
)
|
|
2442
2442
|
`);
|
|
2443
|
+
const legacyProcedureObject = await client.execute({
|
|
2444
|
+
sql: "SELECT type FROM sqlite_master WHERE name = 'global_procedures'",
|
|
2445
|
+
args: []
|
|
2446
|
+
});
|
|
2447
|
+
const legacyProcedureType = legacyProcedureObject.rows[0]?.type == null ? null : String(legacyProcedureObject.rows[0].type);
|
|
2448
|
+
if (legacyProcedureType === "table") {
|
|
2449
|
+
await client.execute(`
|
|
2450
|
+
INSERT OR IGNORE INTO company_procedures
|
|
2451
|
+
(id, title, content, priority, domain, active, created_at, updated_at)
|
|
2452
|
+
SELECT id, title, content, priority, domain, active, created_at, updated_at
|
|
2453
|
+
FROM global_procedures
|
|
2454
|
+
`);
|
|
2455
|
+
await client.executeMultiple(`
|
|
2456
|
+
CREATE TRIGGER IF NOT EXISTS global_procedures_mirror_insert
|
|
2457
|
+
AFTER INSERT ON global_procedures
|
|
2458
|
+
BEGIN
|
|
2459
|
+
INSERT OR IGNORE INTO company_procedures
|
|
2460
|
+
(id, title, content, priority, domain, active, created_at, updated_at)
|
|
2461
|
+
VALUES
|
|
2462
|
+
(NEW.id, NEW.title, NEW.content, NEW.priority, NEW.domain, NEW.active, NEW.created_at, NEW.updated_at);
|
|
2463
|
+
END;
|
|
2464
|
+
|
|
2465
|
+
CREATE TRIGGER IF NOT EXISTS global_procedures_mirror_update
|
|
2466
|
+
AFTER UPDATE ON global_procedures
|
|
2467
|
+
BEGIN
|
|
2468
|
+
UPDATE company_procedures
|
|
2469
|
+
SET title = NEW.title,
|
|
2470
|
+
content = NEW.content,
|
|
2471
|
+
priority = NEW.priority,
|
|
2472
|
+
domain = NEW.domain,
|
|
2473
|
+
active = NEW.active,
|
|
2474
|
+
created_at = NEW.created_at,
|
|
2475
|
+
updated_at = NEW.updated_at
|
|
2476
|
+
WHERE id = OLD.id;
|
|
2477
|
+
END;
|
|
2478
|
+
`);
|
|
2479
|
+
} else {
|
|
2480
|
+
await client.execute(`
|
|
2481
|
+
CREATE VIEW IF NOT EXISTS global_procedures AS
|
|
2482
|
+
SELECT id, title, content, priority, domain, active, created_at, updated_at
|
|
2483
|
+
FROM company_procedures
|
|
2484
|
+
`);
|
|
2485
|
+
await client.executeMultiple(`
|
|
2486
|
+
CREATE TRIGGER IF NOT EXISTS global_procedures_insert
|
|
2487
|
+
INSTEAD OF INSERT ON global_procedures
|
|
2488
|
+
BEGIN
|
|
2489
|
+
INSERT INTO company_procedures
|
|
2490
|
+
(id, title, content, priority, domain, active, created_at, updated_at)
|
|
2491
|
+
VALUES
|
|
2492
|
+
(NEW.id, NEW.title, NEW.content, NEW.priority, NEW.domain, NEW.active, NEW.created_at, NEW.updated_at);
|
|
2493
|
+
END;
|
|
2494
|
+
|
|
2495
|
+
CREATE TRIGGER IF NOT EXISTS global_procedures_update
|
|
2496
|
+
INSTEAD OF UPDATE ON global_procedures
|
|
2497
|
+
BEGIN
|
|
2498
|
+
UPDATE company_procedures
|
|
2499
|
+
SET title = NEW.title,
|
|
2500
|
+
content = NEW.content,
|
|
2501
|
+
priority = NEW.priority,
|
|
2502
|
+
domain = NEW.domain,
|
|
2503
|
+
active = NEW.active,
|
|
2504
|
+
created_at = NEW.created_at,
|
|
2505
|
+
updated_at = NEW.updated_at
|
|
2506
|
+
WHERE id = OLD.id;
|
|
2507
|
+
END;
|
|
2508
|
+
`);
|
|
2509
|
+
}
|
|
2443
2510
|
await client.executeMultiple(`
|
|
2444
2511
|
CREATE TABLE IF NOT EXISTS conversations (
|
|
2445
2512
|
id TEXT PRIMARY KEY,
|
|
@@ -2579,6 +2646,51 @@ async function ensureSchema() {
|
|
|
2579
2646
|
VALUES (new.rowid, new.content_text, new.sender_name, new.agent_response);
|
|
2580
2647
|
END;
|
|
2581
2648
|
`);
|
|
2649
|
+
await client.executeMultiple(`
|
|
2650
|
+
CREATE TABLE IF NOT EXISTS memory_cards (
|
|
2651
|
+
id TEXT PRIMARY KEY,
|
|
2652
|
+
memory_id TEXT NOT NULL,
|
|
2653
|
+
agent_id TEXT NOT NULL,
|
|
2654
|
+
session_id TEXT NOT NULL,
|
|
2655
|
+
project_name TEXT,
|
|
2656
|
+
timestamp TEXT NOT NULL,
|
|
2657
|
+
card_type TEXT NOT NULL,
|
|
2658
|
+
subject TEXT,
|
|
2659
|
+
predicate TEXT,
|
|
2660
|
+
object TEXT,
|
|
2661
|
+
content TEXT NOT NULL,
|
|
2662
|
+
source_ref TEXT,
|
|
2663
|
+
confidence REAL DEFAULT 0.6,
|
|
2664
|
+
active INTEGER DEFAULT 1,
|
|
2665
|
+
created_at TEXT NOT NULL
|
|
2666
|
+
);
|
|
2667
|
+
|
|
2668
|
+
CREATE INDEX IF NOT EXISTS idx_memory_cards_agent
|
|
2669
|
+
ON memory_cards(agent_id, active, timestamp);
|
|
2670
|
+
|
|
2671
|
+
CREATE INDEX IF NOT EXISTS idx_memory_cards_memory
|
|
2672
|
+
ON memory_cards(memory_id);
|
|
2673
|
+
|
|
2674
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS memory_cards_fts
|
|
2675
|
+
USING fts5(content, subject, predicate, object, content='memory_cards', content_rowid='rowid');
|
|
2676
|
+
|
|
2677
|
+
CREATE TRIGGER IF NOT EXISTS memory_cards_fts_ai AFTER INSERT ON memory_cards BEGIN
|
|
2678
|
+
INSERT INTO memory_cards_fts(rowid, content, subject, predicate, object)
|
|
2679
|
+
VALUES (new.rowid, new.content, new.subject, new.predicate, new.object);
|
|
2680
|
+
END;
|
|
2681
|
+
|
|
2682
|
+
CREATE TRIGGER IF NOT EXISTS memory_cards_fts_ad AFTER DELETE ON memory_cards BEGIN
|
|
2683
|
+
INSERT INTO memory_cards_fts(memory_cards_fts, rowid, content, subject, predicate, object)
|
|
2684
|
+
VALUES('delete', old.rowid, old.content, old.subject, old.predicate, old.object);
|
|
2685
|
+
END;
|
|
2686
|
+
|
|
2687
|
+
CREATE TRIGGER IF NOT EXISTS memory_cards_fts_au AFTER UPDATE ON memory_cards BEGIN
|
|
2688
|
+
INSERT INTO memory_cards_fts(memory_cards_fts, rowid, content, subject, predicate, object)
|
|
2689
|
+
VALUES('delete', old.rowid, old.content, old.subject, old.predicate, old.object);
|
|
2690
|
+
INSERT INTO memory_cards_fts(rowid, content, subject, predicate, object)
|
|
2691
|
+
VALUES (new.rowid, new.content, new.subject, new.predicate, new.object);
|
|
2692
|
+
END;
|
|
2693
|
+
`);
|
|
2582
2694
|
try {
|
|
2583
2695
|
await client.execute({
|
|
2584
2696
|
sql: `ALTER TABLE memories ADD COLUMN tier INTEGER DEFAULT 3`,
|
|
@@ -3316,7 +3428,7 @@ var init_platform_procedures = __esm({
|
|
|
3316
3428
|
title: "MCP tools \u2014 advanced (triggers, skills, orchestration)",
|
|
3317
3429
|
domain: "tool-use",
|
|
3318
3430
|
priority: "p1",
|
|
3319
|
-
content: "create_trigger: set up a scheduled recurring agent job (cron). list_triggers: view active triggers. load_skill: load a slash-command skill dynamically. apply_starter_pack: import a pre-built behavior + identity pack for a role. export_orchestration: export full org state (tasks, behaviors, identities) as portable JSON. import_orchestration: import org state into a new instance. deploy_client: deploy a customer client instance. query_company_brain: unified RAG query across all company knowledge. create_reminder: set a text reminder (shown in boot brief). list_reminders: view pending reminders. complete_reminder: mark a reminder done.
|
|
3431
|
+
content: "create_trigger: set up a scheduled recurring agent job (cron). list_triggers: view active triggers. load_skill: load a slash-command skill dynamically. apply_starter_pack: import a pre-built behavior + identity pack for a role. export_orchestration: export full org state (tasks, behaviors, identities) as portable JSON. import_orchestration: import org state into a new instance. deploy_client: deploy a customer client instance. query_company_brain: unified RAG query across all company knowledge. create_reminder: set a text reminder (shown in boot brief). list_reminders: view pending reminders. complete_reminder: mark a reminder done. company_procedure: manage customer-owned company procedures (Layer 0; actions: store, list, deactivate). Legacy aliases: global_procedure, store_global_procedure, list_global_procedures, deactivate_global_procedure."
|
|
3320
3432
|
}
|
|
3321
3433
|
];
|
|
3322
3434
|
PLATFORM_PROCEDURE_TITLES = new Set(
|
|
@@ -3337,7 +3449,7 @@ import { randomUUID as randomUUID2 } from "crypto";
|
|
|
3337
3449
|
async function loadGlobalProcedures() {
|
|
3338
3450
|
const client = getClient();
|
|
3339
3451
|
const result = await client.execute({
|
|
3340
|
-
sql: "SELECT * FROM
|
|
3452
|
+
sql: "SELECT * FROM company_procedures WHERE active = 1 ORDER BY priority ASC, created_at ASC",
|
|
3341
3453
|
args: []
|
|
3342
3454
|
});
|
|
3343
3455
|
const allRows = result.rows;
|
|
@@ -3366,7 +3478,7 @@ async function storeGlobalProcedure(input) {
|
|
|
3366
3478
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3367
3479
|
const client = getClient();
|
|
3368
3480
|
await client.execute({
|
|
3369
|
-
sql: `INSERT INTO
|
|
3481
|
+
sql: `INSERT INTO company_procedures (id, title, content, priority, domain, active, created_at, updated_at)
|
|
3370
3482
|
VALUES (?, ?, ?, ?, ?, 1, ?, ?)`,
|
|
3371
3483
|
args: [id, input.title, input.content, input.priority ?? "p0", input.domain ?? null, now, now]
|
|
3372
3484
|
});
|
|
@@ -3377,7 +3489,7 @@ async function deactivateGlobalProcedure(id) {
|
|
|
3377
3489
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3378
3490
|
const client = getClient();
|
|
3379
3491
|
const result = await client.execute({
|
|
3380
|
-
sql: "UPDATE
|
|
3492
|
+
sql: "UPDATE company_procedures SET active = 0, updated_at = ? WHERE id = ?",
|
|
3381
3493
|
args: [now, id]
|
|
3382
3494
|
});
|
|
3383
3495
|
await loadGlobalProcedures();
|
|
@@ -3396,6 +3508,164 @@ ${p.content}`).join("\n\n");
|
|
|
3396
3508
|
}
|
|
3397
3509
|
});
|
|
3398
3510
|
|
|
3511
|
+
// src/lib/memory-cards.ts
|
|
3512
|
+
var memory_cards_exports = {};
|
|
3513
|
+
__export(memory_cards_exports, {
|
|
3514
|
+
extractMemoryCards: () => extractMemoryCards,
|
|
3515
|
+
insertMemoryCardsForBatch: () => insertMemoryCardsForBatch,
|
|
3516
|
+
searchMemoryCards: () => searchMemoryCards
|
|
3517
|
+
});
|
|
3518
|
+
import { createHash as createHash2 } from "crypto";
|
|
3519
|
+
function stableId(memoryId, type, content) {
|
|
3520
|
+
return createHash2("sha256").update(`${memoryId}:${type}:${content}`).digest("hex").slice(0, 32);
|
|
3521
|
+
}
|
|
3522
|
+
function cleanText(text) {
|
|
3523
|
+
return text.replace(/```[\s\S]*?```/g, " ").replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
|
|
3524
|
+
}
|
|
3525
|
+
function splitSentences(text) {
|
|
3526
|
+
return cleanText(text).split(/(?<=[.!?])\s+|\n+/).map((s) => s.trim()).filter((s) => s.length >= 24 && s.length <= MAX_SENTENCE_CHARS);
|
|
3527
|
+
}
|
|
3528
|
+
function inferCardType(sentence, toolName) {
|
|
3529
|
+
const lower = sentence.toLowerCase();
|
|
3530
|
+
if (toolName === "store_decision" || /\b(decided|decision|adr|approved|rejected)\b/.test(lower)) return "decision";
|
|
3531
|
+
if (/\b(prefers|preference|likes|dislikes|wants|doesn't want|does not want)\b/.test(lower)) return "preference";
|
|
3532
|
+
if (/\b(changed|updated|replaced|now|no longer|instead|supersedes)\b/.test(lower)) return "belief_update";
|
|
3533
|
+
if (toolName && ["Read", "Write", "Edit", "Bash"].includes(toolName)) return "code";
|
|
3534
|
+
if (/\b(meeting|deadline|shipped|launched|completed|failed|blocked|assigned|created)\b/.test(lower)) return "event";
|
|
3535
|
+
return "fact";
|
|
3536
|
+
}
|
|
3537
|
+
function extractSubject(sentence, agentId) {
|
|
3538
|
+
const explicit = sentence.match(/\b([A-Z][a-zA-Z0-9_-]{2,}(?:\s+[A-Z][a-zA-Z0-9_-]{2,})?)\b/);
|
|
3539
|
+
return explicit?.[1] ?? agentId;
|
|
3540
|
+
}
|
|
3541
|
+
function predicateFor(type) {
|
|
3542
|
+
switch (type) {
|
|
3543
|
+
case "preference":
|
|
3544
|
+
return "prefers";
|
|
3545
|
+
case "belief_update":
|
|
3546
|
+
return "updated";
|
|
3547
|
+
case "decision":
|
|
3548
|
+
return "decided";
|
|
3549
|
+
case "event":
|
|
3550
|
+
return "happened";
|
|
3551
|
+
case "code":
|
|
3552
|
+
return "implemented";
|
|
3553
|
+
default:
|
|
3554
|
+
return "states";
|
|
3555
|
+
}
|
|
3556
|
+
}
|
|
3557
|
+
function extractMemoryCards(row) {
|
|
3558
|
+
const sentences = splitSentences(row.raw_text);
|
|
3559
|
+
const cards = [];
|
|
3560
|
+
for (const sentence of sentences) {
|
|
3561
|
+
const type = inferCardType(sentence, row.tool_name);
|
|
3562
|
+
const subject = extractSubject(sentence, row.agent_id);
|
|
3563
|
+
const content = sentence.length > MAX_SENTENCE_CHARS ? `${sentence.slice(0, MAX_SENTENCE_CHARS - 1)}\u2026` : sentence;
|
|
3564
|
+
cards.push({
|
|
3565
|
+
id: stableId(row.id, type, content),
|
|
3566
|
+
memory_id: row.id,
|
|
3567
|
+
agent_id: row.agent_id,
|
|
3568
|
+
session_id: row.session_id,
|
|
3569
|
+
project_name: row.project_name ?? null,
|
|
3570
|
+
timestamp: row.timestamp,
|
|
3571
|
+
card_type: type,
|
|
3572
|
+
subject,
|
|
3573
|
+
predicate: predicateFor(type),
|
|
3574
|
+
object: content,
|
|
3575
|
+
content,
|
|
3576
|
+
source_ref: row.id,
|
|
3577
|
+
confidence: type === "fact" ? 0.55 : 0.65
|
|
3578
|
+
});
|
|
3579
|
+
if (cards.length >= MAX_CARDS_PER_MEMORY) break;
|
|
3580
|
+
}
|
|
3581
|
+
return cards;
|
|
3582
|
+
}
|
|
3583
|
+
async function insertMemoryCardsForBatch(rows) {
|
|
3584
|
+
const cards = rows.flatMap(extractMemoryCards);
|
|
3585
|
+
if (cards.length === 0) return 0;
|
|
3586
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3587
|
+
const client = getClient();
|
|
3588
|
+
const stmts = cards.map((card) => ({
|
|
3589
|
+
sql: `INSERT OR IGNORE INTO memory_cards
|
|
3590
|
+
(id, memory_id, agent_id, session_id, project_name, timestamp, card_type,
|
|
3591
|
+
subject, predicate, object, content, source_ref, confidence, active, created_at)
|
|
3592
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?)`,
|
|
3593
|
+
args: [
|
|
3594
|
+
card.id,
|
|
3595
|
+
card.memory_id,
|
|
3596
|
+
card.agent_id,
|
|
3597
|
+
card.session_id,
|
|
3598
|
+
card.project_name,
|
|
3599
|
+
card.timestamp,
|
|
3600
|
+
card.card_type,
|
|
3601
|
+
card.subject,
|
|
3602
|
+
card.predicate,
|
|
3603
|
+
card.object,
|
|
3604
|
+
card.content,
|
|
3605
|
+
card.source_ref,
|
|
3606
|
+
card.confidence,
|
|
3607
|
+
now
|
|
3608
|
+
]
|
|
3609
|
+
}));
|
|
3610
|
+
await client.batch(stmts, "write");
|
|
3611
|
+
return cards.length;
|
|
3612
|
+
}
|
|
3613
|
+
function buildMatchExpr(queryText) {
|
|
3614
|
+
const terms = queryText.toLowerCase().split(/\s+/).filter((t) => t.length >= 3).map((t) => t.replace(/[^a-z0-9_]/g, "")).filter((t) => t.length >= 3).slice(0, 12);
|
|
3615
|
+
if (terms.length === 0) return null;
|
|
3616
|
+
return terms.map((t) => `${t}*`).join(terms.length >= 3 ? " AND " : " OR ");
|
|
3617
|
+
}
|
|
3618
|
+
async function searchMemoryCards(queryText, agentId, options) {
|
|
3619
|
+
const limit = options?.limit ?? 10;
|
|
3620
|
+
const matchExpr = buildMatchExpr(queryText);
|
|
3621
|
+
if (!matchExpr) return [];
|
|
3622
|
+
let sql = `SELECT c.id, c.memory_id, c.agent_id, c.session_id, c.project_name,
|
|
3623
|
+
c.timestamp, c.card_type, c.content, c.source_ref, c.confidence
|
|
3624
|
+
FROM memory_cards c
|
|
3625
|
+
JOIN memory_cards_fts fts ON c.rowid = fts.rowid
|
|
3626
|
+
WHERE memory_cards_fts MATCH ?
|
|
3627
|
+
AND c.agent_id = ?
|
|
3628
|
+
AND COALESCE(c.active, 1) = 1`;
|
|
3629
|
+
const args = [matchExpr, agentId];
|
|
3630
|
+
if (options?.projectName) {
|
|
3631
|
+
sql += ` AND c.project_name = ?`;
|
|
3632
|
+
args.push(options.projectName);
|
|
3633
|
+
}
|
|
3634
|
+
if (options?.since) {
|
|
3635
|
+
sql += ` AND c.timestamp >= ?`;
|
|
3636
|
+
args.push(options.since);
|
|
3637
|
+
}
|
|
3638
|
+
sql += ` ORDER BY rank LIMIT ?`;
|
|
3639
|
+
args.push(limit);
|
|
3640
|
+
const result = await getClient().execute({ sql, args });
|
|
3641
|
+
return result.rows.map((row) => ({
|
|
3642
|
+
id: `card:${String(row.id)}`,
|
|
3643
|
+
agent_id: String(row.agent_id),
|
|
3644
|
+
agent_role: "memory_card",
|
|
3645
|
+
session_id: String(row.session_id),
|
|
3646
|
+
timestamp: String(row.timestamp),
|
|
3647
|
+
tool_name: `memory_card:${String(row.card_type)}`,
|
|
3648
|
+
project_name: row.project_name == null ? "" : String(row.project_name),
|
|
3649
|
+
has_error: false,
|
|
3650
|
+
raw_text: `[${String(row.card_type)}] ${String(row.content)}
|
|
3651
|
+
Source memory: ${String(row.source_ref ?? row.memory_id)}`,
|
|
3652
|
+
vector: [],
|
|
3653
|
+
importance: 6,
|
|
3654
|
+
status: "active",
|
|
3655
|
+
confidence: Number(row.confidence ?? 0.6),
|
|
3656
|
+
last_accessed: String(row.timestamp)
|
|
3657
|
+
}));
|
|
3658
|
+
}
|
|
3659
|
+
var MAX_CARDS_PER_MEMORY, MAX_SENTENCE_CHARS;
|
|
3660
|
+
var init_memory_cards = __esm({
|
|
3661
|
+
"src/lib/memory-cards.ts"() {
|
|
3662
|
+
"use strict";
|
|
3663
|
+
init_database();
|
|
3664
|
+
MAX_CARDS_PER_MEMORY = 6;
|
|
3665
|
+
MAX_SENTENCE_CHARS = 360;
|
|
3666
|
+
}
|
|
3667
|
+
});
|
|
3668
|
+
|
|
3399
3669
|
// src/bin/backfill-conversations.ts
|
|
3400
3670
|
import crypto2 from "crypto";
|
|
3401
3671
|
import { createReadStream } from "fs";
|
|
@@ -4195,6 +4465,11 @@ async function flushBatch() {
|
|
|
4195
4465
|
const globalClient = getClient();
|
|
4196
4466
|
const globalStmts = batch.map(buildStmt);
|
|
4197
4467
|
await globalClient.batch(globalStmts, "write");
|
|
4468
|
+
try {
|
|
4469
|
+
const { insertMemoryCardsForBatch: insertMemoryCardsForBatch2 } = await Promise.resolve().then(() => (init_memory_cards(), memory_cards_exports));
|
|
4470
|
+
await insertMemoryCardsForBatch2(batch);
|
|
4471
|
+
} catch {
|
|
4472
|
+
}
|
|
4198
4473
|
schedulePostWriteMemoryHygiene(batch.map((row) => row.id));
|
|
4199
4474
|
_pendingRecords.splice(0, batch.length);
|
|
4200
4475
|
try {
|