@askexenow/exe-os 0.9.37 → 0.9.39
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 +55 -0
- package/dist/bin/backfill-conversations.js +36 -9
- package/dist/bin/backfill-responses.js +36 -9
- package/dist/bin/backfill-vectors.js +36 -9
- package/dist/bin/cleanup-stale-review-tasks.js +37 -10
- package/dist/bin/cli.js +624 -204
- package/dist/bin/exe-agent.js +13 -5
- package/dist/bin/exe-assign.js +36 -9
- package/dist/bin/exe-boot.js +50 -20
- package/dist/bin/exe-call.js +134 -342
- package/dist/bin/exe-dispatch.js +36 -9
- package/dist/bin/exe-doctor.js +39 -12
- package/dist/bin/exe-export-behaviors.js +38 -11
- package/dist/bin/exe-forget.js +36 -9
- package/dist/bin/exe-gateway.js +64 -15
- package/dist/bin/exe-heartbeat.js +37 -10
- package/dist/bin/exe-kill.js +36 -9
- package/dist/bin/exe-launch-agent.js +287 -1081
- package/dist/bin/exe-new-employee.js +100 -14
- package/dist/bin/exe-pending-messages.js +36 -9
- package/dist/bin/exe-pending-notifications.js +36 -9
- package/dist/bin/exe-pending-reviews.js +36 -9
- package/dist/bin/exe-rename.js +1780 -204
- package/dist/bin/exe-review.js +36 -9
- package/dist/bin/exe-search.js +38 -11
- package/dist/bin/exe-session-cleanup.js +38 -11
- package/dist/bin/exe-start-codex.js +38 -11
- package/dist/bin/exe-start-opencode.js +38 -11
- package/dist/bin/exe-status.js +37 -10
- package/dist/bin/exe-team.js +36 -9
- package/dist/bin/git-sweep.js +36 -9
- package/dist/bin/graph-backfill.js +36 -9
- package/dist/bin/graph-export.js +36 -9
- package/dist/bin/install.js +70 -3
- package/dist/bin/intercom-check.js +38 -11
- package/dist/bin/scan-tasks.js +36 -9
- package/dist/bin/setup.js +20 -19
- package/dist/bin/shard-migrate.js +36 -9
- package/dist/bin/stack-update.js +308 -0
- package/dist/gateway/index.js +62 -13
- package/dist/hooks/bug-report-worker.js +40 -12
- package/dist/hooks/codex-stop-task-finalizer.js +38 -11
- package/dist/hooks/commit-complete.js +36 -9
- package/dist/hooks/error-recall.js +38 -11
- package/dist/hooks/ingest.js +38 -10
- package/dist/hooks/instructions-loaded.js +44 -12
- package/dist/hooks/notification.js +36 -9
- package/dist/hooks/post-compact.js +36 -9
- package/dist/hooks/post-tool-combined.js +39 -12
- package/dist/hooks/pre-compact.js +37 -10
- package/dist/hooks/pre-tool-use.js +38 -10
- package/dist/hooks/prompt-submit.js +43 -15
- package/dist/hooks/session-end.js +37 -10
- package/dist/hooks/session-start.js +49 -16
- package/dist/hooks/stop.js +37 -10
- package/dist/hooks/subagent-stop.js +36 -9
- package/dist/hooks/summary-worker.js +45 -18
- package/dist/index.js +60 -11
- package/dist/lib/consolidation.js +2 -1
- package/dist/lib/employee-templates.js +4 -3
- package/dist/lib/employees.js +2 -1
- package/dist/lib/exe-daemon.js +11229 -10537
- package/dist/lib/hybrid-search.js +38 -11
- package/dist/lib/identity.js +8 -3
- package/dist/lib/schedules.js +36 -9
- package/dist/lib/store.js +36 -9
- package/dist/mcp/server.js +6873 -6249
- package/dist/mcp/tools/create-task.js +10 -4
- package/dist/runtime/index.js +36 -9
- package/dist/tui/App.js +42 -13
- package/package.json +4 -1
- package/stack.release.json +31 -0
- package/stack.release.schema.json +31 -0
|
@@ -3238,7 +3238,7 @@ __export(shard_manager_exports, {
|
|
|
3238
3238
|
shardExists: () => shardExists
|
|
3239
3239
|
});
|
|
3240
3240
|
import path7 from "path";
|
|
3241
|
-
import { existsSync as existsSync7, mkdirSync as mkdirSync2, readdirSync } from "fs";
|
|
3241
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync2, readdirSync, renameSync as renameSync3, statSync as statSync2 } from "fs";
|
|
3242
3242
|
import { createClient as createClient2 } from "@libsql/client";
|
|
3243
3243
|
function initShardManager(encryptionKey) {
|
|
3244
3244
|
_encryptionKey = encryptionKey;
|
|
@@ -3260,7 +3260,7 @@ function getShardClient(projectName) {
|
|
|
3260
3260
|
if (!_encryptionKey) {
|
|
3261
3261
|
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
3262
3262
|
}
|
|
3263
|
-
const safeName = projectName
|
|
3263
|
+
const safeName = safeShardName(projectName);
|
|
3264
3264
|
if (!safeName || safeName === "unknown") {
|
|
3265
3265
|
throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
|
|
3266
3266
|
}
|
|
@@ -3282,9 +3282,12 @@ function getShardClient(projectName) {
|
|
|
3282
3282
|
return client;
|
|
3283
3283
|
}
|
|
3284
3284
|
function shardExists(projectName) {
|
|
3285
|
-
const safeName = projectName
|
|
3285
|
+
const safeName = safeShardName(projectName);
|
|
3286
3286
|
return existsSync7(path7.join(SHARDS_DIR, `${safeName}.db`));
|
|
3287
3287
|
}
|
|
3288
|
+
function safeShardName(projectName) {
|
|
3289
|
+
return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
3290
|
+
}
|
|
3288
3291
|
function listShards() {
|
|
3289
3292
|
if (!existsSync7(SHARDS_DIR)) return [];
|
|
3290
3293
|
return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
@@ -3378,7 +3381,8 @@ async function ensureShardSchema(client) {
|
|
|
3378
3381
|
"ALTER TABLE memories ADD COLUMN token_cost REAL",
|
|
3379
3382
|
"ALTER TABLE memories ADD COLUMN audience TEXT",
|
|
3380
3383
|
"ALTER TABLE memories ADD COLUMN language_type TEXT",
|
|
3381
|
-
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
|
|
3384
|
+
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT",
|
|
3385
|
+
"ALTER TABLE memories ADD COLUMN deleted_at TEXT"
|
|
3382
3386
|
]) {
|
|
3383
3387
|
try {
|
|
3384
3388
|
await client.execute(col);
|
|
@@ -3474,9 +3478,32 @@ async function ensureShardSchema(client) {
|
|
|
3474
3478
|
}
|
|
3475
3479
|
}
|
|
3476
3480
|
async function getReadyShardClient(projectName) {
|
|
3477
|
-
const
|
|
3478
|
-
|
|
3479
|
-
|
|
3481
|
+
const safeName = safeShardName(projectName);
|
|
3482
|
+
let client = getShardClient(projectName);
|
|
3483
|
+
try {
|
|
3484
|
+
await ensureShardSchema(client);
|
|
3485
|
+
return client;
|
|
3486
|
+
} catch (err) {
|
|
3487
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
3488
|
+
if (!/SQLITE_NOTADB|file is not a database/i.test(message)) throw err;
|
|
3489
|
+
client.close();
|
|
3490
|
+
_shards.delete(safeName);
|
|
3491
|
+
_shardLastAccess.delete(safeName);
|
|
3492
|
+
const dbPath = path7.join(SHARDS_DIR, `${safeName}.db`);
|
|
3493
|
+
if (existsSync7(dbPath)) {
|
|
3494
|
+
const stat = statSync2(dbPath);
|
|
3495
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
3496
|
+
const archivedPath = path7.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
|
|
3497
|
+
renameSync3(dbPath, archivedPath);
|
|
3498
|
+
process.stderr.write(
|
|
3499
|
+
`[shard-manager] Archived unreadable shard ${safeName}: ${archivedPath} (${stat.size} bytes, mtime ${stat.mtime.toISOString()})
|
|
3500
|
+
`
|
|
3501
|
+
);
|
|
3502
|
+
}
|
|
3503
|
+
client = getShardClient(projectName);
|
|
3504
|
+
await ensureShardSchema(client);
|
|
3505
|
+
return client;
|
|
3506
|
+
}
|
|
3480
3507
|
}
|
|
3481
3508
|
function evictLRU() {
|
|
3482
3509
|
let oldest = null;
|
|
@@ -3697,7 +3724,7 @@ var init_platform_procedures = __esm({
|
|
|
3697
3724
|
title: "MCP tools \u2014 wiki, documents, and content",
|
|
3698
3725
|
domain: "tool-use",
|
|
3699
3726
|
priority: "p1",
|
|
3700
|
-
content: "
|
|
3727
|
+
content: "wiki: read/list wiki pages only. Direct wiki write tools are removed; wiki updates flow through raw-data ingestion/projection into the curated wiki store. Legacy aliases: list_wiki_pages/get_wiki_page. crm: read/list/get CRM records from exe-db. raw_data: read capped raw landing-pad events from exe-db with payload opt-in. ingest_document: import a file (PDF, MD, etc.) into memory as chunks. list_documents: browse ingested documents by workspace. purge_document: remove a document and its memory chunks. set_document_importance: adjust chunk importance scores. rerank_documents: re-score document relevance for a query."
|
|
3701
3728
|
},
|
|
3702
3729
|
{
|
|
3703
3730
|
title: "MCP tools \u2014 system, operations, and admin",
|
|
@@ -3715,7 +3742,7 @@ var init_platform_procedures = __esm({
|
|
|
3715
3742
|
title: "MCP tools \u2014 advanced (triggers, skills, orchestration)",
|
|
3716
3743
|
domain: "tool-use",
|
|
3717
3744
|
priority: "p1",
|
|
3718
|
-
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. global_procedure: manage
|
|
3745
|
+
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. global_procedure: manage customer-owned company procedures (Layer 0; actions: store, list, deactivate). Legacy aliases: store_global_procedure, list_global_procedures, deactivate_global_procedure."
|
|
3719
3746
|
}
|
|
3720
3747
|
];
|
|
3721
3748
|
PLATFORM_PROCEDURE_TITLES = new Set(
|
|
@@ -4751,7 +4778,7 @@ __export(file_grep_exports, {
|
|
|
4751
4778
|
grepProjectFiles: () => grepProjectFiles
|
|
4752
4779
|
});
|
|
4753
4780
|
import { execSync as execSync4 } from "child_process";
|
|
4754
|
-
import { readFileSync as readFileSync5, readdirSync as readdirSync2, statSync as
|
|
4781
|
+
import { readFileSync as readFileSync5, readdirSync as readdirSync2, statSync as statSync3, existsSync as existsSync9 } from "fs";
|
|
4755
4782
|
import path10 from "path";
|
|
4756
4783
|
import crypto2 from "crypto";
|
|
4757
4784
|
function hasRipgrep() {
|
|
@@ -4868,7 +4895,7 @@ function grepWithNodeFs(pattern, projectRoot, patterns) {
|
|
|
4868
4895
|
for (const filePath of files.slice(0, MAX_FILES)) {
|
|
4869
4896
|
const absPath = path10.join(projectRoot, filePath);
|
|
4870
4897
|
try {
|
|
4871
|
-
const stat =
|
|
4898
|
+
const stat = statSync3(absPath);
|
|
4872
4899
|
if (stat.size > MAX_FILE_SIZE) continue;
|
|
4873
4900
|
const content = readFileSync5(absPath, "utf8");
|
|
4874
4901
|
const lines = content.split("\n");
|
package/dist/lib/identity.js
CHANGED
|
@@ -169,6 +169,9 @@ function ensureDir() {
|
|
|
169
169
|
function identityPath(agentId) {
|
|
170
170
|
return path4.join(IDENTITY_DIR2, `${agentId}.md`);
|
|
171
171
|
}
|
|
172
|
+
function sanitizeIdentityBody(body) {
|
|
173
|
+
return body.replace(/<!--[\s\S]*?-->/g, "").trim();
|
|
174
|
+
}
|
|
172
175
|
function parseFrontmatter(raw) {
|
|
173
176
|
const match = raw.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
174
177
|
if (!match) {
|
|
@@ -181,11 +184,11 @@ function parseFrontmatter(raw) {
|
|
|
181
184
|
created_by: "system",
|
|
182
185
|
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
183
186
|
},
|
|
184
|
-
body: raw
|
|
187
|
+
body: sanitizeIdentityBody(raw)
|
|
185
188
|
};
|
|
186
189
|
}
|
|
187
190
|
const yamlStr = match[1];
|
|
188
|
-
const body = match[2]
|
|
191
|
+
const body = sanitizeIdentityBody(match[2]);
|
|
189
192
|
const fm = {};
|
|
190
193
|
for (const line of yamlStr.split("\n")) {
|
|
191
194
|
const kv = line.match(/^(\w+):\s*(.+)$/);
|
|
@@ -250,7 +253,9 @@ function listIdentities() {
|
|
|
250
253
|
const summary = lines[0]?.trim().slice(0, 120) ?? identity.frontmatter.title;
|
|
251
254
|
results.push({
|
|
252
255
|
agentId,
|
|
253
|
-
title
|
|
256
|
+
// User-facing/team-facing title only. `frontmatter.role` is internal
|
|
257
|
+
// routing metadata and must not leak as an external title.
|
|
258
|
+
title: identity.frontmatter.title,
|
|
254
259
|
summary
|
|
255
260
|
});
|
|
256
261
|
}
|
package/dist/lib/schedules.js
CHANGED
|
@@ -2600,7 +2600,7 @@ __export(shard_manager_exports, {
|
|
|
2600
2600
|
shardExists: () => shardExists
|
|
2601
2601
|
});
|
|
2602
2602
|
import path7 from "path";
|
|
2603
|
-
import { existsSync as existsSync7, mkdirSync as mkdirSync2, readdirSync } from "fs";
|
|
2603
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync2, readdirSync, renameSync as renameSync3, statSync as statSync2 } from "fs";
|
|
2604
2604
|
import { createClient as createClient2 } from "@libsql/client";
|
|
2605
2605
|
function initShardManager(encryptionKey) {
|
|
2606
2606
|
_encryptionKey = encryptionKey;
|
|
@@ -2622,7 +2622,7 @@ function getShardClient(projectName) {
|
|
|
2622
2622
|
if (!_encryptionKey) {
|
|
2623
2623
|
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
2624
2624
|
}
|
|
2625
|
-
const safeName = projectName
|
|
2625
|
+
const safeName = safeShardName(projectName);
|
|
2626
2626
|
if (!safeName || safeName === "unknown") {
|
|
2627
2627
|
throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
|
|
2628
2628
|
}
|
|
@@ -2644,9 +2644,12 @@ function getShardClient(projectName) {
|
|
|
2644
2644
|
return client;
|
|
2645
2645
|
}
|
|
2646
2646
|
function shardExists(projectName) {
|
|
2647
|
-
const safeName = projectName
|
|
2647
|
+
const safeName = safeShardName(projectName);
|
|
2648
2648
|
return existsSync7(path7.join(SHARDS_DIR, `${safeName}.db`));
|
|
2649
2649
|
}
|
|
2650
|
+
function safeShardName(projectName) {
|
|
2651
|
+
return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
2652
|
+
}
|
|
2650
2653
|
function listShards() {
|
|
2651
2654
|
if (!existsSync7(SHARDS_DIR)) return [];
|
|
2652
2655
|
return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
@@ -2740,7 +2743,8 @@ async function ensureShardSchema(client) {
|
|
|
2740
2743
|
"ALTER TABLE memories ADD COLUMN token_cost REAL",
|
|
2741
2744
|
"ALTER TABLE memories ADD COLUMN audience TEXT",
|
|
2742
2745
|
"ALTER TABLE memories ADD COLUMN language_type TEXT",
|
|
2743
|
-
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
|
|
2746
|
+
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT",
|
|
2747
|
+
"ALTER TABLE memories ADD COLUMN deleted_at TEXT"
|
|
2744
2748
|
]) {
|
|
2745
2749
|
try {
|
|
2746
2750
|
await client.execute(col);
|
|
@@ -2836,9 +2840,32 @@ async function ensureShardSchema(client) {
|
|
|
2836
2840
|
}
|
|
2837
2841
|
}
|
|
2838
2842
|
async function getReadyShardClient(projectName) {
|
|
2839
|
-
const
|
|
2840
|
-
|
|
2841
|
-
|
|
2843
|
+
const safeName = safeShardName(projectName);
|
|
2844
|
+
let client = getShardClient(projectName);
|
|
2845
|
+
try {
|
|
2846
|
+
await ensureShardSchema(client);
|
|
2847
|
+
return client;
|
|
2848
|
+
} catch (err) {
|
|
2849
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2850
|
+
if (!/SQLITE_NOTADB|file is not a database/i.test(message)) throw err;
|
|
2851
|
+
client.close();
|
|
2852
|
+
_shards.delete(safeName);
|
|
2853
|
+
_shardLastAccess.delete(safeName);
|
|
2854
|
+
const dbPath = path7.join(SHARDS_DIR, `${safeName}.db`);
|
|
2855
|
+
if (existsSync7(dbPath)) {
|
|
2856
|
+
const stat = statSync2(dbPath);
|
|
2857
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
2858
|
+
const archivedPath = path7.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
|
|
2859
|
+
renameSync3(dbPath, archivedPath);
|
|
2860
|
+
process.stderr.write(
|
|
2861
|
+
`[shard-manager] Archived unreadable shard ${safeName}: ${archivedPath} (${stat.size} bytes, mtime ${stat.mtime.toISOString()})
|
|
2862
|
+
`
|
|
2863
|
+
);
|
|
2864
|
+
}
|
|
2865
|
+
client = getShardClient(projectName);
|
|
2866
|
+
await ensureShardSchema(client);
|
|
2867
|
+
return client;
|
|
2868
|
+
}
|
|
2842
2869
|
}
|
|
2843
2870
|
function evictLRU() {
|
|
2844
2871
|
let oldest = null;
|
|
@@ -3059,7 +3086,7 @@ var init_platform_procedures = __esm({
|
|
|
3059
3086
|
title: "MCP tools \u2014 wiki, documents, and content",
|
|
3060
3087
|
domain: "tool-use",
|
|
3061
3088
|
priority: "p1",
|
|
3062
|
-
content: "
|
|
3089
|
+
content: "wiki: read/list wiki pages only. Direct wiki write tools are removed; wiki updates flow through raw-data ingestion/projection into the curated wiki store. Legacy aliases: list_wiki_pages/get_wiki_page. crm: read/list/get CRM records from exe-db. raw_data: read capped raw landing-pad events from exe-db with payload opt-in. ingest_document: import a file (PDF, MD, etc.) into memory as chunks. list_documents: browse ingested documents by workspace. purge_document: remove a document and its memory chunks. set_document_importance: adjust chunk importance scores. rerank_documents: re-score document relevance for a query."
|
|
3063
3090
|
},
|
|
3064
3091
|
{
|
|
3065
3092
|
title: "MCP tools \u2014 system, operations, and admin",
|
|
@@ -3077,7 +3104,7 @@ var init_platform_procedures = __esm({
|
|
|
3077
3104
|
title: "MCP tools \u2014 advanced (triggers, skills, orchestration)",
|
|
3078
3105
|
domain: "tool-use",
|
|
3079
3106
|
priority: "p1",
|
|
3080
|
-
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. global_procedure: manage
|
|
3107
|
+
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. global_procedure: manage customer-owned company procedures (Layer 0; actions: store, list, deactivate). Legacy aliases: store_global_procedure, list_global_procedures, deactivate_global_procedure."
|
|
3081
3108
|
}
|
|
3082
3109
|
];
|
|
3083
3110
|
PLATFORM_PROCEDURE_TITLES = new Set(
|
package/dist/lib/store.js
CHANGED
|
@@ -2600,7 +2600,7 @@ __export(shard_manager_exports, {
|
|
|
2600
2600
|
shardExists: () => shardExists
|
|
2601
2601
|
});
|
|
2602
2602
|
import path7 from "path";
|
|
2603
|
-
import { existsSync as existsSync7, mkdirSync as mkdirSync2, readdirSync } from "fs";
|
|
2603
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync2, readdirSync, renameSync as renameSync3, statSync as statSync2 } from "fs";
|
|
2604
2604
|
import { createClient as createClient2 } from "@libsql/client";
|
|
2605
2605
|
function initShardManager(encryptionKey) {
|
|
2606
2606
|
_encryptionKey = encryptionKey;
|
|
@@ -2622,7 +2622,7 @@ function getShardClient(projectName) {
|
|
|
2622
2622
|
if (!_encryptionKey) {
|
|
2623
2623
|
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
2624
2624
|
}
|
|
2625
|
-
const safeName = projectName
|
|
2625
|
+
const safeName = safeShardName(projectName);
|
|
2626
2626
|
if (!safeName || safeName === "unknown") {
|
|
2627
2627
|
throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
|
|
2628
2628
|
}
|
|
@@ -2644,9 +2644,12 @@ function getShardClient(projectName) {
|
|
|
2644
2644
|
return client;
|
|
2645
2645
|
}
|
|
2646
2646
|
function shardExists(projectName) {
|
|
2647
|
-
const safeName = projectName
|
|
2647
|
+
const safeName = safeShardName(projectName);
|
|
2648
2648
|
return existsSync7(path7.join(SHARDS_DIR, `${safeName}.db`));
|
|
2649
2649
|
}
|
|
2650
|
+
function safeShardName(projectName) {
|
|
2651
|
+
return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
2652
|
+
}
|
|
2650
2653
|
function listShards() {
|
|
2651
2654
|
if (!existsSync7(SHARDS_DIR)) return [];
|
|
2652
2655
|
return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
@@ -2740,7 +2743,8 @@ async function ensureShardSchema(client) {
|
|
|
2740
2743
|
"ALTER TABLE memories ADD COLUMN token_cost REAL",
|
|
2741
2744
|
"ALTER TABLE memories ADD COLUMN audience TEXT",
|
|
2742
2745
|
"ALTER TABLE memories ADD COLUMN language_type TEXT",
|
|
2743
|
-
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
|
|
2746
|
+
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT",
|
|
2747
|
+
"ALTER TABLE memories ADD COLUMN deleted_at TEXT"
|
|
2744
2748
|
]) {
|
|
2745
2749
|
try {
|
|
2746
2750
|
await client.execute(col);
|
|
@@ -2836,9 +2840,32 @@ async function ensureShardSchema(client) {
|
|
|
2836
2840
|
}
|
|
2837
2841
|
}
|
|
2838
2842
|
async function getReadyShardClient(projectName) {
|
|
2839
|
-
const
|
|
2840
|
-
|
|
2841
|
-
|
|
2843
|
+
const safeName = safeShardName(projectName);
|
|
2844
|
+
let client = getShardClient(projectName);
|
|
2845
|
+
try {
|
|
2846
|
+
await ensureShardSchema(client);
|
|
2847
|
+
return client;
|
|
2848
|
+
} catch (err) {
|
|
2849
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2850
|
+
if (!/SQLITE_NOTADB|file is not a database/i.test(message)) throw err;
|
|
2851
|
+
client.close();
|
|
2852
|
+
_shards.delete(safeName);
|
|
2853
|
+
_shardLastAccess.delete(safeName);
|
|
2854
|
+
const dbPath = path7.join(SHARDS_DIR, `${safeName}.db`);
|
|
2855
|
+
if (existsSync7(dbPath)) {
|
|
2856
|
+
const stat = statSync2(dbPath);
|
|
2857
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
2858
|
+
const archivedPath = path7.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
|
|
2859
|
+
renameSync3(dbPath, archivedPath);
|
|
2860
|
+
process.stderr.write(
|
|
2861
|
+
`[shard-manager] Archived unreadable shard ${safeName}: ${archivedPath} (${stat.size} bytes, mtime ${stat.mtime.toISOString()})
|
|
2862
|
+
`
|
|
2863
|
+
);
|
|
2864
|
+
}
|
|
2865
|
+
client = getShardClient(projectName);
|
|
2866
|
+
await ensureShardSchema(client);
|
|
2867
|
+
return client;
|
|
2868
|
+
}
|
|
2842
2869
|
}
|
|
2843
2870
|
function evictLRU() {
|
|
2844
2871
|
let oldest = null;
|
|
@@ -3059,7 +3086,7 @@ var init_platform_procedures = __esm({
|
|
|
3059
3086
|
title: "MCP tools \u2014 wiki, documents, and content",
|
|
3060
3087
|
domain: "tool-use",
|
|
3061
3088
|
priority: "p1",
|
|
3062
|
-
content: "
|
|
3089
|
+
content: "wiki: read/list wiki pages only. Direct wiki write tools are removed; wiki updates flow through raw-data ingestion/projection into the curated wiki store. Legacy aliases: list_wiki_pages/get_wiki_page. crm: read/list/get CRM records from exe-db. raw_data: read capped raw landing-pad events from exe-db with payload opt-in. ingest_document: import a file (PDF, MD, etc.) into memory as chunks. list_documents: browse ingested documents by workspace. purge_document: remove a document and its memory chunks. set_document_importance: adjust chunk importance scores. rerank_documents: re-score document relevance for a query."
|
|
3063
3090
|
},
|
|
3064
3091
|
{
|
|
3065
3092
|
title: "MCP tools \u2014 system, operations, and admin",
|
|
@@ -3077,7 +3104,7 @@ var init_platform_procedures = __esm({
|
|
|
3077
3104
|
title: "MCP tools \u2014 advanced (triggers, skills, orchestration)",
|
|
3078
3105
|
domain: "tool-use",
|
|
3079
3106
|
priority: "p1",
|
|
3080
|
-
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. global_procedure: manage
|
|
3107
|
+
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. global_procedure: manage customer-owned company procedures (Layer 0; actions: store, list, deactivate). Legacy aliases: store_global_procedure, list_global_procedures, deactivate_global_procedure."
|
|
3081
3108
|
}
|
|
3082
3109
|
];
|
|
3083
3110
|
PLATFORM_PROCEDURE_TITLES = new Set(
|