@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
|
@@ -3333,7 +3333,7 @@ __export(shard_manager_exports, {
|
|
|
3333
3333
|
shardExists: () => shardExists
|
|
3334
3334
|
});
|
|
3335
3335
|
import path7 from "path";
|
|
3336
|
-
import { existsSync as existsSync7, mkdirSync as mkdirSync2, readdirSync } from "fs";
|
|
3336
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync2, readdirSync, renameSync as renameSync3, statSync as statSync2 } from "fs";
|
|
3337
3337
|
import { createClient as createClient2 } from "@libsql/client";
|
|
3338
3338
|
function initShardManager(encryptionKey) {
|
|
3339
3339
|
_encryptionKey = encryptionKey;
|
|
@@ -3355,7 +3355,7 @@ function getShardClient(projectName) {
|
|
|
3355
3355
|
if (!_encryptionKey) {
|
|
3356
3356
|
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
3357
3357
|
}
|
|
3358
|
-
const safeName = projectName
|
|
3358
|
+
const safeName = safeShardName(projectName);
|
|
3359
3359
|
if (!safeName || safeName === "unknown") {
|
|
3360
3360
|
throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
|
|
3361
3361
|
}
|
|
@@ -3377,9 +3377,12 @@ function getShardClient(projectName) {
|
|
|
3377
3377
|
return client;
|
|
3378
3378
|
}
|
|
3379
3379
|
function shardExists(projectName) {
|
|
3380
|
-
const safeName = projectName
|
|
3380
|
+
const safeName = safeShardName(projectName);
|
|
3381
3381
|
return existsSync7(path7.join(SHARDS_DIR, `${safeName}.db`));
|
|
3382
3382
|
}
|
|
3383
|
+
function safeShardName(projectName) {
|
|
3384
|
+
return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
3385
|
+
}
|
|
3383
3386
|
function listShards() {
|
|
3384
3387
|
if (!existsSync7(SHARDS_DIR)) return [];
|
|
3385
3388
|
return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
@@ -3473,7 +3476,8 @@ async function ensureShardSchema(client) {
|
|
|
3473
3476
|
"ALTER TABLE memories ADD COLUMN token_cost REAL",
|
|
3474
3477
|
"ALTER TABLE memories ADD COLUMN audience TEXT",
|
|
3475
3478
|
"ALTER TABLE memories ADD COLUMN language_type TEXT",
|
|
3476
|
-
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
|
|
3479
|
+
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT",
|
|
3480
|
+
"ALTER TABLE memories ADD COLUMN deleted_at TEXT"
|
|
3477
3481
|
]) {
|
|
3478
3482
|
try {
|
|
3479
3483
|
await client.execute(col);
|
|
@@ -3569,9 +3573,32 @@ async function ensureShardSchema(client) {
|
|
|
3569
3573
|
}
|
|
3570
3574
|
}
|
|
3571
3575
|
async function getReadyShardClient(projectName) {
|
|
3572
|
-
const
|
|
3573
|
-
|
|
3574
|
-
|
|
3576
|
+
const safeName = safeShardName(projectName);
|
|
3577
|
+
let client = getShardClient(projectName);
|
|
3578
|
+
try {
|
|
3579
|
+
await ensureShardSchema(client);
|
|
3580
|
+
return client;
|
|
3581
|
+
} catch (err) {
|
|
3582
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
3583
|
+
if (!/SQLITE_NOTADB|file is not a database/i.test(message)) throw err;
|
|
3584
|
+
client.close();
|
|
3585
|
+
_shards.delete(safeName);
|
|
3586
|
+
_shardLastAccess.delete(safeName);
|
|
3587
|
+
const dbPath = path7.join(SHARDS_DIR, `${safeName}.db`);
|
|
3588
|
+
if (existsSync7(dbPath)) {
|
|
3589
|
+
const stat = statSync2(dbPath);
|
|
3590
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
3591
|
+
const archivedPath = path7.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
|
|
3592
|
+
renameSync3(dbPath, archivedPath);
|
|
3593
|
+
process.stderr.write(
|
|
3594
|
+
`[shard-manager] Archived unreadable shard ${safeName}: ${archivedPath} (${stat.size} bytes, mtime ${stat.mtime.toISOString()})
|
|
3595
|
+
`
|
|
3596
|
+
);
|
|
3597
|
+
}
|
|
3598
|
+
client = getShardClient(projectName);
|
|
3599
|
+
await ensureShardSchema(client);
|
|
3600
|
+
return client;
|
|
3601
|
+
}
|
|
3575
3602
|
}
|
|
3576
3603
|
function evictLRU() {
|
|
3577
3604
|
let oldest = null;
|
|
@@ -3792,7 +3819,7 @@ var init_platform_procedures = __esm({
|
|
|
3792
3819
|
title: "MCP tools \u2014 wiki, documents, and content",
|
|
3793
3820
|
domain: "tool-use",
|
|
3794
3821
|
priority: "p1",
|
|
3795
|
-
content: "
|
|
3822
|
+
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."
|
|
3796
3823
|
},
|
|
3797
3824
|
{
|
|
3798
3825
|
title: "MCP tools \u2014 system, operations, and admin",
|
|
@@ -3810,7 +3837,7 @@ var init_platform_procedures = __esm({
|
|
|
3810
3837
|
title: "MCP tools \u2014 advanced (triggers, skills, orchestration)",
|
|
3811
3838
|
domain: "tool-use",
|
|
3812
3839
|
priority: "p1",
|
|
3813
|
-
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
|
|
3840
|
+
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."
|
|
3814
3841
|
}
|
|
3815
3842
|
];
|
|
3816
3843
|
PLATFORM_PROCEDURE_TITLES = new Set(
|
|
@@ -4799,7 +4826,7 @@ __export(intercom_queue_exports, {
|
|
|
4799
4826
|
queueIntercom: () => queueIntercom,
|
|
4800
4827
|
readQueue: () => readQueue
|
|
4801
4828
|
});
|
|
4802
|
-
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, renameSync as
|
|
4829
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, renameSync as renameSync4, existsSync as existsSync9, mkdirSync as mkdirSync3 } from "fs";
|
|
4803
4830
|
import path10 from "path";
|
|
4804
4831
|
import os7 from "os";
|
|
4805
4832
|
function ensureDir() {
|
|
@@ -4818,7 +4845,7 @@ function writeQueue(queue) {
|
|
|
4818
4845
|
ensureDir();
|
|
4819
4846
|
const tmp = `${QUEUE_PATH}.tmp`;
|
|
4820
4847
|
writeFileSync4(tmp, JSON.stringify(queue, null, 2));
|
|
4821
|
-
|
|
4848
|
+
renameSync4(tmp, QUEUE_PATH);
|
|
4822
4849
|
}
|
|
4823
4850
|
function queueIntercom(targetSession, reason) {
|
|
4824
4851
|
const queue = readQueue();
|
|
@@ -6949,7 +6949,7 @@ __export(shard_manager_exports, {
|
|
|
6949
6949
|
shardExists: () => shardExists
|
|
6950
6950
|
});
|
|
6951
6951
|
import path19 from "path";
|
|
6952
|
-
import { existsSync as existsSync16, mkdirSync as mkdirSync7, readdirSync as readdirSync4 } from "fs";
|
|
6952
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync7, readdirSync as readdirSync4, renameSync as renameSync4, statSync as statSync2 } from "fs";
|
|
6953
6953
|
import { createClient as createClient2 } from "@libsql/client";
|
|
6954
6954
|
function initShardManager(encryptionKey) {
|
|
6955
6955
|
_encryptionKey = encryptionKey;
|
|
@@ -6971,7 +6971,7 @@ function getShardClient(projectName) {
|
|
|
6971
6971
|
if (!_encryptionKey) {
|
|
6972
6972
|
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
6973
6973
|
}
|
|
6974
|
-
const safeName = projectName
|
|
6974
|
+
const safeName = safeShardName(projectName);
|
|
6975
6975
|
if (!safeName || safeName === "unknown") {
|
|
6976
6976
|
throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
|
|
6977
6977
|
}
|
|
@@ -6993,9 +6993,12 @@ function getShardClient(projectName) {
|
|
|
6993
6993
|
return client;
|
|
6994
6994
|
}
|
|
6995
6995
|
function shardExists(projectName) {
|
|
6996
|
-
const safeName = projectName
|
|
6996
|
+
const safeName = safeShardName(projectName);
|
|
6997
6997
|
return existsSync16(path19.join(SHARDS_DIR, `${safeName}.db`));
|
|
6998
6998
|
}
|
|
6999
|
+
function safeShardName(projectName) {
|
|
7000
|
+
return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
7001
|
+
}
|
|
6999
7002
|
function listShards() {
|
|
7000
7003
|
if (!existsSync16(SHARDS_DIR)) return [];
|
|
7001
7004
|
return readdirSync4(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
@@ -7089,7 +7092,8 @@ async function ensureShardSchema(client) {
|
|
|
7089
7092
|
"ALTER TABLE memories ADD COLUMN token_cost REAL",
|
|
7090
7093
|
"ALTER TABLE memories ADD COLUMN audience TEXT",
|
|
7091
7094
|
"ALTER TABLE memories ADD COLUMN language_type TEXT",
|
|
7092
|
-
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
|
|
7095
|
+
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT",
|
|
7096
|
+
"ALTER TABLE memories ADD COLUMN deleted_at TEXT"
|
|
7093
7097
|
]) {
|
|
7094
7098
|
try {
|
|
7095
7099
|
await client.execute(col);
|
|
@@ -7185,9 +7189,32 @@ async function ensureShardSchema(client) {
|
|
|
7185
7189
|
}
|
|
7186
7190
|
}
|
|
7187
7191
|
async function getReadyShardClient(projectName) {
|
|
7188
|
-
const
|
|
7189
|
-
|
|
7190
|
-
|
|
7192
|
+
const safeName = safeShardName(projectName);
|
|
7193
|
+
let client = getShardClient(projectName);
|
|
7194
|
+
try {
|
|
7195
|
+
await ensureShardSchema(client);
|
|
7196
|
+
return client;
|
|
7197
|
+
} catch (err) {
|
|
7198
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
7199
|
+
if (!/SQLITE_NOTADB|file is not a database/i.test(message)) throw err;
|
|
7200
|
+
client.close();
|
|
7201
|
+
_shards.delete(safeName);
|
|
7202
|
+
_shardLastAccess.delete(safeName);
|
|
7203
|
+
const dbPath = path19.join(SHARDS_DIR, `${safeName}.db`);
|
|
7204
|
+
if (existsSync16(dbPath)) {
|
|
7205
|
+
const stat = statSync2(dbPath);
|
|
7206
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
7207
|
+
const archivedPath = path19.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
|
|
7208
|
+
renameSync4(dbPath, archivedPath);
|
|
7209
|
+
process.stderr.write(
|
|
7210
|
+
`[shard-manager] Archived unreadable shard ${safeName}: ${archivedPath} (${stat.size} bytes, mtime ${stat.mtime.toISOString()})
|
|
7211
|
+
`
|
|
7212
|
+
);
|
|
7213
|
+
}
|
|
7214
|
+
client = getShardClient(projectName);
|
|
7215
|
+
await ensureShardSchema(client);
|
|
7216
|
+
return client;
|
|
7217
|
+
}
|
|
7191
7218
|
}
|
|
7192
7219
|
function evictLRU() {
|
|
7193
7220
|
let oldest = null;
|
|
@@ -7408,7 +7435,7 @@ var init_platform_procedures = __esm({
|
|
|
7408
7435
|
title: "MCP tools \u2014 wiki, documents, and content",
|
|
7409
7436
|
domain: "tool-use",
|
|
7410
7437
|
priority: "p1",
|
|
7411
|
-
content: "
|
|
7438
|
+
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."
|
|
7412
7439
|
},
|
|
7413
7440
|
{
|
|
7414
7441
|
title: "MCP tools \u2014 system, operations, and admin",
|
|
@@ -7426,7 +7453,7 @@ var init_platform_procedures = __esm({
|
|
|
7426
7453
|
title: "MCP tools \u2014 advanced (triggers, skills, orchestration)",
|
|
7427
7454
|
domain: "tool-use",
|
|
7428
7455
|
priority: "p1",
|
|
7429
|
-
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
|
|
7456
|
+
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."
|
|
7430
7457
|
}
|
|
7431
7458
|
];
|
|
7432
7459
|
PLATFORM_PROCEDURE_TITLES = new Set(
|
|
@@ -3241,7 +3241,7 @@ __export(shard_manager_exports, {
|
|
|
3241
3241
|
shardExists: () => shardExists
|
|
3242
3242
|
});
|
|
3243
3243
|
import path7 from "path";
|
|
3244
|
-
import { existsSync as existsSync7, mkdirSync as mkdirSync2, readdirSync } from "fs";
|
|
3244
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync2, readdirSync, renameSync as renameSync3, statSync as statSync2 } from "fs";
|
|
3245
3245
|
import { createClient as createClient2 } from "@libsql/client";
|
|
3246
3246
|
function initShardManager(encryptionKey) {
|
|
3247
3247
|
_encryptionKey = encryptionKey;
|
|
@@ -3263,7 +3263,7 @@ function getShardClient(projectName) {
|
|
|
3263
3263
|
if (!_encryptionKey) {
|
|
3264
3264
|
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
3265
3265
|
}
|
|
3266
|
-
const safeName = projectName
|
|
3266
|
+
const safeName = safeShardName(projectName);
|
|
3267
3267
|
if (!safeName || safeName === "unknown") {
|
|
3268
3268
|
throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
|
|
3269
3269
|
}
|
|
@@ -3285,9 +3285,12 @@ function getShardClient(projectName) {
|
|
|
3285
3285
|
return client;
|
|
3286
3286
|
}
|
|
3287
3287
|
function shardExists(projectName) {
|
|
3288
|
-
const safeName = projectName
|
|
3288
|
+
const safeName = safeShardName(projectName);
|
|
3289
3289
|
return existsSync7(path7.join(SHARDS_DIR, `${safeName}.db`));
|
|
3290
3290
|
}
|
|
3291
|
+
function safeShardName(projectName) {
|
|
3292
|
+
return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
3293
|
+
}
|
|
3291
3294
|
function listShards() {
|
|
3292
3295
|
if (!existsSync7(SHARDS_DIR)) return [];
|
|
3293
3296
|
return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
@@ -3381,7 +3384,8 @@ async function ensureShardSchema(client) {
|
|
|
3381
3384
|
"ALTER TABLE memories ADD COLUMN token_cost REAL",
|
|
3382
3385
|
"ALTER TABLE memories ADD COLUMN audience TEXT",
|
|
3383
3386
|
"ALTER TABLE memories ADD COLUMN language_type TEXT",
|
|
3384
|
-
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
|
|
3387
|
+
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT",
|
|
3388
|
+
"ALTER TABLE memories ADD COLUMN deleted_at TEXT"
|
|
3385
3389
|
]) {
|
|
3386
3390
|
try {
|
|
3387
3391
|
await client.execute(col);
|
|
@@ -3477,9 +3481,32 @@ async function ensureShardSchema(client) {
|
|
|
3477
3481
|
}
|
|
3478
3482
|
}
|
|
3479
3483
|
async function getReadyShardClient(projectName) {
|
|
3480
|
-
const
|
|
3481
|
-
|
|
3482
|
-
|
|
3484
|
+
const safeName = safeShardName(projectName);
|
|
3485
|
+
let client = getShardClient(projectName);
|
|
3486
|
+
try {
|
|
3487
|
+
await ensureShardSchema(client);
|
|
3488
|
+
return client;
|
|
3489
|
+
} catch (err) {
|
|
3490
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
3491
|
+
if (!/SQLITE_NOTADB|file is not a database/i.test(message)) throw err;
|
|
3492
|
+
client.close();
|
|
3493
|
+
_shards.delete(safeName);
|
|
3494
|
+
_shardLastAccess.delete(safeName);
|
|
3495
|
+
const dbPath = path7.join(SHARDS_DIR, `${safeName}.db`);
|
|
3496
|
+
if (existsSync7(dbPath)) {
|
|
3497
|
+
const stat = statSync2(dbPath);
|
|
3498
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
3499
|
+
const archivedPath = path7.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
|
|
3500
|
+
renameSync3(dbPath, archivedPath);
|
|
3501
|
+
process.stderr.write(
|
|
3502
|
+
`[shard-manager] Archived unreadable shard ${safeName}: ${archivedPath} (${stat.size} bytes, mtime ${stat.mtime.toISOString()})
|
|
3503
|
+
`
|
|
3504
|
+
);
|
|
3505
|
+
}
|
|
3506
|
+
client = getShardClient(projectName);
|
|
3507
|
+
await ensureShardSchema(client);
|
|
3508
|
+
return client;
|
|
3509
|
+
}
|
|
3483
3510
|
}
|
|
3484
3511
|
function evictLRU() {
|
|
3485
3512
|
let oldest = null;
|
|
@@ -3700,7 +3727,7 @@ var init_platform_procedures = __esm({
|
|
|
3700
3727
|
title: "MCP tools \u2014 wiki, documents, and content",
|
|
3701
3728
|
domain: "tool-use",
|
|
3702
3729
|
priority: "p1",
|
|
3703
|
-
content: "
|
|
3730
|
+
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."
|
|
3704
3731
|
},
|
|
3705
3732
|
{
|
|
3706
3733
|
title: "MCP tools \u2014 system, operations, and admin",
|
|
@@ -3718,7 +3745,7 @@ var init_platform_procedures = __esm({
|
|
|
3718
3745
|
title: "MCP tools \u2014 advanced (triggers, skills, orchestration)",
|
|
3719
3746
|
domain: "tool-use",
|
|
3720
3747
|
priority: "p1",
|
|
3721
|
-
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
|
|
3748
|
+
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."
|
|
3722
3749
|
}
|
|
3723
3750
|
];
|
|
3724
3751
|
PLATFORM_PROCEDURE_TITLES = new Set(
|
|
@@ -4754,7 +4781,7 @@ __export(file_grep_exports, {
|
|
|
4754
4781
|
grepProjectFiles: () => grepProjectFiles
|
|
4755
4782
|
});
|
|
4756
4783
|
import { execSync as execSync4 } from "child_process";
|
|
4757
|
-
import { readFileSync as readFileSync5, readdirSync as readdirSync2, statSync as
|
|
4784
|
+
import { readFileSync as readFileSync5, readdirSync as readdirSync2, statSync as statSync3, existsSync as existsSync9 } from "fs";
|
|
4758
4785
|
import path10 from "path";
|
|
4759
4786
|
import crypto3 from "crypto";
|
|
4760
4787
|
function hasRipgrep() {
|
|
@@ -4871,7 +4898,7 @@ function grepWithNodeFs(pattern, projectRoot, patterns) {
|
|
|
4871
4898
|
for (const filePath of files.slice(0, MAX_FILES)) {
|
|
4872
4899
|
const absPath = path10.join(projectRoot, filePath);
|
|
4873
4900
|
try {
|
|
4874
|
-
const stat =
|
|
4901
|
+
const stat = statSync3(absPath);
|
|
4875
4902
|
if (stat.size > MAX_FILE_SIZE) continue;
|
|
4876
4903
|
const content = readFileSync5(absPath, "utf8");
|
|
4877
4904
|
const lines = content.split("\n");
|
package/dist/hooks/ingest.js
CHANGED
|
@@ -492,7 +492,8 @@ function isMultiInstance(agentName, employees) {
|
|
|
492
492
|
return MULTI_INSTANCE_ROLES.has(emp.role.toLowerCase());
|
|
493
493
|
}
|
|
494
494
|
function addEmployee(employees, employee) {
|
|
495
|
-
const
|
|
495
|
+
const { systemPrompt: _legacyPrompt, ...rest } = employee;
|
|
496
|
+
const normalized = { ...rest, name: employee.name.toLowerCase() };
|
|
496
497
|
if (employees.some((e) => e.name.toLowerCase() === normalized.name)) {
|
|
497
498
|
throw new Error(`Employee '${normalized.name}' already exists`);
|
|
498
499
|
}
|
|
@@ -3417,7 +3418,7 @@ __export(shard_manager_exports, {
|
|
|
3417
3418
|
shardExists: () => shardExists
|
|
3418
3419
|
});
|
|
3419
3420
|
import path11 from "path";
|
|
3420
|
-
import { existsSync as existsSync10, mkdirSync as mkdirSync5, readdirSync as readdirSync3 } from "fs";
|
|
3421
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync5, readdirSync as readdirSync3, renameSync as renameSync3, statSync as statSync2 } from "fs";
|
|
3421
3422
|
import { createClient as createClient2 } from "@libsql/client";
|
|
3422
3423
|
function initShardManager(encryptionKey) {
|
|
3423
3424
|
_encryptionKey = encryptionKey;
|
|
@@ -3439,7 +3440,7 @@ function getShardClient(projectName) {
|
|
|
3439
3440
|
if (!_encryptionKey) {
|
|
3440
3441
|
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
3441
3442
|
}
|
|
3442
|
-
const safeName = projectName
|
|
3443
|
+
const safeName = safeShardName(projectName);
|
|
3443
3444
|
if (!safeName || safeName === "unknown") {
|
|
3444
3445
|
throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
|
|
3445
3446
|
}
|
|
@@ -3461,9 +3462,12 @@ function getShardClient(projectName) {
|
|
|
3461
3462
|
return client;
|
|
3462
3463
|
}
|
|
3463
3464
|
function shardExists(projectName) {
|
|
3464
|
-
const safeName = projectName
|
|
3465
|
+
const safeName = safeShardName(projectName);
|
|
3465
3466
|
return existsSync10(path11.join(SHARDS_DIR, `${safeName}.db`));
|
|
3466
3467
|
}
|
|
3468
|
+
function safeShardName(projectName) {
|
|
3469
|
+
return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
3470
|
+
}
|
|
3467
3471
|
function listShards() {
|
|
3468
3472
|
if (!existsSync10(SHARDS_DIR)) return [];
|
|
3469
3473
|
return readdirSync3(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
@@ -3557,7 +3561,8 @@ async function ensureShardSchema(client) {
|
|
|
3557
3561
|
"ALTER TABLE memories ADD COLUMN token_cost REAL",
|
|
3558
3562
|
"ALTER TABLE memories ADD COLUMN audience TEXT",
|
|
3559
3563
|
"ALTER TABLE memories ADD COLUMN language_type TEXT",
|
|
3560
|
-
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
|
|
3564
|
+
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT",
|
|
3565
|
+
"ALTER TABLE memories ADD COLUMN deleted_at TEXT"
|
|
3561
3566
|
]) {
|
|
3562
3567
|
try {
|
|
3563
3568
|
await client.execute(col);
|
|
@@ -3653,9 +3658,32 @@ async function ensureShardSchema(client) {
|
|
|
3653
3658
|
}
|
|
3654
3659
|
}
|
|
3655
3660
|
async function getReadyShardClient(projectName) {
|
|
3656
|
-
const
|
|
3657
|
-
|
|
3658
|
-
|
|
3661
|
+
const safeName = safeShardName(projectName);
|
|
3662
|
+
let client = getShardClient(projectName);
|
|
3663
|
+
try {
|
|
3664
|
+
await ensureShardSchema(client);
|
|
3665
|
+
return client;
|
|
3666
|
+
} catch (err) {
|
|
3667
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
3668
|
+
if (!/SQLITE_NOTADB|file is not a database/i.test(message)) throw err;
|
|
3669
|
+
client.close();
|
|
3670
|
+
_shards.delete(safeName);
|
|
3671
|
+
_shardLastAccess.delete(safeName);
|
|
3672
|
+
const dbPath = path11.join(SHARDS_DIR, `${safeName}.db`);
|
|
3673
|
+
if (existsSync10(dbPath)) {
|
|
3674
|
+
const stat = statSync2(dbPath);
|
|
3675
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
3676
|
+
const archivedPath = path11.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
|
|
3677
|
+
renameSync3(dbPath, archivedPath);
|
|
3678
|
+
process.stderr.write(
|
|
3679
|
+
`[shard-manager] Archived unreadable shard ${safeName}: ${archivedPath} (${stat.size} bytes, mtime ${stat.mtime.toISOString()})
|
|
3680
|
+
`
|
|
3681
|
+
);
|
|
3682
|
+
}
|
|
3683
|
+
client = getShardClient(projectName);
|
|
3684
|
+
await ensureShardSchema(client);
|
|
3685
|
+
return client;
|
|
3686
|
+
}
|
|
3659
3687
|
}
|
|
3660
3688
|
function evictLRU() {
|
|
3661
3689
|
let oldest = null;
|
|
@@ -3876,7 +3904,7 @@ var init_platform_procedures = __esm({
|
|
|
3876
3904
|
title: "MCP tools \u2014 wiki, documents, and content",
|
|
3877
3905
|
domain: "tool-use",
|
|
3878
3906
|
priority: "p1",
|
|
3879
|
-
content: "
|
|
3907
|
+
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."
|
|
3880
3908
|
},
|
|
3881
3909
|
{
|
|
3882
3910
|
title: "MCP tools \u2014 system, operations, and admin",
|
|
@@ -3894,7 +3922,7 @@ var init_platform_procedures = __esm({
|
|
|
3894
3922
|
title: "MCP tools \u2014 advanced (triggers, skills, orchestration)",
|
|
3895
3923
|
domain: "tool-use",
|
|
3896
3924
|
priority: "p1",
|
|
3897
|
-
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
|
|
3925
|
+
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."
|
|
3898
3926
|
}
|
|
3899
3927
|
];
|
|
3900
3928
|
PLATFORM_PROCEDURE_TITLES = new Set(
|
|
@@ -3252,7 +3252,7 @@ __export(shard_manager_exports, {
|
|
|
3252
3252
|
shardExists: () => shardExists
|
|
3253
3253
|
});
|
|
3254
3254
|
import path9 from "path";
|
|
3255
|
-
import { existsSync as existsSync8, mkdirSync as mkdirSync4, readdirSync as readdirSync3 } from "fs";
|
|
3255
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync4, readdirSync as readdirSync3, renameSync as renameSync3, statSync as statSync2 } from "fs";
|
|
3256
3256
|
import { createClient as createClient2 } from "@libsql/client";
|
|
3257
3257
|
function initShardManager(encryptionKey) {
|
|
3258
3258
|
_encryptionKey = encryptionKey;
|
|
@@ -3274,7 +3274,7 @@ function getShardClient(projectName) {
|
|
|
3274
3274
|
if (!_encryptionKey) {
|
|
3275
3275
|
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
3276
3276
|
}
|
|
3277
|
-
const safeName = projectName
|
|
3277
|
+
const safeName = safeShardName(projectName);
|
|
3278
3278
|
if (!safeName || safeName === "unknown") {
|
|
3279
3279
|
throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
|
|
3280
3280
|
}
|
|
@@ -3296,9 +3296,12 @@ function getShardClient(projectName) {
|
|
|
3296
3296
|
return client;
|
|
3297
3297
|
}
|
|
3298
3298
|
function shardExists(projectName) {
|
|
3299
|
-
const safeName = projectName
|
|
3299
|
+
const safeName = safeShardName(projectName);
|
|
3300
3300
|
return existsSync8(path9.join(SHARDS_DIR, `${safeName}.db`));
|
|
3301
3301
|
}
|
|
3302
|
+
function safeShardName(projectName) {
|
|
3303
|
+
return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
3304
|
+
}
|
|
3302
3305
|
function listShards() {
|
|
3303
3306
|
if (!existsSync8(SHARDS_DIR)) return [];
|
|
3304
3307
|
return readdirSync3(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
@@ -3392,7 +3395,8 @@ async function ensureShardSchema(client) {
|
|
|
3392
3395
|
"ALTER TABLE memories ADD COLUMN token_cost REAL",
|
|
3393
3396
|
"ALTER TABLE memories ADD COLUMN audience TEXT",
|
|
3394
3397
|
"ALTER TABLE memories ADD COLUMN language_type TEXT",
|
|
3395
|
-
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
|
|
3398
|
+
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT",
|
|
3399
|
+
"ALTER TABLE memories ADD COLUMN deleted_at TEXT"
|
|
3396
3400
|
]) {
|
|
3397
3401
|
try {
|
|
3398
3402
|
await client.execute(col);
|
|
@@ -3488,9 +3492,32 @@ async function ensureShardSchema(client) {
|
|
|
3488
3492
|
}
|
|
3489
3493
|
}
|
|
3490
3494
|
async function getReadyShardClient(projectName) {
|
|
3491
|
-
const
|
|
3492
|
-
|
|
3493
|
-
|
|
3495
|
+
const safeName = safeShardName(projectName);
|
|
3496
|
+
let client = getShardClient(projectName);
|
|
3497
|
+
try {
|
|
3498
|
+
await ensureShardSchema(client);
|
|
3499
|
+
return client;
|
|
3500
|
+
} catch (err) {
|
|
3501
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
3502
|
+
if (!/SQLITE_NOTADB|file is not a database/i.test(message)) throw err;
|
|
3503
|
+
client.close();
|
|
3504
|
+
_shards.delete(safeName);
|
|
3505
|
+
_shardLastAccess.delete(safeName);
|
|
3506
|
+
const dbPath = path9.join(SHARDS_DIR, `${safeName}.db`);
|
|
3507
|
+
if (existsSync8(dbPath)) {
|
|
3508
|
+
const stat = statSync2(dbPath);
|
|
3509
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
3510
|
+
const archivedPath = path9.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
|
|
3511
|
+
renameSync3(dbPath, archivedPath);
|
|
3512
|
+
process.stderr.write(
|
|
3513
|
+
`[shard-manager] Archived unreadable shard ${safeName}: ${archivedPath} (${stat.size} bytes, mtime ${stat.mtime.toISOString()})
|
|
3514
|
+
`
|
|
3515
|
+
);
|
|
3516
|
+
}
|
|
3517
|
+
client = getShardClient(projectName);
|
|
3518
|
+
await ensureShardSchema(client);
|
|
3519
|
+
return client;
|
|
3520
|
+
}
|
|
3494
3521
|
}
|
|
3495
3522
|
function evictLRU() {
|
|
3496
3523
|
let oldest = null;
|
|
@@ -3711,7 +3738,7 @@ var init_platform_procedures = __esm({
|
|
|
3711
3738
|
title: "MCP tools \u2014 wiki, documents, and content",
|
|
3712
3739
|
domain: "tool-use",
|
|
3713
3740
|
priority: "p1",
|
|
3714
|
-
content: "
|
|
3741
|
+
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."
|
|
3715
3742
|
},
|
|
3716
3743
|
{
|
|
3717
3744
|
title: "MCP tools \u2014 system, operations, and admin",
|
|
@@ -3729,7 +3756,7 @@ var init_platform_procedures = __esm({
|
|
|
3729
3756
|
title: "MCP tools \u2014 advanced (triggers, skills, orchestration)",
|
|
3730
3757
|
domain: "tool-use",
|
|
3731
3758
|
priority: "p1",
|
|
3732
|
-
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
|
|
3759
|
+
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."
|
|
3733
3760
|
}
|
|
3734
3761
|
];
|
|
3735
3762
|
PLATFORM_PROCEDURE_TITLES = new Set(
|
|
@@ -4679,6 +4706,9 @@ function ensureDir() {
|
|
|
4679
4706
|
function identityPath(agentId) {
|
|
4680
4707
|
return path7.join(IDENTITY_DIR2, `${agentId}.md`);
|
|
4681
4708
|
}
|
|
4709
|
+
function sanitizeIdentityBody(body) {
|
|
4710
|
+
return body.replace(/<!--[\s\S]*?-->/g, "").trim();
|
|
4711
|
+
}
|
|
4682
4712
|
function parseFrontmatter(raw) {
|
|
4683
4713
|
const match = raw.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
4684
4714
|
if (!match) {
|
|
@@ -4691,11 +4721,11 @@ function parseFrontmatter(raw) {
|
|
|
4691
4721
|
created_by: "system",
|
|
4692
4722
|
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
4693
4723
|
},
|
|
4694
|
-
body: raw
|
|
4724
|
+
body: sanitizeIdentityBody(raw)
|
|
4695
4725
|
};
|
|
4696
4726
|
}
|
|
4697
4727
|
const yamlStr = match[1];
|
|
4698
|
-
const body = match[2]
|
|
4728
|
+
const body = sanitizeIdentityBody(match[2]);
|
|
4699
4729
|
const fm = {};
|
|
4700
4730
|
for (const line of yamlStr.split("\n")) {
|
|
4701
4731
|
const kv = line.match(/^(\w+):\s*(.+)$/);
|
|
@@ -4741,7 +4771,9 @@ function listIdentities() {
|
|
|
4741
4771
|
const summary = lines[0]?.trim().slice(0, 120) ?? identity.frontmatter.title;
|
|
4742
4772
|
results.push({
|
|
4743
4773
|
agentId,
|
|
4744
|
-
title
|
|
4774
|
+
// User-facing/team-facing title only. `frontmatter.role` is internal
|
|
4775
|
+
// routing metadata and must not leak as an external title.
|
|
4776
|
+
title: identity.frontmatter.title,
|
|
4745
4777
|
summary
|
|
4746
4778
|
});
|
|
4747
4779
|
}
|