@askexenow/exe-os 0.9.85 → 0.9.87
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/agentic-ontology-backfill.js +50 -14
- package/dist/bin/agentic-reflection-backfill.js +50 -14
- package/dist/bin/agentic-semantic-label.js +50 -14
- package/dist/bin/backfill-conversations.js +50 -14
- package/dist/bin/backfill-responses.js +50 -14
- package/dist/bin/backfill-vectors.js +50 -14
- package/dist/bin/bulk-sync-postgres.js +50 -14
- package/dist/bin/cleanup-stale-review-tasks.js +53 -17
- package/dist/bin/cli.js +339 -81
- package/dist/bin/exe-agent.js +18 -0
- package/dist/bin/exe-assign.js +50 -14
- package/dist/bin/exe-boot.js +75 -39
- package/dist/bin/exe-call.js +18 -0
- package/dist/bin/exe-cloud.js +40 -4
- package/dist/bin/exe-dispatch.js +61 -25
- package/dist/bin/exe-doctor.js +40 -4
- package/dist/bin/exe-export-behaviors.js +50 -14
- package/dist/bin/exe-forget.js +50 -14
- package/dist/bin/exe-gateway.js +65 -29
- package/dist/bin/exe-heartbeat.js +55 -19
- package/dist/bin/exe-kill.js +54 -18
- package/dist/bin/exe-launch-agent.js +58 -22
- package/dist/bin/exe-new-employee.js +33 -2
- package/dist/bin/exe-pending-messages.js +53 -17
- package/dist/bin/exe-pending-notifications.js +53 -17
- package/dist/bin/exe-pending-reviews.js +55 -19
- package/dist/bin/exe-rename.js +52 -16
- package/dist/bin/exe-review.js +50 -14
- package/dist/bin/exe-search.js +58 -22
- package/dist/bin/exe-session-cleanup.js +85 -44
- package/dist/bin/exe-start-codex.js +57 -21
- package/dist/bin/exe-start-opencode.js +55 -19
- package/dist/bin/exe-status.js +62 -26
- package/dist/bin/exe-team.js +50 -14
- package/dist/bin/git-sweep.js +63 -27
- package/dist/bin/graph-backfill.js +50 -14
- package/dist/bin/graph-export.js +50 -14
- package/dist/bin/install.js +9 -0
- package/dist/bin/intercom-check.js +67 -31
- package/dist/bin/scan-tasks.js +63 -27
- package/dist/bin/setup.js +53 -13
- package/dist/bin/shard-migrate.js +50 -14
- package/dist/bin/stack-update.js +59 -2
- package/dist/bin/update.js +1 -1
- package/dist/gateway/index.js +65 -29
- package/dist/hooks/bug-report-worker.js +65 -29
- package/dist/hooks/codex-stop-task-finalizer.js +59 -23
- package/dist/hooks/commit-complete.js +64 -28
- package/dist/hooks/error-recall.js +62 -26
- package/dist/hooks/ingest-worker.js +4 -4
- package/dist/hooks/ingest.js +56 -20
- package/dist/hooks/instructions-loaded.js +50 -14
- package/dist/hooks/notification.js +50 -14
- package/dist/hooks/post-compact.js +50 -14
- package/dist/hooks/post-tool-combined.js +63 -27
- package/dist/hooks/pre-compact.js +61 -25
- package/dist/hooks/pre-tool-use.js +58 -22
- package/dist/hooks/prompt-submit.js +78 -42
- package/dist/hooks/session-end.js +66 -30
- package/dist/hooks/session-start.js +68 -32
- package/dist/hooks/stop.js +53 -17
- package/dist/hooks/subagent-stop.js +50 -14
- package/dist/hooks/summary-worker.js +55 -19
- package/dist/index.js +61 -25
- package/dist/lib/cloud-sync.js +32 -14
- package/dist/lib/database.js +22 -4
- package/dist/lib/db-daemon-client.js +16 -4
- package/dist/lib/db.js +22 -4
- package/dist/lib/device-registry.js +22 -4
- package/dist/lib/embedder.js +16 -4
- package/dist/lib/employee-templates.js +18 -0
- package/dist/lib/exe-daemon-client.js +16 -4
- package/dist/lib/exe-daemon.js +874 -232
- package/dist/lib/hybrid-search.js +58 -22
- package/dist/lib/identity-templates.js +6 -2
- package/dist/lib/schedules.js +53 -17
- package/dist/lib/skill-learning.js +16 -4
- package/dist/lib/store.js +50 -14
- package/dist/lib/tasks.js +16 -4
- package/dist/lib/tmux-routing.js +18 -6
- package/dist/mcp/server.js +809 -200
- package/dist/mcp/tools/create-task.js +24 -8
- package/dist/mcp/tools/update-task.js +18 -6
- package/dist/runtime/index.js +61 -25
- package/dist/tui/App.js +91 -55
- package/package.json +1 -1
package/dist/bin/exe-agent.js
CHANGED
|
@@ -1377,6 +1377,24 @@ var PLATFORM_PROCEDURES = [
|
|
|
1377
1377
|
priority: "p0",
|
|
1378
1378
|
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
1379
|
},
|
|
1380
|
+
{
|
|
1381
|
+
title: "Bug report status check \u2014 surface available fixes on boot",
|
|
1382
|
+
domain: "support",
|
|
1383
|
+
priority: "p1",
|
|
1384
|
+
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."
|
|
1385
|
+
},
|
|
1386
|
+
{
|
|
1387
|
+
title: "Feature request triage \u2014 upstream feature vs local customization",
|
|
1388
|
+
domain: "support",
|
|
1389
|
+
priority: "p0",
|
|
1390
|
+
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."
|
|
1391
|
+
},
|
|
1392
|
+
{
|
|
1393
|
+
title: "Feature request status check \u2014 surface shipped features on boot",
|
|
1394
|
+
domain: "support",
|
|
1395
|
+
priority: "p1",
|
|
1396
|
+
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."
|
|
1397
|
+
},
|
|
1380
1398
|
// --- Operations ---
|
|
1381
1399
|
{
|
|
1382
1400
|
title: "Managers must supervise deployed workers",
|
package/dist/bin/exe-assign.js
CHANGED
|
@@ -356,7 +356,7 @@ var init_daemon_auth = __esm({
|
|
|
356
356
|
// src/lib/exe-daemon-client.ts
|
|
357
357
|
import net from "net";
|
|
358
358
|
import os3 from "os";
|
|
359
|
-
import { spawn } from "child_process";
|
|
359
|
+
import { spawn, execSync as execSync2 } from "child_process";
|
|
360
360
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
361
361
|
import { existsSync as existsSync5, unlinkSync as unlinkSync2, readFileSync as readFileSync4, openSync, closeSync, statSync } from "fs";
|
|
362
362
|
import path4 from "path";
|
|
@@ -386,6 +386,14 @@ function handleData(chunk) {
|
|
|
386
386
|
}
|
|
387
387
|
}
|
|
388
388
|
}
|
|
389
|
+
function isZombie(pid) {
|
|
390
|
+
try {
|
|
391
|
+
const state = execSync2(`ps -p ${pid} -o state=`, { encoding: "utf8", timeout: 2e3 }).trim();
|
|
392
|
+
return state.startsWith("Z");
|
|
393
|
+
} catch {
|
|
394
|
+
return false;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
389
397
|
function cleanupStaleFiles() {
|
|
390
398
|
if (existsSync5(PID_PATH)) {
|
|
391
399
|
try {
|
|
@@ -393,7 +401,11 @@ function cleanupStaleFiles() {
|
|
|
393
401
|
if (pid > 0) {
|
|
394
402
|
try {
|
|
395
403
|
process.kill(pid, 0);
|
|
396
|
-
|
|
404
|
+
if (!isZombie(pid)) {
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
process.stderr.write(`[exed-client] PID ${pid} is a zombie \u2014 cleaning up stale files
|
|
408
|
+
`);
|
|
397
409
|
} catch {
|
|
398
410
|
}
|
|
399
411
|
}
|
|
@@ -421,8 +433,8 @@ function findPackageRoot() {
|
|
|
421
433
|
function getAvailableMemoryGB() {
|
|
422
434
|
if (process.platform === "darwin") {
|
|
423
435
|
try {
|
|
424
|
-
const { execSync:
|
|
425
|
-
const vmstat =
|
|
436
|
+
const { execSync: execSync4 } = __require("child_process");
|
|
437
|
+
const vmstat = execSync4("vm_stat", { encoding: "utf8" });
|
|
426
438
|
const pageSize = 16384;
|
|
427
439
|
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
428
440
|
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
@@ -2983,6 +2995,12 @@ async function disposeDatabase() {
|
|
|
2983
2995
|
clearInterval(_walCheckpointTimer);
|
|
2984
2996
|
_walCheckpointTimer = null;
|
|
2985
2997
|
}
|
|
2998
|
+
if (_client) {
|
|
2999
|
+
try {
|
|
3000
|
+
await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
3001
|
+
} catch {
|
|
3002
|
+
}
|
|
3003
|
+
}
|
|
2986
3004
|
if (_daemonClient) {
|
|
2987
3005
|
_daemonClient.close();
|
|
2988
3006
|
_daemonClient = null;
|
|
@@ -3514,6 +3532,24 @@ var init_platform_procedures = __esm({
|
|
|
3514
3532
|
priority: "p0",
|
|
3515
3533
|
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."
|
|
3516
3534
|
},
|
|
3535
|
+
{
|
|
3536
|
+
title: "Bug report status check \u2014 surface available fixes on boot",
|
|
3537
|
+
domain: "support",
|
|
3538
|
+
priority: "p1",
|
|
3539
|
+
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."
|
|
3540
|
+
},
|
|
3541
|
+
{
|
|
3542
|
+
title: "Feature request triage \u2014 upstream feature vs local customization",
|
|
3543
|
+
domain: "support",
|
|
3544
|
+
priority: "p0",
|
|
3545
|
+
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."
|
|
3546
|
+
},
|
|
3547
|
+
{
|
|
3548
|
+
title: "Feature request status check \u2014 surface shipped features on boot",
|
|
3549
|
+
domain: "support",
|
|
3550
|
+
priority: "p1",
|
|
3551
|
+
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."
|
|
3552
|
+
},
|
|
3517
3553
|
// --- Operations ---
|
|
3518
3554
|
{
|
|
3519
3555
|
title: "Managers must supervise deployed workers",
|
|
@@ -4283,7 +4319,7 @@ init_database();
|
|
|
4283
4319
|
// src/lib/keychain.ts
|
|
4284
4320
|
import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
4285
4321
|
import { existsSync as existsSync6, statSync as statSync2 } from "fs";
|
|
4286
|
-
import { execSync as
|
|
4322
|
+
import { execSync as execSync3 } from "child_process";
|
|
4287
4323
|
import path6 from "path";
|
|
4288
4324
|
import os5 from "os";
|
|
4289
4325
|
var SERVICE = "exe-os";
|
|
@@ -4304,13 +4340,13 @@ function linuxSecretAvailable() {
|
|
|
4304
4340
|
if (process.platform !== "linux") return false;
|
|
4305
4341
|
if (linuxSecretAvailability !== null) return linuxSecretAvailability;
|
|
4306
4342
|
try {
|
|
4307
|
-
|
|
4343
|
+
execSync3("command -v secret-tool >/dev/null 2>&1", { timeout: 1e3 });
|
|
4308
4344
|
} catch {
|
|
4309
4345
|
linuxSecretAvailability = false;
|
|
4310
4346
|
return false;
|
|
4311
4347
|
}
|
|
4312
4348
|
try {
|
|
4313
|
-
|
|
4349
|
+
execSync3("secret-tool search --all exe-os probe >/dev/null 2>&1", { timeout: 1e3 });
|
|
4314
4350
|
linuxSecretAvailability = true;
|
|
4315
4351
|
} catch {
|
|
4316
4352
|
linuxSecretAvailability = false;
|
|
@@ -4334,7 +4370,7 @@ function macKeychainGet(service = SERVICE) {
|
|
|
4334
4370
|
if (!nativeKeychainAllowed()) return null;
|
|
4335
4371
|
if (process.platform !== "darwin") return null;
|
|
4336
4372
|
try {
|
|
4337
|
-
return
|
|
4373
|
+
return execSync3(
|
|
4338
4374
|
`security find-generic-password -s "${service}" -a "${ACCOUNT}" -w 2>/dev/null`,
|
|
4339
4375
|
{ encoding: "utf-8", timeout: 5e3 }
|
|
4340
4376
|
).trim();
|
|
@@ -4347,13 +4383,13 @@ function macKeychainSet(value, service = SERVICE) {
|
|
|
4347
4383
|
if (process.platform !== "darwin") return false;
|
|
4348
4384
|
try {
|
|
4349
4385
|
try {
|
|
4350
|
-
|
|
4386
|
+
execSync3(
|
|
4351
4387
|
`security delete-generic-password -s "${service}" -a "${ACCOUNT}" 2>/dev/null`,
|
|
4352
4388
|
{ timeout: 5e3 }
|
|
4353
4389
|
);
|
|
4354
4390
|
} catch {
|
|
4355
4391
|
}
|
|
4356
|
-
|
|
4392
|
+
execSync3(
|
|
4357
4393
|
`security add-generic-password -s "${service}" -a "${ACCOUNT}" -w "${value}"`,
|
|
4358
4394
|
{ timeout: 5e3 }
|
|
4359
4395
|
);
|
|
@@ -4366,7 +4402,7 @@ function macKeychainDelete(service = SERVICE) {
|
|
|
4366
4402
|
if (!nativeKeychainAllowed()) return false;
|
|
4367
4403
|
if (process.platform !== "darwin") return false;
|
|
4368
4404
|
try {
|
|
4369
|
-
|
|
4405
|
+
execSync3(
|
|
4370
4406
|
`security delete-generic-password -s "${service}" -a "${ACCOUNT}" 2>/dev/null`,
|
|
4371
4407
|
{ timeout: 5e3 }
|
|
4372
4408
|
);
|
|
@@ -4378,7 +4414,7 @@ function macKeychainDelete(service = SERVICE) {
|
|
|
4378
4414
|
function linuxSecretGet(service = SERVICE) {
|
|
4379
4415
|
if (!linuxSecretAvailable()) return null;
|
|
4380
4416
|
try {
|
|
4381
|
-
return
|
|
4417
|
+
return execSync3(
|
|
4382
4418
|
`secret-tool lookup service "${service}" account "${ACCOUNT}" 2>/dev/null`,
|
|
4383
4419
|
{ encoding: "utf-8", timeout: 5e3 }
|
|
4384
4420
|
).trim();
|
|
@@ -4389,7 +4425,7 @@ function linuxSecretGet(service = SERVICE) {
|
|
|
4389
4425
|
function linuxSecretSet(value, service = SERVICE) {
|
|
4390
4426
|
if (!linuxSecretAvailable()) return false;
|
|
4391
4427
|
try {
|
|
4392
|
-
|
|
4428
|
+
execSync3(
|
|
4393
4429
|
`echo -n "${value}" | secret-tool store --label="exe-os master key" service "${service}" account "${ACCOUNT}" 2>/dev/null`,
|
|
4394
4430
|
{ timeout: 5e3 }
|
|
4395
4431
|
);
|
|
@@ -4402,7 +4438,7 @@ function linuxSecretDelete(service = SERVICE) {
|
|
|
4402
4438
|
if (!nativeKeychainAllowed()) return false;
|
|
4403
4439
|
if (process.platform !== "linux") return false;
|
|
4404
4440
|
try {
|
|
4405
|
-
|
|
4441
|
+
execSync3(
|
|
4406
4442
|
`secret-tool clear service "${service}" account "${ACCOUNT}" 2>/dev/null`,
|
|
4407
4443
|
{ timeout: 5e3 }
|
|
4408
4444
|
);
|
package/dist/bin/exe-boot.js
CHANGED
|
@@ -1134,7 +1134,7 @@ var init_daemon_auth = __esm({
|
|
|
1134
1134
|
// src/lib/exe-daemon-client.ts
|
|
1135
1135
|
import net from "net";
|
|
1136
1136
|
import os4 from "os";
|
|
1137
|
-
import { spawn } from "child_process";
|
|
1137
|
+
import { spawn, execSync as execSync2 } from "child_process";
|
|
1138
1138
|
import { randomUUID } from "crypto";
|
|
1139
1139
|
import { existsSync as existsSync5, unlinkSync as unlinkSync2, readFileSync as readFileSync4, openSync, closeSync, statSync } from "fs";
|
|
1140
1140
|
import path5 from "path";
|
|
@@ -1164,6 +1164,14 @@ function handleData(chunk) {
|
|
|
1164
1164
|
}
|
|
1165
1165
|
}
|
|
1166
1166
|
}
|
|
1167
|
+
function isZombie(pid) {
|
|
1168
|
+
try {
|
|
1169
|
+
const state = execSync2(`ps -p ${pid} -o state=`, { encoding: "utf8", timeout: 2e3 }).trim();
|
|
1170
|
+
return state.startsWith("Z");
|
|
1171
|
+
} catch {
|
|
1172
|
+
return false;
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1167
1175
|
function cleanupStaleFiles() {
|
|
1168
1176
|
if (existsSync5(PID_PATH)) {
|
|
1169
1177
|
try {
|
|
@@ -1171,7 +1179,11 @@ function cleanupStaleFiles() {
|
|
|
1171
1179
|
if (pid > 0) {
|
|
1172
1180
|
try {
|
|
1173
1181
|
process.kill(pid, 0);
|
|
1174
|
-
|
|
1182
|
+
if (!isZombie(pid)) {
|
|
1183
|
+
return;
|
|
1184
|
+
}
|
|
1185
|
+
process.stderr.write(`[exed-client] PID ${pid} is a zombie \u2014 cleaning up stale files
|
|
1186
|
+
`);
|
|
1175
1187
|
} catch {
|
|
1176
1188
|
}
|
|
1177
1189
|
}
|
|
@@ -1199,8 +1211,8 @@ function findPackageRoot() {
|
|
|
1199
1211
|
function getAvailableMemoryGB() {
|
|
1200
1212
|
if (process.platform === "darwin") {
|
|
1201
1213
|
try {
|
|
1202
|
-
const { execSync:
|
|
1203
|
-
const vmstat =
|
|
1214
|
+
const { execSync: execSync12 } = __require("child_process");
|
|
1215
|
+
const vmstat = execSync12("vm_stat", { encoding: "utf8" });
|
|
1204
1216
|
const pageSize = 16384;
|
|
1205
1217
|
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
1206
1218
|
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
@@ -3135,6 +3147,12 @@ async function disposeDatabase() {
|
|
|
3135
3147
|
clearInterval(_walCheckpointTimer);
|
|
3136
3148
|
_walCheckpointTimer = null;
|
|
3137
3149
|
}
|
|
3150
|
+
if (_client) {
|
|
3151
|
+
try {
|
|
3152
|
+
await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
3153
|
+
} catch {
|
|
3154
|
+
}
|
|
3155
|
+
}
|
|
3138
3156
|
if (_daemonClient) {
|
|
3139
3157
|
_daemonClient.close();
|
|
3140
3158
|
_daemonClient = null;
|
|
@@ -3251,6 +3269,24 @@ var init_platform_procedures = __esm({
|
|
|
3251
3269
|
priority: "p0",
|
|
3252
3270
|
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."
|
|
3253
3271
|
},
|
|
3272
|
+
{
|
|
3273
|
+
title: "Bug report status check \u2014 surface available fixes on boot",
|
|
3274
|
+
domain: "support",
|
|
3275
|
+
priority: "p1",
|
|
3276
|
+
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."
|
|
3277
|
+
},
|
|
3278
|
+
{
|
|
3279
|
+
title: "Feature request triage \u2014 upstream feature vs local customization",
|
|
3280
|
+
domain: "support",
|
|
3281
|
+
priority: "p0",
|
|
3282
|
+
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."
|
|
3283
|
+
},
|
|
3284
|
+
{
|
|
3285
|
+
title: "Feature request status check \u2014 surface shipped features on boot",
|
|
3286
|
+
domain: "support",
|
|
3287
|
+
priority: "p1",
|
|
3288
|
+
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."
|
|
3289
|
+
},
|
|
3254
3290
|
// --- Operations ---
|
|
3255
3291
|
{
|
|
3256
3292
|
title: "Managers must supervise deployed workers",
|
|
@@ -3453,7 +3489,7 @@ __export(keychain_exports, {
|
|
|
3453
3489
|
});
|
|
3454
3490
|
import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
3455
3491
|
import { existsSync as existsSync6, statSync as statSync2 } from "fs";
|
|
3456
|
-
import { execSync as
|
|
3492
|
+
import { execSync as execSync3 } from "child_process";
|
|
3457
3493
|
import path6 from "path";
|
|
3458
3494
|
import os5 from "os";
|
|
3459
3495
|
function getKeyDir() {
|
|
@@ -3470,13 +3506,13 @@ function linuxSecretAvailable() {
|
|
|
3470
3506
|
if (process.platform !== "linux") return false;
|
|
3471
3507
|
if (linuxSecretAvailability !== null) return linuxSecretAvailability;
|
|
3472
3508
|
try {
|
|
3473
|
-
|
|
3509
|
+
execSync3("command -v secret-tool >/dev/null 2>&1", { timeout: 1e3 });
|
|
3474
3510
|
} catch {
|
|
3475
3511
|
linuxSecretAvailability = false;
|
|
3476
3512
|
return false;
|
|
3477
3513
|
}
|
|
3478
3514
|
try {
|
|
3479
|
-
|
|
3515
|
+
execSync3("secret-tool search --all exe-os probe >/dev/null 2>&1", { timeout: 1e3 });
|
|
3480
3516
|
linuxSecretAvailability = true;
|
|
3481
3517
|
} catch {
|
|
3482
3518
|
linuxSecretAvailability = false;
|
|
@@ -3500,7 +3536,7 @@ function macKeychainGet(service = SERVICE) {
|
|
|
3500
3536
|
if (!nativeKeychainAllowed()) return null;
|
|
3501
3537
|
if (process.platform !== "darwin") return null;
|
|
3502
3538
|
try {
|
|
3503
|
-
return
|
|
3539
|
+
return execSync3(
|
|
3504
3540
|
`security find-generic-password -s "${service}" -a "${ACCOUNT}" -w 2>/dev/null`,
|
|
3505
3541
|
{ encoding: "utf-8", timeout: 5e3 }
|
|
3506
3542
|
).trim();
|
|
@@ -3513,13 +3549,13 @@ function macKeychainSet(value, service = SERVICE) {
|
|
|
3513
3549
|
if (process.platform !== "darwin") return false;
|
|
3514
3550
|
try {
|
|
3515
3551
|
try {
|
|
3516
|
-
|
|
3552
|
+
execSync3(
|
|
3517
3553
|
`security delete-generic-password -s "${service}" -a "${ACCOUNT}" 2>/dev/null`,
|
|
3518
3554
|
{ timeout: 5e3 }
|
|
3519
3555
|
);
|
|
3520
3556
|
} catch {
|
|
3521
3557
|
}
|
|
3522
|
-
|
|
3558
|
+
execSync3(
|
|
3523
3559
|
`security add-generic-password -s "${service}" -a "${ACCOUNT}" -w "${value}"`,
|
|
3524
3560
|
{ timeout: 5e3 }
|
|
3525
3561
|
);
|
|
@@ -3532,7 +3568,7 @@ function macKeychainDelete(service = SERVICE) {
|
|
|
3532
3568
|
if (!nativeKeychainAllowed()) return false;
|
|
3533
3569
|
if (process.platform !== "darwin") return false;
|
|
3534
3570
|
try {
|
|
3535
|
-
|
|
3571
|
+
execSync3(
|
|
3536
3572
|
`security delete-generic-password -s "${service}" -a "${ACCOUNT}" 2>/dev/null`,
|
|
3537
3573
|
{ timeout: 5e3 }
|
|
3538
3574
|
);
|
|
@@ -3544,7 +3580,7 @@ function macKeychainDelete(service = SERVICE) {
|
|
|
3544
3580
|
function linuxSecretGet(service = SERVICE) {
|
|
3545
3581
|
if (!linuxSecretAvailable()) return null;
|
|
3546
3582
|
try {
|
|
3547
|
-
return
|
|
3583
|
+
return execSync3(
|
|
3548
3584
|
`secret-tool lookup service "${service}" account "${ACCOUNT}" 2>/dev/null`,
|
|
3549
3585
|
{ encoding: "utf-8", timeout: 5e3 }
|
|
3550
3586
|
).trim();
|
|
@@ -3555,7 +3591,7 @@ function linuxSecretGet(service = SERVICE) {
|
|
|
3555
3591
|
function linuxSecretSet(value, service = SERVICE) {
|
|
3556
3592
|
if (!linuxSecretAvailable()) return false;
|
|
3557
3593
|
try {
|
|
3558
|
-
|
|
3594
|
+
execSync3(
|
|
3559
3595
|
`echo -n "${value}" | secret-tool store --label="exe-os master key" service "${service}" account "${ACCOUNT}" 2>/dev/null`,
|
|
3560
3596
|
{ timeout: 5e3 }
|
|
3561
3597
|
);
|
|
@@ -3568,7 +3604,7 @@ function linuxSecretDelete(service = SERVICE) {
|
|
|
3568
3604
|
if (!nativeKeychainAllowed()) return false;
|
|
3569
3605
|
if (process.platform !== "linux") return false;
|
|
3570
3606
|
try {
|
|
3571
|
-
|
|
3607
|
+
execSync3(
|
|
3572
3608
|
`secret-tool clear service "${service}" account "${ACCOUNT}" 2>/dev/null`,
|
|
3573
3609
|
{ timeout: 5e3 }
|
|
3574
3610
|
);
|
|
@@ -4502,7 +4538,7 @@ __export(session_registry_exports, {
|
|
|
4502
4538
|
registerSession: () => registerSession
|
|
4503
4539
|
});
|
|
4504
4540
|
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, existsSync as existsSync8 } from "fs";
|
|
4505
|
-
import { execSync as
|
|
4541
|
+
import { execSync as execSync4 } from "child_process";
|
|
4506
4542
|
import path8 from "path";
|
|
4507
4543
|
import os6 from "os";
|
|
4508
4544
|
function registerSession(entry) {
|
|
@@ -4542,7 +4578,7 @@ function pruneStaleSessions() {
|
|
|
4542
4578
|
if (sessions.length === 0) return 0;
|
|
4543
4579
|
let liveSessions = [];
|
|
4544
4580
|
try {
|
|
4545
|
-
liveSessions =
|
|
4581
|
+
liveSessions = execSync4("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
|
|
4546
4582
|
encoding: "utf8"
|
|
4547
4583
|
}).trim().split("\n").filter(Boolean);
|
|
4548
4584
|
} catch {
|
|
@@ -4565,7 +4601,7 @@ var init_session_registry = __esm({
|
|
|
4565
4601
|
});
|
|
4566
4602
|
|
|
4567
4603
|
// src/lib/session-key.ts
|
|
4568
|
-
import { execSync as
|
|
4604
|
+
import { execSync as execSync5 } from "child_process";
|
|
4569
4605
|
function normalizeCommand(command) {
|
|
4570
4606
|
const trimmed = command.trim().toLowerCase();
|
|
4571
4607
|
const parts = trimmed.split(/[\\/]/);
|
|
@@ -4584,7 +4620,7 @@ function resolveRuntimeProcess() {
|
|
|
4584
4620
|
let pid = process.ppid;
|
|
4585
4621
|
for (let i = 0; i < 10; i++) {
|
|
4586
4622
|
try {
|
|
4587
|
-
const info =
|
|
4623
|
+
const info = execSync5(`ps -p ${pid} -o ppid=,comm=`, {
|
|
4588
4624
|
encoding: "utf8",
|
|
4589
4625
|
timeout: 2e3
|
|
4590
4626
|
}).trim();
|
|
@@ -4750,14 +4786,14 @@ var init_transport = __esm({
|
|
|
4750
4786
|
});
|
|
4751
4787
|
|
|
4752
4788
|
// src/lib/cc-agent-support.ts
|
|
4753
|
-
import { execSync as
|
|
4789
|
+
import { execSync as execSync6 } from "child_process";
|
|
4754
4790
|
function _resetCcAgentSupportCache() {
|
|
4755
4791
|
_cachedSupport = null;
|
|
4756
4792
|
}
|
|
4757
4793
|
function claudeSupportsAgentFlag() {
|
|
4758
4794
|
if (_cachedSupport !== null) return _cachedSupport;
|
|
4759
4795
|
try {
|
|
4760
|
-
const helpOutput =
|
|
4796
|
+
const helpOutput = execSync6("claude --help 2>&1", {
|
|
4761
4797
|
encoding: "utf-8",
|
|
4762
4798
|
timeout: 5e3
|
|
4763
4799
|
});
|
|
@@ -5914,7 +5950,7 @@ __export(project_name_exports, {
|
|
|
5914
5950
|
_resetCache: () => _resetCache,
|
|
5915
5951
|
getProjectName: () => getProjectName
|
|
5916
5952
|
});
|
|
5917
|
-
import { execSync as
|
|
5953
|
+
import { execSync as execSync7 } from "child_process";
|
|
5918
5954
|
import path15 from "path";
|
|
5919
5955
|
function getProjectName(cwd) {
|
|
5920
5956
|
const dir = cwd ?? process.cwd();
|
|
@@ -5922,7 +5958,7 @@ function getProjectName(cwd) {
|
|
|
5922
5958
|
try {
|
|
5923
5959
|
let repoRoot;
|
|
5924
5960
|
try {
|
|
5925
|
-
const gitCommonDir =
|
|
5961
|
+
const gitCommonDir = execSync7("git rev-parse --path-format=absolute --git-common-dir", {
|
|
5926
5962
|
cwd: dir,
|
|
5927
5963
|
encoding: "utf8",
|
|
5928
5964
|
timeout: 2e3,
|
|
@@ -5930,7 +5966,7 @@ function getProjectName(cwd) {
|
|
|
5930
5966
|
}).trim();
|
|
5931
5967
|
repoRoot = path15.dirname(gitCommonDir);
|
|
5932
5968
|
} catch {
|
|
5933
|
-
repoRoot =
|
|
5969
|
+
repoRoot = execSync7("git rev-parse --show-toplevel", {
|
|
5934
5970
|
cwd: dir,
|
|
5935
5971
|
encoding: "utf8",
|
|
5936
5972
|
timeout: 2e3,
|
|
@@ -6025,7 +6061,7 @@ var init_session_scope = __esm({
|
|
|
6025
6061
|
import crypto4 from "crypto";
|
|
6026
6062
|
import path16 from "path";
|
|
6027
6063
|
import os11 from "os";
|
|
6028
|
-
import { execSync as
|
|
6064
|
+
import { execSync as execSync8 } from "child_process";
|
|
6029
6065
|
import { mkdir as mkdir4, writeFile as writeFile4, appendFile } from "fs/promises";
|
|
6030
6066
|
import { existsSync as existsSync15, readFileSync as readFileSync11 } from "fs";
|
|
6031
6067
|
async function writeCheckpoint(input) {
|
|
@@ -6370,14 +6406,14 @@ function isTmuxSessionAlive(identifier) {
|
|
|
6370
6406
|
if (!identifier || identifier === "unknown") return true;
|
|
6371
6407
|
try {
|
|
6372
6408
|
if (identifier.startsWith("%")) {
|
|
6373
|
-
const output =
|
|
6409
|
+
const output = execSync8("tmux list-panes -a -F '#{pane_id}'", {
|
|
6374
6410
|
timeout: 2e3,
|
|
6375
6411
|
encoding: "utf8",
|
|
6376
6412
|
stdio: ["pipe", "pipe", "pipe"]
|
|
6377
6413
|
});
|
|
6378
6414
|
return output.split("\n").some((l) => l.trim() === identifier);
|
|
6379
6415
|
} else {
|
|
6380
|
-
|
|
6416
|
+
execSync8(`tmux has-session -t ${JSON.stringify(identifier)}`, {
|
|
6381
6417
|
timeout: 2e3,
|
|
6382
6418
|
stdio: ["pipe", "pipe", "pipe"]
|
|
6383
6419
|
});
|
|
@@ -6386,7 +6422,7 @@ function isTmuxSessionAlive(identifier) {
|
|
|
6386
6422
|
} catch {
|
|
6387
6423
|
if (identifier.startsWith("%")) return true;
|
|
6388
6424
|
try {
|
|
6389
|
-
|
|
6425
|
+
execSync8("tmux list-sessions", {
|
|
6390
6426
|
timeout: 2e3,
|
|
6391
6427
|
stdio: ["pipe", "pipe", "pipe"]
|
|
6392
6428
|
});
|
|
@@ -6401,12 +6437,12 @@ function checkStaleCompletion(taskContext, taskCreatedAt) {
|
|
|
6401
6437
|
if (!DELEGATION_KEYWORDS.test(taskContext)) return null;
|
|
6402
6438
|
try {
|
|
6403
6439
|
const since = new Date(taskCreatedAt).toISOString();
|
|
6404
|
-
const branch =
|
|
6440
|
+
const branch = execSync8(
|
|
6405
6441
|
"git rev-parse --abbrev-ref HEAD 2>/dev/null",
|
|
6406
6442
|
{ encoding: "utf8", timeout: 3e3 }
|
|
6407
6443
|
).trim();
|
|
6408
6444
|
const branchArg = branch && branch !== "HEAD" ? branch : "";
|
|
6409
|
-
const commitCount =
|
|
6445
|
+
const commitCount = execSync8(
|
|
6410
6446
|
`git log --oneline --since="${since}" ${branchArg} 2>/dev/null | wc -l`,
|
|
6411
6447
|
{ encoding: "utf8", timeout: 5e3 }
|
|
6412
6448
|
).trim();
|
|
@@ -8005,7 +8041,7 @@ __export(tmux_routing_exports, {
|
|
|
8005
8041
|
spawnEmployee: () => spawnEmployee,
|
|
8006
8042
|
verifyPaneAtCapacity: () => verifyPaneAtCapacity
|
|
8007
8043
|
});
|
|
8008
|
-
import { execFileSync as execFileSync2, execSync as
|
|
8044
|
+
import { execFileSync as execFileSync2, execSync as execSync9 } from "child_process";
|
|
8009
8045
|
import { readFileSync as readFileSync12, writeFileSync as writeFileSync8, mkdirSync as mkdirSync8, existsSync as existsSync17, appendFileSync, readdirSync as readdirSync4 } from "fs";
|
|
8010
8046
|
import path20 from "path";
|
|
8011
8047
|
import os12 from "os";
|
|
@@ -8726,7 +8762,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
8726
8762
|
let booted = false;
|
|
8727
8763
|
for (let i = 0; i < 30; i++) {
|
|
8728
8764
|
try {
|
|
8729
|
-
|
|
8765
|
+
execSync9("sleep 0.5");
|
|
8730
8766
|
} catch {
|
|
8731
8767
|
}
|
|
8732
8768
|
try {
|
|
@@ -10692,7 +10728,7 @@ __export(schedules_exports, {
|
|
|
10692
10728
|
parseHumanCron: () => parseHumanCron
|
|
10693
10729
|
});
|
|
10694
10730
|
import crypto9 from "crypto";
|
|
10695
|
-
import { execSync as
|
|
10731
|
+
import { execSync as execSync11 } from "child_process";
|
|
10696
10732
|
function isValidCron(cron) {
|
|
10697
10733
|
const fields = cron.trim().split(/\s+/);
|
|
10698
10734
|
if (fields.length !== 5) return false;
|
|
@@ -10852,7 +10888,7 @@ function addToCrontab(id, cron, prompt, projectDir) {
|
|
|
10852
10888
|
const cwd = projectDir ? `cd ${JSON.stringify(projectDir)} && ` : "";
|
|
10853
10889
|
const escapedPrompt = prompt.replace(/"/g, '\\"');
|
|
10854
10890
|
const entry = `${cron} ${cwd}claude -p --dangerously-skip-permissions "${escapedPrompt}" # exe-schedule:${id}`;
|
|
10855
|
-
|
|
10891
|
+
execSync11(
|
|
10856
10892
|
`(crontab -l 2>/dev/null; echo ${JSON.stringify(entry)}) | crontab -`,
|
|
10857
10893
|
{ timeout: 5e3, stdio: "ignore" }
|
|
10858
10894
|
);
|
|
@@ -10863,7 +10899,7 @@ function addToCrontab(id, cron, prompt, projectDir) {
|
|
|
10863
10899
|
function removeFromCrontab(id) {
|
|
10864
10900
|
if (!isValidScheduleId(id)) return;
|
|
10865
10901
|
try {
|
|
10866
|
-
|
|
10902
|
+
execSync11(
|
|
10867
10903
|
`crontab -l 2>/dev/null | grep -v "exe-schedule:${id}" | crontab -`,
|
|
10868
10904
|
{ timeout: 5e3, stdio: "ignore" }
|
|
10869
10905
|
);
|
|
@@ -11428,7 +11464,7 @@ init_notifications();
|
|
|
11428
11464
|
init_config();
|
|
11429
11465
|
init_session_key();
|
|
11430
11466
|
import { readFileSync as readFileSync13, writeFileSync as writeFileSync9, mkdirSync as mkdirSync9, unlinkSync as unlinkSync7, readdirSync as readdirSync5 } from "fs";
|
|
11431
|
-
import { execSync as
|
|
11467
|
+
import { execSync as execSync10 } from "child_process";
|
|
11432
11468
|
import path21 from "path";
|
|
11433
11469
|
|
|
11434
11470
|
// src/mcp/agent-context.ts
|
|
@@ -12178,8 +12214,8 @@ async function boot(options) {
|
|
|
12178
12214
|
updatedAt: String(row.updated_at)
|
|
12179
12215
|
}));
|
|
12180
12216
|
try {
|
|
12181
|
-
const { execSync:
|
|
12182
|
-
const gitLog =
|
|
12217
|
+
const { execSync: execSync12 } = await import("child_process");
|
|
12218
|
+
const gitLog = execSync12(
|
|
12183
12219
|
"git log --oneline -10 --grep='Co-Authored-By: Claude' --grep='task(' --all-match 2>/dev/null || git log --oneline -5 --grep='Co-Authored-By: Claude' 2>/dev/null || git log --oneline -5 --grep='^task(' 2>/dev/null",
|
|
12184
12220
|
{
|
|
12185
12221
|
encoding: "utf8",
|
|
@@ -12468,11 +12504,11 @@ async function updateIdleKillSuspectStreak(client, killsToday, liveSessions, tod
|
|
|
12468
12504
|
}
|
|
12469
12505
|
function runSplash() {
|
|
12470
12506
|
try {
|
|
12471
|
-
const { execSync:
|
|
12507
|
+
const { execSync: execSync12 } = __require("child_process");
|
|
12472
12508
|
const { loadConfigSync: loadConfigSync2 } = (init_config(), __toCommonJS(config_exports));
|
|
12473
12509
|
const config = loadConfigSync2();
|
|
12474
12510
|
if (!config.splashEffect) return;
|
|
12475
|
-
|
|
12511
|
+
execSync12(
|
|
12476
12512
|
'echo "EXE OS" | python3 -m terminaltexteffects decrypt --typing-speed 2 --ciphertext-colors 6B4C9A F5D76E --final-gradient-stops F5D76E F0EDE8 --final-gradient-direction vertical',
|
|
12477
12513
|
{ stdio: "inherit", timeout: 5e3 }
|
|
12478
12514
|
);
|
package/dist/bin/exe-call.js
CHANGED
|
@@ -315,6 +315,24 @@ var init_platform_procedures = __esm({
|
|
|
315
315
|
priority: "p0",
|
|
316
316
|
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."
|
|
317
317
|
},
|
|
318
|
+
{
|
|
319
|
+
title: "Bug report status check \u2014 surface available fixes on boot",
|
|
320
|
+
domain: "support",
|
|
321
|
+
priority: "p1",
|
|
322
|
+
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."
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
title: "Feature request triage \u2014 upstream feature vs local customization",
|
|
326
|
+
domain: "support",
|
|
327
|
+
priority: "p0",
|
|
328
|
+
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."
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
title: "Feature request status check \u2014 surface shipped features on boot",
|
|
332
|
+
domain: "support",
|
|
333
|
+
priority: "p1",
|
|
334
|
+
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."
|
|
335
|
+
},
|
|
318
336
|
// --- Operations ---
|
|
319
337
|
{
|
|
320
338
|
title: "Managers must supervise deployed workers",
|