@askexenow/exe-os 0.9.294 → 0.9.296
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/compose/cloudflared/config.yml.example +14 -9
- package/deploy/compose/docker-compose.yml +86 -8
- package/deploy/compose/sso-edge/default.conf.template +87 -0
- package/deploy/compose/sso-edge/entrypoint.sh +23 -0
- package/deploy/compose/sso-edge/sso-redirect.conf +63 -0
- package/deploy/stack-manifests/v0.9.json +2 -2
- package/dist/active-agent-AFX2FODG.js +28 -0
- package/dist/active-agent-E2IJA7YX.js +27 -0
- package/dist/agentic-ontology-A2YUZK5O.js +25 -0
- package/dist/assets/com.askexe.exed.plist +4 -1
- package/dist/backfill-metadata-OC7EOD5U.js +600 -0
- package/dist/behaviors-H5ZOVHDH.js +46 -0
- package/dist/bin/agentic-ontology-backfill.js +5 -5
- package/dist/bin/agentic-reflection-backfill.js +6 -6
- package/dist/bin/agentic-semantic-label.js +5 -5
- package/dist/bin/backfill-conversations.js +6 -6
- package/dist/bin/backfill-responses.js +6 -6
- package/dist/bin/backfill-vectors.js +8 -8
- package/dist/bin/bulk-sync-postgres.js +7 -7
- package/dist/bin/cc-doctor.js +4 -4
- package/dist/bin/cleanup-stale-review-tasks.js +11 -11
- package/dist/bin/cli.js +16 -16
- package/dist/bin/deferred-daemon-restart.js +1 -1
- package/dist/bin/exe-agent-config.js +2 -2
- package/dist/bin/exe-agent.js +4 -4
- package/dist/bin/exe-assign.js +8 -8
- package/dist/bin/exe-boot.js +21 -18
- package/dist/bin/exe-call.js +4 -4
- package/dist/bin/exe-cloud.js +7 -7
- package/dist/bin/exe-dispatch.js +11 -11
- package/dist/bin/exe-doctor.js +3 -2
- package/dist/bin/exe-export-behaviors.js +7 -7
- package/dist/bin/exe-forget.js +6 -6
- package/dist/bin/exe-gateway.js +7 -7
- package/dist/bin/exe-healthcheck.js +6 -4
- package/dist/bin/exe-heartbeat.js +11 -11
- package/dist/bin/exe-kill.js +14 -14
- package/dist/bin/exe-launch-agent.js +18 -18
- package/dist/bin/exe-new-employee.js +6 -6
- package/dist/bin/exe-pending-messages.js +12 -12
- package/dist/bin/exe-pending-notifications.js +11 -11
- package/dist/bin/exe-pending-reviews.js +11 -11
- package/dist/bin/exe-rename.js +4 -4
- package/dist/bin/exe-review.js +13 -13
- package/dist/bin/exe-search.js +5 -5
- package/dist/bin/exe-session-cleanup.js +16 -16
- package/dist/bin/exe-settings.js +39 -9
- package/dist/bin/exe-start-codex.js +11 -11
- package/dist/bin/exe-start-opencode.js +8 -8
- package/dist/bin/exe-status.js +12 -12
- package/dist/bin/exe-team.js +3 -3
- package/dist/bin/git-sweep.js +12 -12
- package/dist/bin/graph-backfill.js +4 -4
- package/dist/bin/graph-export.js +5 -5
- package/dist/bin/import-history.js +7 -7
- package/dist/bin/install-launchd.js +13 -6
- package/dist/bin/install.js +26 -14
- package/dist/bin/intercom-check.js +4 -4
- package/dist/bin/mcp-sessions.js +2 -2
- package/dist/bin/orchestration-metrics.js +4 -4
- package/dist/bin/postgres-agentic-reflection-backfill.js +2 -2
- package/dist/bin/postgres-agentic-semantic-backfill.js +1 -1
- package/dist/bin/scan-tasks.js +11 -11
- package/dist/bin/setup.js +1 -1
- package/dist/bin/shard-migrate.js +4 -4
- package/dist/bin/stack-update.js +2 -2
- package/dist/bin/vps-health-gate.js +1 -1
- package/dist/capability-cards-4USI7CUW.js +89 -0
- package/dist/capacity-monitor-WLCBTEYR.js +51 -0
- package/dist/catchup-brief-ZR3NX6LZ.js +175 -0
- package/dist/chunk-22TVSRQQ.js +226 -0
- package/dist/chunk-2E43UXRH.js +395 -0
- package/dist/chunk-2PIGT6UJ.js +460 -0
- package/dist/chunk-3XTMW2MZ.js +535 -0
- package/dist/chunk-465PQFTH.js +262 -0
- package/dist/chunk-5CCXU2AW.js +129 -0
- package/dist/chunk-5D6MPWR7.js +1094 -0
- package/dist/chunk-5Q4MR6SL.js +123 -0
- package/dist/chunk-6327RBWR.js +345 -0
- package/dist/chunk-6MZZREZY.js +199 -0
- package/dist/chunk-7DI2Q4O5.js +1186 -0
- package/dist/chunk-7PW5VNIY.js +122 -0
- package/dist/chunk-7T7Y56HW.js +43 -0
- package/dist/chunk-7UHCWCLT.js +128 -0
- package/dist/chunk-A2ZUMF6L.js +1350 -0
- package/dist/chunk-AKV44JEH.js +185 -0
- package/dist/chunk-ANHWGX5N.js +735 -0
- package/dist/chunk-BQ3P4TKD.js +97 -0
- package/dist/chunk-BUZMT3KZ.js +604 -0
- package/dist/chunk-C2SBESBO.js +210 -0
- package/dist/chunk-CLSXZUZW.js +51 -0
- package/dist/chunk-CONHLVAR.js +1079 -0
- package/dist/chunk-D3WTZPFX.js +456 -0
- package/dist/chunk-DE6SOIYL.js +197 -0
- package/dist/chunk-EIVNMA3Q.js +284 -0
- package/dist/chunk-EJIF4FNT.js +12 -0
- package/dist/chunk-FDFOW564.js +171 -0
- package/dist/chunk-GZUBJ5EC.js +127 -0
- package/dist/chunk-HGZITN22.js +105 -0
- package/dist/chunk-HSRKDU6X.js +362 -0
- package/dist/chunk-IIEN2PHV.js +85 -0
- package/dist/chunk-JQ56VLMM.js +567 -0
- package/dist/chunk-JVHHXRFY.js +280 -0
- package/dist/chunk-JXCXGZ3S.js +55 -0
- package/dist/chunk-K5ZO532Q.js +4388 -0
- package/dist/chunk-K6CAAMXF.js +97 -0
- package/dist/chunk-KA26YTNU.js +81 -0
- package/dist/chunk-KMUW5C3R.js +381 -0
- package/dist/chunk-KOO3J5PV.js +20 -0
- package/dist/chunk-LSV7OFIH.js +290 -0
- package/dist/chunk-LSVFDVNY.js +1158 -0
- package/dist/chunk-LXDQTW32.js +230 -0
- package/dist/chunk-MEP7OUVZ.js +181 -0
- package/dist/chunk-MN2B2LKS.js +240 -0
- package/dist/chunk-N2EAYPYQ.js +1352 -0
- package/dist/chunk-N7I2A667.js +70 -0
- package/dist/chunk-NLZHVIOP.js +630 -0
- package/dist/chunk-NUH5TRZL.js +227 -0
- package/dist/chunk-OAHEIH3G.js +167 -0
- package/dist/chunk-OBHRQGCK.js +58 -0
- package/dist/chunk-ODFA7B2V.js +54 -0
- package/dist/chunk-OSNUP45F.js +731 -0
- package/dist/chunk-OTPRHBTO.js +33 -0
- package/dist/chunk-P6MUA4QU.js +157 -0
- package/dist/chunk-PGIOFKSK.js +2093 -0
- package/dist/chunk-PSE7VHWK.js +50 -0
- package/dist/chunk-QIFUVZFW.js +331 -0
- package/dist/chunk-RDPXKTVK.js +221 -0
- package/dist/chunk-RKYTYJGB.js +76 -0
- package/dist/chunk-RXLR6EFM.js +348 -0
- package/dist/chunk-SDB67PQJ.js +159 -0
- package/dist/chunk-SF2T7MP3.js +402 -0
- package/dist/chunk-SLU3FRFQ.js +2133 -0
- package/dist/chunk-SNDZJ5IV.js +214 -0
- package/dist/chunk-STEEAABW.js +448 -0
- package/dist/chunk-TUTWNHIQ.js +244 -0
- package/dist/chunk-UDP35QBR.js +30 -0
- package/dist/chunk-UKFHNJBI.js +85 -0
- package/dist/chunk-VC2DTK2X.js +382 -0
- package/dist/chunk-VRRAE5JX.js +836 -0
- package/dist/chunk-VVJTBQPR.js +38 -0
- package/dist/chunk-W3EQ362K.js +581 -0
- package/dist/chunk-WHIXIFHC.js +2242 -0
- package/dist/chunk-WRNGJJNR.js +377 -0
- package/dist/chunk-WUKHLCBE.js +3313 -0
- package/dist/chunk-WVPLHGDG.js +150 -0
- package/dist/chunk-XJZBSTL5.js +204 -0
- package/dist/chunk-Y3PMNUM5.js +304 -0
- package/dist/chunk-YHVS4QOV.js +14597 -0
- package/dist/chunk-YJ2OYAOC.js +668 -0
- package/dist/chunk-YYAD2GXX.js +128 -0
- package/dist/chunk-ZQML7EWE.js +333 -0
- package/dist/co-activation-XJLH46OX.js +74 -0
- package/dist/co-occurrence-GNN2X526.js +95 -0
- package/dist/code-context-index-OCPRLFG5.js +30 -0
- package/dist/core-memory-J4W2IYOF.js +110 -0
- package/dist/crdt-sync-QCBTSHIH.js +33 -0
- package/dist/crm-webhook-EM442VUW.js +10 -0
- package/dist/cto-delegation-gate-MLJMVHBK.js +280 -0
- package/dist/daemon-orchestration-2VNLZVTW.js +139 -0
- package/dist/db-backup-VUGFTPJ4.js +43 -0
- package/dist/doc-graph-extractor-PNRSFPSS.js +133 -0
- package/dist/dreaming-SK5VEQRF.js +34 -0
- package/dist/entity-boost-TQWWJUC2.js +375 -0
- package/dist/exe-drift-N34UPO7S.js +70 -0
- package/dist/exe-export-KACBKGVV.js +77 -0
- package/dist/exe-import-GXGDWACG.js +80 -0
- package/dist/exe-key-XPDOZBWW.js +673 -0
- package/dist/exe-snapshot-32GQKGQ5.js +338 -0
- package/dist/fast-db-init-F3TDD5VV.js +7 -0
- package/dist/gateway/index.js +8 -8
- package/dist/git-staleness-J45WNYRF.js +112 -0
- package/dist/git-task-sweep-BTGVQPFB.js +42 -0
- package/dist/global-procedures-6JCQWU4D.js +22 -0
- package/dist/graph-auto-extract-3ZQNXTPC.js +183 -0
- package/dist/hooks/bug-report-worker.js +13 -13
- package/dist/hooks/codex-stop-task-finalizer.js +13 -13
- package/dist/hooks/commit-complete.js +13 -13
- package/dist/hooks/error-recall.js +6 -6
- package/dist/hooks/exe-heartbeat-hook.js +3 -3
- package/dist/hooks/ingest-worker.js +3 -3
- package/dist/hooks/ingest.js +6 -6
- package/dist/hooks/instructions-loaded.js +4 -4
- package/dist/hooks/manifest.json +20 -20
- package/dist/hooks/notification.js +4 -4
- package/dist/hooks/post-compact.js +12 -12
- package/dist/hooks/post-tool-combined.js +6 -6
- package/dist/hooks/pre-compact.js +16 -16
- package/dist/hooks/pre-tool-use.js +16 -16
- package/dist/hooks/prompt-submit.js +24 -24
- package/dist/hooks/session-end.js +21 -21
- package/dist/hooks/session-start.js +12 -12
- package/dist/hooks/stop.js +19 -19
- package/dist/hooks/subagent-stop.js +12 -12
- package/dist/hooks/summary-worker.js +19 -19
- package/dist/index.js +19 -19
- package/dist/installer-5VPFY7SB.js +298 -0
- package/dist/installer-OENFPMA2.js +344 -0
- package/dist/installer-OIX4QOG5.js +40 -0
- package/dist/lib/cloud-sync.js +7 -7
- package/dist/lib/consolidation.js +6 -5
- package/dist/lib/database.js +2 -2
- package/dist/lib/db-daemon-client.js +2 -2
- package/dist/lib/db.js +2 -2
- package/dist/lib/embed-worker.js +1 -0
- package/dist/lib/embedder.js +7 -3
- package/dist/lib/employee-templates.js +4 -4
- package/dist/lib/employees.js +2 -2
- package/dist/lib/exe-daemon-client.js +2 -2
- package/dist/lib/exe-daemon.js +160 -79
- package/dist/lib/hybrid-search.js +5 -5
- package/dist/lib/identity.js +2 -2
- package/dist/lib/messaging.js +11 -11
- package/dist/lib/reminders.js +3 -3
- package/dist/lib/schedules.js +5 -5
- package/dist/lib/session-registry.js +4 -4
- package/dist/lib/skill-learning.js +6 -6
- package/dist/lib/store.js +4 -4
- package/dist/lib/task-router.js +3 -3
- package/dist/lib/tasks.js +12 -12
- package/dist/lib/tmux-routing.js +12 -10
- package/dist/lib/tmux-transport.js +1 -1
- package/dist/lib/token-spend.js +3 -3
- package/dist/lib/transport.js +2 -2
- package/dist/mcp/register-tools.js +62 -61
- package/dist/mcp/server.js +63 -62
- package/dist/mcp/tools/complete-reminder.js +4 -4
- package/dist/mcp/tools/create-reminder.js +4 -4
- package/dist/mcp/tools/create-task.js +14 -14
- package/dist/mcp/tools/deactivate-behavior.js +7 -7
- package/dist/mcp/tools/list-reminders.js +4 -4
- package/dist/mcp/tools/list-tasks.js +14 -14
- package/dist/mcp/tools/send-message.js +13 -13
- package/dist/mcp/tools/update-task.js +13 -13
- package/dist/mcp-http-config-PQTOLCTP.js +29 -0
- package/dist/memory-cards-4RVDZIY2.js +180 -0
- package/dist/memory-graph-extractor-L6YC7G4M.js +22 -0
- package/dist/memory-poisoning-defense-4YVJYH4G.js +224 -0
- package/dist/memory-queue-client-MVAUOZNJ.js +16 -0
- package/dist/memory-reflection-SHHDQNOH.js +244 -0
- package/dist/message-queue-client-DCKZT6X2.js +92 -0
- package/dist/notifications-JFR3G42W.js +47 -0
- package/dist/orchestration-events-MGCGPTDN.js +27 -0
- package/dist/orchestrator-DAFL2YZB.js +35 -0
- package/dist/pipeline-router-WWSZVPCH.js +15 -0
- package/dist/plan-limits-C7XCSDZC.js +28 -0
- package/dist/project-boot-N3NTBVLE.js +299 -0
- package/dist/projection-worker-MTPAPCWX.js +1084 -0
- package/dist/prospective-memory-BTIVUJSB.js +232 -0
- package/dist/reranker-UA6WVESJ.js +19 -0
- package/dist/retrieval-health-7XNZJEBF.js +12 -0
- package/dist/review-polling-4ALGMXC3.js +126 -0
- package/dist/runtime/index.js +13 -13
- package/dist/self-query-router-MROFQLQB.js +192 -0
- package/dist/session-events-CK44XOU4.js +38 -0
- package/dist/session-kill-telemetry-MT6ITDOG.js +31 -0
- package/dist/session-scope-3XDBWV65.js +88 -0
- package/dist/setup-wizard-X6DOD7MC.js +12 -0
- package/dist/skill-refinement-G2CCY3GM.js +159 -0
- package/dist/stack-update-JF7F56AS.js +84 -0
- package/dist/steward-gate-YF2CYXE7.js +15 -0
- package/dist/task-enforcement-YN6HK7NE.js +506 -0
- package/dist/task-scope-CVK6ISCZ.js +37 -0
- package/dist/tasks-crud-NTNET4JE.js +79 -0
- package/dist/tasks-notify-4LJVFPCV.js +40 -0
- package/dist/tasks-review-3V4WOIRG.js +49 -0
- package/dist/telemetry-upload-5PNUKGTM.js +741 -0
- package/dist/token-budget-E46G7ZAQ.js +86 -0
- package/dist/tool-capability-index-JDSMKJER.js +10 -0
- package/dist/tool-telemetry-J3NLS3LJ.js +17 -0
- package/dist/tui/App.js +18 -18
- package/dist/tui-data-6DOMUUCM.js +260 -0
- package/dist/wiki-acl-5UK37LKF.js +111 -0
- package/dist/worker-gate-FM7AEC7G.js +21 -0
- package/dist/workflow-engine-2EDUHUIY.js +28 -0
- package/dist/worktree-7YKKJIYR.js +28 -0
- package/dist/worktree-sweep-C3ELFGDN.js +21 -0
- package/package.json +1 -1
- package/release-notes.json +88 -88
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getCurrentSessionScope,
|
|
3
|
+
strictSessionScopeFilter
|
|
4
|
+
} from "./chunk-K5ZO532Q.js";
|
|
5
|
+
import {
|
|
6
|
+
getProjectName
|
|
7
|
+
} from "./chunk-OPU3NYOO.js";
|
|
8
|
+
|
|
9
|
+
// src/lib/session-events.ts
|
|
10
|
+
import { randomUUID } from "crypto";
|
|
11
|
+
async function ensureSessionEventsTable(client) {
|
|
12
|
+
await client.execute(`
|
|
13
|
+
CREATE TABLE IF NOT EXISTS session_events (
|
|
14
|
+
id TEXT PRIMARY KEY,
|
|
15
|
+
agent_id TEXT NOT NULL,
|
|
16
|
+
agent_role TEXT NOT NULL,
|
|
17
|
+
session_id TEXT NOT NULL,
|
|
18
|
+
session_scope TEXT,
|
|
19
|
+
project_name TEXT NOT NULL,
|
|
20
|
+
event_index INTEGER NOT NULL,
|
|
21
|
+
event_type TEXT NOT NULL,
|
|
22
|
+
tool_name TEXT,
|
|
23
|
+
tool_use_id TEXT,
|
|
24
|
+
content TEXT NOT NULL,
|
|
25
|
+
payload_json TEXT,
|
|
26
|
+
has_error INTEGER NOT NULL DEFAULT 0,
|
|
27
|
+
created_at TEXT NOT NULL
|
|
28
|
+
)
|
|
29
|
+
`);
|
|
30
|
+
await client.execute(`
|
|
31
|
+
CREATE INDEX IF NOT EXISTS idx_session_events_agent_time
|
|
32
|
+
ON session_events(agent_id, created_at DESC)
|
|
33
|
+
`);
|
|
34
|
+
await client.execute(`
|
|
35
|
+
CREATE INDEX IF NOT EXISTS idx_session_events_session_index
|
|
36
|
+
ON session_events(session_id, event_index)
|
|
37
|
+
`);
|
|
38
|
+
await client.execute(`
|
|
39
|
+
CREATE INDEX IF NOT EXISTS idx_session_events_scope_agent_time
|
|
40
|
+
ON session_events(session_scope, agent_id, created_at DESC)
|
|
41
|
+
`);
|
|
42
|
+
}
|
|
43
|
+
async function recordSessionEvent(client, input) {
|
|
44
|
+
if (!input.content || input.content.trim().length === 0) return;
|
|
45
|
+
await ensureSessionEventsTable(client);
|
|
46
|
+
const maxResult = await client.execute({
|
|
47
|
+
sql: "SELECT COALESCE(MAX(event_index), 0) AS max_index FROM session_events WHERE session_id = ?",
|
|
48
|
+
args: [input.sessionId]
|
|
49
|
+
});
|
|
50
|
+
const currentMax = Number(maxResult.rows[0]?.max_index ?? 0);
|
|
51
|
+
const eventIndex = Number.isFinite(currentMax) ? currentMax + 1 : 1;
|
|
52
|
+
await client.execute({
|
|
53
|
+
sql: `INSERT INTO session_events (
|
|
54
|
+
id, agent_id, agent_role, session_id, session_scope, project_name,
|
|
55
|
+
event_index, event_type, tool_name, tool_use_id, content,
|
|
56
|
+
payload_json, has_error, created_at
|
|
57
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
58
|
+
args: [
|
|
59
|
+
randomUUID(),
|
|
60
|
+
input.agentId,
|
|
61
|
+
input.agentRole,
|
|
62
|
+
input.sessionId,
|
|
63
|
+
input.sessionScope ?? getCurrentSessionScope(),
|
|
64
|
+
input.projectName ?? getProjectName(input.cwd),
|
|
65
|
+
eventIndex,
|
|
66
|
+
input.eventType,
|
|
67
|
+
input.toolName ?? null,
|
|
68
|
+
input.toolUseId ?? null,
|
|
69
|
+
input.content,
|
|
70
|
+
input.payloadJson ?? null,
|
|
71
|
+
input.hasError ? 1 : 0,
|
|
72
|
+
input.timestamp ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
73
|
+
]
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
async function listRecentSessionEvents(client, options) {
|
|
77
|
+
await ensureSessionEventsTable(client);
|
|
78
|
+
const conditions = ["agent_id = ?"];
|
|
79
|
+
const args = [options.agentId];
|
|
80
|
+
if (options.sessionId) {
|
|
81
|
+
conditions.push("session_id = ?");
|
|
82
|
+
args.push(options.sessionId);
|
|
83
|
+
}
|
|
84
|
+
if (options.eventType) {
|
|
85
|
+
conditions.push("event_type = ?");
|
|
86
|
+
args.push(options.eventType);
|
|
87
|
+
}
|
|
88
|
+
if (options.projectName && options.projectName !== "all") {
|
|
89
|
+
conditions.push("project_name = ?");
|
|
90
|
+
args.push(options.projectName);
|
|
91
|
+
}
|
|
92
|
+
const scope = strictSessionScopeFilter(options.sessionScope);
|
|
93
|
+
const where = `WHERE ${conditions.join(" AND ")}${scope.sql}`;
|
|
94
|
+
args.push(...scope.args);
|
|
95
|
+
args.push(Math.min(Math.max(options.limit ?? 20, 1), 100));
|
|
96
|
+
const result = await client.execute({
|
|
97
|
+
sql: `SELECT id, agent_id, agent_role, session_id, session_scope,
|
|
98
|
+
project_name, event_index, event_type, tool_name, tool_use_id,
|
|
99
|
+
content, payload_json, has_error, created_at
|
|
100
|
+
FROM session_events
|
|
101
|
+
${where}
|
|
102
|
+
ORDER BY created_at DESC, event_index DESC
|
|
103
|
+
LIMIT ?`,
|
|
104
|
+
args
|
|
105
|
+
});
|
|
106
|
+
return result.rows.map((row) => ({
|
|
107
|
+
id: String(row.id),
|
|
108
|
+
agentId: String(row.agent_id),
|
|
109
|
+
agentRole: String(row.agent_role),
|
|
110
|
+
sessionId: String(row.session_id),
|
|
111
|
+
sessionScope: row.session_scope == null ? null : String(row.session_scope),
|
|
112
|
+
projectName: String(row.project_name),
|
|
113
|
+
eventIndex: Number(row.event_index),
|
|
114
|
+
eventType: String(row.event_type),
|
|
115
|
+
toolName: row.tool_name == null ? null : String(row.tool_name),
|
|
116
|
+
toolUseId: row.tool_use_id == null ? null : String(row.tool_use_id),
|
|
117
|
+
content: String(row.content),
|
|
118
|
+
payloadJson: row.payload_json == null ? null : String(row.payload_json),
|
|
119
|
+
hasError: Number(row.has_error) === 1,
|
|
120
|
+
createdAt: String(row.created_at)
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export {
|
|
125
|
+
ensureSessionEventsTable,
|
|
126
|
+
recordSessionEvent,
|
|
127
|
+
listRecentSessionEvents
|
|
128
|
+
};
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
import {
|
|
2
|
+
executeAction,
|
|
3
|
+
substituteTemplate
|
|
4
|
+
} from "./chunk-VC2DTK2X.js";
|
|
5
|
+
|
|
6
|
+
// src/automation/workflow-engine.ts
|
|
7
|
+
import { randomUUID } from "crypto";
|
|
8
|
+
var _definitions = /* @__PURE__ */ new Map();
|
|
9
|
+
var _instances = /* @__PURE__ */ new Map();
|
|
10
|
+
function createWorkflowDefinition(input) {
|
|
11
|
+
const def = {
|
|
12
|
+
id: randomUUID().slice(0, 12),
|
|
13
|
+
...input,
|
|
14
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
15
|
+
};
|
|
16
|
+
def.steps = def.steps.map((s, i) => ({ ...s, index: s.index || i + 1 }));
|
|
17
|
+
_definitions.set(def.id, def);
|
|
18
|
+
return def;
|
|
19
|
+
}
|
|
20
|
+
function getWorkflowDefinition(id) {
|
|
21
|
+
return _definitions.get(id);
|
|
22
|
+
}
|
|
23
|
+
function listWorkflowDefinitions() {
|
|
24
|
+
return [..._definitions.values()];
|
|
25
|
+
}
|
|
26
|
+
function buildTemplateContext(instance) {
|
|
27
|
+
const ctx = { ...instance.context };
|
|
28
|
+
const stepMap = {};
|
|
29
|
+
for (const sr of instance.step_results) {
|
|
30
|
+
stepMap[String(sr.step_index)] = {
|
|
31
|
+
status: sr.status,
|
|
32
|
+
result: sr.result,
|
|
33
|
+
error: sr.error
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
ctx.step = stepMap;
|
|
37
|
+
return ctx;
|
|
38
|
+
}
|
|
39
|
+
function resolveActionParams(action, context) {
|
|
40
|
+
const resolved = {};
|
|
41
|
+
for (const [key, val] of Object.entries(action.params)) {
|
|
42
|
+
resolved[key] = substituteTemplate(val, context);
|
|
43
|
+
}
|
|
44
|
+
return { ...action, params: resolved };
|
|
45
|
+
}
|
|
46
|
+
function startWorkflow(definitionId, context = {}) {
|
|
47
|
+
const def = _definitions.get(definitionId);
|
|
48
|
+
if (!def) throw new Error(`Workflow definition "${definitionId}" not found`);
|
|
49
|
+
const instance = {
|
|
50
|
+
id: randomUUID().slice(0, 12),
|
|
51
|
+
definition_id: definitionId,
|
|
52
|
+
status: "running",
|
|
53
|
+
current_step: 1,
|
|
54
|
+
step_results: [],
|
|
55
|
+
context,
|
|
56
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
57
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
58
|
+
};
|
|
59
|
+
_instances.set(instance.id, instance);
|
|
60
|
+
return instance;
|
|
61
|
+
}
|
|
62
|
+
function getWorkflowInstance(id) {
|
|
63
|
+
return _instances.get(id);
|
|
64
|
+
}
|
|
65
|
+
function listWorkflowInstances(status) {
|
|
66
|
+
const all = [..._instances.values()];
|
|
67
|
+
return status ? all.filter((i) => i.status === status) : all;
|
|
68
|
+
}
|
|
69
|
+
async function advanceWorkflow(instanceId) {
|
|
70
|
+
const instance = _instances.get(instanceId);
|
|
71
|
+
if (!instance) throw new Error(`Workflow instance "${instanceId}" not found`);
|
|
72
|
+
if (instance.status !== "running") {
|
|
73
|
+
throw new Error(`Workflow "${instanceId}" is ${instance.status}, cannot advance`);
|
|
74
|
+
}
|
|
75
|
+
const def = _definitions.get(instance.definition_id);
|
|
76
|
+
if (!def) throw new Error(`Workflow definition "${instance.definition_id}" not found`);
|
|
77
|
+
const step = def.steps.find((s) => s.index === instance.current_step);
|
|
78
|
+
if (!step) {
|
|
79
|
+
instance.status = "completed";
|
|
80
|
+
instance.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
81
|
+
return instance;
|
|
82
|
+
}
|
|
83
|
+
const templateCtx = buildTemplateContext(instance);
|
|
84
|
+
const stepResult = {
|
|
85
|
+
step_index: step.index,
|
|
86
|
+
status: "success",
|
|
87
|
+
started_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
88
|
+
};
|
|
89
|
+
switch (step.type) {
|
|
90
|
+
case "execute_action": {
|
|
91
|
+
const action = step.action ?? buildActionFromConnector(step);
|
|
92
|
+
if (!action) {
|
|
93
|
+
stepResult.status = "failed";
|
|
94
|
+
stepResult.error = "No action defined for execute_action step";
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
const resolvedAction = resolveActionParams(action, templateCtx);
|
|
98
|
+
const result = await executeAction(resolvedAction, templateCtx);
|
|
99
|
+
stepResult.status = result.success ? "success" : "failed";
|
|
100
|
+
stepResult.result = result;
|
|
101
|
+
stepResult.error = result.error;
|
|
102
|
+
if (!result.success) {
|
|
103
|
+
instance.status = "failed";
|
|
104
|
+
}
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
case "wait_for_approval": {
|
|
108
|
+
const { createTask } = await import("./lib/tasks.js");
|
|
109
|
+
const { getCoordinatorName } = await import("./lib/employees.js");
|
|
110
|
+
const message = step.approval_message ? substituteTemplate(step.approval_message, templateCtx) : `Workflow "${def.name}" step ${step.index} ("${step.name}") requires approval.`;
|
|
111
|
+
const task = await createTask({
|
|
112
|
+
title: `[Workflow Approval] ${def.name}: ${step.name}`,
|
|
113
|
+
assignedTo: getCoordinatorName(),
|
|
114
|
+
assignedBy: "workflow-engine",
|
|
115
|
+
projectName: "exe-os",
|
|
116
|
+
priority: "p1",
|
|
117
|
+
context: `${message}
|
|
118
|
+
|
|
119
|
+
**Workflow:** ${def.name} (${instance.id})
|
|
120
|
+
**Step:** ${step.index} \u2014 ${step.name}
|
|
121
|
+
|
|
122
|
+
To approve: call approve_workflow_step with instance_id="${instance.id}"
|
|
123
|
+
To reject: call approve_workflow_step with instance_id="${instance.id}" approved=false`,
|
|
124
|
+
baseDir: process.cwd()
|
|
125
|
+
});
|
|
126
|
+
instance.approval_task_id = task.id;
|
|
127
|
+
instance.status = "waiting_approval";
|
|
128
|
+
stepResult.status = "pending_approval";
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
case "conditional": {
|
|
132
|
+
if (!step.condition) {
|
|
133
|
+
stepResult.status = "failed";
|
|
134
|
+
stepResult.error = "No condition defined for conditional step";
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
const resolvedExpr = substituteTemplate(step.condition.expression, templateCtx);
|
|
138
|
+
const conditionMet = evaluateSimpleExpression(resolvedExpr);
|
|
139
|
+
stepResult.result = { expression: resolvedExpr, met: conditionMet };
|
|
140
|
+
if (conditionMet && step.condition.then_step) {
|
|
141
|
+
instance.current_step = step.condition.then_step;
|
|
142
|
+
stepResult.completed_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
143
|
+
instance.step_results.push(stepResult);
|
|
144
|
+
instance.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
145
|
+
return instance;
|
|
146
|
+
} else if (!conditionMet && step.condition.else_step) {
|
|
147
|
+
instance.current_step = step.condition.else_step;
|
|
148
|
+
stepResult.completed_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
149
|
+
instance.step_results.push(stepResult);
|
|
150
|
+
instance.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
151
|
+
return instance;
|
|
152
|
+
}
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
stepResult.completed_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
157
|
+
instance.step_results.push(stepResult);
|
|
158
|
+
if (instance.status === "running") {
|
|
159
|
+
const nextStep = def.steps.find((s) => s.index > step.index);
|
|
160
|
+
if (nextStep) {
|
|
161
|
+
instance.current_step = nextStep.index;
|
|
162
|
+
} else {
|
|
163
|
+
instance.status = "completed";
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
instance.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
167
|
+
return instance;
|
|
168
|
+
}
|
|
169
|
+
async function runWorkflow(instanceId) {
|
|
170
|
+
let instance = _instances.get(instanceId);
|
|
171
|
+
if (!instance) throw new Error(`Workflow instance "${instanceId}" not found`);
|
|
172
|
+
while (instance.status === "running") {
|
|
173
|
+
instance = await advanceWorkflow(instanceId);
|
|
174
|
+
}
|
|
175
|
+
return instance;
|
|
176
|
+
}
|
|
177
|
+
async function approveWorkflowStep(instanceId, approved = true) {
|
|
178
|
+
const instance = _instances.get(instanceId);
|
|
179
|
+
if (!instance) throw new Error(`Workflow instance "${instanceId}" not found`);
|
|
180
|
+
if (instance.status !== "waiting_approval") {
|
|
181
|
+
throw new Error(`Workflow "${instanceId}" is not waiting for approval (status: ${instance.status})`);
|
|
182
|
+
}
|
|
183
|
+
const pendingResult = instance.step_results.find(
|
|
184
|
+
(sr) => sr.step_index === instance.current_step && sr.status === "pending_approval"
|
|
185
|
+
);
|
|
186
|
+
if (pendingResult) {
|
|
187
|
+
pendingResult.status = approved ? "approved" : "failed";
|
|
188
|
+
pendingResult.completed_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
189
|
+
pendingResult.result = { approved };
|
|
190
|
+
}
|
|
191
|
+
if (!approved) {
|
|
192
|
+
instance.status = "cancelled";
|
|
193
|
+
instance.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
194
|
+
return instance;
|
|
195
|
+
}
|
|
196
|
+
const def = _definitions.get(instance.definition_id);
|
|
197
|
+
if (!def) throw new Error(`Workflow definition "${instance.definition_id}" not found`);
|
|
198
|
+
const currentStep = def.steps.find((s) => s.index === instance.current_step);
|
|
199
|
+
const nextStep = currentStep ? def.steps.find((s) => s.index > currentStep.index) : void 0;
|
|
200
|
+
if (nextStep) {
|
|
201
|
+
instance.current_step = nextStep.index;
|
|
202
|
+
instance.status = "running";
|
|
203
|
+
} else {
|
|
204
|
+
instance.status = "completed";
|
|
205
|
+
}
|
|
206
|
+
instance.approval_task_id = void 0;
|
|
207
|
+
instance.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
208
|
+
if (instance.status === "running") {
|
|
209
|
+
return runWorkflow(instanceId);
|
|
210
|
+
}
|
|
211
|
+
return instance;
|
|
212
|
+
}
|
|
213
|
+
function buildActionFromConnector(step) {
|
|
214
|
+
if (!step.connector || !step.operation) return null;
|
|
215
|
+
const params = {};
|
|
216
|
+
if (step.payload) {
|
|
217
|
+
for (const [k, v] of Object.entries(step.payload)) {
|
|
218
|
+
params[k] = String(v);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
params._connector = step.connector;
|
|
222
|
+
params._operation = step.operation;
|
|
223
|
+
return {
|
|
224
|
+
type: "mcp_tool",
|
|
225
|
+
params
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
function evaluateSimpleExpression(expr) {
|
|
229
|
+
const operators = ["==", "!=", ">=", "<=", ">", "<"];
|
|
230
|
+
for (const op of operators) {
|
|
231
|
+
const idx = expr.indexOf(op);
|
|
232
|
+
if (idx === -1) continue;
|
|
233
|
+
const left = expr.slice(0, idx).trim();
|
|
234
|
+
const right = expr.slice(idx + op.length).trim();
|
|
235
|
+
switch (op) {
|
|
236
|
+
case "==":
|
|
237
|
+
return left === right;
|
|
238
|
+
case "!=":
|
|
239
|
+
return left !== right;
|
|
240
|
+
case ">":
|
|
241
|
+
return Number(left) > Number(right);
|
|
242
|
+
case "<":
|
|
243
|
+
return Number(left) < Number(right);
|
|
244
|
+
case ">=":
|
|
245
|
+
return Number(left) >= Number(right);
|
|
246
|
+
case "<=":
|
|
247
|
+
return Number(left) <= Number(right);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return expr.trim() !== "" && expr.trim() !== "false" && expr.trim() !== "0";
|
|
251
|
+
}
|
|
252
|
+
async function persistWorkflows() {
|
|
253
|
+
try {
|
|
254
|
+
const { getClient } = await import("./lib/database.js");
|
|
255
|
+
const client = getClient();
|
|
256
|
+
for (const def of _definitions.values()) {
|
|
257
|
+
await client.execute({
|
|
258
|
+
sql: `INSERT OR REPLACE INTO workflow_definitions (id, name, description, steps, trigger_event, created_at)
|
|
259
|
+
VALUES (?, ?, ?, ?, ?, ?)`,
|
|
260
|
+
args: [def.id, def.name, def.description ?? null, JSON.stringify(def.steps), def.trigger_event ?? null, def.created_at]
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
for (const inst of _instances.values()) {
|
|
264
|
+
await client.execute({
|
|
265
|
+
sql: `INSERT OR REPLACE INTO workflow_instances
|
|
266
|
+
(id, definition_id, status, current_step, step_results, context, approval_task_id, created_at, updated_at)
|
|
267
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
268
|
+
args: [
|
|
269
|
+
inst.id,
|
|
270
|
+
inst.definition_id,
|
|
271
|
+
inst.status,
|
|
272
|
+
inst.current_step,
|
|
273
|
+
JSON.stringify(inst.step_results),
|
|
274
|
+
JSON.stringify(inst.context),
|
|
275
|
+
inst.approval_task_id ?? null,
|
|
276
|
+
inst.created_at,
|
|
277
|
+
inst.updated_at
|
|
278
|
+
]
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
} catch (e) {
|
|
282
|
+
process.stderr.write(`[workflow-engine] persist failed: ${e instanceof Error ? e.message : String(e)}
|
|
283
|
+
`);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
async function loadWorkflows() {
|
|
287
|
+
try {
|
|
288
|
+
const { getClient } = await import("./lib/database.js");
|
|
289
|
+
const client = getClient();
|
|
290
|
+
const defs = await client.execute("SELECT * FROM workflow_definitions");
|
|
291
|
+
for (const row of defs.rows) {
|
|
292
|
+
const def = {
|
|
293
|
+
id: String(row.id),
|
|
294
|
+
name: String(row.name),
|
|
295
|
+
description: String(row.description),
|
|
296
|
+
steps: JSON.parse(String(row.steps)),
|
|
297
|
+
trigger_event: String(row.trigger_event),
|
|
298
|
+
created_at: String(row.created_at)
|
|
299
|
+
};
|
|
300
|
+
_definitions.set(def.id, def);
|
|
301
|
+
}
|
|
302
|
+
const insts = await client.execute("SELECT * FROM workflow_instances WHERE status NOT IN ('completed', 'cancelled')");
|
|
303
|
+
for (const row of insts.rows) {
|
|
304
|
+
const inst = {
|
|
305
|
+
id: String(row.id),
|
|
306
|
+
definition_id: String(row.definition_id),
|
|
307
|
+
status: String(row.status),
|
|
308
|
+
current_step: Number(row.current_step),
|
|
309
|
+
step_results: JSON.parse(String(row.step_results)),
|
|
310
|
+
context: JSON.parse(String(row.context)),
|
|
311
|
+
approval_task_id: row.approval_task_id ? String(row.approval_task_id) : void 0,
|
|
312
|
+
created_at: String(row.created_at),
|
|
313
|
+
updated_at: String(row.updated_at)
|
|
314
|
+
};
|
|
315
|
+
_instances.set(inst.id, inst);
|
|
316
|
+
}
|
|
317
|
+
} catch {
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
export {
|
|
322
|
+
createWorkflowDefinition,
|
|
323
|
+
getWorkflowDefinition,
|
|
324
|
+
listWorkflowDefinitions,
|
|
325
|
+
startWorkflow,
|
|
326
|
+
getWorkflowInstance,
|
|
327
|
+
listWorkflowInstances,
|
|
328
|
+
advanceWorkflow,
|
|
329
|
+
runWorkflow,
|
|
330
|
+
approveWorkflowStep,
|
|
331
|
+
persistWorkflows,
|
|
332
|
+
loadWorkflows
|
|
333
|
+
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getClient
|
|
3
|
+
} from "./chunk-WUKHLCBE.js";
|
|
4
|
+
import "./chunk-2I23RPSI.js";
|
|
5
|
+
import "./chunk-2E43UXRH.js";
|
|
6
|
+
import "./chunk-PNQDP3OA.js";
|
|
7
|
+
import "./chunk-7HLWBYH7.js";
|
|
8
|
+
import "./chunk-FXU7JOXK.js";
|
|
9
|
+
import "./chunk-R36FAN53.js";
|
|
10
|
+
import "./chunk-LYH5HE24.js";
|
|
11
|
+
import "./chunk-MLKGABMK.js";
|
|
12
|
+
|
|
13
|
+
// src/lib/co-activation.ts
|
|
14
|
+
async function recordCoActivations(entityIds) {
|
|
15
|
+
if (entityIds.length < 2) return;
|
|
16
|
+
const unique = [...new Set(entityIds)].slice(0, 20);
|
|
17
|
+
const client = getClient();
|
|
18
|
+
const pairs = [];
|
|
19
|
+
for (let i = 0; i < unique.length; i++) {
|
|
20
|
+
for (let j = i + 1; j < unique.length; j++) {
|
|
21
|
+
const idI = unique[i];
|
|
22
|
+
const idJ = unique[j];
|
|
23
|
+
const pair = idI < idJ ? [idI, idJ] : [idJ, idI];
|
|
24
|
+
pairs.push(pair);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
for (const [a, b] of pairs) {
|
|
28
|
+
await client.execute({
|
|
29
|
+
sql: `INSERT INTO co_activations (entity_a_id, entity_b_id, count, last_activated_at)
|
|
30
|
+
VALUES (?, ?, 1, datetime('now'))
|
|
31
|
+
ON CONFLICT (entity_a_id, entity_b_id)
|
|
32
|
+
DO UPDATE SET count = count + 1, last_activated_at = datetime('now')`,
|
|
33
|
+
args: [a, b]
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async function getHotPairs(limit = 20) {
|
|
38
|
+
const client = getClient();
|
|
39
|
+
const result = await client.execute({
|
|
40
|
+
sql: `SELECT entity_a_id, entity_b_id, count, last_activated_at
|
|
41
|
+
FROM co_activations
|
|
42
|
+
ORDER BY count DESC
|
|
43
|
+
LIMIT ?`,
|
|
44
|
+
args: [limit]
|
|
45
|
+
});
|
|
46
|
+
return result.rows.map((r) => ({
|
|
47
|
+
entity_a_id: String(r.entity_a_id),
|
|
48
|
+
entity_b_id: String(r.entity_b_id),
|
|
49
|
+
count: Number(r.count),
|
|
50
|
+
last_activated_at: String(r.last_activated_at)
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
53
|
+
async function getCoActivationNeighbors(entityId, limit = 20) {
|
|
54
|
+
const client = getClient();
|
|
55
|
+
const result = await client.execute({
|
|
56
|
+
sql: `SELECT entity_a_id, entity_b_id, count, last_activated_at
|
|
57
|
+
FROM co_activations
|
|
58
|
+
WHERE entity_a_id = ? OR entity_b_id = ?
|
|
59
|
+
ORDER BY count DESC
|
|
60
|
+
LIMIT ?`,
|
|
61
|
+
args: [entityId, entityId, limit]
|
|
62
|
+
});
|
|
63
|
+
return result.rows.map((r) => ({
|
|
64
|
+
entity_a_id: String(r.entity_a_id),
|
|
65
|
+
entity_b_id: String(r.entity_b_id),
|
|
66
|
+
count: Number(r.count),
|
|
67
|
+
last_activated_at: String(r.last_activated_at)
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
export {
|
|
71
|
+
getCoActivationNeighbors,
|
|
72
|
+
getHotPairs,
|
|
73
|
+
recordCoActivations
|
|
74
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import {
|
|
2
|
+
entityId,
|
|
3
|
+
normalizeEntityName
|
|
4
|
+
} from "./chunk-6OAAN25C.js";
|
|
5
|
+
import "./chunk-GUMRIUI5.js";
|
|
6
|
+
import "./chunk-I7AW4237.js";
|
|
7
|
+
import {
|
|
8
|
+
getClient
|
|
9
|
+
} from "./chunk-WUKHLCBE.js";
|
|
10
|
+
import "./chunk-2I23RPSI.js";
|
|
11
|
+
import "./chunk-2E43UXRH.js";
|
|
12
|
+
import "./chunk-PNQDP3OA.js";
|
|
13
|
+
import "./chunk-7HLWBYH7.js";
|
|
14
|
+
import "./chunk-FXU7JOXK.js";
|
|
15
|
+
import "./chunk-R36FAN53.js";
|
|
16
|
+
import "./chunk-LYH5HE24.js";
|
|
17
|
+
import "./chunk-MLKGABMK.js";
|
|
18
|
+
|
|
19
|
+
// src/lib/co-occurrence.ts
|
|
20
|
+
var SPECIFICITY = {
|
|
21
|
+
file: 5,
|
|
22
|
+
function: 4,
|
|
23
|
+
error: 3,
|
|
24
|
+
tool: 2,
|
|
25
|
+
agent: 1,
|
|
26
|
+
project: 0
|
|
27
|
+
};
|
|
28
|
+
function getSpecificity(type) {
|
|
29
|
+
return SPECIFICITY[type] ?? 1;
|
|
30
|
+
}
|
|
31
|
+
function coOccurrenceId(entityId1, entityId2) {
|
|
32
|
+
const sorted = [entityId1, entityId2].sort();
|
|
33
|
+
return `cooccur:${sorted[0]}:${sorted[1]}`;
|
|
34
|
+
}
|
|
35
|
+
async function actualEntityId(name, type, fallbackId) {
|
|
36
|
+
try {
|
|
37
|
+
const result = await getClient().execute({
|
|
38
|
+
sql: "SELECT id FROM entities WHERE LOWER(name) = LOWER(?) AND type = ? LIMIT 1",
|
|
39
|
+
args: [name, type]
|
|
40
|
+
});
|
|
41
|
+
return result.rows[0]?.id ? String(result.rows[0].id) : fallbackId;
|
|
42
|
+
} catch {
|
|
43
|
+
return fallbackId;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
async function createCoOccurrenceEdges(entities, _memoryId) {
|
|
47
|
+
if (entities.length < 2) return 0;
|
|
48
|
+
const client = getClient();
|
|
49
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
50
|
+
const seen = /* @__PURE__ */ new Set();
|
|
51
|
+
const deduped = entities.filter((e) => {
|
|
52
|
+
const key = `${e.type.toLowerCase()}:${normalizeEntityName(e.name)}`;
|
|
53
|
+
if (seen.has(key)) return false;
|
|
54
|
+
seen.add(key);
|
|
55
|
+
return true;
|
|
56
|
+
});
|
|
57
|
+
const sorted = deduped.sort((a, b) => getSpecificity(b.type) - getSpecificity(a.type));
|
|
58
|
+
const MAX_PAIRS = 10;
|
|
59
|
+
const pairs = [];
|
|
60
|
+
for (let i = 0; i < sorted.length && pairs.length < MAX_PAIRS; i++) {
|
|
61
|
+
for (let j = i + 1; j < sorted.length && pairs.length < MAX_PAIRS; j++) {
|
|
62
|
+
pairs.push([sorted[i], sorted[j]]);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
let created = 0;
|
|
66
|
+
for (const [a, b] of pairs) {
|
|
67
|
+
const aName = normalizeEntityName(a.name);
|
|
68
|
+
const bName = normalizeEntityName(b.name);
|
|
69
|
+
const aType = a.type.toLowerCase();
|
|
70
|
+
const bType = b.type.toLowerCase();
|
|
71
|
+
const aId = await actualEntityId(aName, aType, entityId(aName, aType));
|
|
72
|
+
const bId = await actualEntityId(bName, bType, entityId(bName, bType));
|
|
73
|
+
if (aId === bId) continue;
|
|
74
|
+
const relId = coOccurrenceId(aId, bId);
|
|
75
|
+
const sortedIds = [aId, bId].sort();
|
|
76
|
+
const sourceId = sortedIds[0];
|
|
77
|
+
const targetId = sortedIds[1];
|
|
78
|
+
try {
|
|
79
|
+
await client.execute({
|
|
80
|
+
sql: `INSERT INTO relationships (id, source_entity_id, target_entity_id, type, weight, timestamp, properties)
|
|
81
|
+
VALUES (?, ?, ?, 'co_occurs_with', 1.0, ?, '{}')
|
|
82
|
+
ON CONFLICT(source_entity_id, target_entity_id, type) DO UPDATE SET
|
|
83
|
+
weight = MIN(weight + 0.1, 10.0),
|
|
84
|
+
timestamp = ?`,
|
|
85
|
+
args: [relId, sourceId, targetId, now, now]
|
|
86
|
+
});
|
|
87
|
+
created++;
|
|
88
|
+
} catch {
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return created;
|
|
92
|
+
}
|
|
93
|
+
export {
|
|
94
|
+
createCoOccurrenceEdges
|
|
95
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import {
|
|
2
|
+
analyzeBlastRadius,
|
|
3
|
+
buildCodeContextIndex,
|
|
4
|
+
buildCodeContextIndexWithEmbeddings,
|
|
5
|
+
getCodeContextIndexPath,
|
|
6
|
+
getCodeContextStats,
|
|
7
|
+
loadOrBuildCodeContextIndex,
|
|
8
|
+
searchCodeContext,
|
|
9
|
+
searchCodeContextSemantic,
|
|
10
|
+
traceCodeSymbol
|
|
11
|
+
} from "./chunk-BUZMT3KZ.js";
|
|
12
|
+
import "./chunk-I7AW4237.js";
|
|
13
|
+
import "./chunk-W3EQ362K.js";
|
|
14
|
+
import "./chunk-QOZQ2MYZ.js";
|
|
15
|
+
import "./chunk-7T7Y56HW.js";
|
|
16
|
+
import "./chunk-7L2EV3XX.js";
|
|
17
|
+
import "./chunk-R36FAN53.js";
|
|
18
|
+
import "./chunk-LYH5HE24.js";
|
|
19
|
+
import "./chunk-MLKGABMK.js";
|
|
20
|
+
export {
|
|
21
|
+
analyzeBlastRadius,
|
|
22
|
+
buildCodeContextIndex,
|
|
23
|
+
buildCodeContextIndexWithEmbeddings,
|
|
24
|
+
getCodeContextIndexPath,
|
|
25
|
+
getCodeContextStats,
|
|
26
|
+
loadOrBuildCodeContextIndex,
|
|
27
|
+
searchCodeContext,
|
|
28
|
+
searchCodeContextSemantic,
|
|
29
|
+
traceCodeSymbol
|
|
30
|
+
};
|