@askexenow/exe-os 0.8.37 → 0.8.38
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 +66 -60
- package/dist/bin/backfill-responses.js +7 -8
- package/dist/bin/backfill-vectors.js +1 -8
- package/dist/bin/cleanup-stale-review-tasks.js +1 -8
- package/dist/bin/cli.js +520 -325
- package/dist/bin/exe-assign.js +7 -8
- package/dist/bin/exe-boot.js +54 -21
- package/dist/bin/exe-call.js +9 -4
- package/dist/bin/exe-cloud.js +37 -3
- package/dist/bin/exe-doctor.js +1 -8
- package/dist/bin/exe-export-behaviors.js +4 -11
- package/dist/bin/exe-forget.js +1 -8
- package/dist/bin/exe-gateway.js +72 -30
- package/dist/bin/exe-heartbeat.js +4 -11
- package/dist/bin/exe-kill.js +1 -8
- package/dist/bin/exe-launch-agent.js +51 -14
- package/dist/bin/exe-link.js +13 -3
- package/dist/bin/exe-new-employee.js +35 -10
- package/dist/bin/exe-pending-messages.js +1 -8
- package/dist/bin/exe-pending-notifications.js +1 -8
- package/dist/bin/exe-pending-reviews.js +4 -11
- package/dist/bin/exe-review.js +7 -8
- package/dist/bin/exe-search.js +10 -11
- package/dist/bin/exe-session-cleanup.js +11 -12
- package/dist/bin/exe-status.js +1 -8
- package/dist/bin/exe-team.js +1 -8
- package/dist/bin/git-sweep.js +7 -8
- package/dist/bin/graph-backfill.js +1 -8
- package/dist/bin/graph-export.js +1 -8
- package/dist/bin/install.js +9 -0
- package/dist/bin/scan-tasks.js +7 -8
- package/dist/bin/setup.js +396 -245
- package/dist/bin/shard-migrate.js +1 -8
- package/dist/bin/wiki-sync.js +1 -8
- package/dist/gateway/index.js +30 -30
- package/dist/hooks/bug-report-worker.js +4 -11
- package/dist/hooks/commit-complete.js +7 -8
- package/dist/hooks/error-recall.js +11 -12
- package/dist/hooks/ingest-worker.js +24 -9
- package/dist/hooks/instructions-loaded.js +7 -8
- package/dist/hooks/notification.js +7 -8
- package/dist/hooks/post-compact.js +7 -8
- package/dist/hooks/pre-compact.js +7 -8
- package/dist/hooks/pre-tool-use.js +7 -8
- package/dist/hooks/prompt-ingest-worker.js +19 -4
- package/dist/hooks/prompt-submit.js +14 -9
- package/dist/hooks/response-ingest-worker.js +20 -5
- package/dist/hooks/session-end.js +11 -12
- package/dist/hooks/session-start.js +11 -12
- package/dist/hooks/stop.js +7 -8
- package/dist/hooks/subagent-stop.js +7 -8
- package/dist/hooks/summary-worker.js +24 -9
- package/dist/index.js +11 -5
- package/dist/lib/cloud-sync.js +19 -2
- package/dist/lib/employee-templates.js +5 -0
- package/dist/lib/exe-daemon.js +24 -8
- package/dist/lib/hybrid-search.js +10 -11
- package/dist/lib/identity-templates.js +16 -7
- package/dist/lib/license.js +43 -2
- package/dist/lib/schedules.js +1 -8
- package/dist/lib/store.js +7 -8
- package/dist/mcp/server.js +184 -113
- package/dist/mcp/tools/list-tasks.js +35 -27
- package/dist/runtime/index.js +7 -2
- package/dist/tui/App.js +44 -5
- package/package.json +4 -2
package/dist/mcp/server.js
CHANGED
|
@@ -1642,7 +1642,7 @@ __export(shard_manager_exports, {
|
|
|
1642
1642
|
shardExists: () => shardExists
|
|
1643
1643
|
});
|
|
1644
1644
|
import path4 from "path";
|
|
1645
|
-
import { existsSync as existsSync4, mkdirSync } from "fs";
|
|
1645
|
+
import { existsSync as existsSync4, mkdirSync, readdirSync } from "fs";
|
|
1646
1646
|
import { createClient as createClient2 } from "@libsql/client";
|
|
1647
1647
|
function initShardManager(encryptionKey) {
|
|
1648
1648
|
_encryptionKey = encryptionKey;
|
|
@@ -1681,8 +1681,7 @@ function shardExists(projectName) {
|
|
|
1681
1681
|
}
|
|
1682
1682
|
function listShards() {
|
|
1683
1683
|
if (!existsSync4(SHARDS_DIR)) return [];
|
|
1684
|
-
|
|
1685
|
-
return readdirSync8(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
1684
|
+
return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
1686
1685
|
}
|
|
1687
1686
|
async function ensureShardSchema(client) {
|
|
1688
1687
|
await client.execute("PRAGMA journal_mode = WAL");
|
|
@@ -1965,6 +1964,12 @@ async function writeMemory(record) {
|
|
|
1965
1964
|
supersedes_id: record.supersedes_id ?? null
|
|
1966
1965
|
};
|
|
1967
1966
|
_pendingRecords.push(dbRow);
|
|
1967
|
+
const MAX_PENDING = 1e3;
|
|
1968
|
+
if (_pendingRecords.length > MAX_PENDING) {
|
|
1969
|
+
const dropped = _pendingRecords.length - MAX_PENDING;
|
|
1970
|
+
_pendingRecords = _pendingRecords.slice(-MAX_PENDING);
|
|
1971
|
+
console.warn(`[store] Dropped ${dropped} oldest pending records (overflow)`);
|
|
1972
|
+
}
|
|
1968
1973
|
if (_flushTimer === null) {
|
|
1969
1974
|
_flushTimer = setInterval(() => {
|
|
1970
1975
|
void flushBatch();
|
|
@@ -2459,7 +2464,7 @@ __export(file_grep_exports, {
|
|
|
2459
2464
|
grepProjectFiles: () => grepProjectFiles
|
|
2460
2465
|
});
|
|
2461
2466
|
import { execSync as execSync2 } from "child_process";
|
|
2462
|
-
import { readFileSync as readFileSync3, readdirSync, statSync as statSync2, existsSync as existsSync5 } from "fs";
|
|
2467
|
+
import { readFileSync as readFileSync3, readdirSync as readdirSync2, statSync as statSync2, existsSync as existsSync5 } from "fs";
|
|
2463
2468
|
import path6 from "path";
|
|
2464
2469
|
import crypto2 from "crypto";
|
|
2465
2470
|
function hasRipgrep() {
|
|
@@ -2604,7 +2609,7 @@ function collectFiles(root, patterns) {
|
|
|
2604
2609
|
const basename = path6.basename(dir);
|
|
2605
2610
|
if (EXCLUDE_DIRS.includes(basename)) return;
|
|
2606
2611
|
try {
|
|
2607
|
-
const entries =
|
|
2612
|
+
const entries = readdirSync2(dir, { withFileTypes: true });
|
|
2608
2613
|
for (const entry of entries) {
|
|
2609
2614
|
if (files.length >= MAX_FILES) return;
|
|
2610
2615
|
const rel = path6.join(relative, entry.name);
|
|
@@ -2836,7 +2841,7 @@ __export(active_agent_exports, {
|
|
|
2836
2841
|
getAllActiveAgents: () => getAllActiveAgents,
|
|
2837
2842
|
writeActiveAgent: () => writeActiveAgent
|
|
2838
2843
|
});
|
|
2839
|
-
import { readFileSync as readFileSync4, writeFileSync, mkdirSync as mkdirSync2, unlinkSync as unlinkSync2, readdirSync as
|
|
2844
|
+
import { readFileSync as readFileSync4, writeFileSync, mkdirSync as mkdirSync2, unlinkSync as unlinkSync2, readdirSync as readdirSync3 } from "fs";
|
|
2840
2845
|
import { execSync as execSync4 } from "child_process";
|
|
2841
2846
|
import path8 from "path";
|
|
2842
2847
|
function getMarkerPath() {
|
|
@@ -2907,7 +2912,7 @@ function getActiveAgent() {
|
|
|
2907
2912
|
}
|
|
2908
2913
|
function getAllActiveAgents() {
|
|
2909
2914
|
try {
|
|
2910
|
-
const files =
|
|
2915
|
+
const files = readdirSync3(CACHE_DIR);
|
|
2911
2916
|
const sessions = [];
|
|
2912
2917
|
for (const file of files) {
|
|
2913
2918
|
if (!file.startsWith("active-agent-") || !file.endsWith(".json")) continue;
|
|
@@ -3108,6 +3113,8 @@ __export(license_exports, {
|
|
|
3108
3113
|
loadLicense: () => loadLicense,
|
|
3109
3114
|
mirrorLicenseKey: () => mirrorLicenseKey,
|
|
3110
3115
|
saveLicense: () => saveLicense,
|
|
3116
|
+
startLicenseRevalidation: () => startLicenseRevalidation,
|
|
3117
|
+
stopLicenseRevalidation: () => stopLicenseRevalidation,
|
|
3111
3118
|
validateLicense: () => validateLicense
|
|
3112
3119
|
});
|
|
3113
3120
|
import { readFileSync as readFileSync6, writeFileSync as writeFileSync2, existsSync as existsSync8, mkdirSync as mkdirSync3 } from "fs";
|
|
@@ -3232,14 +3239,23 @@ async function validateLicense(apiKey, deviceId) {
|
|
|
3232
3239
|
} catch {
|
|
3233
3240
|
const cached = await getCachedLicense();
|
|
3234
3241
|
if (cached) return cached;
|
|
3235
|
-
return FREE_LICENSE;
|
|
3242
|
+
return { ...FREE_LICENSE, valid: false, error: "offline" };
|
|
3243
|
+
}
|
|
3244
|
+
}
|
|
3245
|
+
function getCacheAgeMs() {
|
|
3246
|
+
try {
|
|
3247
|
+
const { statSync: statSync4 } = __require("fs");
|
|
3248
|
+
const s = statSync4(CACHE_PATH);
|
|
3249
|
+
return Date.now() - s.mtimeMs;
|
|
3250
|
+
} catch {
|
|
3251
|
+
return Infinity;
|
|
3236
3252
|
}
|
|
3237
3253
|
}
|
|
3238
3254
|
async function checkLicense() {
|
|
3239
3255
|
const key = loadLicense();
|
|
3240
3256
|
if (!key) return FREE_LICENSE;
|
|
3241
3257
|
const cached = await getCachedLicense();
|
|
3242
|
-
if (cached) return cached;
|
|
3258
|
+
if (cached && getCacheAgeMs() < CACHE_MAX_AGE_MS) return cached;
|
|
3243
3259
|
const deviceId = loadDeviceId();
|
|
3244
3260
|
return validateLicense(key, deviceId);
|
|
3245
3261
|
}
|
|
@@ -3360,7 +3376,28 @@ async function assertVpsLicense(opts) {
|
|
|
3360
3376
|
`License validation unreachable for more than ${graceDays} days. Restore network connectivity to https://askexe.com/cloud and retry. This VPS image refuses to boot after the offline grace window.`
|
|
3361
3377
|
);
|
|
3362
3378
|
}
|
|
3363
|
-
|
|
3379
|
+
function startLicenseRevalidation(intervalMs = 36e5) {
|
|
3380
|
+
if (_revalTimer) return;
|
|
3381
|
+
_revalTimer = setInterval(async () => {
|
|
3382
|
+
try {
|
|
3383
|
+
const license = await checkLicense();
|
|
3384
|
+
if (!license.valid) {
|
|
3385
|
+
process.stderr.write("[exe-os] License expired or invalid \u2014 features may be restricted\n");
|
|
3386
|
+
}
|
|
3387
|
+
} catch {
|
|
3388
|
+
}
|
|
3389
|
+
}, intervalMs);
|
|
3390
|
+
if (_revalTimer && typeof _revalTimer === "object" && "unref" in _revalTimer) {
|
|
3391
|
+
_revalTimer.unref();
|
|
3392
|
+
}
|
|
3393
|
+
}
|
|
3394
|
+
function stopLicenseRevalidation() {
|
|
3395
|
+
if (_revalTimer) {
|
|
3396
|
+
clearInterval(_revalTimer);
|
|
3397
|
+
_revalTimer = null;
|
|
3398
|
+
}
|
|
3399
|
+
}
|
|
3400
|
+
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH, API_BASE, LICENSE_PUBLIC_KEY_PEM, LICENSE_JWT_ALG, PLAN_LIMITS, FREE_LICENSE, CACHE_MAX_AGE_MS, _revalTimer;
|
|
3364
3401
|
var init_license = __esm({
|
|
3365
3402
|
"src/lib/license.ts"() {
|
|
3366
3403
|
"use strict";
|
|
@@ -3390,6 +3427,8 @@ MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeHztAMOpR/ZMh+rWuOASjEZ54CGY
|
|
|
3390
3427
|
employeeLimit: 1,
|
|
3391
3428
|
memoryLimit: 5e3
|
|
3392
3429
|
};
|
|
3430
|
+
CACHE_MAX_AGE_MS = 36e5;
|
|
3431
|
+
_revalTimer = null;
|
|
3393
3432
|
}
|
|
3394
3433
|
});
|
|
3395
3434
|
|
|
@@ -3524,7 +3563,7 @@ import path14 from "path";
|
|
|
3524
3563
|
import os2 from "os";
|
|
3525
3564
|
import {
|
|
3526
3565
|
readFileSync as readFileSync8,
|
|
3527
|
-
readdirSync as
|
|
3566
|
+
readdirSync as readdirSync4,
|
|
3528
3567
|
unlinkSync as unlinkSync3,
|
|
3529
3568
|
existsSync as existsSync10,
|
|
3530
3569
|
rmdirSync
|
|
@@ -4776,7 +4815,7 @@ var init_tmux_routing = __esm({
|
|
|
4776
4815
|
|
|
4777
4816
|
// src/lib/tasks-review.ts
|
|
4778
4817
|
import path19 from "path";
|
|
4779
|
-
import { existsSync as existsSync15, readdirSync as
|
|
4818
|
+
import { existsSync as existsSync15, readdirSync as readdirSync5, unlinkSync as unlinkSync5 } from "fs";
|
|
4780
4819
|
async function countPendingReviews() {
|
|
4781
4820
|
const client = getClient();
|
|
4782
4821
|
const result = await client.execute({
|
|
@@ -4898,7 +4937,7 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
|
|
|
4898
4937
|
try {
|
|
4899
4938
|
const cacheDir = path19.join(EXE_AI_DIR, "session-cache");
|
|
4900
4939
|
if (existsSync15(cacheDir)) {
|
|
4901
|
-
for (const f of
|
|
4940
|
+
for (const f of readdirSync5(cacheDir)) {
|
|
4902
4941
|
if (f.startsWith("review-notified-")) {
|
|
4903
4942
|
unlinkSync5(path19.join(cacheDir, f));
|
|
4904
4943
|
}
|
|
@@ -6681,50 +6720,59 @@ function registerRecallMyMemory(server2) {
|
|
|
6681
6720
|
user_id,
|
|
6682
6721
|
include_source
|
|
6683
6722
|
}) => {
|
|
6684
|
-
|
|
6685
|
-
|
|
6686
|
-
|
|
6687
|
-
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
|
|
6692
|
-
|
|
6693
|
-
|
|
6694
|
-
|
|
6695
|
-
|
|
6696
|
-
|
|
6697
|
-
|
|
6723
|
+
try {
|
|
6724
|
+
const { agentId } = getActiveAgent();
|
|
6725
|
+
const searchOptions = {
|
|
6726
|
+
projectName: project_name,
|
|
6727
|
+
hasError: has_error,
|
|
6728
|
+
toolName: tool_name,
|
|
6729
|
+
limit,
|
|
6730
|
+
since,
|
|
6731
|
+
includeArchived: include_archived,
|
|
6732
|
+
workspaceId: workspace_id,
|
|
6733
|
+
includeSource: include_source,
|
|
6734
|
+
...user_id !== void 0 ? { userId: user_id } : {}
|
|
6735
|
+
};
|
|
6736
|
+
const results = await hybridSearch(query, agentId, searchOptions);
|
|
6737
|
+
if (results.length === 0) {
|
|
6738
|
+
return {
|
|
6739
|
+
content: [
|
|
6740
|
+
{ type: "text", text: "No matching memories found." }
|
|
6741
|
+
]
|
|
6742
|
+
};
|
|
6743
|
+
}
|
|
6744
|
+
const formatted = results.map((r) => {
|
|
6745
|
+
const header = `[${r.timestamp}] ${r.tool_name} (${r.project_name})${r.has_error ? " [ERROR]" : ""}`;
|
|
6746
|
+
const body = r.raw_text.slice(0, 500);
|
|
6747
|
+
const parts = [header];
|
|
6748
|
+
if (r.source_path) {
|
|
6749
|
+
const typeTag = r.source_type && r.source_type !== "text" ? ` [${r.source_type}]` : "";
|
|
6750
|
+
parts.push(`source: ${r.source_path}${typeTag}`);
|
|
6751
|
+
} else if (include_source) {
|
|
6752
|
+
const sourceLine = formatSourceLine(r);
|
|
6753
|
+
if (sourceLine) parts.push(sourceLine);
|
|
6754
|
+
}
|
|
6755
|
+
parts.push(body);
|
|
6756
|
+
return parts.join("\n");
|
|
6757
|
+
}).join("\n\n---\n\n");
|
|
6698
6758
|
return {
|
|
6699
6759
|
content: [
|
|
6700
|
-
{
|
|
6760
|
+
{
|
|
6761
|
+
type: "text",
|
|
6762
|
+
text: `Found ${results.length} memories:
|
|
6763
|
+
|
|
6764
|
+
${formatted}`
|
|
6765
|
+
}
|
|
6701
6766
|
]
|
|
6702
6767
|
};
|
|
6768
|
+
} catch (err) {
|
|
6769
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6770
|
+
const friendly = msg.includes("SQLITE_BUSY") ? "Memory system is busy \u2014 please retry." : "Failed to search memories. Please retry.";
|
|
6771
|
+
return {
|
|
6772
|
+
content: [{ type: "text", text: friendly }],
|
|
6773
|
+
isError: true
|
|
6774
|
+
};
|
|
6703
6775
|
}
|
|
6704
|
-
const formatted = results.map((r) => {
|
|
6705
|
-
const header = `[${r.timestamp}] ${r.tool_name} (${r.project_name})${r.has_error ? " [ERROR]" : ""}`;
|
|
6706
|
-
const body = r.raw_text.slice(0, 500);
|
|
6707
|
-
const parts = [header];
|
|
6708
|
-
if (r.source_path) {
|
|
6709
|
-
const typeTag = r.source_type && r.source_type !== "text" ? ` [${r.source_type}]` : "";
|
|
6710
|
-
parts.push(`source: ${r.source_path}${typeTag}`);
|
|
6711
|
-
} else if (include_source) {
|
|
6712
|
-
const sourceLine = formatSourceLine(r);
|
|
6713
|
-
if (sourceLine) parts.push(sourceLine);
|
|
6714
|
-
}
|
|
6715
|
-
parts.push(body);
|
|
6716
|
-
return parts.join("\n");
|
|
6717
|
-
}).join("\n\n---\n\n");
|
|
6718
|
-
return {
|
|
6719
|
-
content: [
|
|
6720
|
-
{
|
|
6721
|
-
type: "text",
|
|
6722
|
-
text: `Found ${results.length} memories:
|
|
6723
|
-
|
|
6724
|
-
${formatted}`
|
|
6725
|
-
}
|
|
6726
|
-
]
|
|
6727
|
-
};
|
|
6728
6776
|
}
|
|
6729
6777
|
);
|
|
6730
6778
|
}
|
|
@@ -6751,36 +6799,45 @@ function registerAskTeamMemory(server2) {
|
|
|
6751
6799
|
}
|
|
6752
6800
|
},
|
|
6753
6801
|
async ({ team_member, query, project_name, limit, since, include_archived }) => {
|
|
6754
|
-
|
|
6755
|
-
|
|
6756
|
-
|
|
6757
|
-
|
|
6758
|
-
|
|
6759
|
-
|
|
6760
|
-
|
|
6802
|
+
try {
|
|
6803
|
+
const results = await hybridSearch(query, team_member, {
|
|
6804
|
+
projectName: project_name,
|
|
6805
|
+
limit,
|
|
6806
|
+
since,
|
|
6807
|
+
includeArchived: include_archived
|
|
6808
|
+
});
|
|
6809
|
+
if (results.length === 0) {
|
|
6810
|
+
return {
|
|
6811
|
+
content: [
|
|
6812
|
+
{
|
|
6813
|
+
type: "text",
|
|
6814
|
+
text: `No memories found for team member '${team_member}'.`
|
|
6815
|
+
}
|
|
6816
|
+
]
|
|
6817
|
+
};
|
|
6818
|
+
}
|
|
6819
|
+
const formatted = results.map(
|
|
6820
|
+
(r) => `[${r.timestamp}] ${r.tool_name} (${r.project_name})${r.has_error ? " [ERROR]" : ""}
|
|
6821
|
+
${r.raw_text.slice(0, 500)}`
|
|
6822
|
+
).join("\n\n---\n\n");
|
|
6761
6823
|
return {
|
|
6762
6824
|
content: [
|
|
6763
6825
|
{
|
|
6764
6826
|
type: "text",
|
|
6765
|
-
text: `
|
|
6827
|
+
text: `From ${team_member}'s memories (${results.length} results):
|
|
6828
|
+
|
|
6829
|
+
${formatted}`
|
|
6766
6830
|
}
|
|
6767
6831
|
]
|
|
6768
6832
|
};
|
|
6833
|
+
} catch (err) {
|
|
6834
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6835
|
+
const friendly = msg.includes("SQLITE_BUSY") ? "Memory system is busy \u2014 please retry." : "Failed to search team memories. Please retry.";
|
|
6836
|
+
return {
|
|
6837
|
+
content: [{ type: "text", text: friendly }],
|
|
6838
|
+
isError: true
|
|
6839
|
+
};
|
|
6769
6840
|
}
|
|
6770
|
-
const formatted = results.map(
|
|
6771
|
-
(r) => `[${r.timestamp}] ${r.tool_name} (${r.project_name})${r.has_error ? " [ERROR]" : ""}
|
|
6772
|
-
${r.raw_text.slice(0, 500)}`
|
|
6773
|
-
).join("\n\n---\n\n");
|
|
6774
|
-
return {
|
|
6775
|
-
content: [
|
|
6776
|
-
{
|
|
6777
|
-
type: "text",
|
|
6778
|
-
text: `From ${team_member}'s memories (${results.length} results):
|
|
6779
|
-
|
|
6780
|
-
${formatted}`
|
|
6781
|
-
}
|
|
6782
|
-
]
|
|
6783
|
-
};
|
|
6784
6841
|
}
|
|
6785
6842
|
);
|
|
6786
6843
|
}
|
|
@@ -7428,36 +7485,44 @@ function registerListTasks(server2) {
|
|
|
7428
7485
|
}
|
|
7429
7486
|
},
|
|
7430
7487
|
async ({ assigned_to, status, project_name, priority }) => {
|
|
7431
|
-
|
|
7432
|
-
|
|
7433
|
-
|
|
7434
|
-
|
|
7435
|
-
|
|
7436
|
-
|
|
7437
|
-
|
|
7438
|
-
|
|
7488
|
+
try {
|
|
7489
|
+
const resolvedProject = project_name === "all" ? void 0 : project_name ?? getProjectName();
|
|
7490
|
+
const tasks = await listTasks({
|
|
7491
|
+
assignedTo: assigned_to,
|
|
7492
|
+
status,
|
|
7493
|
+
projectName: resolvedProject,
|
|
7494
|
+
priority
|
|
7495
|
+
});
|
|
7496
|
+
if (tasks.length === 0) {
|
|
7497
|
+
return {
|
|
7498
|
+
content: [{ type: "text", text: "No tasks found." }]
|
|
7499
|
+
};
|
|
7500
|
+
}
|
|
7501
|
+
const lines = tasks.map((t) => {
|
|
7502
|
+
const cpIndicator = t.checkpointCount && t.checkpointCount > 0 ? ` [cp:${t.checkpointCount}]` : "";
|
|
7503
|
+
let budgetNote = "";
|
|
7504
|
+
if (t.budgetTokens !== null) {
|
|
7505
|
+
const pct = Math.round(t.tokensUsed / t.budgetTokens * 100);
|
|
7506
|
+
budgetNote = ` [${t.tokensUsed}/${t.budgetTokens} tokens, ${pct}%]`;
|
|
7507
|
+
}
|
|
7508
|
+
return `- [${t.priority.toUpperCase()}] ${t.title} (${t.projectName}) \u2014 ${t.status}${cpIndicator}${budgetNote} \u2192 ${t.assignedTo}`;
|
|
7509
|
+
});
|
|
7510
|
+
return {
|
|
7511
|
+
content: [
|
|
7512
|
+
{
|
|
7513
|
+
type: "text",
|
|
7514
|
+
text: `${tasks.length} task(s):
|
|
7515
|
+
${lines.join("\n")}`
|
|
7516
|
+
}
|
|
7517
|
+
]
|
|
7518
|
+
};
|
|
7519
|
+
} catch (err) {
|
|
7520
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
7439
7521
|
return {
|
|
7440
|
-
content: [{ type: "text", text:
|
|
7522
|
+
content: [{ type: "text", text: `Failed to list tasks: ${msg}` }],
|
|
7523
|
+
isError: true
|
|
7441
7524
|
};
|
|
7442
7525
|
}
|
|
7443
|
-
const lines = tasks.map((t) => {
|
|
7444
|
-
const cpIndicator = t.checkpointCount && t.checkpointCount > 0 ? ` [cp:${t.checkpointCount}]` : "";
|
|
7445
|
-
let budgetNote = "";
|
|
7446
|
-
if (t.budgetTokens !== null) {
|
|
7447
|
-
const pct = Math.round(t.tokensUsed / t.budgetTokens * 100);
|
|
7448
|
-
budgetNote = ` [${t.tokensUsed}/${t.budgetTokens} tokens, ${pct}%]`;
|
|
7449
|
-
}
|
|
7450
|
-
return `- [${t.priority.toUpperCase()}] ${t.title} (${t.projectName}) \u2014 ${t.status}${cpIndicator}${budgetNote} \u2192 ${t.assignedTo}`;
|
|
7451
|
-
});
|
|
7452
|
-
return {
|
|
7453
|
-
content: [
|
|
7454
|
-
{
|
|
7455
|
-
type: "text",
|
|
7456
|
-
text: `${tasks.length} task(s):
|
|
7457
|
-
${lines.join("\n")}`
|
|
7458
|
-
}
|
|
7459
|
-
]
|
|
7460
|
-
};
|
|
7461
7526
|
}
|
|
7462
7527
|
);
|
|
7463
7528
|
}
|
|
@@ -8171,7 +8236,7 @@ import { z as z20 } from "zod";
|
|
|
8171
8236
|
init_config();
|
|
8172
8237
|
init_database();
|
|
8173
8238
|
import { existsSync as existsSync16, mkdirSync as mkdirSync8, readFileSync as readFileSync13, writeFileSync as writeFileSync9 } from "fs";
|
|
8174
|
-
import { readdirSync as
|
|
8239
|
+
import { readdirSync as readdirSync6 } from "fs";
|
|
8175
8240
|
import path22 from "path";
|
|
8176
8241
|
import { createHash } from "crypto";
|
|
8177
8242
|
var IDENTITY_DIR = path22.join(EXE_AI_DIR, "identity");
|
|
@@ -8254,7 +8319,7 @@ async function updateIdentity(agentId, content, updatedBy) {
|
|
|
8254
8319
|
}
|
|
8255
8320
|
function listIdentities() {
|
|
8256
8321
|
ensureDir2();
|
|
8257
|
-
const files =
|
|
8322
|
+
const files = readdirSync6(IDENTITY_DIR).filter((f) => f.endsWith(".md"));
|
|
8258
8323
|
const results = [];
|
|
8259
8324
|
for (const file of files) {
|
|
8260
8325
|
const agentId = file.replace(".md", "");
|
|
@@ -8725,10 +8790,12 @@ function registerIngestDocument(server2) {
|
|
|
8725
8790
|
}]
|
|
8726
8791
|
};
|
|
8727
8792
|
} catch (err) {
|
|
8793
|
+
const raw = err instanceof Error ? err.message : String(err);
|
|
8794
|
+
const friendly = raw.includes("SQLITE_BUSY") ? "Memory system is busy, please retry in a moment." : raw.includes("SQLITE_") ? "A database error occurred. Please retry." : `ingest_document failed: ${raw}`;
|
|
8728
8795
|
return {
|
|
8729
8796
|
content: [{
|
|
8730
8797
|
type: "text",
|
|
8731
|
-
text:
|
|
8798
|
+
text: friendly
|
|
8732
8799
|
}],
|
|
8733
8800
|
isError: true
|
|
8734
8801
|
};
|
|
@@ -9108,8 +9175,8 @@ async function sendWhatsAppMessage(phoneNumberId, accessToken, to, text) {
|
|
|
9108
9175
|
})
|
|
9109
9176
|
});
|
|
9110
9177
|
if (!res.ok) {
|
|
9111
|
-
|
|
9112
|
-
throw new Error(`WhatsApp
|
|
9178
|
+
await res.text();
|
|
9179
|
+
throw new Error(`WhatsApp message could not be delivered (HTTP ${res.status}). Check your WhatsApp configuration.`);
|
|
9113
9180
|
}
|
|
9114
9181
|
}
|
|
9115
9182
|
function isPhoneNumber(value) {
|
|
@@ -9193,11 +9260,13 @@ function registerSendWhatsapp(server2) {
|
|
|
9193
9260
|
});
|
|
9194
9261
|
results.push({ recipient, phone, ok: true });
|
|
9195
9262
|
} catch (err) {
|
|
9263
|
+
const raw = err instanceof Error ? err.message : String(err);
|
|
9264
|
+
const friendly = raw.includes("HTTP") ? raw : `Message delivery failed. Check WhatsApp configuration.`;
|
|
9196
9265
|
results.push({
|
|
9197
9266
|
recipient,
|
|
9198
9267
|
phone,
|
|
9199
9268
|
ok: false,
|
|
9200
|
-
error:
|
|
9269
|
+
error: friendly
|
|
9201
9270
|
});
|
|
9202
9271
|
}
|
|
9203
9272
|
}
|
|
@@ -9522,14 +9591,14 @@ function registerListTriggers(server2) {
|
|
|
9522
9591
|
import { z as z31 } from "zod";
|
|
9523
9592
|
|
|
9524
9593
|
// src/automation/starter-packs/index.ts
|
|
9525
|
-
import { readFileSync as readFileSync16, readdirSync as
|
|
9594
|
+
import { readFileSync as readFileSync16, readdirSync as readdirSync7, existsSync as existsSync18 } from "fs";
|
|
9526
9595
|
import path24 from "path";
|
|
9527
9596
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
9528
9597
|
var __dirname = path24.dirname(fileURLToPath3(import.meta.url));
|
|
9529
9598
|
function listPacks() {
|
|
9530
9599
|
const packsDir = path24.join(__dirname, ".");
|
|
9531
9600
|
if (!existsSync18(packsDir)) return [];
|
|
9532
|
-
return
|
|
9601
|
+
return readdirSync7(packsDir, { withFileTypes: true }).filter(
|
|
9533
9602
|
(d) => d.isDirectory() && existsSync18(path24.join(packsDir, d.name, "custom-objects.json"))
|
|
9534
9603
|
).map((d) => d.name);
|
|
9535
9604
|
}
|
|
@@ -9561,7 +9630,7 @@ function loadPack(industry) {
|
|
|
9561
9630
|
}
|
|
9562
9631
|
const wikiSeeds = [];
|
|
9563
9632
|
if (existsSync18(wikiDir)) {
|
|
9564
|
-
const files =
|
|
9633
|
+
const files = readdirSync7(wikiDir).filter((f) => f.endsWith(".md"));
|
|
9565
9634
|
for (const file of files) {
|
|
9566
9635
|
const content = readFileSync16(path24.join(wikiDir, file), "utf-8");
|
|
9567
9636
|
const titleMatch = content.match(/^#\s+(.+)/m);
|
|
@@ -11047,11 +11116,13 @@ function registerQueryConversations(server2) {
|
|
|
11047
11116
|
]
|
|
11048
11117
|
};
|
|
11049
11118
|
} catch (err) {
|
|
11119
|
+
const raw = err instanceof Error ? err.message : String(err);
|
|
11120
|
+
const friendly = raw.includes("SQLITE_BUSY") ? "Memory system is busy, please retry in a moment." : raw.includes("SQLITE_") ? "A database error occurred. Please retry." : `Error querying conversations: ${raw}`;
|
|
11050
11121
|
return {
|
|
11051
11122
|
content: [
|
|
11052
11123
|
{
|
|
11053
11124
|
type: "text",
|
|
11054
|
-
text:
|
|
11125
|
+
text: friendly
|
|
11055
11126
|
}
|
|
11056
11127
|
],
|
|
11057
11128
|
isError: true
|
|
@@ -11063,13 +11134,13 @@ function registerQueryConversations(server2) {
|
|
|
11063
11134
|
|
|
11064
11135
|
// src/mcp/tools/load-skill.ts
|
|
11065
11136
|
import { z as z39 } from "zod";
|
|
11066
|
-
import { readFileSync as readFileSync17, readdirSync as
|
|
11137
|
+
import { readFileSync as readFileSync17, readdirSync as readdirSync8, statSync as statSync3 } from "fs";
|
|
11067
11138
|
import path27 from "path";
|
|
11068
11139
|
import { homedir as homedir2 } from "os";
|
|
11069
11140
|
var SKILLS_DIR = path27.join(homedir2(), ".claude", "skills");
|
|
11070
11141
|
function listAvailableSkills() {
|
|
11071
11142
|
try {
|
|
11072
|
-
const entries =
|
|
11143
|
+
const entries = readdirSync8(SKILLS_DIR);
|
|
11073
11144
|
return entries.filter((entry) => {
|
|
11074
11145
|
try {
|
|
11075
11146
|
const entryPath = path27.join(SKILLS_DIR, entry);
|
|
@@ -455,36 +455,44 @@ function registerListTasks(server) {
|
|
|
455
455
|
}
|
|
456
456
|
},
|
|
457
457
|
async ({ assigned_to, status, project_name, priority }) => {
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
458
|
+
try {
|
|
459
|
+
const resolvedProject = project_name === "all" ? void 0 : project_name ?? getProjectName();
|
|
460
|
+
const tasks = await listTasks({
|
|
461
|
+
assignedTo: assigned_to,
|
|
462
|
+
status,
|
|
463
|
+
projectName: resolvedProject,
|
|
464
|
+
priority
|
|
465
|
+
});
|
|
466
|
+
if (tasks.length === 0) {
|
|
467
|
+
return {
|
|
468
|
+
content: [{ type: "text", text: "No tasks found." }]
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
const lines = tasks.map((t) => {
|
|
472
|
+
const cpIndicator = t.checkpointCount && t.checkpointCount > 0 ? ` [cp:${t.checkpointCount}]` : "";
|
|
473
|
+
let budgetNote = "";
|
|
474
|
+
if (t.budgetTokens !== null) {
|
|
475
|
+
const pct = Math.round(t.tokensUsed / t.budgetTokens * 100);
|
|
476
|
+
budgetNote = ` [${t.tokensUsed}/${t.budgetTokens} tokens, ${pct}%]`;
|
|
477
|
+
}
|
|
478
|
+
return `- [${t.priority.toUpperCase()}] ${t.title} (${t.projectName}) \u2014 ${t.status}${cpIndicator}${budgetNote} \u2192 ${t.assignedTo}`;
|
|
479
|
+
});
|
|
480
|
+
return {
|
|
481
|
+
content: [
|
|
482
|
+
{
|
|
483
|
+
type: "text",
|
|
484
|
+
text: `${tasks.length} task(s):
|
|
485
|
+
${lines.join("\n")}`
|
|
486
|
+
}
|
|
487
|
+
]
|
|
488
|
+
};
|
|
489
|
+
} catch (err) {
|
|
490
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
466
491
|
return {
|
|
467
|
-
content: [{ type: "text", text:
|
|
492
|
+
content: [{ type: "text", text: `Failed to list tasks: ${msg}` }],
|
|
493
|
+
isError: true
|
|
468
494
|
};
|
|
469
495
|
}
|
|
470
|
-
const lines = tasks.map((t) => {
|
|
471
|
-
const cpIndicator = t.checkpointCount && t.checkpointCount > 0 ? ` [cp:${t.checkpointCount}]` : "";
|
|
472
|
-
let budgetNote = "";
|
|
473
|
-
if (t.budgetTokens !== null) {
|
|
474
|
-
const pct = Math.round(t.tokensUsed / t.budgetTokens * 100);
|
|
475
|
-
budgetNote = ` [${t.tokensUsed}/${t.budgetTokens} tokens, ${pct}%]`;
|
|
476
|
-
}
|
|
477
|
-
return `- [${t.priority.toUpperCase()}] ${t.title} (${t.projectName}) \u2014 ${t.status}${cpIndicator}${budgetNote} \u2192 ${t.assignedTo}`;
|
|
478
|
-
});
|
|
479
|
-
return {
|
|
480
|
-
content: [
|
|
481
|
-
{
|
|
482
|
-
type: "text",
|
|
483
|
-
text: `${tasks.length} task(s):
|
|
484
|
-
${lines.join("\n")}`
|
|
485
|
-
}
|
|
486
|
-
]
|
|
487
|
-
};
|
|
488
496
|
}
|
|
489
497
|
);
|
|
490
498
|
}
|
package/dist/runtime/index.js
CHANGED
|
@@ -3966,7 +3966,7 @@ __export(shard_manager_exports, {
|
|
|
3966
3966
|
shardExists: () => shardExists
|
|
3967
3967
|
});
|
|
3968
3968
|
import path16 from "path";
|
|
3969
|
-
import { existsSync as existsSync12, mkdirSync as mkdirSync6 } from "fs";
|
|
3969
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync6, readdirSync as readdirSync3 } from "fs";
|
|
3970
3970
|
import { createClient as createClient2 } from "@libsql/client";
|
|
3971
3971
|
function initShardManager(encryptionKey) {
|
|
3972
3972
|
_encryptionKey = encryptionKey;
|
|
@@ -4005,7 +4005,6 @@ function shardExists(projectName) {
|
|
|
4005
4005
|
}
|
|
4006
4006
|
function listShards() {
|
|
4007
4007
|
if (!existsSync12(SHARDS_DIR)) return [];
|
|
4008
|
-
const { readdirSync: readdirSync3 } = __require("fs");
|
|
4009
4008
|
return readdirSync3(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
4010
4009
|
}
|
|
4011
4010
|
async function ensureShardSchema(client) {
|
|
@@ -4289,6 +4288,12 @@ async function writeMemory(record) {
|
|
|
4289
4288
|
supersedes_id: record.supersedes_id ?? null
|
|
4290
4289
|
};
|
|
4291
4290
|
_pendingRecords.push(dbRow);
|
|
4291
|
+
const MAX_PENDING = 1e3;
|
|
4292
|
+
if (_pendingRecords.length > MAX_PENDING) {
|
|
4293
|
+
const dropped = _pendingRecords.length - MAX_PENDING;
|
|
4294
|
+
_pendingRecords = _pendingRecords.slice(-MAX_PENDING);
|
|
4295
|
+
console.warn(`[store] Dropped ${dropped} oldest pending records (overflow)`);
|
|
4296
|
+
}
|
|
4292
4297
|
if (_flushTimer === null) {
|
|
4293
4298
|
_flushTimer = setInterval(() => {
|
|
4294
4299
|
void flushBatch();
|