@askexenow/exe-os 0.9.86 → 0.9.88
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/compose/docker-compose.yml +3 -3
- package/dist/bin/age-ontology-load.js +8 -2
- package/dist/bin/agentic-ontology-backfill.js +29 -0
- package/dist/bin/agentic-reflection-backfill.js +29 -0
- package/dist/bin/agentic-semantic-label.js +29 -0
- package/dist/bin/backfill-conversations.js +30 -0
- package/dist/bin/backfill-responses.js +30 -0
- package/dist/bin/backfill-vectors.js +30 -0
- package/dist/bin/bulk-sync-postgres.js +47 -1
- package/dist/bin/cc-doctor.js +3 -2
- package/dist/bin/cleanup-stale-review-tasks.js +30 -0
- package/dist/bin/cli.js +357 -19
- package/dist/bin/exe-agent.js +19 -0
- package/dist/bin/exe-assign.js +30 -0
- package/dist/bin/exe-boot.js +157 -4
- package/dist/bin/exe-call.js +20 -0
- package/dist/bin/exe-cloud.js +156 -3
- package/dist/bin/exe-dispatch.js +30 -1
- package/dist/bin/exe-doctor.js +30 -0
- package/dist/bin/exe-export-behaviors.js +29 -0
- package/dist/bin/exe-forget.js +30 -0
- package/dist/bin/exe-gateway.js +150 -35
- package/dist/bin/exe-healthcheck.js +2 -1
- package/dist/bin/exe-heartbeat.js +30 -0
- package/dist/bin/exe-kill.js +29 -0
- package/dist/bin/exe-launch-agent.js +29 -0
- package/dist/bin/exe-new-employee.js +37 -4
- package/dist/bin/exe-pending-messages.js +29 -0
- package/dist/bin/exe-pending-notifications.js +30 -0
- package/dist/bin/exe-pending-reviews.js +30 -0
- package/dist/bin/exe-rename.js +30 -0
- package/dist/bin/exe-review.js +30 -0
- package/dist/bin/exe-search.js +30 -0
- package/dist/bin/exe-session-cleanup.js +30 -1
- package/dist/bin/exe-settings.js +3 -0
- package/dist/bin/exe-start-codex.js +31 -2
- package/dist/bin/exe-start-opencode.js +31 -2
- package/dist/bin/exe-status.js +30 -0
- package/dist/bin/exe-team.js +30 -0
- package/dist/bin/git-sweep.js +30 -1
- package/dist/bin/graph-backfill.js +29 -0
- package/dist/bin/graph-export.js +29 -0
- package/dist/bin/graph-layer-benchmark.js +9 -1
- package/dist/bin/install.js +9 -0
- package/dist/bin/intercom-check.js +31 -1
- package/dist/bin/list-providers.js +1 -0
- package/dist/bin/postgres-agentic-reflection-backfill.js +7 -1
- package/dist/bin/postgres-agentic-semantic-backfill.js +7 -1
- package/dist/bin/registry-proxy.js +1 -0
- package/dist/bin/scan-tasks.js +31 -1
- package/dist/bin/setup.js +165 -9
- package/dist/bin/shard-migrate.js +29 -0
- package/dist/bin/stack-update.js +24 -7
- package/dist/bin/update.js +5 -0
- package/dist/gateway/index.js +30 -1
- package/dist/hooks/bug-report-worker.js +30 -1
- package/dist/hooks/codex-stop-task-finalizer.js +30 -1
- package/dist/hooks/commit-complete.js +30 -1
- package/dist/hooks/error-recall.js +29 -0
- package/dist/hooks/ingest.js +29 -0
- package/dist/hooks/instructions-loaded.js +29 -0
- package/dist/hooks/notification.js +29 -0
- package/dist/hooks/post-compact.js +29 -0
- package/dist/hooks/post-tool-combined.js +29 -0
- package/dist/hooks/pre-compact.js +30 -1
- package/dist/hooks/pre-tool-use.js +29 -0
- package/dist/hooks/prompt-submit.js +30 -1
- package/dist/hooks/session-end.js +30 -1
- package/dist/hooks/session-start.js +29 -0
- package/dist/hooks/stop.js +29 -0
- package/dist/hooks/subagent-stop.js +29 -0
- package/dist/hooks/summary-worker.js +155 -3
- package/dist/index.js +30 -1
- package/dist/lib/cloud-sync.js +136 -2
- package/dist/lib/consolidation.js +1 -0
- package/dist/lib/database.js +11 -0
- package/dist/lib/db.js +11 -0
- package/dist/lib/device-registry.js +11 -0
- package/dist/lib/employee-templates.js +19 -0
- package/dist/lib/exe-daemon.js +1455 -208
- package/dist/lib/hybrid-search.js +29 -0
- package/dist/lib/identity-templates.js +6 -2
- package/dist/lib/identity.js +1 -0
- package/dist/lib/messaging.js +2 -1
- package/dist/lib/reminders.js +1 -0
- package/dist/lib/schedules.js +29 -0
- package/dist/lib/skill-learning.js +1 -0
- package/dist/lib/store.js +29 -0
- package/dist/lib/tasks.js +2 -1
- package/dist/lib/tmux-routing.js +2 -1
- package/dist/lib/token-spend.js +1 -0
- package/dist/mcp/server.js +1278 -165
- package/dist/mcp/tools/complete-reminder.js +1 -0
- package/dist/mcp/tools/create-reminder.js +1 -0
- package/dist/mcp/tools/create-task.js +8 -3
- package/dist/mcp/tools/deactivate-behavior.js +1 -0
- package/dist/mcp/tools/list-reminders.js +1 -0
- package/dist/mcp/tools/list-tasks.js +1 -0
- package/dist/mcp/tools/send-message.js +2 -1
- package/dist/mcp/tools/update-task.js +2 -1
- package/dist/runtime/index.js +30 -1
- package/dist/tui/App.js +30 -1
- package/package.json +2 -2
package/dist/bin/cli.js
CHANGED
|
@@ -1229,6 +1229,15 @@ async function registerMcpServer(packageRoot, homeDir = os6.homedir()) {
|
|
|
1229
1229
|
delete claudeJson.mcpServers[MCP_LEGACY_KEY];
|
|
1230
1230
|
process.stderr.write("exe-os: migrated MCP server key exe-mem \u2192 exe-os\n");
|
|
1231
1231
|
}
|
|
1232
|
+
if (claudeJson.projects) {
|
|
1233
|
+
for (const [projectPath, projectConfig] of Object.entries(claudeJson.projects)) {
|
|
1234
|
+
if (projectConfig.mcpServers?.[MCP_LEGACY_KEY]) {
|
|
1235
|
+
delete projectConfig.mcpServers[MCP_LEGACY_KEY];
|
|
1236
|
+
process.stderr.write(`exe-os: removed stale project-level exe-mem from ${projectPath}
|
|
1237
|
+
`);
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1232
1241
|
const currentOs = claudeJson.mcpServers[MCP_PRIMARY_KEY];
|
|
1233
1242
|
const osMatches = currentOs && JSON.stringify(currentOs) === JSON.stringify(newEntry);
|
|
1234
1243
|
if (osMatches) {
|
|
@@ -4340,6 +4349,7 @@ __export(database_exports, {
|
|
|
4340
4349
|
isInitialized: () => isInitialized,
|
|
4341
4350
|
setExternalClient: () => setExternalClient
|
|
4342
4351
|
});
|
|
4352
|
+
import { chmodSync as chmodSync3 } from "fs";
|
|
4343
4353
|
import { createClient } from "@libsql/client";
|
|
4344
4354
|
async function initDatabase(config) {
|
|
4345
4355
|
if (_walCheckpointTimer) {
|
|
@@ -4381,6 +4391,16 @@ async function initDatabase(config) {
|
|
|
4381
4391
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
4382
4392
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
4383
4393
|
}
|
|
4394
|
+
try {
|
|
4395
|
+
chmodSync3(config.dbPath, 384);
|
|
4396
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
4397
|
+
try {
|
|
4398
|
+
chmodSync3(config.dbPath + suffix, 384);
|
|
4399
|
+
} catch {
|
|
4400
|
+
}
|
|
4401
|
+
}
|
|
4402
|
+
} catch {
|
|
4403
|
+
}
|
|
4384
4404
|
}
|
|
4385
4405
|
function isInitialized() {
|
|
4386
4406
|
return _adapterClient !== null || _client !== null;
|
|
@@ -5743,6 +5763,7 @@ import { fileURLToPath as fileURLToPath3 } from "url";
|
|
|
5743
5763
|
function isMainModule(importMetaUrl) {
|
|
5744
5764
|
if (process.argv[1] == null) return false;
|
|
5745
5765
|
if (process.argv[1].includes("mcp/server")) return false;
|
|
5766
|
+
if (process.argv[1].includes("exe-daemon")) return false;
|
|
5746
5767
|
try {
|
|
5747
5768
|
const scriptPath = realpathSync(process.argv[1]);
|
|
5748
5769
|
const modulePath = realpathSync(fileURLToPath3(importMetaUrl));
|
|
@@ -6556,6 +6577,21 @@ var init_crdt_sync = __esm({
|
|
|
6556
6577
|
}
|
|
6557
6578
|
});
|
|
6558
6579
|
|
|
6580
|
+
// src/lib/pg-ssl.ts
|
|
6581
|
+
var pg_ssl_exports = {};
|
|
6582
|
+
__export(pg_ssl_exports, {
|
|
6583
|
+
pgSslConfig: () => pgSslConfig
|
|
6584
|
+
});
|
|
6585
|
+
function pgSslConfig() {
|
|
6586
|
+
if (process.env.EXE_DB_SSL_DISABLED === "true") return {};
|
|
6587
|
+
return { ssl: { rejectUnauthorized: process.env.EXE_DB_SSL_ALLOW_SELFSIGNED !== "true" } };
|
|
6588
|
+
}
|
|
6589
|
+
var init_pg_ssl = __esm({
|
|
6590
|
+
"src/lib/pg-ssl.ts"() {
|
|
6591
|
+
"use strict";
|
|
6592
|
+
}
|
|
6593
|
+
});
|
|
6594
|
+
|
|
6559
6595
|
// src/lib/db-backup.ts
|
|
6560
6596
|
var db_backup_exports = {};
|
|
6561
6597
|
__export(db_backup_exports, {
|
|
@@ -6669,6 +6705,7 @@ __export(cloud_sync_exports, {
|
|
|
6669
6705
|
cloudPull: () => cloudPull,
|
|
6670
6706
|
cloudPullBehaviors: () => cloudPullBehaviors,
|
|
6671
6707
|
cloudPullBlob: () => cloudPullBlob,
|
|
6708
|
+
cloudPullCodeContext: () => cloudPullCodeContext,
|
|
6672
6709
|
cloudPullConversations: () => cloudPullConversations,
|
|
6673
6710
|
cloudPullDocuments: () => cloudPullDocuments,
|
|
6674
6711
|
cloudPullGlobalProcedures: () => cloudPullGlobalProcedures,
|
|
@@ -6678,6 +6715,7 @@ __export(cloud_sync_exports, {
|
|
|
6678
6715
|
cloudPush: () => cloudPush,
|
|
6679
6716
|
cloudPushBehaviors: () => cloudPushBehaviors,
|
|
6680
6717
|
cloudPushBlob: () => cloudPushBlob,
|
|
6718
|
+
cloudPushCodeContext: () => cloudPushCodeContext,
|
|
6681
6719
|
cloudPushConversations: () => cloudPushConversations,
|
|
6682
6720
|
cloudPushDocuments: () => cloudPushDocuments,
|
|
6683
6721
|
cloudPushGlobalProcedures: () => cloudPushGlobalProcedures,
|
|
@@ -6756,7 +6794,8 @@ function loadPgClient() {
|
|
|
6756
6794
|
return new Ctor();
|
|
6757
6795
|
}
|
|
6758
6796
|
const { Pool } = await import("pg");
|
|
6759
|
-
const
|
|
6797
|
+
const { pgSslConfig: pgSslConfig2 } = await Promise.resolve().then(() => (init_pg_ssl(), pg_ssl_exports));
|
|
6798
|
+
const pool = new Pool({ connectionString: process.env.DATABASE_URL, ...pgSslConfig2() });
|
|
6760
6799
|
return {
|
|
6761
6800
|
async $queryRawUnsafe(query, ...values) {
|
|
6762
6801
|
const result = await pool.query(query, values);
|
|
@@ -7301,6 +7340,17 @@ async function cloudSync(config) {
|
|
|
7301
7340
|
} catch (err) {
|
|
7302
7341
|
logError(`[cloud-sync] DB backup upload error: ${err instanceof Error ? err.message : String(err)}`);
|
|
7303
7342
|
}
|
|
7343
|
+
let codeContextResult = { pushed: 0, pulled: 0 };
|
|
7344
|
+
try {
|
|
7345
|
+
codeContextResult.pushed = await cloudPushCodeContext(config);
|
|
7346
|
+
} catch (err) {
|
|
7347
|
+
logError(`[cloud-sync] Code context push: ${err instanceof Error ? err.message : String(err)}`);
|
|
7348
|
+
}
|
|
7349
|
+
try {
|
|
7350
|
+
codeContextResult.pulled = await cloudPullCodeContext(config);
|
|
7351
|
+
} catch (err) {
|
|
7352
|
+
logError(`[cloud-sync] Code context pull: ${err instanceof Error ? err.message : String(err)}`);
|
|
7353
|
+
}
|
|
7304
7354
|
return {
|
|
7305
7355
|
pushed,
|
|
7306
7356
|
pulled,
|
|
@@ -7310,7 +7360,8 @@ async function cloudSync(config) {
|
|
|
7310
7360
|
tasks: tasksResult,
|
|
7311
7361
|
conversations: conversationsResult,
|
|
7312
7362
|
documents: documentsResult,
|
|
7313
|
-
roster: rosterResult
|
|
7363
|
+
roster: rosterResult,
|
|
7364
|
+
codeContext: codeContextResult
|
|
7314
7365
|
};
|
|
7315
7366
|
}
|
|
7316
7367
|
function recordRosterDeletion(name) {
|
|
@@ -7948,7 +7999,99 @@ async function cloudPullDocuments(config) {
|
|
|
7948
7999
|
}
|
|
7949
8000
|
return { pulled };
|
|
7950
8001
|
}
|
|
7951
|
-
|
|
8002
|
+
async function cloudPushCodeContext(config) {
|
|
8003
|
+
assertSecureEndpoint(config.endpoint);
|
|
8004
|
+
if (!existsSync16(CODE_CONTEXT_DIR)) return 0;
|
|
8005
|
+
const files = readdirSync2(CODE_CONTEXT_DIR).filter(
|
|
8006
|
+
(f) => f.endsWith(".json") && !f.endsWith(".vectors.json") && !f.startsWith(".")
|
|
8007
|
+
);
|
|
8008
|
+
if (files.length === 0) return 0;
|
|
8009
|
+
const metaPath = path16.join(CODE_CONTEXT_DIR, ".sync-meta.json");
|
|
8010
|
+
let syncMeta = {};
|
|
8011
|
+
if (existsSync16(metaPath)) {
|
|
8012
|
+
try {
|
|
8013
|
+
syncMeta = JSON.parse(readFileSync12(metaPath, "utf-8"));
|
|
8014
|
+
} catch {
|
|
8015
|
+
}
|
|
8016
|
+
}
|
|
8017
|
+
let pushed = 0;
|
|
8018
|
+
for (const file of files) {
|
|
8019
|
+
const filePath = path16.join(CODE_CONTEXT_DIR, file);
|
|
8020
|
+
try {
|
|
8021
|
+
const stat2 = statSync4(filePath);
|
|
8022
|
+
const lastPushed = syncMeta[file] ?? 0;
|
|
8023
|
+
if (stat2.mtimeMs <= lastPushed) continue;
|
|
8024
|
+
const content = readFileSync12(filePath, "utf-8");
|
|
8025
|
+
const header = content.substring(0, 300);
|
|
8026
|
+
if (header.includes("/tmp") || header.includes("/var/folders") || header.includes(".worktrees/")) continue;
|
|
8027
|
+
const compressed = compress(Buffer.from(content, "utf8"));
|
|
8028
|
+
const encrypted = encryptSyncBlob(compressed);
|
|
8029
|
+
const resp = await fetchWithRetry(`${config.endpoint}/sync/push-code-context`, {
|
|
8030
|
+
method: "POST",
|
|
8031
|
+
headers: {
|
|
8032
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
8033
|
+
"Content-Type": "application/json",
|
|
8034
|
+
"X-Device-Id": loadDeviceId()
|
|
8035
|
+
},
|
|
8036
|
+
body: JSON.stringify({ key: file, blob: encrypted })
|
|
8037
|
+
});
|
|
8038
|
+
if (resp.ok) {
|
|
8039
|
+
syncMeta[file] = stat2.mtimeMs;
|
|
8040
|
+
pushed++;
|
|
8041
|
+
}
|
|
8042
|
+
} catch {
|
|
8043
|
+
}
|
|
8044
|
+
}
|
|
8045
|
+
if (pushed > 0) {
|
|
8046
|
+
try {
|
|
8047
|
+
writeFileSync10(metaPath, JSON.stringify(syncMeta));
|
|
8048
|
+
} catch {
|
|
8049
|
+
}
|
|
8050
|
+
}
|
|
8051
|
+
return pushed;
|
|
8052
|
+
}
|
|
8053
|
+
async function cloudPullCodeContext(config) {
|
|
8054
|
+
assertSecureEndpoint(config.endpoint);
|
|
8055
|
+
try {
|
|
8056
|
+
const resp = await fetchWithRetry(`${config.endpoint}/sync/pull-code-context`, {
|
|
8057
|
+
method: "GET",
|
|
8058
|
+
headers: {
|
|
8059
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
8060
|
+
"X-Device-Id": loadDeviceId()
|
|
8061
|
+
}
|
|
8062
|
+
});
|
|
8063
|
+
if (!resp.ok) return 0;
|
|
8064
|
+
const data = await resp.json();
|
|
8065
|
+
if (!data.indexes || data.indexes.length === 0) return 0;
|
|
8066
|
+
mkdirSync9(CODE_CONTEXT_DIR, { recursive: true });
|
|
8067
|
+
let pulled = 0;
|
|
8068
|
+
for (const { key, blob } of data.indexes) {
|
|
8069
|
+
try {
|
|
8070
|
+
if (key.endsWith(".vectors.json")) continue;
|
|
8071
|
+
const localPath = path16.join(CODE_CONTEXT_DIR, key);
|
|
8072
|
+
const compressed = decryptSyncBlob(blob);
|
|
8073
|
+
const content = decompress(compressed).toString("utf8");
|
|
8074
|
+
if (!existsSync16(localPath)) {
|
|
8075
|
+
writeFileSync10(localPath, content, "utf-8");
|
|
8076
|
+
pulled++;
|
|
8077
|
+
} else {
|
|
8078
|
+
const localContent = readFileSync12(localPath, "utf-8");
|
|
8079
|
+
if (localContent.length !== content.length) {
|
|
8080
|
+
writeFileSync10(localPath, content, "utf-8");
|
|
8081
|
+
pulled++;
|
|
8082
|
+
}
|
|
8083
|
+
}
|
|
8084
|
+
} catch {
|
|
8085
|
+
}
|
|
8086
|
+
}
|
|
8087
|
+
return pulled;
|
|
8088
|
+
} catch (err) {
|
|
8089
|
+
process.stderr.write(`[cloud-sync] Code context pull failed: ${err instanceof Error ? err.message : String(err)}
|
|
8090
|
+
`);
|
|
8091
|
+
return 0;
|
|
8092
|
+
}
|
|
8093
|
+
}
|
|
8094
|
+
var LOCALHOST_PATTERNS, FETCH_TIMEOUT_MS, PUSH_BATCH_SIZE, ROSTER_LOCK_PATH, LOCK_STALE_MS, _pgPromise, _pgFailed, CLOUD_REUPLOAD_REQUIRED_MESSAGE, ROSTER_DELETIONS_PATH, CODE_CONTEXT_DIR;
|
|
7952
8095
|
var init_cloud_sync = __esm({
|
|
7953
8096
|
"src/lib/cloud-sync.ts"() {
|
|
7954
8097
|
"use strict";
|
|
@@ -7969,6 +8112,7 @@ var init_cloud_sync = __esm({
|
|
|
7969
8112
|
_pgFailed = false;
|
|
7970
8113
|
CLOUD_REUPLOAD_REQUIRED_MESSAGE = "Cloud sync is blocked because this device rotated its memory encryption key. Run `exe-os cloud reupload` first to re-upload the cloud backup with the new key.";
|
|
7971
8114
|
ROSTER_DELETIONS_PATH = path16.join(EXE_AI_DIR, "roster-deletions.json");
|
|
8115
|
+
CODE_CONTEXT_DIR = path16.join(EXE_AI_DIR, "code-context");
|
|
7972
8116
|
}
|
|
7973
8117
|
});
|
|
7974
8118
|
|
|
@@ -8719,6 +8863,24 @@ var init_platform_procedures = __esm({
|
|
|
8719
8863
|
priority: "p0",
|
|
8720
8864
|
content: "When an agent encounters a suspected Exe OS bug, update breakage, MCP/tool failure, installer issue, memory/orchestration defect, or customer-local patch need, it MUST use create_bug_report. Do this before or alongside any local workaround so the report reaches AskExe support directly via the customer's license. Do NOT ask the founder for permission to file a required bug report. If create_bug_report is deferred/lazy-loaded, load it and call it. If it is unavailable in the live MCP surface, report 'create_bug_report unavailable in this session' and save a local report in exe/output \u2014 never claim the tool does not exist unless the live MCP surface was checked. If upstream delivery fails, call support_test (MCP) and include its result in the local report so AskExe can distinguish customer setup, license provisioning, and server intake issues; only ask the founder to run `exe-os support test` if MCP is disconnected/unavailable. Classify first: upstream_bug = reproducible exe-os/platform defect; customer_customization = identity, behavior, procedure, config, branding, workflow preference that belongs in customer-owned layers; emergency_hotfix = temporary local patch. For upstream bugs/emergency hotfixes include version, repro steps, expected/actual, files changed, workaround, and local diff summary. Avoid permanent platform-code patches unless founder approves; if a hotfix is unavoidable, document it in the bug report and re-check after npm update."
|
|
8721
8865
|
},
|
|
8866
|
+
{
|
|
8867
|
+
title: "Bug report status check \u2014 surface available fixes on boot",
|
|
8868
|
+
domain: "support",
|
|
8869
|
+
priority: "p1",
|
|
8870
|
+
content: "Once per session (COO boot only, never repeat), call list_my_bug_reports to check if any previously filed bug reports have been fixed by AskExe. If any report has status 'fixed' with a fixed_version, surface it to the founder immediately: '\u{1F527} N bug fix(es) available \u2014 run exe-os update to get version X.Y.Z'. This is a one-time check at boot, not a recurring poll. If no reports exist or none are fixed, skip silently. If the MCP tool is unavailable or the network call fails, skip silently \u2014 this is informational, not blocking."
|
|
8871
|
+
},
|
|
8872
|
+
{
|
|
8873
|
+
title: "Feature request triage \u2014 upstream feature vs local customization",
|
|
8874
|
+
domain: "support",
|
|
8875
|
+
priority: "p0",
|
|
8876
|
+
content: "When an agent or founder identifies a desired capability that exe-os does not yet provide, the COO (or equivalent coordinator) must decide: is this a local customization (identity, behavior, procedure, config, branding, workflow preference that can be configured in customer-owned layers) or an upstream feature request (a platform capability that requires changes to exe-os code, shipped via npm update)? Local customizations: implement immediately using store_behavior, update_identity, company_procedure, or config changes. Upstream features: use create_feature_request to submit to AskExe. Include use case, business impact, and current workaround. Do NOT ask the founder for permission to file a feature request \u2014 file it proactively when the need is clear."
|
|
8877
|
+
},
|
|
8878
|
+
{
|
|
8879
|
+
title: "Feature request status check \u2014 surface shipped features on boot",
|
|
8880
|
+
domain: "support",
|
|
8881
|
+
priority: "p1",
|
|
8882
|
+
content: "Once per session (COO boot only, never repeat), call list_my_feature_requests to check if any previously filed feature requests have been shipped by AskExe. If any request has status 'shipped' with a shipped_version, surface it to the founder immediately: '\u{1F680} N feature(s) shipped \u2014 run exe-os update to get version X.Y.Z'. This is a one-time check at boot, not a recurring poll. If no requests exist or none are shipped, skip silently. If the MCP tool is unavailable or the network call fails, skip silently \u2014 this is informational, not blocking."
|
|
8883
|
+
},
|
|
8722
8884
|
// --- Operations ---
|
|
8723
8885
|
{
|
|
8724
8886
|
title: "Managers must supervise deployed workers",
|
|
@@ -13300,7 +13462,7 @@ function readQueue() {
|
|
|
13300
13462
|
function writeQueue(queue) {
|
|
13301
13463
|
ensureDir2();
|
|
13302
13464
|
const tmp = `${QUEUE_PATH}.tmp`;
|
|
13303
|
-
writeFileSync18(tmp, JSON.stringify(queue, null, 2));
|
|
13465
|
+
writeFileSync18(tmp, JSON.stringify(queue, null, 2), { mode: 384 });
|
|
13304
13466
|
renameSync5(tmp, QUEUE_PATH);
|
|
13305
13467
|
}
|
|
13306
13468
|
function queueIntercom(targetSession, reason) {
|
|
@@ -18017,12 +18179,14 @@ On EVERY new conversation, before doing anything else:
|
|
|
18017
18179
|
1. **Memory scan**: Run recall_my_memory with broad queries \u2014 "project", "client", "pipeline", "campaign", "deal", "decision", "blocker". Summarize what you find.
|
|
18018
18180
|
2. **Task scan**: Run list_tasks to see what's open, in progress, blocked, or needs review across all employees.
|
|
18019
18181
|
3. **Team check**: Run ask_team_memory for recent activity from CTO/CMO/engineers.
|
|
18020
|
-
4. **
|
|
18182
|
+
4. **Bug fix check** (one-time, never repeat): Call list_my_bug_reports to see if AskExe has fixed any previously filed bugs. If any have status "fixed" with a fixed_version, tell the founder: "\u{1F527} N bug fix(es) available \u2014 run \`exe-os update\` to get version X.Y.Z." Skip silently if none or if the call fails.
|
|
18183
|
+
5. **Present the brief**: Give the founder a concise status report:
|
|
18021
18184
|
- What's active and progressing
|
|
18022
18185
|
- What's blocked and needs attention
|
|
18023
18186
|
- What decisions are pending
|
|
18187
|
+
- Available bug fixes (from step 4, if any)
|
|
18024
18188
|
- What you recommend doing next
|
|
18025
|
-
|
|
18189
|
+
6. Then ask: "What's the priority?"
|
|
18026
18190
|
|
|
18027
18191
|
If this is your FIRST ever conversation (few or no prior memories):
|
|
18028
18192
|
- Search more broadly: "product", "SEO", "meeting", "strategy", "revenue"
|
|
@@ -18042,6 +18206,8 @@ Never say "I have no memories" without first searching broadly. Your memory may
|
|
|
18042
18206
|
- **get_identity** \u2014 read any agent's identity for coordination
|
|
18043
18207
|
- **set_agent_config** \u2014 view or change which tool (Claude Code, Codex, OpenCode) and model each agent uses. Call with no args to show all agents' current settings. Call with agent_id + runtime + model to change.
|
|
18044
18208
|
- **send_message** \u2014 direct intercom to employees
|
|
18209
|
+
- **create_bug_report** \u2014 file a bug when you encounter an Exe OS platform issue
|
|
18210
|
+
- **list_my_bug_reports** \u2014 check status of filed bugs (boot check: surface available fixes to founder)
|
|
18045
18211
|
${PLAN_MODE_COMPAT}
|
|
18046
18212
|
## Completion Workflow
|
|
18047
18213
|
|
|
@@ -18467,7 +18633,7 @@ import {
|
|
|
18467
18633
|
readFileSync as readFileSync26,
|
|
18468
18634
|
writeFileSync as writeFileSync23,
|
|
18469
18635
|
mkdirSync as mkdirSync22,
|
|
18470
|
-
chmodSync as
|
|
18636
|
+
chmodSync as chmodSync4,
|
|
18471
18637
|
readdirSync as readdirSync9,
|
|
18472
18638
|
unlinkSync as unlinkSync15
|
|
18473
18639
|
} from "fs";
|
|
@@ -18488,7 +18654,7 @@ function generateSessionWrappers(packageRoot, homeDir) {
|
|
|
18488
18654
|
for (const src of candidates) {
|
|
18489
18655
|
if (existsSync31(src)) {
|
|
18490
18656
|
writeFileSync23(exeStartDst, readFileSync26(src));
|
|
18491
|
-
|
|
18657
|
+
chmodSync4(exeStartDst, 493);
|
|
18492
18658
|
break;
|
|
18493
18659
|
}
|
|
18494
18660
|
}
|
|
@@ -18552,7 +18718,7 @@ exec "${exeStartDst}" "$0" "$@"
|
|
|
18552
18718
|
exec node "${codexLauncher}" --agent ${emp.name} "$@"
|
|
18553
18719
|
`;
|
|
18554
18720
|
writeFileSync23(wrapperPath, content);
|
|
18555
|
-
|
|
18721
|
+
chmodSync4(wrapperPath, 493);
|
|
18556
18722
|
created++;
|
|
18557
18723
|
}
|
|
18558
18724
|
}
|
|
@@ -18562,7 +18728,7 @@ exec node "${codexLauncher}" --agent ${emp.name} "$@"
|
|
|
18562
18728
|
function writeWrapper(wrapperPath, content) {
|
|
18563
18729
|
try {
|
|
18564
18730
|
writeFileSync23(wrapperPath, content);
|
|
18565
|
-
|
|
18731
|
+
chmodSync4(wrapperPath, 493);
|
|
18566
18732
|
} catch {
|
|
18567
18733
|
}
|
|
18568
18734
|
}
|
|
@@ -19656,6 +19822,10 @@ async function runUpdate(cliArgs) {
|
|
|
19656
19822
|
\u{1F4E6} Update available: v${result.localVersion} \u2192 v${result.remoteVersion}
|
|
19657
19823
|
`);
|
|
19658
19824
|
let proceed = autoMode;
|
|
19825
|
+
if (!proceed && !process.stdin.isTTY) {
|
|
19826
|
+
console.log("Non-interactive mode detected (no TTY). Use --yes to auto-confirm, or run interactively.");
|
|
19827
|
+
process.exit(1);
|
|
19828
|
+
}
|
|
19659
19829
|
if (!proceed) {
|
|
19660
19830
|
const rl = createInterface5({ input: process.stdin, output: process.stdout });
|
|
19661
19831
|
const answer = await new Promise((resolve) => {
|
|
@@ -20107,8 +20277,9 @@ function hydrateEnv(raw, opts) {
|
|
|
20107
20277
|
else if (key === "MONITOR_AGENT_KEY") continue;
|
|
20108
20278
|
else if (key === "EXE_GATEWAY_WS_RELAY_AUTH_TOKEN") replacements[key] = randomHexSecret(24);
|
|
20109
20279
|
else if (key.endsWith("_PASSWORD")) replacements[key] = randomSecret(24);
|
|
20110
|
-
else if (key.endsWith("
|
|
20111
|
-
else if (key
|
|
20280
|
+
else if (key.endsWith("_TOKEN")) replacements[key] = randomHexSecret(32);
|
|
20281
|
+
else if (key.endsWith("_SECRET") || key.endsWith("_SALT")) replacements[key] = randomSecret(32);
|
|
20282
|
+
else if (key.endsWith("_KEY") && key !== "EXE_LICENSE_KEY") continue;
|
|
20112
20283
|
}
|
|
20113
20284
|
if (domain) next = next.replaceAll("CHANGEME_DOMAIN", domain);
|
|
20114
20285
|
next = patchEnv(next, replacements);
|
|
@@ -20505,8 +20676,8 @@ Options:
|
|
|
20505
20676
|
}
|
|
20506
20677
|
function printChanges(changes, composeFile, envFile) {
|
|
20507
20678
|
if (changes.length === 0) {
|
|
20508
|
-
const
|
|
20509
|
-
if (
|
|
20679
|
+
const running2 = areCliContainersRunning(composeFile, envFile);
|
|
20680
|
+
if (running2) {
|
|
20510
20681
|
console.log("Stack .env matches target manifest. Checking container health...\n");
|
|
20511
20682
|
const unhealthy = printContainerHealth(composeFile, envFile);
|
|
20512
20683
|
if (unhealthy > 0) {
|
|
@@ -20515,16 +20686,28 @@ function printChanges(changes, composeFile, envFile) {
|
|
|
20515
20686
|
} else {
|
|
20516
20687
|
console.log("\n\u2705 Stack already matches target manifest. All services healthy.");
|
|
20517
20688
|
}
|
|
20689
|
+
return unhealthy;
|
|
20518
20690
|
} else {
|
|
20519
20691
|
console.log("\u26A0\uFE0F Stack .env matches target manifest but containers are not running. Will start them.");
|
|
20692
|
+
return 1;
|
|
20520
20693
|
}
|
|
20521
|
-
return;
|
|
20522
20694
|
}
|
|
20523
20695
|
console.log("Planned image tag changes:");
|
|
20524
20696
|
for (const c of changes) {
|
|
20525
20697
|
console.log(` - ${c.service}: ${c.key}`);
|
|
20526
20698
|
console.log(` ${c.before ?? "<unset>"} \u2192 ${c.after}`);
|
|
20527
20699
|
}
|
|
20700
|
+
const running = areCliContainersRunning(composeFile, envFile);
|
|
20701
|
+
if (running) {
|
|
20702
|
+
console.log("\nCurrent container health:");
|
|
20703
|
+
const unhealthy = printContainerHealth(composeFile, envFile);
|
|
20704
|
+
if (unhealthy > 0) {
|
|
20705
|
+
console.log(`
|
|
20706
|
+
\u{1F534} ${unhealthy} service(s) currently unhealthy or crashlooping.`);
|
|
20707
|
+
}
|
|
20708
|
+
return unhealthy;
|
|
20709
|
+
}
|
|
20710
|
+
return 0;
|
|
20528
20711
|
}
|
|
20529
20712
|
function areCliContainersRunning(composeFile, envFile) {
|
|
20530
20713
|
try {
|
|
@@ -20634,9 +20817,12 @@ async function main7(args2 = process.argv.slice(2)) {
|
|
|
20634
20817
|
console.log(`Compose: ${opts.composeFile}`);
|
|
20635
20818
|
console.log(`Env: ${opts.envFile}
|
|
20636
20819
|
`);
|
|
20637
|
-
printChanges(plan.changes, opts.composeFile, opts.envFile);
|
|
20820
|
+
const unhealthyCount = printChanges(plan.changes, opts.composeFile, opts.envFile);
|
|
20638
20821
|
printBreaking(plan.breakingChanges);
|
|
20639
|
-
if (opts.check || opts.dryRun)
|
|
20822
|
+
if (opts.check || opts.dryRun) {
|
|
20823
|
+
if (unhealthyCount > 0) process.exitCode = 1;
|
|
20824
|
+
return;
|
|
20825
|
+
}
|
|
20640
20826
|
if (!opts.yes) {
|
|
20641
20827
|
console.error("\nRefusing to update without --yes. Re-run with --yes after reviewing the plan.");
|
|
20642
20828
|
process.exit(2);
|
|
@@ -35190,16 +35376,89 @@ var code_context_index_exports = {};
|
|
|
35190
35376
|
__export(code_context_index_exports, {
|
|
35191
35377
|
analyzeBlastRadius: () => analyzeBlastRadius,
|
|
35192
35378
|
buildCodeContextIndex: () => buildCodeContextIndex,
|
|
35379
|
+
buildCodeContextIndexWithEmbeddings: () => buildCodeContextIndexWithEmbeddings,
|
|
35193
35380
|
getCodeContextIndexPath: () => getCodeContextIndexPath,
|
|
35194
35381
|
getCodeContextStats: () => getCodeContextStats,
|
|
35195
35382
|
loadOrBuildCodeContextIndex: () => loadOrBuildCodeContextIndex,
|
|
35196
35383
|
searchCodeContext: () => searchCodeContext,
|
|
35384
|
+
searchCodeContextSemantic: () => searchCodeContextSemantic,
|
|
35197
35385
|
traceCodeSymbol: () => traceCodeSymbol
|
|
35198
35386
|
});
|
|
35199
35387
|
import crypto14 from "crypto";
|
|
35200
35388
|
import path51 from "path";
|
|
35201
35389
|
import { existsSync as existsSync36, mkdirSync as mkdirSync25, readFileSync as readFileSync32, readdirSync as readdirSync11, statSync as statSync7, writeFileSync as writeFileSync26 } from "fs";
|
|
35202
35390
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
35391
|
+
function vectorStorePath(projectRoot) {
|
|
35392
|
+
const rootHash = hashText(projectRoot).slice(0, 16);
|
|
35393
|
+
return path51.join(indexDir(), `${rootHash}.vectors.json`);
|
|
35394
|
+
}
|
|
35395
|
+
function loadVectorStore(projectRoot) {
|
|
35396
|
+
const file = vectorStorePath(projectRoot);
|
|
35397
|
+
if (!existsSync36(file)) return null;
|
|
35398
|
+
try {
|
|
35399
|
+
const parsed = JSON.parse(readFileSync32(file, "utf8"));
|
|
35400
|
+
if (parsed.version !== VECTOR_STORE_VERSION) return null;
|
|
35401
|
+
return parsed;
|
|
35402
|
+
} catch {
|
|
35403
|
+
return null;
|
|
35404
|
+
}
|
|
35405
|
+
}
|
|
35406
|
+
function saveVectorStore(projectRoot, store) {
|
|
35407
|
+
writeFileSync26(vectorStorePath(projectRoot), JSON.stringify(store));
|
|
35408
|
+
}
|
|
35409
|
+
function cosineSimilarity(a, b) {
|
|
35410
|
+
let dot = 0, normA = 0, normB = 0;
|
|
35411
|
+
for (let i = 0; i < a.length; i++) {
|
|
35412
|
+
dot += a[i] * b[i];
|
|
35413
|
+
normA += a[i] * a[i];
|
|
35414
|
+
normB += b[i] * b[i];
|
|
35415
|
+
}
|
|
35416
|
+
const denom = Math.sqrt(normA) * Math.sqrt(normB);
|
|
35417
|
+
return denom === 0 ? 0 : dot / denom;
|
|
35418
|
+
}
|
|
35419
|
+
async function embedSymbols(index) {
|
|
35420
|
+
const rootHash = hashText(index.projectRoot).slice(0, 16);
|
|
35421
|
+
const existing = loadVectorStore(index.projectRoot);
|
|
35422
|
+
const store = {
|
|
35423
|
+
version: VECTOR_STORE_VERSION,
|
|
35424
|
+
projectRootHash: rootHash,
|
|
35425
|
+
vectors: {}
|
|
35426
|
+
};
|
|
35427
|
+
const allSymbols = [];
|
|
35428
|
+
for (const file of Object.values(index.files)) {
|
|
35429
|
+
for (const symbol of file.symbols) {
|
|
35430
|
+
if (existing?.vectors[symbol.id]) {
|
|
35431
|
+
store.vectors[symbol.id] = existing.vectors[symbol.id];
|
|
35432
|
+
} else {
|
|
35433
|
+
allSymbols.push({ id: symbol.id, text: symbol.summary || `${symbol.kind} ${symbol.name} in ${symbol.filePath}` });
|
|
35434
|
+
}
|
|
35435
|
+
}
|
|
35436
|
+
}
|
|
35437
|
+
if (allSymbols.length === 0) {
|
|
35438
|
+
saveVectorStore(index.projectRoot, store);
|
|
35439
|
+
return store;
|
|
35440
|
+
}
|
|
35441
|
+
const connected = await connectEmbedDaemon().catch(() => false);
|
|
35442
|
+
if (!connected) {
|
|
35443
|
+
saveVectorStore(index.projectRoot, store);
|
|
35444
|
+
return store;
|
|
35445
|
+
}
|
|
35446
|
+
for (let i = 0; i < allSymbols.length; i += EMBED_BATCH_SIZE) {
|
|
35447
|
+
const batch = allSymbols.slice(i, i + EMBED_BATCH_SIZE);
|
|
35448
|
+
const texts = batch.map((s) => s.text);
|
|
35449
|
+
try {
|
|
35450
|
+
const vectors = await embedBatchViaClient(texts, "low");
|
|
35451
|
+
if (vectors && vectors.length === batch.length) {
|
|
35452
|
+
for (let j = 0; j < batch.length; j++) {
|
|
35453
|
+
store.vectors[batch[j].id] = vectors[j];
|
|
35454
|
+
}
|
|
35455
|
+
}
|
|
35456
|
+
} catch {
|
|
35457
|
+
}
|
|
35458
|
+
}
|
|
35459
|
+
saveVectorStore(index.projectRoot, store);
|
|
35460
|
+
return store;
|
|
35461
|
+
}
|
|
35203
35462
|
function normalizeProjectRoot(projectRoot) {
|
|
35204
35463
|
return path51.resolve(projectRoot || process.cwd());
|
|
35205
35464
|
}
|
|
@@ -35475,7 +35734,7 @@ function filteredFiles(index, options = {}) {
|
|
|
35475
35734
|
return matchesPath(file.path, options.paths);
|
|
35476
35735
|
});
|
|
35477
35736
|
}
|
|
35478
|
-
function
|
|
35737
|
+
function lexicalSearch(query, options = {}) {
|
|
35479
35738
|
const terms = tokenize2(query);
|
|
35480
35739
|
if (terms.length === 0) return [];
|
|
35481
35740
|
const index = loadOrBuildCodeContextIndex({ projectRoot: options.projectRoot, force: options.force || options.refreshIndex, maxFiles: options.maxFiles });
|
|
@@ -35501,6 +35760,81 @@ function searchCodeContext(query, options = {}) {
|
|
|
35501
35760
|
const limit = options.limit ?? 20;
|
|
35502
35761
|
return results.sort((a, b) => b.score - a.score || a.filePath.localeCompare(b.filePath)).slice(offset, offset + limit);
|
|
35503
35762
|
}
|
|
35763
|
+
function searchCodeContext(query, options = {}) {
|
|
35764
|
+
return lexicalSearch(query, options);
|
|
35765
|
+
}
|
|
35766
|
+
async function searchCodeContextSemantic(query, options = {}) {
|
|
35767
|
+
const terms = tokenize2(query);
|
|
35768
|
+
if (terms.length === 0) return [];
|
|
35769
|
+
const index = loadOrBuildCodeContextIndex({ projectRoot: options.projectRoot, force: options.force || options.refreshIndex, maxFiles: options.maxFiles });
|
|
35770
|
+
const projectRoot = normalizeProjectRoot(options.projectRoot);
|
|
35771
|
+
const vectorStore = loadVectorStore(projectRoot);
|
|
35772
|
+
if (!vectorStore || Object.keys(vectorStore.vectors).length === 0) {
|
|
35773
|
+
return lexicalSearch(query, options);
|
|
35774
|
+
}
|
|
35775
|
+
let queryVector = null;
|
|
35776
|
+
try {
|
|
35777
|
+
const connected = await connectEmbedDaemon().catch(() => false);
|
|
35778
|
+
if (connected) {
|
|
35779
|
+
const result = await embedBatchViaClient([query], "high");
|
|
35780
|
+
if (result && result.length === 1) queryVector = result[0];
|
|
35781
|
+
}
|
|
35782
|
+
} catch {
|
|
35783
|
+
}
|
|
35784
|
+
if (!queryVector) return lexicalSearch(query, options);
|
|
35785
|
+
const files = filteredFiles(index, options);
|
|
35786
|
+
const candidates = [];
|
|
35787
|
+
for (const file of files) {
|
|
35788
|
+
for (const symbol of file.symbols) {
|
|
35789
|
+
const lexical = scoreSymbol(symbol, terms);
|
|
35790
|
+
const vec = vectorStore.vectors[symbol.id];
|
|
35791
|
+
const vectorScore = vec ? cosineSimilarity(queryVector, vec) : 0;
|
|
35792
|
+
if (lexical.score > 0 || vectorScore > 0.3) {
|
|
35793
|
+
candidates.push({
|
|
35794
|
+
symbol,
|
|
35795
|
+
lexicalScore: lexical.score,
|
|
35796
|
+
vectorScore,
|
|
35797
|
+
matches: lexical.matches
|
|
35798
|
+
});
|
|
35799
|
+
}
|
|
35800
|
+
}
|
|
35801
|
+
}
|
|
35802
|
+
const byLexical = [...candidates].sort((a, b) => b.lexicalScore - a.lexicalScore);
|
|
35803
|
+
const byVector = [...candidates].sort((a, b) => b.vectorScore - a.vectorScore);
|
|
35804
|
+
const lexicalRank = /* @__PURE__ */ new Map();
|
|
35805
|
+
const vectorRank = /* @__PURE__ */ new Map();
|
|
35806
|
+
byLexical.forEach((c, i) => lexicalRank.set(c.symbol.id, i + 1));
|
|
35807
|
+
byVector.forEach((c, i) => vectorRank.set(c.symbol.id, i + 1));
|
|
35808
|
+
const VECTOR_WEIGHT = 0.6;
|
|
35809
|
+
const LEXICAL_WEIGHT = 0.4;
|
|
35810
|
+
const fused = candidates.map((c) => {
|
|
35811
|
+
const lRank = lexicalRank.get(c.symbol.id) ?? candidates.length + 1;
|
|
35812
|
+
const vRank = vectorRank.get(c.symbol.id) ?? candidates.length + 1;
|
|
35813
|
+
const rrfScore = VECTOR_WEIGHT * (1 / (RRF_K + vRank)) + LEXICAL_WEIGHT * (1 / (RRF_K + lRank));
|
|
35814
|
+
return {
|
|
35815
|
+
symbol: c.symbol,
|
|
35816
|
+
score: rrfScore,
|
|
35817
|
+
matches: c.vectorScore > 0.3 ? [...c.matches, `semantic=${c.vectorScore.toFixed(3)}`] : c.matches,
|
|
35818
|
+
filePath: c.symbol.filePath,
|
|
35819
|
+
language: c.symbol.language,
|
|
35820
|
+
content: c.symbol.text,
|
|
35821
|
+
startLine: c.symbol.startLine,
|
|
35822
|
+
endLine: c.symbol.endLine
|
|
35823
|
+
};
|
|
35824
|
+
});
|
|
35825
|
+
const offset = Math.max(0, options.offset ?? 0);
|
|
35826
|
+
const limit = options.limit ?? 20;
|
|
35827
|
+
return fused.sort((a, b) => b.score - a.score || a.filePath.localeCompare(b.filePath)).slice(offset, offset + limit);
|
|
35828
|
+
}
|
|
35829
|
+
async function buildCodeContextIndexWithEmbeddings(options = {}) {
|
|
35830
|
+
const index = buildCodeContextIndex(options);
|
|
35831
|
+
const existingStore = loadVectorStore(index.projectRoot);
|
|
35832
|
+
const existingCount = existingStore ? Object.keys(existingStore.vectors).length : 0;
|
|
35833
|
+
const store = await embedSymbols(index);
|
|
35834
|
+
const vectorCount = Object.keys(store.vectors).length;
|
|
35835
|
+
const newEmbeddings = vectorCount - Math.min(existingCount, vectorCount);
|
|
35836
|
+
return { index, vectorCount, newEmbeddings };
|
|
35837
|
+
}
|
|
35504
35838
|
function dependentsMap(index) {
|
|
35505
35839
|
const map = /* @__PURE__ */ new Map();
|
|
35506
35840
|
for (const file of Object.values(index.files)) {
|
|
@@ -35592,15 +35926,19 @@ function getCodeContextStats(options = {}) {
|
|
|
35592
35926
|
indexPath: getCodeContextIndexPath(index.projectRoot)
|
|
35593
35927
|
};
|
|
35594
35928
|
}
|
|
35595
|
-
var INDEX_VERSION, DEFAULT_MAX_FILES, IGNORE_SEGMENTS;
|
|
35929
|
+
var VECTOR_STORE_VERSION, EMBED_BATCH_SIZE, INDEX_VERSION, DEFAULT_MAX_FILES, IGNORE_SEGMENTS, RRF_K;
|
|
35596
35930
|
var init_code_context_index = __esm({
|
|
35597
35931
|
"src/lib/code-context-index.ts"() {
|
|
35598
35932
|
"use strict";
|
|
35599
35933
|
init_config();
|
|
35600
35934
|
init_code_chunker();
|
|
35935
|
+
init_exe_daemon_client();
|
|
35936
|
+
VECTOR_STORE_VERSION = 1;
|
|
35937
|
+
EMBED_BATCH_SIZE = 64;
|
|
35601
35938
|
INDEX_VERSION = 2;
|
|
35602
35939
|
DEFAULT_MAX_FILES = 5e3;
|
|
35603
35940
|
IGNORE_SEGMENTS = /* @__PURE__ */ new Set(["node_modules", "dist", ".git", "coverage", ".worktrees", ".next", "build", "target", "vendor"]);
|
|
35941
|
+
RRF_K = 60;
|
|
35604
35942
|
}
|
|
35605
35943
|
});
|
|
35606
35944
|
|
package/dist/bin/exe-agent.js
CHANGED
|
@@ -1271,6 +1271,7 @@ var OllamaProvider = class {
|
|
|
1271
1271
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
1272
1272
|
|
|
1273
1273
|
// src/lib/database.ts
|
|
1274
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
1274
1275
|
import { createClient } from "@libsql/client";
|
|
1275
1276
|
|
|
1276
1277
|
// src/lib/employees.ts
|
|
@@ -1377,6 +1378,24 @@ var PLATFORM_PROCEDURES = [
|
|
|
1377
1378
|
priority: "p0",
|
|
1378
1379
|
content: "When an agent encounters a suspected Exe OS bug, update breakage, MCP/tool failure, installer issue, memory/orchestration defect, or customer-local patch need, it MUST use create_bug_report. Do this before or alongside any local workaround so the report reaches AskExe support directly via the customer's license. Do NOT ask the founder for permission to file a required bug report. If create_bug_report is deferred/lazy-loaded, load it and call it. If it is unavailable in the live MCP surface, report 'create_bug_report unavailable in this session' and save a local report in exe/output \u2014 never claim the tool does not exist unless the live MCP surface was checked. If upstream delivery fails, call support_test (MCP) and include its result in the local report so AskExe can distinguish customer setup, license provisioning, and server intake issues; only ask the founder to run `exe-os support test` if MCP is disconnected/unavailable. Classify first: upstream_bug = reproducible exe-os/platform defect; customer_customization = identity, behavior, procedure, config, branding, workflow preference that belongs in customer-owned layers; emergency_hotfix = temporary local patch. For upstream bugs/emergency hotfixes include version, repro steps, expected/actual, files changed, workaround, and local diff summary. Avoid permanent platform-code patches unless founder approves; if a hotfix is unavoidable, document it in the bug report and re-check after npm update."
|
|
1379
1380
|
},
|
|
1381
|
+
{
|
|
1382
|
+
title: "Bug report status check \u2014 surface available fixes on boot",
|
|
1383
|
+
domain: "support",
|
|
1384
|
+
priority: "p1",
|
|
1385
|
+
content: "Once per session (COO boot only, never repeat), call list_my_bug_reports to check if any previously filed bug reports have been fixed by AskExe. If any report has status 'fixed' with a fixed_version, surface it to the founder immediately: '\u{1F527} N bug fix(es) available \u2014 run exe-os update to get version X.Y.Z'. This is a one-time check at boot, not a recurring poll. If no reports exist or none are fixed, skip silently. If the MCP tool is unavailable or the network call fails, skip silently \u2014 this is informational, not blocking."
|
|
1386
|
+
},
|
|
1387
|
+
{
|
|
1388
|
+
title: "Feature request triage \u2014 upstream feature vs local customization",
|
|
1389
|
+
domain: "support",
|
|
1390
|
+
priority: "p0",
|
|
1391
|
+
content: "When an agent or founder identifies a desired capability that exe-os does not yet provide, the COO (or equivalent coordinator) must decide: is this a local customization (identity, behavior, procedure, config, branding, workflow preference that can be configured in customer-owned layers) or an upstream feature request (a platform capability that requires changes to exe-os code, shipped via npm update)? Local customizations: implement immediately using store_behavior, update_identity, company_procedure, or config changes. Upstream features: use create_feature_request to submit to AskExe. Include use case, business impact, and current workaround. Do NOT ask the founder for permission to file a feature request \u2014 file it proactively when the need is clear."
|
|
1392
|
+
},
|
|
1393
|
+
{
|
|
1394
|
+
title: "Feature request status check \u2014 surface shipped features on boot",
|
|
1395
|
+
domain: "support",
|
|
1396
|
+
priority: "p1",
|
|
1397
|
+
content: "Once per session (COO boot only, never repeat), call list_my_feature_requests to check if any previously filed feature requests have been shipped by AskExe. If any request has status 'shipped' with a shipped_version, surface it to the founder immediately: '\u{1F680} N feature(s) shipped \u2014 run exe-os update to get version X.Y.Z'. This is a one-time check at boot, not a recurring poll. If no requests exist or none are shipped, skip silently. If the MCP tool is unavailable or the network call fails, skip silently \u2014 this is informational, not blocking."
|
|
1398
|
+
},
|
|
1380
1399
|
// --- Operations ---
|
|
1381
1400
|
{
|
|
1382
1401
|
title: "Managers must supervise deployed workers",
|