@askexenow/exe-os 0.9.38 → 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/dist/bin/backfill-conversations.js +34 -7
- package/dist/bin/backfill-responses.js +34 -7
- package/dist/bin/backfill-vectors.js +34 -7
- package/dist/bin/cleanup-stale-review-tasks.js +35 -8
- package/dist/bin/cli.js +72 -42
- package/dist/bin/exe-agent.js +11 -3
- package/dist/bin/exe-assign.js +34 -7
- package/dist/bin/exe-boot.js +48 -18
- package/dist/bin/exe-call.js +132 -340
- package/dist/bin/exe-dispatch.js +34 -7
- package/dist/bin/exe-doctor.js +37 -10
- package/dist/bin/exe-export-behaviors.js +36 -9
- package/dist/bin/exe-forget.js +34 -7
- package/dist/bin/exe-gateway.js +40 -12
- package/dist/bin/exe-heartbeat.js +35 -8
- package/dist/bin/exe-kill.js +34 -7
- package/dist/bin/exe-launch-agent.js +285 -1079
- package/dist/bin/exe-new-employee.js +29 -10
- package/dist/bin/exe-pending-messages.js +34 -7
- package/dist/bin/exe-pending-notifications.js +34 -7
- package/dist/bin/exe-pending-reviews.js +34 -7
- package/dist/bin/exe-rename.js +41 -13
- package/dist/bin/exe-review.js +34 -7
- package/dist/bin/exe-search.js +36 -9
- package/dist/bin/exe-session-cleanup.js +36 -9
- package/dist/bin/exe-start-codex.js +36 -9
- package/dist/bin/exe-start-opencode.js +36 -9
- package/dist/bin/exe-status.js +35 -8
- package/dist/bin/exe-team.js +34 -7
- package/dist/bin/git-sweep.js +34 -7
- package/dist/bin/graph-backfill.js +34 -7
- package/dist/bin/graph-export.js +34 -7
- package/dist/bin/install.js +2 -1
- package/dist/bin/intercom-check.js +36 -9
- package/dist/bin/scan-tasks.js +34 -7
- package/dist/bin/setup.js +18 -17
- package/dist/bin/shard-migrate.js +34 -7
- package/dist/gateway/index.js +38 -10
- package/dist/hooks/bug-report-worker.js +38 -10
- package/dist/hooks/codex-stop-task-finalizer.js +36 -9
- package/dist/hooks/commit-complete.js +34 -7
- package/dist/hooks/error-recall.js +36 -9
- package/dist/hooks/ingest.js +36 -8
- package/dist/hooks/instructions-loaded.js +42 -10
- package/dist/hooks/notification.js +34 -7
- package/dist/hooks/post-compact.js +34 -7
- package/dist/hooks/post-tool-combined.js +37 -10
- package/dist/hooks/pre-compact.js +35 -8
- package/dist/hooks/pre-tool-use.js +36 -8
- package/dist/hooks/prompt-submit.js +41 -13
- package/dist/hooks/session-end.js +35 -8
- package/dist/hooks/session-start.js +47 -14
- package/dist/hooks/stop.js +35 -8
- package/dist/hooks/subagent-stop.js +34 -7
- package/dist/hooks/summary-worker.js +43 -16
- package/dist/index.js +36 -8
- package/dist/lib/consolidation.js +2 -1
- package/dist/lib/employee-templates.js +2 -1
- package/dist/lib/employees.js +2 -1
- package/dist/lib/exe-daemon.js +136 -36
- package/dist/lib/hybrid-search.js +36 -9
- package/dist/lib/identity.js +8 -3
- package/dist/lib/schedules.js +34 -7
- package/dist/lib/store.js +34 -7
- package/dist/mcp/server.js +133 -33
- package/dist/mcp/tools/create-task.js +10 -4
- package/dist/runtime/index.js +34 -7
- package/dist/tui/App.js +40 -11
- package/package.json +1 -1
|
@@ -302,7 +302,8 @@ function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
|
|
|
302
302
|
}
|
|
303
303
|
}
|
|
304
304
|
function addEmployee(employees, employee) {
|
|
305
|
-
const
|
|
305
|
+
const { systemPrompt: _legacyPrompt, ...rest } = employee;
|
|
306
|
+
const normalized = { ...rest, name: employee.name.toLowerCase() };
|
|
306
307
|
if (employees.some((e) => e.name.toLowerCase() === normalized.name)) {
|
|
307
308
|
throw new Error(`Employee '${normalized.name}' already exists`);
|
|
308
309
|
}
|
|
@@ -1034,6 +1035,9 @@ function ensureDir() {
|
|
|
1034
1035
|
function identityPath(agentId) {
|
|
1035
1036
|
return path8.join(IDENTITY_DIR2, `${agentId}.md`);
|
|
1036
1037
|
}
|
|
1038
|
+
function sanitizeIdentityBody(body) {
|
|
1039
|
+
return body.replace(/<!--[\s\S]*?-->/g, "").trim();
|
|
1040
|
+
}
|
|
1037
1041
|
function parseFrontmatter(raw) {
|
|
1038
1042
|
const match = raw.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
1039
1043
|
if (!match) {
|
|
@@ -1046,11 +1050,11 @@ function parseFrontmatter(raw) {
|
|
|
1046
1050
|
created_by: "system",
|
|
1047
1051
|
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1048
1052
|
},
|
|
1049
|
-
body: raw
|
|
1053
|
+
body: sanitizeIdentityBody(raw)
|
|
1050
1054
|
};
|
|
1051
1055
|
}
|
|
1052
1056
|
const yamlStr = match[1];
|
|
1053
|
-
const body = match[2]
|
|
1057
|
+
const body = sanitizeIdentityBody(match[2]);
|
|
1054
1058
|
const fm = {};
|
|
1055
1059
|
for (const line of yamlStr.split("\n")) {
|
|
1056
1060
|
const kv = line.match(/^(\w+):\s*(.+)$/);
|
|
@@ -1115,7 +1119,9 @@ function listIdentities() {
|
|
|
1115
1119
|
const summary = lines[0]?.trim().slice(0, 120) ?? identity.frontmatter.title;
|
|
1116
1120
|
results.push({
|
|
1117
1121
|
agentId,
|
|
1118
|
-
title
|
|
1122
|
+
// User-facing/team-facing title only. `frontmatter.role` is internal
|
|
1123
|
+
// routing metadata and must not leak as an external title.
|
|
1124
|
+
title: identity.frontmatter.title,
|
|
1119
1125
|
summary
|
|
1120
1126
|
});
|
|
1121
1127
|
}
|
|
@@ -3179,11 +3185,12 @@ async function main() {
|
|
|
3179
3185
|
);
|
|
3180
3186
|
process.exit(1);
|
|
3181
3187
|
}
|
|
3188
|
+
const rolePrompt = template ? personalizePrompt(template.systemPrompt, template.name, name) : buildCustomEmployeePrompt(name, "specialist");
|
|
3182
3189
|
if (template) {
|
|
3190
|
+
const { systemPrompt: _templatePrompt, ...templateMeta } = template;
|
|
3183
3191
|
newEmployee = {
|
|
3184
|
-
...
|
|
3192
|
+
...templateMeta,
|
|
3185
3193
|
name,
|
|
3186
|
-
systemPrompt: personalizePrompt(template.systemPrompt, template.name, name),
|
|
3187
3194
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3188
3195
|
templateName: effectiveTemplate,
|
|
3189
3196
|
templateVersion: TEMPLATE_VERSION
|
|
@@ -3192,7 +3199,6 @@ async function main() {
|
|
|
3192
3199
|
newEmployee = {
|
|
3193
3200
|
name,
|
|
3194
3201
|
role: "specialist",
|
|
3195
|
-
systemPrompt: buildCustomEmployeePrompt(name, "specialist"),
|
|
3196
3202
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3197
3203
|
templateName: "custom",
|
|
3198
3204
|
templateVersion: TEMPLATE_VERSION
|
|
@@ -3227,13 +3233,26 @@ async function main() {
|
|
|
3227
3233
|
};
|
|
3228
3234
|
const templateKey = roleMap[effectiveTemplate] ?? null;
|
|
3229
3235
|
const identityTemplate = templateKey ? getIdentityTemplate(templateKey) : null;
|
|
3236
|
+
const idPath = identityPath2(name);
|
|
3237
|
+
const dir = path12.dirname(idPath);
|
|
3238
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
3230
3239
|
if (identityTemplate) {
|
|
3231
|
-
const idPath = identityPath2(name);
|
|
3232
|
-
const dir = path12.dirname(idPath);
|
|
3233
|
-
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
3234
3240
|
const content = identityTemplate.replace(/^agent_id: \w+/m, `agent_id: ${name}`);
|
|
3235
3241
|
fs.writeFileSync(idPath, content, "utf-8");
|
|
3236
3242
|
console.log(`Identity doc written: ~/.exe-os/identity/${name}.md`);
|
|
3243
|
+
} else if (!fs.existsSync(idPath)) {
|
|
3244
|
+
const content = `---
|
|
3245
|
+
role: specialist
|
|
3246
|
+
title: Specialist
|
|
3247
|
+
agent_id: ${name}
|
|
3248
|
+
org_level: specialist
|
|
3249
|
+
created_by: exe-new-employee
|
|
3250
|
+
updated_at: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
3251
|
+
---
|
|
3252
|
+
|
|
3253
|
+
${rolePrompt}`;
|
|
3254
|
+
fs.writeFileSync(idPath, content, "utf-8");
|
|
3255
|
+
console.log(`Identity doc written: ~/.exe-os/identity/${name}.md`);
|
|
3237
3256
|
}
|
|
3238
3257
|
} catch {
|
|
3239
3258
|
}
|
|
@@ -3669,7 +3669,7 @@ __export(shard_manager_exports, {
|
|
|
3669
3669
|
shardExists: () => shardExists
|
|
3670
3670
|
});
|
|
3671
3671
|
import path13 from "path";
|
|
3672
|
-
import { existsSync as existsSync12, mkdirSync as mkdirSync5, readdirSync as readdirSync2 } from "fs";
|
|
3672
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync5, readdirSync as readdirSync2, renameSync as renameSync4, statSync as statSync2 } from "fs";
|
|
3673
3673
|
import { createClient as createClient2 } from "@libsql/client";
|
|
3674
3674
|
function initShardManager(encryptionKey) {
|
|
3675
3675
|
_encryptionKey = encryptionKey;
|
|
@@ -3691,7 +3691,7 @@ function getShardClient(projectName) {
|
|
|
3691
3691
|
if (!_encryptionKey) {
|
|
3692
3692
|
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
3693
3693
|
}
|
|
3694
|
-
const safeName = projectName
|
|
3694
|
+
const safeName = safeShardName(projectName);
|
|
3695
3695
|
if (!safeName || safeName === "unknown") {
|
|
3696
3696
|
throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
|
|
3697
3697
|
}
|
|
@@ -3713,9 +3713,12 @@ function getShardClient(projectName) {
|
|
|
3713
3713
|
return client;
|
|
3714
3714
|
}
|
|
3715
3715
|
function shardExists(projectName) {
|
|
3716
|
-
const safeName = projectName
|
|
3716
|
+
const safeName = safeShardName(projectName);
|
|
3717
3717
|
return existsSync12(path13.join(SHARDS_DIR, `${safeName}.db`));
|
|
3718
3718
|
}
|
|
3719
|
+
function safeShardName(projectName) {
|
|
3720
|
+
return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
3721
|
+
}
|
|
3719
3722
|
function listShards() {
|
|
3720
3723
|
if (!existsSync12(SHARDS_DIR)) return [];
|
|
3721
3724
|
return readdirSync2(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
@@ -3809,7 +3812,8 @@ async function ensureShardSchema(client) {
|
|
|
3809
3812
|
"ALTER TABLE memories ADD COLUMN token_cost REAL",
|
|
3810
3813
|
"ALTER TABLE memories ADD COLUMN audience TEXT",
|
|
3811
3814
|
"ALTER TABLE memories ADD COLUMN language_type TEXT",
|
|
3812
|
-
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
|
|
3815
|
+
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT",
|
|
3816
|
+
"ALTER TABLE memories ADD COLUMN deleted_at TEXT"
|
|
3813
3817
|
]) {
|
|
3814
3818
|
try {
|
|
3815
3819
|
await client.execute(col);
|
|
@@ -3905,9 +3909,32 @@ async function ensureShardSchema(client) {
|
|
|
3905
3909
|
}
|
|
3906
3910
|
}
|
|
3907
3911
|
async function getReadyShardClient(projectName) {
|
|
3908
|
-
const
|
|
3909
|
-
|
|
3910
|
-
|
|
3912
|
+
const safeName = safeShardName(projectName);
|
|
3913
|
+
let client = getShardClient(projectName);
|
|
3914
|
+
try {
|
|
3915
|
+
await ensureShardSchema(client);
|
|
3916
|
+
return client;
|
|
3917
|
+
} catch (err) {
|
|
3918
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
3919
|
+
if (!/SQLITE_NOTADB|file is not a database/i.test(message)) throw err;
|
|
3920
|
+
client.close();
|
|
3921
|
+
_shards.delete(safeName);
|
|
3922
|
+
_shardLastAccess.delete(safeName);
|
|
3923
|
+
const dbPath = path13.join(SHARDS_DIR, `${safeName}.db`);
|
|
3924
|
+
if (existsSync12(dbPath)) {
|
|
3925
|
+
const stat = statSync2(dbPath);
|
|
3926
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
3927
|
+
const archivedPath = path13.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
|
|
3928
|
+
renameSync4(dbPath, archivedPath);
|
|
3929
|
+
process.stderr.write(
|
|
3930
|
+
`[shard-manager] Archived unreadable shard ${safeName}: ${archivedPath} (${stat.size} bytes, mtime ${stat.mtime.toISOString()})
|
|
3931
|
+
`
|
|
3932
|
+
);
|
|
3933
|
+
}
|
|
3934
|
+
client = getShardClient(projectName);
|
|
3935
|
+
await ensureShardSchema(client);
|
|
3936
|
+
return client;
|
|
3937
|
+
}
|
|
3911
3938
|
}
|
|
3912
3939
|
function evictLRU() {
|
|
3913
3940
|
let oldest = null;
|
|
@@ -3735,7 +3735,7 @@ __export(shard_manager_exports, {
|
|
|
3735
3735
|
shardExists: () => shardExists
|
|
3736
3736
|
});
|
|
3737
3737
|
import path14 from "path";
|
|
3738
|
-
import { existsSync as existsSync13, mkdirSync as mkdirSync5, readdirSync as readdirSync3 } from "fs";
|
|
3738
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync5, readdirSync as readdirSync3, renameSync as renameSync4, statSync as statSync2 } from "fs";
|
|
3739
3739
|
import { createClient as createClient2 } from "@libsql/client";
|
|
3740
3740
|
function initShardManager(encryptionKey) {
|
|
3741
3741
|
_encryptionKey = encryptionKey;
|
|
@@ -3757,7 +3757,7 @@ function getShardClient(projectName) {
|
|
|
3757
3757
|
if (!_encryptionKey) {
|
|
3758
3758
|
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
3759
3759
|
}
|
|
3760
|
-
const safeName = projectName
|
|
3760
|
+
const safeName = safeShardName(projectName);
|
|
3761
3761
|
if (!safeName || safeName === "unknown") {
|
|
3762
3762
|
throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
|
|
3763
3763
|
}
|
|
@@ -3779,9 +3779,12 @@ function getShardClient(projectName) {
|
|
|
3779
3779
|
return client;
|
|
3780
3780
|
}
|
|
3781
3781
|
function shardExists(projectName) {
|
|
3782
|
-
const safeName = projectName
|
|
3782
|
+
const safeName = safeShardName(projectName);
|
|
3783
3783
|
return existsSync13(path14.join(SHARDS_DIR, `${safeName}.db`));
|
|
3784
3784
|
}
|
|
3785
|
+
function safeShardName(projectName) {
|
|
3786
|
+
return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
3787
|
+
}
|
|
3785
3788
|
function listShards() {
|
|
3786
3789
|
if (!existsSync13(SHARDS_DIR)) return [];
|
|
3787
3790
|
return readdirSync3(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
@@ -3875,7 +3878,8 @@ async function ensureShardSchema(client) {
|
|
|
3875
3878
|
"ALTER TABLE memories ADD COLUMN token_cost REAL",
|
|
3876
3879
|
"ALTER TABLE memories ADD COLUMN audience TEXT",
|
|
3877
3880
|
"ALTER TABLE memories ADD COLUMN language_type TEXT",
|
|
3878
|
-
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
|
|
3881
|
+
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT",
|
|
3882
|
+
"ALTER TABLE memories ADD COLUMN deleted_at TEXT"
|
|
3879
3883
|
]) {
|
|
3880
3884
|
try {
|
|
3881
3885
|
await client.execute(col);
|
|
@@ -3971,9 +3975,32 @@ async function ensureShardSchema(client) {
|
|
|
3971
3975
|
}
|
|
3972
3976
|
}
|
|
3973
3977
|
async function getReadyShardClient(projectName) {
|
|
3974
|
-
const
|
|
3975
|
-
|
|
3976
|
-
|
|
3978
|
+
const safeName = safeShardName(projectName);
|
|
3979
|
+
let client = getShardClient(projectName);
|
|
3980
|
+
try {
|
|
3981
|
+
await ensureShardSchema(client);
|
|
3982
|
+
return client;
|
|
3983
|
+
} catch (err) {
|
|
3984
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
3985
|
+
if (!/SQLITE_NOTADB|file is not a database/i.test(message)) throw err;
|
|
3986
|
+
client.close();
|
|
3987
|
+
_shards.delete(safeName);
|
|
3988
|
+
_shardLastAccess.delete(safeName);
|
|
3989
|
+
const dbPath = path14.join(SHARDS_DIR, `${safeName}.db`);
|
|
3990
|
+
if (existsSync13(dbPath)) {
|
|
3991
|
+
const stat = statSync2(dbPath);
|
|
3992
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
3993
|
+
const archivedPath = path14.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
|
|
3994
|
+
renameSync4(dbPath, archivedPath);
|
|
3995
|
+
process.stderr.write(
|
|
3996
|
+
`[shard-manager] Archived unreadable shard ${safeName}: ${archivedPath} (${stat.size} bytes, mtime ${stat.mtime.toISOString()})
|
|
3997
|
+
`
|
|
3998
|
+
);
|
|
3999
|
+
}
|
|
4000
|
+
client = getShardClient(projectName);
|
|
4001
|
+
await ensureShardSchema(client);
|
|
4002
|
+
return client;
|
|
4003
|
+
}
|
|
3977
4004
|
}
|
|
3978
4005
|
function evictLRU() {
|
|
3979
4006
|
let oldest = null;
|
|
@@ -3774,7 +3774,7 @@ __export(shard_manager_exports, {
|
|
|
3774
3774
|
shardExists: () => shardExists
|
|
3775
3775
|
});
|
|
3776
3776
|
import path15 from "path";
|
|
3777
|
-
import { existsSync as existsSync14, mkdirSync as mkdirSync5, readdirSync as readdirSync4 } from "fs";
|
|
3777
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync5, readdirSync as readdirSync4, renameSync as renameSync4, statSync as statSync2 } from "fs";
|
|
3778
3778
|
import { createClient as createClient2 } from "@libsql/client";
|
|
3779
3779
|
function initShardManager(encryptionKey) {
|
|
3780
3780
|
_encryptionKey = encryptionKey;
|
|
@@ -3796,7 +3796,7 @@ function getShardClient(projectName) {
|
|
|
3796
3796
|
if (!_encryptionKey) {
|
|
3797
3797
|
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
3798
3798
|
}
|
|
3799
|
-
const safeName = projectName
|
|
3799
|
+
const safeName = safeShardName(projectName);
|
|
3800
3800
|
if (!safeName || safeName === "unknown") {
|
|
3801
3801
|
throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
|
|
3802
3802
|
}
|
|
@@ -3818,9 +3818,12 @@ function getShardClient(projectName) {
|
|
|
3818
3818
|
return client;
|
|
3819
3819
|
}
|
|
3820
3820
|
function shardExists(projectName) {
|
|
3821
|
-
const safeName = projectName
|
|
3821
|
+
const safeName = safeShardName(projectName);
|
|
3822
3822
|
return existsSync14(path15.join(SHARDS_DIR, `${safeName}.db`));
|
|
3823
3823
|
}
|
|
3824
|
+
function safeShardName(projectName) {
|
|
3825
|
+
return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
3826
|
+
}
|
|
3824
3827
|
function listShards() {
|
|
3825
3828
|
if (!existsSync14(SHARDS_DIR)) return [];
|
|
3826
3829
|
return readdirSync4(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
@@ -3914,7 +3917,8 @@ async function ensureShardSchema(client) {
|
|
|
3914
3917
|
"ALTER TABLE memories ADD COLUMN token_cost REAL",
|
|
3915
3918
|
"ALTER TABLE memories ADD COLUMN audience TEXT",
|
|
3916
3919
|
"ALTER TABLE memories ADD COLUMN language_type TEXT",
|
|
3917
|
-
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
|
|
3920
|
+
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT",
|
|
3921
|
+
"ALTER TABLE memories ADD COLUMN deleted_at TEXT"
|
|
3918
3922
|
]) {
|
|
3919
3923
|
try {
|
|
3920
3924
|
await client.execute(col);
|
|
@@ -4010,9 +4014,32 @@ async function ensureShardSchema(client) {
|
|
|
4010
4014
|
}
|
|
4011
4015
|
}
|
|
4012
4016
|
async function getReadyShardClient(projectName) {
|
|
4013
|
-
const
|
|
4014
|
-
|
|
4015
|
-
|
|
4017
|
+
const safeName = safeShardName(projectName);
|
|
4018
|
+
let client = getShardClient(projectName);
|
|
4019
|
+
try {
|
|
4020
|
+
await ensureShardSchema(client);
|
|
4021
|
+
return client;
|
|
4022
|
+
} catch (err) {
|
|
4023
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
4024
|
+
if (!/SQLITE_NOTADB|file is not a database/i.test(message)) throw err;
|
|
4025
|
+
client.close();
|
|
4026
|
+
_shards.delete(safeName);
|
|
4027
|
+
_shardLastAccess.delete(safeName);
|
|
4028
|
+
const dbPath = path15.join(SHARDS_DIR, `${safeName}.db`);
|
|
4029
|
+
if (existsSync14(dbPath)) {
|
|
4030
|
+
const stat = statSync2(dbPath);
|
|
4031
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
4032
|
+
const archivedPath = path15.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
|
|
4033
|
+
renameSync4(dbPath, archivedPath);
|
|
4034
|
+
process.stderr.write(
|
|
4035
|
+
`[shard-manager] Archived unreadable shard ${safeName}: ${archivedPath} (${stat.size} bytes, mtime ${stat.mtime.toISOString()})
|
|
4036
|
+
`
|
|
4037
|
+
);
|
|
4038
|
+
}
|
|
4039
|
+
client = getShardClient(projectName);
|
|
4040
|
+
await ensureShardSchema(client);
|
|
4041
|
+
return client;
|
|
4042
|
+
}
|
|
4016
4043
|
}
|
|
4017
4044
|
function evictLRU() {
|
|
4018
4045
|
let oldest = null;
|
package/dist/bin/exe-rename.js
CHANGED
|
@@ -3354,7 +3354,7 @@ __export(shard_manager_exports, {
|
|
|
3354
3354
|
shardExists: () => shardExists
|
|
3355
3355
|
});
|
|
3356
3356
|
import path7 from "path";
|
|
3357
|
-
import { existsSync as existsSync7, mkdirSync as mkdirSync2, readdirSync } from "fs";
|
|
3357
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync2, readdirSync, renameSync as renameSync3, statSync as statSync2 } from "fs";
|
|
3358
3358
|
import { createClient as createClient2 } from "@libsql/client";
|
|
3359
3359
|
function initShardManager(encryptionKey) {
|
|
3360
3360
|
_encryptionKey = encryptionKey;
|
|
@@ -3376,7 +3376,7 @@ function getShardClient(projectName) {
|
|
|
3376
3376
|
if (!_encryptionKey) {
|
|
3377
3377
|
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
3378
3378
|
}
|
|
3379
|
-
const safeName = projectName
|
|
3379
|
+
const safeName = safeShardName(projectName);
|
|
3380
3380
|
if (!safeName || safeName === "unknown") {
|
|
3381
3381
|
throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
|
|
3382
3382
|
}
|
|
@@ -3398,9 +3398,12 @@ function getShardClient(projectName) {
|
|
|
3398
3398
|
return client;
|
|
3399
3399
|
}
|
|
3400
3400
|
function shardExists(projectName) {
|
|
3401
|
-
const safeName = projectName
|
|
3401
|
+
const safeName = safeShardName(projectName);
|
|
3402
3402
|
return existsSync7(path7.join(SHARDS_DIR, `${safeName}.db`));
|
|
3403
3403
|
}
|
|
3404
|
+
function safeShardName(projectName) {
|
|
3405
|
+
return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
3406
|
+
}
|
|
3404
3407
|
function listShards() {
|
|
3405
3408
|
if (!existsSync7(SHARDS_DIR)) return [];
|
|
3406
3409
|
return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
@@ -3494,7 +3497,8 @@ async function ensureShardSchema(client) {
|
|
|
3494
3497
|
"ALTER TABLE memories ADD COLUMN token_cost REAL",
|
|
3495
3498
|
"ALTER TABLE memories ADD COLUMN audience TEXT",
|
|
3496
3499
|
"ALTER TABLE memories ADD COLUMN language_type TEXT",
|
|
3497
|
-
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
|
|
3500
|
+
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT",
|
|
3501
|
+
"ALTER TABLE memories ADD COLUMN deleted_at TEXT"
|
|
3498
3502
|
]) {
|
|
3499
3503
|
try {
|
|
3500
3504
|
await client.execute(col);
|
|
@@ -3590,9 +3594,32 @@ async function ensureShardSchema(client) {
|
|
|
3590
3594
|
}
|
|
3591
3595
|
}
|
|
3592
3596
|
async function getReadyShardClient(projectName) {
|
|
3593
|
-
const
|
|
3594
|
-
|
|
3595
|
-
|
|
3597
|
+
const safeName = safeShardName(projectName);
|
|
3598
|
+
let client = getShardClient(projectName);
|
|
3599
|
+
try {
|
|
3600
|
+
await ensureShardSchema(client);
|
|
3601
|
+
return client;
|
|
3602
|
+
} catch (err) {
|
|
3603
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
3604
|
+
if (!/SQLITE_NOTADB|file is not a database/i.test(message)) throw err;
|
|
3605
|
+
client.close();
|
|
3606
|
+
_shards.delete(safeName);
|
|
3607
|
+
_shardLastAccess.delete(safeName);
|
|
3608
|
+
const dbPath = path7.join(SHARDS_DIR, `${safeName}.db`);
|
|
3609
|
+
if (existsSync7(dbPath)) {
|
|
3610
|
+
const stat = statSync2(dbPath);
|
|
3611
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
3612
|
+
const archivedPath = path7.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
|
|
3613
|
+
renameSync3(dbPath, archivedPath);
|
|
3614
|
+
process.stderr.write(
|
|
3615
|
+
`[shard-manager] Archived unreadable shard ${safeName}: ${archivedPath} (${stat.size} bytes, mtime ${stat.mtime.toISOString()})
|
|
3616
|
+
`
|
|
3617
|
+
);
|
|
3618
|
+
}
|
|
3619
|
+
client = getShardClient(projectName);
|
|
3620
|
+
await ensureShardSchema(client);
|
|
3621
|
+
return client;
|
|
3622
|
+
}
|
|
3596
3623
|
}
|
|
3597
3624
|
function evictLRU() {
|
|
3598
3625
|
let oldest = null;
|
|
@@ -4277,7 +4304,7 @@ var init_store = __esm({
|
|
|
4277
4304
|
|
|
4278
4305
|
// src/bin/exe-rename.ts
|
|
4279
4306
|
init_employees();
|
|
4280
|
-
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, renameSync as
|
|
4307
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, renameSync as renameSync4, unlinkSync as unlinkSync3, existsSync as existsSync8 } from "fs";
|
|
4281
4308
|
import { execSync as execSync3 } from "child_process";
|
|
4282
4309
|
import path8 from "path";
|
|
4283
4310
|
import { homedir } from "os";
|
|
@@ -4331,7 +4358,8 @@ async function renameEmployee(oldName, newName, opts = {}) {
|
|
|
4331
4358
|
const originalName = employee.name;
|
|
4332
4359
|
const originalPrompt = employee.systemPrompt;
|
|
4333
4360
|
employee.name = newName;
|
|
4334
|
-
employee.systemPrompt = personalizePrompt(originalPrompt, rosterOldName, newName);
|
|
4361
|
+
if (originalPrompt) employee.systemPrompt = personalizePrompt(originalPrompt, rosterOldName, newName);
|
|
4362
|
+
else delete employee.systemPrompt;
|
|
4335
4363
|
await saveEmployees(employees, rosterPath);
|
|
4336
4364
|
rollbackStack.push({
|
|
4337
4365
|
description: "restore roster",
|
|
@@ -4349,14 +4377,14 @@ async function renameEmployee(oldName, newName, opts = {}) {
|
|
|
4349
4377
|
/^(agent_id:\s*)\S+/m,
|
|
4350
4378
|
`$1${newName}`
|
|
4351
4379
|
);
|
|
4352
|
-
|
|
4380
|
+
renameSync4(oldIdentityPath, newIdentityPath);
|
|
4353
4381
|
writeFileSync3(newIdentityPath, updatedContent, "utf-8");
|
|
4354
4382
|
rollbackStack.push({
|
|
4355
4383
|
description: "restore identity file",
|
|
4356
4384
|
undo: () => {
|
|
4357
4385
|
if (existsSync8(newIdentityPath)) {
|
|
4358
4386
|
writeFileSync3(newIdentityPath, content, "utf-8");
|
|
4359
|
-
|
|
4387
|
+
renameSync4(newIdentityPath, oldIdentityPath);
|
|
4360
4388
|
}
|
|
4361
4389
|
}
|
|
4362
4390
|
});
|
|
@@ -4365,12 +4393,12 @@ async function renameEmployee(oldName, newName, opts = {}) {
|
|
|
4365
4393
|
const newAgentPath = path8.join(agentsDir, `${newName}.md`);
|
|
4366
4394
|
if (existsSync8(oldAgentPath)) {
|
|
4367
4395
|
const agentContent = readFileSync5(oldAgentPath, "utf-8");
|
|
4368
|
-
|
|
4396
|
+
renameSync4(oldAgentPath, newAgentPath);
|
|
4369
4397
|
rollbackStack.push({
|
|
4370
4398
|
description: "restore agent file",
|
|
4371
4399
|
undo: () => {
|
|
4372
4400
|
if (existsSync8(newAgentPath)) {
|
|
4373
|
-
|
|
4401
|
+
renameSync4(newAgentPath, oldAgentPath);
|
|
4374
4402
|
writeFileSync3(oldAgentPath, agentContent, "utf-8");
|
|
4375
4403
|
}
|
|
4376
4404
|
}
|
package/dist/bin/exe-review.js
CHANGED
|
@@ -3264,7 +3264,7 @@ __export(shard_manager_exports, {
|
|
|
3264
3264
|
shardExists: () => shardExists
|
|
3265
3265
|
});
|
|
3266
3266
|
import path7 from "path";
|
|
3267
|
-
import { existsSync as existsSync7, mkdirSync as mkdirSync2, readdirSync } from "fs";
|
|
3267
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync2, readdirSync, renameSync as renameSync3, statSync as statSync2 } from "fs";
|
|
3268
3268
|
import { createClient as createClient2 } from "@libsql/client";
|
|
3269
3269
|
function initShardManager(encryptionKey) {
|
|
3270
3270
|
_encryptionKey = encryptionKey;
|
|
@@ -3286,7 +3286,7 @@ function getShardClient(projectName) {
|
|
|
3286
3286
|
if (!_encryptionKey) {
|
|
3287
3287
|
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
3288
3288
|
}
|
|
3289
|
-
const safeName = projectName
|
|
3289
|
+
const safeName = safeShardName(projectName);
|
|
3290
3290
|
if (!safeName || safeName === "unknown") {
|
|
3291
3291
|
throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
|
|
3292
3292
|
}
|
|
@@ -3308,9 +3308,12 @@ function getShardClient(projectName) {
|
|
|
3308
3308
|
return client;
|
|
3309
3309
|
}
|
|
3310
3310
|
function shardExists(projectName) {
|
|
3311
|
-
const safeName = projectName
|
|
3311
|
+
const safeName = safeShardName(projectName);
|
|
3312
3312
|
return existsSync7(path7.join(SHARDS_DIR, `${safeName}.db`));
|
|
3313
3313
|
}
|
|
3314
|
+
function safeShardName(projectName) {
|
|
3315
|
+
return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
3316
|
+
}
|
|
3314
3317
|
function listShards() {
|
|
3315
3318
|
if (!existsSync7(SHARDS_DIR)) return [];
|
|
3316
3319
|
return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
@@ -3404,7 +3407,8 @@ async function ensureShardSchema(client) {
|
|
|
3404
3407
|
"ALTER TABLE memories ADD COLUMN token_cost REAL",
|
|
3405
3408
|
"ALTER TABLE memories ADD COLUMN audience TEXT",
|
|
3406
3409
|
"ALTER TABLE memories ADD COLUMN language_type TEXT",
|
|
3407
|
-
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
|
|
3410
|
+
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT",
|
|
3411
|
+
"ALTER TABLE memories ADD COLUMN deleted_at TEXT"
|
|
3408
3412
|
]) {
|
|
3409
3413
|
try {
|
|
3410
3414
|
await client.execute(col);
|
|
@@ -3500,9 +3504,32 @@ async function ensureShardSchema(client) {
|
|
|
3500
3504
|
}
|
|
3501
3505
|
}
|
|
3502
3506
|
async function getReadyShardClient(projectName) {
|
|
3503
|
-
const
|
|
3504
|
-
|
|
3505
|
-
|
|
3507
|
+
const safeName = safeShardName(projectName);
|
|
3508
|
+
let client = getShardClient(projectName);
|
|
3509
|
+
try {
|
|
3510
|
+
await ensureShardSchema(client);
|
|
3511
|
+
return client;
|
|
3512
|
+
} catch (err) {
|
|
3513
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
3514
|
+
if (!/SQLITE_NOTADB|file is not a database/i.test(message)) throw err;
|
|
3515
|
+
client.close();
|
|
3516
|
+
_shards.delete(safeName);
|
|
3517
|
+
_shardLastAccess.delete(safeName);
|
|
3518
|
+
const dbPath = path7.join(SHARDS_DIR, `${safeName}.db`);
|
|
3519
|
+
if (existsSync7(dbPath)) {
|
|
3520
|
+
const stat = statSync2(dbPath);
|
|
3521
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
3522
|
+
const archivedPath = path7.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
|
|
3523
|
+
renameSync3(dbPath, archivedPath);
|
|
3524
|
+
process.stderr.write(
|
|
3525
|
+
`[shard-manager] Archived unreadable shard ${safeName}: ${archivedPath} (${stat.size} bytes, mtime ${stat.mtime.toISOString()})
|
|
3526
|
+
`
|
|
3527
|
+
);
|
|
3528
|
+
}
|
|
3529
|
+
client = getShardClient(projectName);
|
|
3530
|
+
await ensureShardSchema(client);
|
|
3531
|
+
return client;
|
|
3532
|
+
}
|
|
3506
3533
|
}
|
|
3507
3534
|
function evictLRU() {
|
|
3508
3535
|
let oldest = null;
|
package/dist/bin/exe-search.js
CHANGED
|
@@ -3239,7 +3239,7 @@ __export(shard_manager_exports, {
|
|
|
3239
3239
|
shardExists: () => shardExists
|
|
3240
3240
|
});
|
|
3241
3241
|
import path7 from "path";
|
|
3242
|
-
import { existsSync as existsSync7, mkdirSync as mkdirSync2, readdirSync } from "fs";
|
|
3242
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync2, readdirSync, renameSync as renameSync3, statSync as statSync2 } from "fs";
|
|
3243
3243
|
import { createClient as createClient2 } from "@libsql/client";
|
|
3244
3244
|
function initShardManager(encryptionKey) {
|
|
3245
3245
|
_encryptionKey = encryptionKey;
|
|
@@ -3261,7 +3261,7 @@ function getShardClient(projectName) {
|
|
|
3261
3261
|
if (!_encryptionKey) {
|
|
3262
3262
|
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
3263
3263
|
}
|
|
3264
|
-
const safeName = projectName
|
|
3264
|
+
const safeName = safeShardName(projectName);
|
|
3265
3265
|
if (!safeName || safeName === "unknown") {
|
|
3266
3266
|
throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
|
|
3267
3267
|
}
|
|
@@ -3283,9 +3283,12 @@ function getShardClient(projectName) {
|
|
|
3283
3283
|
return client;
|
|
3284
3284
|
}
|
|
3285
3285
|
function shardExists(projectName) {
|
|
3286
|
-
const safeName = projectName
|
|
3286
|
+
const safeName = safeShardName(projectName);
|
|
3287
3287
|
return existsSync7(path7.join(SHARDS_DIR, `${safeName}.db`));
|
|
3288
3288
|
}
|
|
3289
|
+
function safeShardName(projectName) {
|
|
3290
|
+
return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
3291
|
+
}
|
|
3289
3292
|
function listShards() {
|
|
3290
3293
|
if (!existsSync7(SHARDS_DIR)) return [];
|
|
3291
3294
|
return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
@@ -3379,7 +3382,8 @@ async function ensureShardSchema(client) {
|
|
|
3379
3382
|
"ALTER TABLE memories ADD COLUMN token_cost REAL",
|
|
3380
3383
|
"ALTER TABLE memories ADD COLUMN audience TEXT",
|
|
3381
3384
|
"ALTER TABLE memories ADD COLUMN language_type TEXT",
|
|
3382
|
-
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
|
|
3385
|
+
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT",
|
|
3386
|
+
"ALTER TABLE memories ADD COLUMN deleted_at TEXT"
|
|
3383
3387
|
]) {
|
|
3384
3388
|
try {
|
|
3385
3389
|
await client.execute(col);
|
|
@@ -3475,9 +3479,32 @@ async function ensureShardSchema(client) {
|
|
|
3475
3479
|
}
|
|
3476
3480
|
}
|
|
3477
3481
|
async function getReadyShardClient(projectName) {
|
|
3478
|
-
const
|
|
3479
|
-
|
|
3480
|
-
|
|
3482
|
+
const safeName = safeShardName(projectName);
|
|
3483
|
+
let client = getShardClient(projectName);
|
|
3484
|
+
try {
|
|
3485
|
+
await ensureShardSchema(client);
|
|
3486
|
+
return client;
|
|
3487
|
+
} catch (err) {
|
|
3488
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
3489
|
+
if (!/SQLITE_NOTADB|file is not a database/i.test(message)) throw err;
|
|
3490
|
+
client.close();
|
|
3491
|
+
_shards.delete(safeName);
|
|
3492
|
+
_shardLastAccess.delete(safeName);
|
|
3493
|
+
const dbPath = path7.join(SHARDS_DIR, `${safeName}.db`);
|
|
3494
|
+
if (existsSync7(dbPath)) {
|
|
3495
|
+
const stat = statSync2(dbPath);
|
|
3496
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
3497
|
+
const archivedPath = path7.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
|
|
3498
|
+
renameSync3(dbPath, archivedPath);
|
|
3499
|
+
process.stderr.write(
|
|
3500
|
+
`[shard-manager] Archived unreadable shard ${safeName}: ${archivedPath} (${stat.size} bytes, mtime ${stat.mtime.toISOString()})
|
|
3501
|
+
`
|
|
3502
|
+
);
|
|
3503
|
+
}
|
|
3504
|
+
client = getShardClient(projectName);
|
|
3505
|
+
await ensureShardSchema(client);
|
|
3506
|
+
return client;
|
|
3507
|
+
}
|
|
3481
3508
|
}
|
|
3482
3509
|
function evictLRU() {
|
|
3483
3510
|
let oldest = null;
|
|
@@ -4752,7 +4779,7 @@ __export(file_grep_exports, {
|
|
|
4752
4779
|
grepProjectFiles: () => grepProjectFiles
|
|
4753
4780
|
});
|
|
4754
4781
|
import { execSync as execSync4 } from "child_process";
|
|
4755
|
-
import { readFileSync as readFileSync5, readdirSync as readdirSync2, statSync as
|
|
4782
|
+
import { readFileSync as readFileSync5, readdirSync as readdirSync2, statSync as statSync3, existsSync as existsSync9 } from "fs";
|
|
4756
4783
|
import path10 from "path";
|
|
4757
4784
|
import crypto2 from "crypto";
|
|
4758
4785
|
function hasRipgrep() {
|
|
@@ -4869,7 +4896,7 @@ function grepWithNodeFs(pattern, projectRoot, patterns) {
|
|
|
4869
4896
|
for (const filePath of files.slice(0, MAX_FILES)) {
|
|
4870
4897
|
const absPath = path10.join(projectRoot, filePath);
|
|
4871
4898
|
try {
|
|
4872
|
-
const stat =
|
|
4899
|
+
const stat = statSync3(absPath);
|
|
4873
4900
|
if (stat.size > MAX_FILE_SIZE) continue;
|
|
4874
4901
|
const content = readFileSync5(absPath, "utf8");
|
|
4875
4902
|
const lines = content.split("\n");
|