@askexenow/exe-os 0.9.112 → 0.9.113
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/README.md +9 -7
- package/dist/bin/agentic-ontology-backfill.js +54 -11
- package/dist/bin/agentic-reflection-backfill.js +29 -1
- package/dist/bin/agentic-semantic-label.js +29 -1
- package/dist/bin/backfill-conversations.js +53 -10
- package/dist/bin/backfill-responses.js +54 -11
- package/dist/bin/backfill-vectors.js +29 -1
- package/dist/bin/bulk-sync-postgres.js +55 -12
- package/dist/bin/cleanup-stale-review-tasks.js +75 -15
- package/dist/bin/cli.js +293 -76
- package/dist/bin/exe-agent-config.js +7 -1
- package/dist/bin/exe-agent.js +28 -2
- package/dist/bin/exe-assign.js +54 -11
- package/dist/bin/exe-boot.js +481 -147
- package/dist/bin/exe-call.js +45 -4
- package/dist/bin/exe-cloud.js +93 -15
- package/dist/bin/exe-dispatch.js +369 -24
- package/dist/bin/exe-doctor.js +53 -10
- package/dist/bin/exe-export-behaviors.js +54 -11
- package/dist/bin/exe-forget.js +54 -11
- package/dist/bin/exe-gateway.js +128 -23
- package/dist/bin/exe-heartbeat.js +75 -15
- package/dist/bin/exe-kill.js +54 -11
- package/dist/bin/exe-launch-agent.js +70 -12
- package/dist/bin/exe-new-employee.js +175 -7
- package/dist/bin/exe-pending-messages.js +75 -15
- package/dist/bin/exe-pending-notifications.js +75 -15
- package/dist/bin/exe-pending-reviews.js +75 -15
- package/dist/bin/exe-rename.js +54 -11
- package/dist/bin/exe-review.js +54 -11
- package/dist/bin/exe-search.js +54 -11
- package/dist/bin/exe-session-cleanup.js +491 -146
- package/dist/bin/exe-settings.js +10 -4
- package/dist/bin/exe-start-codex.js +524 -245
- package/dist/bin/exe-start-opencode.js +534 -165
- package/dist/bin/exe-status.js +75 -15
- package/dist/bin/exe-support.js +1 -1
- package/dist/bin/exe-team.js +54 -11
- package/dist/bin/git-sweep.js +369 -24
- package/dist/bin/graph-backfill.js +54 -11
- package/dist/bin/graph-export.js +54 -11
- package/dist/bin/install.js +62 -4
- package/dist/bin/intercom-check.js +491 -146
- package/dist/bin/pre-publish.js +13 -1
- package/dist/bin/scan-tasks.js +369 -24
- package/dist/bin/setup.js +91 -13
- package/dist/bin/shard-migrate.js +54 -11
- package/dist/bin/stack-update.js +1 -1
- package/dist/bin/update.js +3 -3
- package/dist/gateway/index.js +128 -23
- package/dist/hooks/bug-report-worker.js +128 -23
- package/dist/hooks/codex-stop-task-finalizer.js +512 -140
- package/dist/hooks/commit-complete.js +369 -24
- package/dist/hooks/error-recall.js +54 -11
- package/dist/hooks/ingest.js +4575 -252
- package/dist/hooks/instructions-loaded.js +54 -11
- package/dist/hooks/notification.js +54 -11
- package/dist/hooks/post-compact.js +75 -15
- package/dist/hooks/post-tool-combined.js +75 -15
- package/dist/hooks/pre-compact.js +449 -104
- package/dist/hooks/pre-tool-use.js +90 -15
- package/dist/hooks/prompt-submit.js +129 -24
- package/dist/hooks/session-end.js +451 -109
- package/dist/hooks/session-start.js +104 -16
- package/dist/hooks/stop.js +74 -14
- package/dist/hooks/subagent-stop.js +75 -15
- package/dist/hooks/summary-worker.js +73 -7
- package/dist/index.js +128 -23
- package/dist/lib/agent-config.js +16 -1
- package/dist/lib/cloud-sync.js +38 -1
- package/dist/lib/consolidation.js +16 -1
- package/dist/lib/database.js +16 -0
- package/dist/lib/db.js +16 -0
- package/dist/lib/device-registry.js +16 -0
- package/dist/lib/employee-templates.js +29 -3
- package/dist/lib/employees.js +16 -1
- package/dist/lib/exe-daemon.js +268 -42
- package/dist/lib/hybrid-search.js +54 -11
- package/dist/lib/license.js +3 -3
- package/dist/lib/messaging.js +21 -4
- package/dist/lib/schedules.js +29 -1
- package/dist/lib/skill-learning.js +458 -70
- package/dist/lib/status-brief.js +14 -1
- package/dist/lib/store.js +54 -11
- package/dist/lib/tasks.js +393 -91
- package/dist/lib/tmux-routing.js +316 -14
- package/dist/mcp/server.js +169 -30
- package/dist/mcp/tools/create-task.js +75 -13
- package/dist/mcp/tools/deactivate-behavior.js +33 -24
- package/dist/mcp/tools/list-tasks.js +21 -4
- package/dist/mcp/tools/send-message.js +21 -4
- package/dist/mcp/tools/update-task.js +390 -91
- package/dist/runtime/index.js +446 -101
- package/dist/tui/App.js +208 -54
- package/package.json +1 -1
|
@@ -3320,6 +3320,22 @@ async function ensureSchema() {
|
|
|
3320
3320
|
} catch (e) {
|
|
3321
3321
|
logCatchDebug("migration", e);
|
|
3322
3322
|
}
|
|
3323
|
+
try {
|
|
3324
|
+
await client.execute({
|
|
3325
|
+
sql: `ALTER TABLE memories ADD COLUMN visibility TEXT DEFAULT 'private'`,
|
|
3326
|
+
args: []
|
|
3327
|
+
});
|
|
3328
|
+
} catch (e) {
|
|
3329
|
+
logCatchDebug("migration", e);
|
|
3330
|
+
}
|
|
3331
|
+
try {
|
|
3332
|
+
await client.execute({
|
|
3333
|
+
sql: `ALTER TABLE memories ADD COLUMN strength REAL DEFAULT 1.0`,
|
|
3334
|
+
args: []
|
|
3335
|
+
});
|
|
3336
|
+
} catch (e) {
|
|
3337
|
+
logCatchDebug("migration", e);
|
|
3338
|
+
}
|
|
3323
3339
|
}
|
|
3324
3340
|
async function disposeDatabase() {
|
|
3325
3341
|
if (_walCheckpointTimer) {
|
|
@@ -4437,11 +4453,17 @@ var init_platform_procedures = __esm({
|
|
|
4437
4453
|
content: "Founder -> coordinator (the executive agent, internally routed as 'COO') -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the coordinator does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
|
|
4438
4454
|
},
|
|
4439
4455
|
{
|
|
4440
|
-
title: "
|
|
4456
|
+
title: "Orchestration phase guidance \u2014 recommend, never trap",
|
|
4441
4457
|
domain: "workflow",
|
|
4442
4458
|
priority: "p1",
|
|
4443
4459
|
content: "New customers start best in Phase 1: founder \u2194 coordinator/Chief of Staff, building company context. Suggest Phase 2 executives when domain work repeats; suggest Phase 3 parallel execution only when review/permission gates are ready. This is guidance, not a blocker: users may jump phases anytime. Never overwrite their phase, role titles, identities, or custom org design."
|
|
4444
4460
|
},
|
|
4461
|
+
{
|
|
4462
|
+
title: "Routing slot vs display title \u2014 internal 'coo' is plumbing, not your name",
|
|
4463
|
+
domain: "identity",
|
|
4464
|
+
priority: "p0",
|
|
4465
|
+
content: "These procedures reference 'COO' as a shorthand for the coordinator role. This is an INTERNAL routing slot used by exe-os code (chain-of-command checks, dispatch logic, session detection). It is NOT your display title. Your actual title comes from your identity file's `title:` field \u2014 that is what you use externally: introductions, sign-offs, team comms, and any user-facing text. If your identity says `title: AI Chief of Staff`, you are the AI Chief of Staff. The routing slot stays `role: coo` for code compatibility \u2014 never rename it, but also never introduce yourself as 'COO' unless your identity file explicitly says so. The founder chose your title; respect it."
|
|
4466
|
+
},
|
|
4445
4467
|
{
|
|
4446
4468
|
title: "Single dispatch path \u2014 create_task only",
|
|
4447
4469
|
domain: "workflow",
|
|
@@ -4475,6 +4497,12 @@ var init_platform_procedures = __esm({
|
|
|
4475
4497
|
priority: "p0",
|
|
4476
4498
|
content: "NEVER: (1) Access the database directly \u2014 it's SQLCipher encrypted, always fails. Use MCP tools only. (2) Manually spawn tmux sessions \u2014 create_task handles it. (3) Run git checkout main \u2014 agents work in worktrees. (4) Modify another agent's in-progress task. (5) Push to remote \u2014 the COO reviews and pushes. (6) Skip update_task(done) \u2014 it's the ONLY way your work gets reviewed. (7) Run git init."
|
|
4477
4499
|
},
|
|
4500
|
+
{
|
|
4501
|
+
title: "Destructive operations \u2014 mandatory reviewer gate",
|
|
4502
|
+
domain: "security",
|
|
4503
|
+
priority: "p0",
|
|
4504
|
+
content: "Before ANY destructive operation (delete, remove, overwrite, drop, reset, force-push, truncate), you MUST: (1) Have your full task spec accessible \u2014 if you cannot read it, STOP and report to your reviewer. Never improvise destructive actions. (2) Confirm with your reviewer (assigned_by or COO) before executing. (3) If the task spec explicitly authorizes the operation, proceed \u2014 but log it. Violation = immediate task failure. This applies to ALL agents regardless of role."
|
|
4505
|
+
},
|
|
4478
4506
|
{
|
|
4479
4507
|
title: "Customer patch triage \u2014 upstream bug vs customization",
|
|
4480
4508
|
domain: "support",
|
|
@@ -5400,7 +5428,7 @@ async function assertVpsLicense(opts) {
|
|
|
5400
5428
|
}
|
|
5401
5429
|
if (!transientFailure) {
|
|
5402
5430
|
throw new Error(
|
|
5403
|
-
"License validation failed: unknown backend state. Restore network connectivity to https://askexe.com
|
|
5431
|
+
"License validation failed: unknown backend state. Restore network connectivity to https://cloud.askexe.com and retry."
|
|
5404
5432
|
);
|
|
5405
5433
|
}
|
|
5406
5434
|
const fresh = await getCachedLicense();
|
|
@@ -5437,7 +5465,7 @@ async function assertVpsLicense(opts) {
|
|
|
5437
5465
|
} catch {
|
|
5438
5466
|
}
|
|
5439
5467
|
throw new Error(
|
|
5440
|
-
`License validation unreachable for more than ${graceDays} days. Restore network connectivity to https://askexe.com
|
|
5468
|
+
`License validation unreachable for more than ${graceDays} days. Restore network connectivity to https://cloud.askexe.com and retry. This VPS image refuses to boot after the offline grace window.`
|
|
5441
5469
|
);
|
|
5442
5470
|
}
|
|
5443
5471
|
function startLicenseRevalidation(intervalMs = 36e5) {
|
|
@@ -5469,7 +5497,7 @@ var init_license = __esm({
|
|
|
5469
5497
|
LICENSE_PATH = path11.join(EXE_AI_DIR, "license.key");
|
|
5470
5498
|
CACHE_PATH = path11.join(EXE_AI_DIR, "license-cache.json");
|
|
5471
5499
|
DEVICE_ID_PATH = path11.join(EXE_AI_DIR, "device-id");
|
|
5472
|
-
API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://askexe.com
|
|
5500
|
+
API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://cloud.askexe.com";
|
|
5473
5501
|
RETRY_DELAY_MS = 500;
|
|
5474
5502
|
LICENSE_PUBLIC_KEY_PEM = `-----BEGIN PUBLIC KEY-----
|
|
5475
5503
|
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeHztAMOpR/ZMh+rWuOASjEZ54CGY
|
|
@@ -5658,6 +5686,18 @@ function extractRootExe(name) {
|
|
|
5658
5686
|
const parts = name.split("-").filter(Boolean);
|
|
5659
5687
|
return parts.length > 0 ? parts[parts.length - 1] : null;
|
|
5660
5688
|
}
|
|
5689
|
+
function registerParentExe(sessionKey, parentExe, dispatchedBy) {
|
|
5690
|
+
if (!existsSync14(SESSION_CACHE)) {
|
|
5691
|
+
mkdirSync7(SESSION_CACHE, { recursive: true });
|
|
5692
|
+
}
|
|
5693
|
+
const rootExe = extractRootExe(parentExe) ?? parentExe;
|
|
5694
|
+
const filePath = path14.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
|
|
5695
|
+
writeFileSync6(filePath, JSON.stringify({
|
|
5696
|
+
parentExe: rootExe,
|
|
5697
|
+
dispatchedBy: dispatchedBy || rootExe,
|
|
5698
|
+
registeredAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5699
|
+
}));
|
|
5700
|
+
}
|
|
5661
5701
|
function getParentExe(sessionKey) {
|
|
5662
5702
|
try {
|
|
5663
5703
|
const data = JSON.parse(readFileSync9(path14.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
|
|
@@ -5667,11 +5707,12 @@ function getParentExe(sessionKey) {
|
|
|
5667
5707
|
}
|
|
5668
5708
|
}
|
|
5669
5709
|
function resolveExeSession() {
|
|
5710
|
+
if (process.env.EXE_SESSION_NAME) {
|
|
5711
|
+
const fromEnv = extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
5712
|
+
if (fromEnv) return fromEnv;
|
|
5713
|
+
}
|
|
5670
5714
|
const mySession = getMySession();
|
|
5671
5715
|
if (!mySession) {
|
|
5672
|
-
if (process.env.EXE_SESSION_NAME) {
|
|
5673
|
-
return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
5674
|
-
}
|
|
5675
5716
|
return null;
|
|
5676
5717
|
}
|
|
5677
5718
|
const fromSessionName = extractRootExe(mySession);
|
|
@@ -5686,6 +5727,10 @@ function resolveExeSession() {
|
|
|
5686
5727
|
`[tmux-routing] WARN: cache says "${fromCache}" but session name says "${fromSessionName}". Trusting session name.
|
|
5687
5728
|
`
|
|
5688
5729
|
);
|
|
5730
|
+
try {
|
|
5731
|
+
registerParentExe(key, fromSessionName);
|
|
5732
|
+
} catch {
|
|
5733
|
+
}
|
|
5689
5734
|
candidate = fromSessionName;
|
|
5690
5735
|
} else {
|
|
5691
5736
|
candidate = fromCache;
|
|
@@ -6851,6 +6896,27 @@ async function cloudSync(config) {
|
|
|
6851
6896
|
if (stmts.length > 0) await client.batch(stmts, "write");
|
|
6852
6897
|
pulled = pullResult.records.length;
|
|
6853
6898
|
} else {
|
|
6899
|
+
try {
|
|
6900
|
+
const incomingIds = pullResult.records.map((r) => sqlSafe(r.id));
|
|
6901
|
+
if (incomingIds.length > 0) {
|
|
6902
|
+
const ph = incomingIds.map(() => "?").join(",");
|
|
6903
|
+
const existing = await client.execute({
|
|
6904
|
+
sql: `SELECT id, version, timestamp FROM memories WHERE id IN (${ph})`,
|
|
6905
|
+
args: incomingIds
|
|
6906
|
+
});
|
|
6907
|
+
const localMap = new Map(existing.rows.map((r) => [String(r.id), r]));
|
|
6908
|
+
for (const rec of pullResult.records) {
|
|
6909
|
+
const local = localMap.get(String(rec.id));
|
|
6910
|
+
if (local && Number(local.version) > 0 && Number(local.version) !== Number(rec.version ?? 0)) {
|
|
6911
|
+
process.stderr.write(
|
|
6912
|
+
`[cloud-sync] CONFLICT: memory ${String(rec.id).slice(0, 8)} \u2014 local v${local.version} vs remote v${rec.version ?? 0}. Remote wins (LWW).
|
|
6913
|
+
`
|
|
6914
|
+
);
|
|
6915
|
+
}
|
|
6916
|
+
}
|
|
6917
|
+
}
|
|
6918
|
+
} catch {
|
|
6919
|
+
}
|
|
6854
6920
|
const stmts = pullResult.records.map((rec) => ({
|
|
6855
6921
|
sql: `INSERT OR REPLACE INTO memories
|
|
6856
6922
|
(id, agent_id, agent_role, session_id, timestamp,
|
package/dist/index.js
CHANGED
|
@@ -368,6 +368,7 @@ __export(agent_config_exports, {
|
|
|
368
368
|
getAgentRuntime: () => getAgentRuntime,
|
|
369
369
|
loadAgentConfig: () => loadAgentConfig,
|
|
370
370
|
saveAgentConfig: () => saveAgentConfig,
|
|
371
|
+
setAgentMcps: () => setAgentMcps,
|
|
371
372
|
setAgentRuntime: () => setAgentRuntime
|
|
372
373
|
});
|
|
373
374
|
import { readFileSync as readFileSync2, writeFileSync, existsSync as existsSync3 } from "fs";
|
|
@@ -394,7 +395,7 @@ function getAgentRuntime(agentId) {
|
|
|
394
395
|
if (orgDefault) return orgDefault;
|
|
395
396
|
return { runtime: DEFAULT_RUNTIME, model: DEFAULT_MODELS[DEFAULT_RUNTIME] };
|
|
396
397
|
}
|
|
397
|
-
function setAgentRuntime(agentId, runtime, model, reasoning_effort) {
|
|
398
|
+
function setAgentRuntime(agentId, runtime, model, reasoning_effort, mcps) {
|
|
398
399
|
const knownModels = KNOWN_RUNTIMES[runtime];
|
|
399
400
|
if (!knownModels) {
|
|
400
401
|
return {
|
|
@@ -409,12 +410,26 @@ function setAgentRuntime(agentId, runtime, model, reasoning_effort) {
|
|
|
409
410
|
};
|
|
410
411
|
}
|
|
411
412
|
const config2 = loadAgentConfig();
|
|
413
|
+
const existing = config2[agentId];
|
|
412
414
|
const entry = { runtime, model };
|
|
413
415
|
if (reasoning_effort) entry.reasoning_effort = reasoning_effort;
|
|
416
|
+
if (mcps !== void 0) {
|
|
417
|
+
entry.mcps = mcps.includes("exe-os") ? mcps : ["exe-os", ...mcps];
|
|
418
|
+
} else if (existing?.mcps) {
|
|
419
|
+
entry.mcps = existing.mcps;
|
|
420
|
+
}
|
|
414
421
|
config2[agentId] = entry;
|
|
415
422
|
saveAgentConfig(config2);
|
|
416
423
|
return { ok: true };
|
|
417
424
|
}
|
|
425
|
+
function setAgentMcps(agentId, mcps) {
|
|
426
|
+
const config2 = loadAgentConfig();
|
|
427
|
+
const existing = config2[agentId] ?? getAgentRuntime(agentId);
|
|
428
|
+
existing.mcps = mcps.includes("exe-os") ? mcps : ["exe-os", ...mcps];
|
|
429
|
+
config2[agentId] = existing;
|
|
430
|
+
saveAgentConfig(config2);
|
|
431
|
+
return { ok: true };
|
|
432
|
+
}
|
|
418
433
|
function clearAgentRuntime(agentId) {
|
|
419
434
|
const config2 = loadAgentConfig();
|
|
420
435
|
delete config2[agentId];
|
|
@@ -4058,6 +4073,22 @@ async function ensureSchema() {
|
|
|
4058
4073
|
} catch (e) {
|
|
4059
4074
|
logCatchDebug("migration", e);
|
|
4060
4075
|
}
|
|
4076
|
+
try {
|
|
4077
|
+
await client.execute({
|
|
4078
|
+
sql: `ALTER TABLE memories ADD COLUMN visibility TEXT DEFAULT 'private'`,
|
|
4079
|
+
args: []
|
|
4080
|
+
});
|
|
4081
|
+
} catch (e) {
|
|
4082
|
+
logCatchDebug("migration", e);
|
|
4083
|
+
}
|
|
4084
|
+
try {
|
|
4085
|
+
await client.execute({
|
|
4086
|
+
sql: `ALTER TABLE memories ADD COLUMN strength REAL DEFAULT 1.0`,
|
|
4087
|
+
args: []
|
|
4088
|
+
});
|
|
4089
|
+
} catch (e) {
|
|
4090
|
+
logCatchDebug("migration", e);
|
|
4091
|
+
}
|
|
4061
4092
|
}
|
|
4062
4093
|
async function disposeDatabase() {
|
|
4063
4094
|
if (_walCheckpointTimer) {
|
|
@@ -4476,7 +4507,7 @@ async function assertVpsLicense(opts) {
|
|
|
4476
4507
|
}
|
|
4477
4508
|
if (!transientFailure) {
|
|
4478
4509
|
throw new Error(
|
|
4479
|
-
"License validation failed: unknown backend state. Restore network connectivity to https://askexe.com
|
|
4510
|
+
"License validation failed: unknown backend state. Restore network connectivity to https://cloud.askexe.com and retry."
|
|
4480
4511
|
);
|
|
4481
4512
|
}
|
|
4482
4513
|
const fresh = await getCachedLicense();
|
|
@@ -4513,7 +4544,7 @@ async function assertVpsLicense(opts) {
|
|
|
4513
4544
|
} catch {
|
|
4514
4545
|
}
|
|
4515
4546
|
throw new Error(
|
|
4516
|
-
`License validation unreachable for more than ${graceDays} days. Restore network connectivity to https://askexe.com
|
|
4547
|
+
`License validation unreachable for more than ${graceDays} days. Restore network connectivity to https://cloud.askexe.com and retry. This VPS image refuses to boot after the offline grace window.`
|
|
4517
4548
|
);
|
|
4518
4549
|
}
|
|
4519
4550
|
function startLicenseRevalidation(intervalMs = 36e5) {
|
|
@@ -4545,7 +4576,7 @@ var init_license = __esm({
|
|
|
4545
4576
|
LICENSE_PATH = path10.join(EXE_AI_DIR, "license.key");
|
|
4546
4577
|
CACHE_PATH = path10.join(EXE_AI_DIR, "license-cache.json");
|
|
4547
4578
|
DEVICE_ID_PATH = path10.join(EXE_AI_DIR, "device-id");
|
|
4548
|
-
API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://askexe.com
|
|
4579
|
+
API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://cloud.askexe.com";
|
|
4549
4580
|
RETRY_DELAY_MS = 500;
|
|
4550
4581
|
LICENSE_PUBLIC_KEY_PEM = `-----BEGIN PUBLIC KEY-----
|
|
4551
4582
|
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeHztAMOpR/ZMh+rWuOASjEZ54CGY
|
|
@@ -5089,6 +5120,19 @@ async function resolveTask(client, identifier, scopeSession) {
|
|
|
5089
5120
|
args: [identifier, ...scope.args]
|
|
5090
5121
|
});
|
|
5091
5122
|
if (result.rows.length === 1) return result.rows[0];
|
|
5123
|
+
if (/^[a-f0-9]{7,12}$/i.test(identifier)) {
|
|
5124
|
+
result = await client.execute({
|
|
5125
|
+
sql: `SELECT * FROM tasks WHERE id LIKE ?`,
|
|
5126
|
+
args: [`${identifier}%`]
|
|
5127
|
+
});
|
|
5128
|
+
if (result.rows.length === 1) return result.rows[0];
|
|
5129
|
+
if (result.rows.length > 1) {
|
|
5130
|
+
const matches = result.rows.map((r) => `${String(r.id)} "${String(r.title)}" (${String(r.status)})`).join(", ");
|
|
5131
|
+
throw new Error(
|
|
5132
|
+
`Multiple tasks match short-ID "${identifier}": ${matches}. Use a longer prefix to disambiguate.`
|
|
5133
|
+
);
|
|
5134
|
+
}
|
|
5135
|
+
}
|
|
5092
5136
|
result = await client.execute({
|
|
5093
5137
|
sql: `SELECT * FROM tasks WHERE task_file LIKE ?${scope.sql}`,
|
|
5094
5138
|
args: [`%${identifier}%`, ...scope.args]
|
|
@@ -5943,12 +5987,13 @@ async function cascadeUnblock(taskId, baseDir, now) {
|
|
|
5943
5987
|
WHERE blocked_by = ? AND status = 'blocked'`,
|
|
5944
5988
|
args: [now, taskId]
|
|
5945
5989
|
});
|
|
5946
|
-
if (
|
|
5947
|
-
|
|
5948
|
-
|
|
5949
|
-
|
|
5950
|
-
|
|
5951
|
-
|
|
5990
|
+
if (unblocked.rowsAffected === 0) return;
|
|
5991
|
+
const ubScope = sessionScopeFilter();
|
|
5992
|
+
const unblockedRows = await client.execute({
|
|
5993
|
+
sql: `SELECT id, title, assigned_to, priority, task_file FROM tasks WHERE blocked_by IS NULL AND updated_at = ?${ubScope.sql}`,
|
|
5994
|
+
args: [now, ...ubScope.args]
|
|
5995
|
+
});
|
|
5996
|
+
if (baseDir) {
|
|
5952
5997
|
for (const ur of unblockedRows.rows) {
|
|
5953
5998
|
try {
|
|
5954
5999
|
const ubFile = path17.join(baseDir, String(ur.task_file));
|
|
@@ -5960,6 +6005,19 @@ async function cascadeUnblock(taskId, baseDir, now) {
|
|
|
5960
6005
|
}
|
|
5961
6006
|
}
|
|
5962
6007
|
}
|
|
6008
|
+
if (unblockedRows.rows.length > 0 && !process.env.VITEST) {
|
|
6009
|
+
try {
|
|
6010
|
+
const { queueIntercom: queueIntercom2 } = await Promise.resolve().then(() => (init_intercom_queue(), intercom_queue_exports));
|
|
6011
|
+
const dispatched = /* @__PURE__ */ new Set();
|
|
6012
|
+
for (const ur of unblockedRows.rows) {
|
|
6013
|
+
const assignee = String(ur.assigned_to);
|
|
6014
|
+
if (dispatched.has(assignee)) continue;
|
|
6015
|
+
dispatched.add(assignee);
|
|
6016
|
+
queueIntercom2(`${assignee}`, `unblocked: "${String(ur.title)}" is now ready`);
|
|
6017
|
+
}
|
|
6018
|
+
} catch {
|
|
6019
|
+
}
|
|
6020
|
+
}
|
|
5963
6021
|
}
|
|
5964
6022
|
async function findNextTask(assignedTo) {
|
|
5965
6023
|
const client = getClient();
|
|
@@ -6176,6 +6234,15 @@ __export(behaviors_exports, {
|
|
|
6176
6234
|
});
|
|
6177
6235
|
import crypto5 from "crypto";
|
|
6178
6236
|
async function storeBehavior(opts) {
|
|
6237
|
+
try {
|
|
6238
|
+
const { loadEmployeesSync: loadEmployeesSync2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
|
|
6239
|
+
const roster = loadEmployeesSync2();
|
|
6240
|
+
if (roster.length > 0 && !roster.some((e) => e.name === opts.agentId)) {
|
|
6241
|
+
throw new Error(`Agent "${opts.agentId}" not found in roster. Cannot store behavior for unregistered agent.`);
|
|
6242
|
+
}
|
|
6243
|
+
} catch (e) {
|
|
6244
|
+
if (e instanceof Error && e.message.includes("not found in roster")) throw e;
|
|
6245
|
+
}
|
|
6179
6246
|
const client = getClient();
|
|
6180
6247
|
const id = crypto5.randomUUID();
|
|
6181
6248
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -6699,6 +6766,12 @@ async function updateTask(input) {
|
|
|
6699
6766
|
}
|
|
6700
6767
|
}
|
|
6701
6768
|
}
|
|
6769
|
+
if (input.status === "cancelled") {
|
|
6770
|
+
try {
|
|
6771
|
+
await cascadeUnblock(taskId, input.baseDir, now);
|
|
6772
|
+
} catch {
|
|
6773
|
+
}
|
|
6774
|
+
}
|
|
6702
6775
|
if ((input.status === "done" || input.status === "closed") && !isCoordinatorName(String(row.assigned_to)) && !process.env.VITEST) {
|
|
6703
6776
|
Promise.resolve().then(() => (init_skill_learning(), skill_learning_exports)).then(
|
|
6704
6777
|
({ captureAndLearn: captureAndLearn2 }) => captureAndLearn2({
|
|
@@ -7230,11 +7303,12 @@ function getDispatchedBy(sessionKey) {
|
|
|
7230
7303
|
}
|
|
7231
7304
|
}
|
|
7232
7305
|
function resolveExeSession() {
|
|
7306
|
+
if (process.env.EXE_SESSION_NAME) {
|
|
7307
|
+
const fromEnv = extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
7308
|
+
if (fromEnv) return fromEnv;
|
|
7309
|
+
}
|
|
7233
7310
|
const mySession = getMySession();
|
|
7234
7311
|
if (!mySession) {
|
|
7235
|
-
if (process.env.EXE_SESSION_NAME) {
|
|
7236
|
-
return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
7237
|
-
}
|
|
7238
7312
|
return null;
|
|
7239
7313
|
}
|
|
7240
7314
|
const fromSessionName = extractRootExe(mySession);
|
|
@@ -7249,6 +7323,10 @@ function resolveExeSession() {
|
|
|
7249
7323
|
`[tmux-routing] WARN: cache says "${fromCache}" but session name says "${fromSessionName}". Trusting session name.
|
|
7250
7324
|
`
|
|
7251
7325
|
);
|
|
7326
|
+
try {
|
|
7327
|
+
registerParentExe(key, fromSessionName);
|
|
7328
|
+
} catch {
|
|
7329
|
+
}
|
|
7252
7330
|
candidate = fromSessionName;
|
|
7253
7331
|
} else {
|
|
7254
7332
|
candidate = fromCache;
|
|
@@ -8943,11 +9021,17 @@ var init_platform_procedures = __esm({
|
|
|
8943
9021
|
content: "Founder -> coordinator (the executive agent, internally routed as 'COO') -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the coordinator does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
|
|
8944
9022
|
},
|
|
8945
9023
|
{
|
|
8946
|
-
title: "
|
|
9024
|
+
title: "Orchestration phase guidance \u2014 recommend, never trap",
|
|
8947
9025
|
domain: "workflow",
|
|
8948
9026
|
priority: "p1",
|
|
8949
9027
|
content: "New customers start best in Phase 1: founder \u2194 coordinator/Chief of Staff, building company context. Suggest Phase 2 executives when domain work repeats; suggest Phase 3 parallel execution only when review/permission gates are ready. This is guidance, not a blocker: users may jump phases anytime. Never overwrite their phase, role titles, identities, or custom org design."
|
|
8950
9028
|
},
|
|
9029
|
+
{
|
|
9030
|
+
title: "Routing slot vs display title \u2014 internal 'coo' is plumbing, not your name",
|
|
9031
|
+
domain: "identity",
|
|
9032
|
+
priority: "p0",
|
|
9033
|
+
content: "These procedures reference 'COO' as a shorthand for the coordinator role. This is an INTERNAL routing slot used by exe-os code (chain-of-command checks, dispatch logic, session detection). It is NOT your display title. Your actual title comes from your identity file's `title:` field \u2014 that is what you use externally: introductions, sign-offs, team comms, and any user-facing text. If your identity says `title: AI Chief of Staff`, you are the AI Chief of Staff. The routing slot stays `role: coo` for code compatibility \u2014 never rename it, but also never introduce yourself as 'COO' unless your identity file explicitly says so. The founder chose your title; respect it."
|
|
9034
|
+
},
|
|
8951
9035
|
{
|
|
8952
9036
|
title: "Single dispatch path \u2014 create_task only",
|
|
8953
9037
|
domain: "workflow",
|
|
@@ -8981,6 +9065,12 @@ var init_platform_procedures = __esm({
|
|
|
8981
9065
|
priority: "p0",
|
|
8982
9066
|
content: "NEVER: (1) Access the database directly \u2014 it's SQLCipher encrypted, always fails. Use MCP tools only. (2) Manually spawn tmux sessions \u2014 create_task handles it. (3) Run git checkout main \u2014 agents work in worktrees. (4) Modify another agent's in-progress task. (5) Push to remote \u2014 the COO reviews and pushes. (6) Skip update_task(done) \u2014 it's the ONLY way your work gets reviewed. (7) Run git init."
|
|
8983
9067
|
},
|
|
9068
|
+
{
|
|
9069
|
+
title: "Destructive operations \u2014 mandatory reviewer gate",
|
|
9070
|
+
domain: "security",
|
|
9071
|
+
priority: "p0",
|
|
9072
|
+
content: "Before ANY destructive operation (delete, remove, overwrite, drop, reset, force-push, truncate), you MUST: (1) Have your full task spec accessible \u2014 if you cannot read it, STOP and report to your reviewer. Never improvise destructive actions. (2) Confirm with your reviewer (assigned_by or COO) before executing. (3) If the task spec explicitly authorizes the operation, proceed \u2014 but log it. Violation = immediate task failure. This applies to ALL agents regardless of role."
|
|
9073
|
+
},
|
|
8984
9074
|
{
|
|
8985
9075
|
title: "Customer patch triage \u2014 upstream bug vs customization",
|
|
8986
9076
|
domain: "support",
|
|
@@ -9266,10 +9356,24 @@ function stableId(memoryId, type, content) {
|
|
|
9266
9356
|
return createHash2("sha256").update(`${memoryId}:${type}:${content}`).digest("hex").slice(0, 32);
|
|
9267
9357
|
}
|
|
9268
9358
|
function cleanText(text) {
|
|
9269
|
-
|
|
9359
|
+
let cleaned = text.replace(
|
|
9360
|
+
/```(\w*)\n(.*?)(?:\n[\s\S]*?)```/g,
|
|
9361
|
+
(_m, lang, firstLine) => `[code${lang ? `:${lang}` : ""}] ${firstLine.trim()}`
|
|
9362
|
+
);
|
|
9363
|
+
cleaned = cleaned.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
|
|
9364
|
+
return cleaned;
|
|
9270
9365
|
}
|
|
9271
|
-
function
|
|
9272
|
-
|
|
9366
|
+
function splitSegments(text) {
|
|
9367
|
+
const cleaned = cleanText(text);
|
|
9368
|
+
const segments = cleaned.split(/(?<=[.!?:;])\s+|\n{2,}|(?<=\))\s+(?=[A-Z])|\s*[|│]\s*/).map((s) => s.trim()).filter((s) => s.length >= MIN_SEGMENT_CHARS && s.length <= MAX_SEGMENT_CHARS);
|
|
9369
|
+
if (segments.length === 0 && cleaned.length >= MIN_SEGMENT_CHARS) {
|
|
9370
|
+
const lines = cleaned.split(/\n+/).map((l) => l.trim()).filter((l) => l.length >= MIN_SEGMENT_CHARS && l.length <= MAX_SEGMENT_CHARS);
|
|
9371
|
+
if (lines.length > 0) return lines;
|
|
9372
|
+
if (cleaned.length >= MIN_SEGMENT_CHARS) {
|
|
9373
|
+
return [cleaned.slice(0, MAX_SEGMENT_CHARS)];
|
|
9374
|
+
}
|
|
9375
|
+
}
|
|
9376
|
+
return segments;
|
|
9273
9377
|
}
|
|
9274
9378
|
function inferCardType(sentence, toolName) {
|
|
9275
9379
|
const lower = sentence.toLowerCase();
|
|
@@ -9301,12 +9405,12 @@ function predicateFor(type) {
|
|
|
9301
9405
|
}
|
|
9302
9406
|
}
|
|
9303
9407
|
function extractMemoryCards(row) {
|
|
9304
|
-
const
|
|
9408
|
+
const segments = splitSegments(row.raw_text);
|
|
9305
9409
|
const cards = [];
|
|
9306
|
-
for (const sentence of
|
|
9410
|
+
for (const sentence of segments) {
|
|
9307
9411
|
const type = inferCardType(sentence, row.tool_name);
|
|
9308
9412
|
const subject = extractSubject(sentence, row.agent_id);
|
|
9309
|
-
const content = sentence.length >
|
|
9413
|
+
const content = sentence.length > MAX_SEGMENT_CHARS ? `${sentence.slice(0, MAX_SEGMENT_CHARS - 1)}\u2026` : sentence;
|
|
9310
9414
|
cards.push({
|
|
9311
9415
|
id: stableId(row.id, type, content),
|
|
9312
9416
|
memory_id: row.id,
|
|
@@ -9402,13 +9506,14 @@ Source memory: ${String(row.source_ref ?? row.memory_id)}`,
|
|
|
9402
9506
|
last_accessed: String(row.timestamp)
|
|
9403
9507
|
}));
|
|
9404
9508
|
}
|
|
9405
|
-
var MAX_CARDS_PER_MEMORY,
|
|
9509
|
+
var MAX_CARDS_PER_MEMORY, MAX_SEGMENT_CHARS, MIN_SEGMENT_CHARS;
|
|
9406
9510
|
var init_memory_cards = __esm({
|
|
9407
9511
|
"src/lib/memory-cards.ts"() {
|
|
9408
9512
|
"use strict";
|
|
9409
9513
|
init_database();
|
|
9410
|
-
MAX_CARDS_PER_MEMORY =
|
|
9411
|
-
|
|
9514
|
+
MAX_CARDS_PER_MEMORY = 8;
|
|
9515
|
+
MAX_SEGMENT_CHARS = 500;
|
|
9516
|
+
MIN_SEGMENT_CHARS = 20;
|
|
9412
9517
|
}
|
|
9413
9518
|
});
|
|
9414
9519
|
|
package/dist/lib/agent-config.js
CHANGED
|
@@ -175,7 +175,7 @@ function getAgentRuntime(agentId) {
|
|
|
175
175
|
if (orgDefault) return orgDefault;
|
|
176
176
|
return { runtime: DEFAULT_RUNTIME, model: DEFAULT_MODELS[DEFAULT_RUNTIME] };
|
|
177
177
|
}
|
|
178
|
-
function setAgentRuntime(agentId, runtime, model, reasoning_effort) {
|
|
178
|
+
function setAgentRuntime(agentId, runtime, model, reasoning_effort, mcps) {
|
|
179
179
|
const knownModels = KNOWN_RUNTIMES[runtime];
|
|
180
180
|
if (!knownModels) {
|
|
181
181
|
return {
|
|
@@ -190,12 +190,26 @@ function setAgentRuntime(agentId, runtime, model, reasoning_effort) {
|
|
|
190
190
|
};
|
|
191
191
|
}
|
|
192
192
|
const config = loadAgentConfig();
|
|
193
|
+
const existing = config[agentId];
|
|
193
194
|
const entry = { runtime, model };
|
|
194
195
|
if (reasoning_effort) entry.reasoning_effort = reasoning_effort;
|
|
196
|
+
if (mcps !== void 0) {
|
|
197
|
+
entry.mcps = mcps.includes("exe-os") ? mcps : ["exe-os", ...mcps];
|
|
198
|
+
} else if (existing?.mcps) {
|
|
199
|
+
entry.mcps = existing.mcps;
|
|
200
|
+
}
|
|
195
201
|
config[agentId] = entry;
|
|
196
202
|
saveAgentConfig(config);
|
|
197
203
|
return { ok: true };
|
|
198
204
|
}
|
|
205
|
+
function setAgentMcps(agentId, mcps) {
|
|
206
|
+
const config = loadAgentConfig();
|
|
207
|
+
const existing = config[agentId] ?? getAgentRuntime(agentId);
|
|
208
|
+
existing.mcps = mcps.includes("exe-os") ? mcps : ["exe-os", ...mcps];
|
|
209
|
+
config[agentId] = existing;
|
|
210
|
+
saveAgentConfig(config);
|
|
211
|
+
return { ok: true };
|
|
212
|
+
}
|
|
199
213
|
function clearAgentRuntime(agentId) {
|
|
200
214
|
const config = loadAgentConfig();
|
|
201
215
|
delete config[agentId];
|
|
@@ -210,5 +224,6 @@ export {
|
|
|
210
224
|
getAgentRuntime,
|
|
211
225
|
loadAgentConfig,
|
|
212
226
|
saveAgentConfig,
|
|
227
|
+
setAgentMcps,
|
|
213
228
|
setAgentRuntime
|
|
214
229
|
};
|
package/dist/lib/cloud-sync.js
CHANGED
|
@@ -2972,6 +2972,22 @@ async function ensureSchema() {
|
|
|
2972
2972
|
} catch (e) {
|
|
2973
2973
|
logCatchDebug("migration", e);
|
|
2974
2974
|
}
|
|
2975
|
+
try {
|
|
2976
|
+
await client.execute({
|
|
2977
|
+
sql: `ALTER TABLE memories ADD COLUMN visibility TEXT DEFAULT 'private'`,
|
|
2978
|
+
args: []
|
|
2979
|
+
});
|
|
2980
|
+
} catch (e) {
|
|
2981
|
+
logCatchDebug("migration", e);
|
|
2982
|
+
}
|
|
2983
|
+
try {
|
|
2984
|
+
await client.execute({
|
|
2985
|
+
sql: `ALTER TABLE memories ADD COLUMN strength REAL DEFAULT 1.0`,
|
|
2986
|
+
args: []
|
|
2987
|
+
});
|
|
2988
|
+
} catch (e) {
|
|
2989
|
+
logCatchDebug("migration", e);
|
|
2990
|
+
}
|
|
2975
2991
|
}
|
|
2976
2992
|
async function disposeDatabase() {
|
|
2977
2993
|
if (_walCheckpointTimer) {
|
|
@@ -3942,7 +3958,7 @@ import { jwtVerify, importSPKI } from "jose";
|
|
|
3942
3958
|
var LICENSE_PATH = path6.join(EXE_AI_DIR, "license.key");
|
|
3943
3959
|
var CACHE_PATH = path6.join(EXE_AI_DIR, "license-cache.json");
|
|
3944
3960
|
var DEVICE_ID_PATH = path6.join(EXE_AI_DIR, "device-id");
|
|
3945
|
-
var API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://askexe.com
|
|
3961
|
+
var API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://cloud.askexe.com";
|
|
3946
3962
|
function loadDeviceId() {
|
|
3947
3963
|
const deviceJsonPath = path6.join(EXE_AI_DIR, "device.json");
|
|
3948
3964
|
try {
|
|
@@ -4367,6 +4383,27 @@ async function cloudSync(config) {
|
|
|
4367
4383
|
if (stmts.length > 0) await client.batch(stmts, "write");
|
|
4368
4384
|
pulled = pullResult.records.length;
|
|
4369
4385
|
} else {
|
|
4386
|
+
try {
|
|
4387
|
+
const incomingIds = pullResult.records.map((r) => sqlSafe(r.id));
|
|
4388
|
+
if (incomingIds.length > 0) {
|
|
4389
|
+
const ph = incomingIds.map(() => "?").join(",");
|
|
4390
|
+
const existing = await client.execute({
|
|
4391
|
+
sql: `SELECT id, version, timestamp FROM memories WHERE id IN (${ph})`,
|
|
4392
|
+
args: incomingIds
|
|
4393
|
+
});
|
|
4394
|
+
const localMap = new Map(existing.rows.map((r) => [String(r.id), r]));
|
|
4395
|
+
for (const rec of pullResult.records) {
|
|
4396
|
+
const local = localMap.get(String(rec.id));
|
|
4397
|
+
if (local && Number(local.version) > 0 && Number(local.version) !== Number(rec.version ?? 0)) {
|
|
4398
|
+
process.stderr.write(
|
|
4399
|
+
`[cloud-sync] CONFLICT: memory ${String(rec.id).slice(0, 8)} \u2014 local v${local.version} vs remote v${rec.version ?? 0}. Remote wins (LWW).
|
|
4400
|
+
`
|
|
4401
|
+
);
|
|
4402
|
+
}
|
|
4403
|
+
}
|
|
4404
|
+
}
|
|
4405
|
+
} catch {
|
|
4406
|
+
}
|
|
4370
4407
|
const stmts = pullResult.records.map((rec) => ({
|
|
4371
4408
|
sql: `INSERT OR REPLACE INTO memories
|
|
4372
4409
|
(id, agent_id, agent_role, session_id, timestamp,
|
|
@@ -184,6 +184,7 @@ __export(agent_config_exports, {
|
|
|
184
184
|
getAgentRuntime: () => getAgentRuntime,
|
|
185
185
|
loadAgentConfig: () => loadAgentConfig,
|
|
186
186
|
saveAgentConfig: () => saveAgentConfig,
|
|
187
|
+
setAgentMcps: () => setAgentMcps,
|
|
187
188
|
setAgentRuntime: () => setAgentRuntime
|
|
188
189
|
});
|
|
189
190
|
import { readFileSync as readFileSync2, writeFileSync, existsSync as existsSync3 } from "fs";
|
|
@@ -210,7 +211,7 @@ function getAgentRuntime(agentId) {
|
|
|
210
211
|
if (orgDefault) return orgDefault;
|
|
211
212
|
return { runtime: DEFAULT_RUNTIME, model: DEFAULT_MODELS[DEFAULT_RUNTIME] };
|
|
212
213
|
}
|
|
213
|
-
function setAgentRuntime(agentId, runtime, model, reasoning_effort) {
|
|
214
|
+
function setAgentRuntime(agentId, runtime, model, reasoning_effort, mcps) {
|
|
214
215
|
const knownModels = KNOWN_RUNTIMES[runtime];
|
|
215
216
|
if (!knownModels) {
|
|
216
217
|
return {
|
|
@@ -225,12 +226,26 @@ function setAgentRuntime(agentId, runtime, model, reasoning_effort) {
|
|
|
225
226
|
};
|
|
226
227
|
}
|
|
227
228
|
const config = loadAgentConfig();
|
|
229
|
+
const existing = config[agentId];
|
|
228
230
|
const entry = { runtime, model };
|
|
229
231
|
if (reasoning_effort) entry.reasoning_effort = reasoning_effort;
|
|
232
|
+
if (mcps !== void 0) {
|
|
233
|
+
entry.mcps = mcps.includes("exe-os") ? mcps : ["exe-os", ...mcps];
|
|
234
|
+
} else if (existing?.mcps) {
|
|
235
|
+
entry.mcps = existing.mcps;
|
|
236
|
+
}
|
|
230
237
|
config[agentId] = entry;
|
|
231
238
|
saveAgentConfig(config);
|
|
232
239
|
return { ok: true };
|
|
233
240
|
}
|
|
241
|
+
function setAgentMcps(agentId, mcps) {
|
|
242
|
+
const config = loadAgentConfig();
|
|
243
|
+
const existing = config[agentId] ?? getAgentRuntime(agentId);
|
|
244
|
+
existing.mcps = mcps.includes("exe-os") ? mcps : ["exe-os", ...mcps];
|
|
245
|
+
config[agentId] = existing;
|
|
246
|
+
saveAgentConfig(config);
|
|
247
|
+
return { ok: true };
|
|
248
|
+
}
|
|
234
249
|
function clearAgentRuntime(agentId) {
|
|
235
250
|
const config = loadAgentConfig();
|
|
236
251
|
delete config[agentId];
|
package/dist/lib/database.js
CHANGED
|
@@ -2885,6 +2885,22 @@ async function ensureSchema() {
|
|
|
2885
2885
|
} catch (e) {
|
|
2886
2886
|
logCatchDebug("migration", e);
|
|
2887
2887
|
}
|
|
2888
|
+
try {
|
|
2889
|
+
await client.execute({
|
|
2890
|
+
sql: `ALTER TABLE memories ADD COLUMN visibility TEXT DEFAULT 'private'`,
|
|
2891
|
+
args: []
|
|
2892
|
+
});
|
|
2893
|
+
} catch (e) {
|
|
2894
|
+
logCatchDebug("migration", e);
|
|
2895
|
+
}
|
|
2896
|
+
try {
|
|
2897
|
+
await client.execute({
|
|
2898
|
+
sql: `ALTER TABLE memories ADD COLUMN strength REAL DEFAULT 1.0`,
|
|
2899
|
+
args: []
|
|
2900
|
+
});
|
|
2901
|
+
} catch (e) {
|
|
2902
|
+
logCatchDebug("migration", e);
|
|
2903
|
+
}
|
|
2888
2904
|
}
|
|
2889
2905
|
var disposeTurso = disposeDatabase;
|
|
2890
2906
|
async function disposeDatabase() {
|
package/dist/lib/db.js
CHANGED
|
@@ -2885,6 +2885,22 @@ async function ensureSchema() {
|
|
|
2885
2885
|
} catch (e) {
|
|
2886
2886
|
logCatchDebug("migration", e);
|
|
2887
2887
|
}
|
|
2888
|
+
try {
|
|
2889
|
+
await client.execute({
|
|
2890
|
+
sql: `ALTER TABLE memories ADD COLUMN visibility TEXT DEFAULT 'private'`,
|
|
2891
|
+
args: []
|
|
2892
|
+
});
|
|
2893
|
+
} catch (e) {
|
|
2894
|
+
logCatchDebug("migration", e);
|
|
2895
|
+
}
|
|
2896
|
+
try {
|
|
2897
|
+
await client.execute({
|
|
2898
|
+
sql: `ALTER TABLE memories ADD COLUMN strength REAL DEFAULT 1.0`,
|
|
2899
|
+
args: []
|
|
2900
|
+
});
|
|
2901
|
+
} catch (e) {
|
|
2902
|
+
logCatchDebug("migration", e);
|
|
2903
|
+
}
|
|
2888
2904
|
}
|
|
2889
2905
|
var disposeTurso = disposeDatabase;
|
|
2890
2906
|
async function disposeDatabase() {
|
|
@@ -2911,6 +2911,22 @@ async function ensureSchema() {
|
|
|
2911
2911
|
} catch (e) {
|
|
2912
2912
|
logCatchDebug("migration", e);
|
|
2913
2913
|
}
|
|
2914
|
+
try {
|
|
2915
|
+
await client.execute({
|
|
2916
|
+
sql: `ALTER TABLE memories ADD COLUMN visibility TEXT DEFAULT 'private'`,
|
|
2917
|
+
args: []
|
|
2918
|
+
});
|
|
2919
|
+
} catch (e) {
|
|
2920
|
+
logCatchDebug("migration", e);
|
|
2921
|
+
}
|
|
2922
|
+
try {
|
|
2923
|
+
await client.execute({
|
|
2924
|
+
sql: `ALTER TABLE memories ADD COLUMN strength REAL DEFAULT 1.0`,
|
|
2925
|
+
args: []
|
|
2926
|
+
});
|
|
2927
|
+
} catch (e) {
|
|
2928
|
+
logCatchDebug("migration", e);
|
|
2929
|
+
}
|
|
2914
2930
|
}
|
|
2915
2931
|
async function disposeDatabase() {
|
|
2916
2932
|
if (_walCheckpointTimer) {
|