@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
|
@@ -584,12 +584,14 @@ On EVERY new conversation, before doing anything else:
|
|
|
584
584
|
1. **Memory scan**: Run recall_my_memory with broad queries \u2014 "project", "client", "pipeline", "campaign", "deal", "decision", "blocker". Summarize what you find.
|
|
585
585
|
2. **Task scan**: Run list_tasks to see what's open, in progress, blocked, or needs review across all employees.
|
|
586
586
|
3. **Team check**: Run ask_team_memory for recent activity from CTO/CMO/engineers.
|
|
587
|
-
4. **
|
|
587
|
+
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.
|
|
588
|
+
5. **Present the brief**: Give the founder a concise status report:
|
|
588
589
|
- What's active and progressing
|
|
589
590
|
- What's blocked and needs attention
|
|
590
591
|
- What decisions are pending
|
|
592
|
+
- Available bug fixes (from step 4, if any)
|
|
591
593
|
- What you recommend doing next
|
|
592
|
-
|
|
594
|
+
6. Then ask: "What's the priority?"
|
|
593
595
|
|
|
594
596
|
If this is your FIRST ever conversation (few or no prior memories):
|
|
595
597
|
- Search more broadly: "product", "SEO", "meeting", "strategy", "revenue"
|
|
@@ -609,6 +611,8 @@ Never say "I have no memories" without first searching broadly. Your memory may
|
|
|
609
611
|
- **get_identity** \u2014 read any agent's identity for coordination
|
|
610
612
|
- **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.
|
|
611
613
|
- **send_message** \u2014 direct intercom to employees
|
|
614
|
+
- **create_bug_report** \u2014 file a bug when you encounter an Exe OS platform issue
|
|
615
|
+
- **list_my_bug_reports** \u2014 check status of filed bugs (boot check: surface available fixes to founder)
|
|
612
616
|
${PLAN_MODE_COMPAT}
|
|
613
617
|
## Completion Workflow
|
|
614
618
|
|
|
@@ -1650,6 +1654,15 @@ async function registerMcpServer(packageRoot, homeDir = os8.homedir()) {
|
|
|
1650
1654
|
delete claudeJson.mcpServers[MCP_LEGACY_KEY];
|
|
1651
1655
|
process.stderr.write("exe-os: migrated MCP server key exe-mem \u2192 exe-os\n");
|
|
1652
1656
|
}
|
|
1657
|
+
if (claudeJson.projects) {
|
|
1658
|
+
for (const [projectPath, projectConfig] of Object.entries(claudeJson.projects)) {
|
|
1659
|
+
if (projectConfig.mcpServers?.[MCP_LEGACY_KEY]) {
|
|
1660
|
+
delete projectConfig.mcpServers[MCP_LEGACY_KEY];
|
|
1661
|
+
process.stderr.write(`exe-os: removed stale project-level exe-mem from ${projectPath}
|
|
1662
|
+
`);
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1665
|
+
}
|
|
1653
1666
|
const currentOs = claudeJson.mcpServers[MCP_PRIMARY_KEY];
|
|
1654
1667
|
const osMatches = currentOs && JSON.stringify(currentOs) === JSON.stringify(newEntry);
|
|
1655
1668
|
if (osMatches) {
|
|
@@ -2679,6 +2692,24 @@ var PLATFORM_PROCEDURES = [
|
|
|
2679
2692
|
priority: "p0",
|
|
2680
2693
|
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."
|
|
2681
2694
|
},
|
|
2695
|
+
{
|
|
2696
|
+
title: "Bug report status check \u2014 surface available fixes on boot",
|
|
2697
|
+
domain: "support",
|
|
2698
|
+
priority: "p1",
|
|
2699
|
+
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."
|
|
2700
|
+
},
|
|
2701
|
+
{
|
|
2702
|
+
title: "Feature request triage \u2014 upstream feature vs local customization",
|
|
2703
|
+
domain: "support",
|
|
2704
|
+
priority: "p0",
|
|
2705
|
+
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."
|
|
2706
|
+
},
|
|
2707
|
+
{
|
|
2708
|
+
title: "Feature request status check \u2014 surface shipped features on boot",
|
|
2709
|
+
domain: "support",
|
|
2710
|
+
priority: "p1",
|
|
2711
|
+
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."
|
|
2712
|
+
},
|
|
2682
2713
|
// --- Operations ---
|
|
2683
2714
|
{
|
|
2684
2715
|
title: "Managers must supervise deployed workers",
|
|
@@ -1002,7 +1002,7 @@ __export(exe_daemon_client_exports, {
|
|
|
1002
1002
|
});
|
|
1003
1003
|
import net from "net";
|
|
1004
1004
|
import os4 from "os";
|
|
1005
|
-
import { spawn } from "child_process";
|
|
1005
|
+
import { spawn, execSync as execSync2 } from "child_process";
|
|
1006
1006
|
import { randomUUID } from "crypto";
|
|
1007
1007
|
import { existsSync as existsSync5, unlinkSync as unlinkSync2, readFileSync as readFileSync4, openSync, closeSync, statSync } from "fs";
|
|
1008
1008
|
import path5 from "path";
|
|
@@ -1032,6 +1032,14 @@ function handleData(chunk) {
|
|
|
1032
1032
|
}
|
|
1033
1033
|
}
|
|
1034
1034
|
}
|
|
1035
|
+
function isZombie(pid) {
|
|
1036
|
+
try {
|
|
1037
|
+
const state = execSync2(`ps -p ${pid} -o state=`, { encoding: "utf8", timeout: 2e3 }).trim();
|
|
1038
|
+
return state.startsWith("Z");
|
|
1039
|
+
} catch {
|
|
1040
|
+
return false;
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1035
1043
|
function cleanupStaleFiles() {
|
|
1036
1044
|
if (existsSync5(PID_PATH)) {
|
|
1037
1045
|
try {
|
|
@@ -1039,7 +1047,11 @@ function cleanupStaleFiles() {
|
|
|
1039
1047
|
if (pid > 0) {
|
|
1040
1048
|
try {
|
|
1041
1049
|
process.kill(pid, 0);
|
|
1042
|
-
|
|
1050
|
+
if (!isZombie(pid)) {
|
|
1051
|
+
return;
|
|
1052
|
+
}
|
|
1053
|
+
process.stderr.write(`[exed-client] PID ${pid} is a zombie \u2014 cleaning up stale files
|
|
1054
|
+
`);
|
|
1043
1055
|
} catch {
|
|
1044
1056
|
}
|
|
1045
1057
|
}
|
|
@@ -1067,8 +1079,8 @@ function findPackageRoot() {
|
|
|
1067
1079
|
function getAvailableMemoryGB() {
|
|
1068
1080
|
if (process.platform === "darwin") {
|
|
1069
1081
|
try {
|
|
1070
|
-
const { execSync:
|
|
1071
|
-
const vmstat =
|
|
1082
|
+
const { execSync: execSync6 } = __require("child_process");
|
|
1083
|
+
const vmstat = execSync6("vm_stat", { encoding: "utf8" });
|
|
1072
1084
|
const pageSize = 16384;
|
|
1073
1085
|
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
1074
1086
|
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
@@ -3058,6 +3070,12 @@ async function disposeDatabase() {
|
|
|
3058
3070
|
clearInterval(_walCheckpointTimer);
|
|
3059
3071
|
_walCheckpointTimer = null;
|
|
3060
3072
|
}
|
|
3073
|
+
if (_client) {
|
|
3074
|
+
try {
|
|
3075
|
+
await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
3076
|
+
} catch {
|
|
3077
|
+
}
|
|
3078
|
+
}
|
|
3061
3079
|
if (_daemonClient) {
|
|
3062
3080
|
_daemonClient.close();
|
|
3063
3081
|
_daemonClient = null;
|
|
@@ -3103,7 +3121,7 @@ var init_session_registry = __esm({
|
|
|
3103
3121
|
});
|
|
3104
3122
|
|
|
3105
3123
|
// src/lib/session-key.ts
|
|
3106
|
-
import { execSync as
|
|
3124
|
+
import { execSync as execSync3 } from "child_process";
|
|
3107
3125
|
function normalizeCommand(command) {
|
|
3108
3126
|
const trimmed = command.trim().toLowerCase();
|
|
3109
3127
|
const parts = trimmed.split(/[\\/]/);
|
|
@@ -3122,7 +3140,7 @@ function resolveRuntimeProcess() {
|
|
|
3122
3140
|
let pid = process.ppid;
|
|
3123
3141
|
for (let i = 0; i < 10; i++) {
|
|
3124
3142
|
try {
|
|
3125
|
-
const info =
|
|
3143
|
+
const info = execSync3(`ps -p ${pid} -o ppid=,comm=`, {
|
|
3126
3144
|
encoding: "utf8",
|
|
3127
3145
|
timeout: 2e3
|
|
3128
3146
|
}).trim();
|
|
@@ -3288,7 +3306,7 @@ var init_transport = __esm({
|
|
|
3288
3306
|
});
|
|
3289
3307
|
|
|
3290
3308
|
// src/lib/cc-agent-support.ts
|
|
3291
|
-
import { execSync as
|
|
3309
|
+
import { execSync as execSync4 } from "child_process";
|
|
3292
3310
|
var init_cc_agent_support = __esm({
|
|
3293
3311
|
"src/lib/cc-agent-support.ts"() {
|
|
3294
3312
|
"use strict";
|
|
@@ -3521,7 +3539,7 @@ var init_task_scope = __esm({
|
|
|
3521
3539
|
// src/lib/keychain.ts
|
|
3522
3540
|
import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
3523
3541
|
import { existsSync as existsSync12, statSync as statSync2 } from "fs";
|
|
3524
|
-
import { execSync as
|
|
3542
|
+
import { execSync as execSync5 } from "child_process";
|
|
3525
3543
|
import path13 from "path";
|
|
3526
3544
|
import os10 from "os";
|
|
3527
3545
|
function getKeyDir() {
|
|
@@ -3538,13 +3556,13 @@ function linuxSecretAvailable() {
|
|
|
3538
3556
|
if (process.platform !== "linux") return false;
|
|
3539
3557
|
if (linuxSecretAvailability !== null) return linuxSecretAvailability;
|
|
3540
3558
|
try {
|
|
3541
|
-
|
|
3559
|
+
execSync5("command -v secret-tool >/dev/null 2>&1", { timeout: 1e3 });
|
|
3542
3560
|
} catch {
|
|
3543
3561
|
linuxSecretAvailability = false;
|
|
3544
3562
|
return false;
|
|
3545
3563
|
}
|
|
3546
3564
|
try {
|
|
3547
|
-
|
|
3565
|
+
execSync5("secret-tool search --all exe-os probe >/dev/null 2>&1", { timeout: 1e3 });
|
|
3548
3566
|
linuxSecretAvailability = true;
|
|
3549
3567
|
} catch {
|
|
3550
3568
|
linuxSecretAvailability = false;
|
|
@@ -3568,7 +3586,7 @@ function macKeychainGet(service = SERVICE) {
|
|
|
3568
3586
|
if (!nativeKeychainAllowed()) return null;
|
|
3569
3587
|
if (process.platform !== "darwin") return null;
|
|
3570
3588
|
try {
|
|
3571
|
-
return
|
|
3589
|
+
return execSync5(
|
|
3572
3590
|
`security find-generic-password -s "${service}" -a "${ACCOUNT}" -w 2>/dev/null`,
|
|
3573
3591
|
{ encoding: "utf-8", timeout: 5e3 }
|
|
3574
3592
|
).trim();
|
|
@@ -3581,13 +3599,13 @@ function macKeychainSet(value, service = SERVICE) {
|
|
|
3581
3599
|
if (process.platform !== "darwin") return false;
|
|
3582
3600
|
try {
|
|
3583
3601
|
try {
|
|
3584
|
-
|
|
3602
|
+
execSync5(
|
|
3585
3603
|
`security delete-generic-password -s "${service}" -a "${ACCOUNT}" 2>/dev/null`,
|
|
3586
3604
|
{ timeout: 5e3 }
|
|
3587
3605
|
);
|
|
3588
3606
|
} catch {
|
|
3589
3607
|
}
|
|
3590
|
-
|
|
3608
|
+
execSync5(
|
|
3591
3609
|
`security add-generic-password -s "${service}" -a "${ACCOUNT}" -w "${value}"`,
|
|
3592
3610
|
{ timeout: 5e3 }
|
|
3593
3611
|
);
|
|
@@ -3600,7 +3618,7 @@ function macKeychainDelete(service = SERVICE) {
|
|
|
3600
3618
|
if (!nativeKeychainAllowed()) return false;
|
|
3601
3619
|
if (process.platform !== "darwin") return false;
|
|
3602
3620
|
try {
|
|
3603
|
-
|
|
3621
|
+
execSync5(
|
|
3604
3622
|
`security delete-generic-password -s "${service}" -a "${ACCOUNT}" 2>/dev/null`,
|
|
3605
3623
|
{ timeout: 5e3 }
|
|
3606
3624
|
);
|
|
@@ -3612,7 +3630,7 @@ function macKeychainDelete(service = SERVICE) {
|
|
|
3612
3630
|
function linuxSecretGet(service = SERVICE) {
|
|
3613
3631
|
if (!linuxSecretAvailable()) return null;
|
|
3614
3632
|
try {
|
|
3615
|
-
return
|
|
3633
|
+
return execSync5(
|
|
3616
3634
|
`secret-tool lookup service "${service}" account "${ACCOUNT}" 2>/dev/null`,
|
|
3617
3635
|
{ encoding: "utf-8", timeout: 5e3 }
|
|
3618
3636
|
).trim();
|
|
@@ -3623,7 +3641,7 @@ function linuxSecretGet(service = SERVICE) {
|
|
|
3623
3641
|
function linuxSecretSet(value, service = SERVICE) {
|
|
3624
3642
|
if (!linuxSecretAvailable()) return false;
|
|
3625
3643
|
try {
|
|
3626
|
-
|
|
3644
|
+
execSync5(
|
|
3627
3645
|
`echo -n "${value}" | secret-tool store --label="exe-os master key" service "${service}" account "${ACCOUNT}" 2>/dev/null`,
|
|
3628
3646
|
{ timeout: 5e3 }
|
|
3629
3647
|
);
|
|
@@ -3636,7 +3654,7 @@ function linuxSecretDelete(service = SERVICE) {
|
|
|
3636
3654
|
if (!nativeKeychainAllowed()) return false;
|
|
3637
3655
|
if (process.platform !== "linux") return false;
|
|
3638
3656
|
try {
|
|
3639
|
-
|
|
3657
|
+
execSync5(
|
|
3640
3658
|
`secret-tool clear service "${service}" account "${ACCOUNT}" 2>/dev/null`,
|
|
3641
3659
|
{ timeout: 5e3 }
|
|
3642
3660
|
);
|
|
@@ -4573,6 +4591,24 @@ var init_platform_procedures = __esm({
|
|
|
4573
4591
|
priority: "p0",
|
|
4574
4592
|
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."
|
|
4575
4593
|
},
|
|
4594
|
+
{
|
|
4595
|
+
title: "Bug report status check \u2014 surface available fixes on boot",
|
|
4596
|
+
domain: "support",
|
|
4597
|
+
priority: "p1",
|
|
4598
|
+
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."
|
|
4599
|
+
},
|
|
4600
|
+
{
|
|
4601
|
+
title: "Feature request triage \u2014 upstream feature vs local customization",
|
|
4602
|
+
domain: "support",
|
|
4603
|
+
priority: "p0",
|
|
4604
|
+
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."
|
|
4605
|
+
},
|
|
4606
|
+
{
|
|
4607
|
+
title: "Feature request status check \u2014 surface shipped features on boot",
|
|
4608
|
+
domain: "support",
|
|
4609
|
+
priority: "p1",
|
|
4610
|
+
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."
|
|
4611
|
+
},
|
|
4576
4612
|
// --- Operations ---
|
|
4577
4613
|
{
|
|
4578
4614
|
title: "Managers must supervise deployed workers",
|
|
@@ -1003,7 +1003,7 @@ __export(exe_daemon_client_exports, {
|
|
|
1003
1003
|
});
|
|
1004
1004
|
import net from "net";
|
|
1005
1005
|
import os4 from "os";
|
|
1006
|
-
import { spawn } from "child_process";
|
|
1006
|
+
import { spawn, execSync as execSync2 } from "child_process";
|
|
1007
1007
|
import { randomUUID } from "crypto";
|
|
1008
1008
|
import { existsSync as existsSync5, unlinkSync as unlinkSync2, readFileSync as readFileSync4, openSync, closeSync, statSync } from "fs";
|
|
1009
1009
|
import path5 from "path";
|
|
@@ -1033,6 +1033,14 @@ function handleData(chunk) {
|
|
|
1033
1033
|
}
|
|
1034
1034
|
}
|
|
1035
1035
|
}
|
|
1036
|
+
function isZombie(pid) {
|
|
1037
|
+
try {
|
|
1038
|
+
const state = execSync2(`ps -p ${pid} -o state=`, { encoding: "utf8", timeout: 2e3 }).trim();
|
|
1039
|
+
return state.startsWith("Z");
|
|
1040
|
+
} catch {
|
|
1041
|
+
return false;
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1036
1044
|
function cleanupStaleFiles() {
|
|
1037
1045
|
if (existsSync5(PID_PATH)) {
|
|
1038
1046
|
try {
|
|
@@ -1040,7 +1048,11 @@ function cleanupStaleFiles() {
|
|
|
1040
1048
|
if (pid > 0) {
|
|
1041
1049
|
try {
|
|
1042
1050
|
process.kill(pid, 0);
|
|
1043
|
-
|
|
1051
|
+
if (!isZombie(pid)) {
|
|
1052
|
+
return;
|
|
1053
|
+
}
|
|
1054
|
+
process.stderr.write(`[exed-client] PID ${pid} is a zombie \u2014 cleaning up stale files
|
|
1055
|
+
`);
|
|
1044
1056
|
} catch {
|
|
1045
1057
|
}
|
|
1046
1058
|
}
|
|
@@ -1068,8 +1080,8 @@ function findPackageRoot() {
|
|
|
1068
1080
|
function getAvailableMemoryGB() {
|
|
1069
1081
|
if (process.platform === "darwin") {
|
|
1070
1082
|
try {
|
|
1071
|
-
const { execSync:
|
|
1072
|
-
const vmstat =
|
|
1083
|
+
const { execSync: execSync6 } = __require("child_process");
|
|
1084
|
+
const vmstat = execSync6("vm_stat", { encoding: "utf8" });
|
|
1073
1085
|
const pageSize = 16384;
|
|
1074
1086
|
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
1075
1087
|
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
@@ -3059,6 +3071,12 @@ async function disposeDatabase() {
|
|
|
3059
3071
|
clearInterval(_walCheckpointTimer);
|
|
3060
3072
|
_walCheckpointTimer = null;
|
|
3061
3073
|
}
|
|
3074
|
+
if (_client) {
|
|
3075
|
+
try {
|
|
3076
|
+
await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
3077
|
+
} catch {
|
|
3078
|
+
}
|
|
3079
|
+
}
|
|
3062
3080
|
if (_daemonClient) {
|
|
3063
3081
|
_daemonClient.close();
|
|
3064
3082
|
_daemonClient = null;
|
|
@@ -3104,7 +3122,7 @@ var init_session_registry = __esm({
|
|
|
3104
3122
|
});
|
|
3105
3123
|
|
|
3106
3124
|
// src/lib/session-key.ts
|
|
3107
|
-
import { execSync as
|
|
3125
|
+
import { execSync as execSync3 } from "child_process";
|
|
3108
3126
|
function normalizeCommand(command) {
|
|
3109
3127
|
const trimmed = command.trim().toLowerCase();
|
|
3110
3128
|
const parts = trimmed.split(/[\\/]/);
|
|
@@ -3123,7 +3141,7 @@ function resolveRuntimeProcess() {
|
|
|
3123
3141
|
let pid = process.ppid;
|
|
3124
3142
|
for (let i = 0; i < 10; i++) {
|
|
3125
3143
|
try {
|
|
3126
|
-
const info =
|
|
3144
|
+
const info = execSync3(`ps -p ${pid} -o ppid=,comm=`, {
|
|
3127
3145
|
encoding: "utf8",
|
|
3128
3146
|
timeout: 2e3
|
|
3129
3147
|
}).trim();
|
|
@@ -3289,7 +3307,7 @@ var init_transport = __esm({
|
|
|
3289
3307
|
});
|
|
3290
3308
|
|
|
3291
3309
|
// src/lib/cc-agent-support.ts
|
|
3292
|
-
import { execSync as
|
|
3310
|
+
import { execSync as execSync4 } from "child_process";
|
|
3293
3311
|
var init_cc_agent_support = __esm({
|
|
3294
3312
|
"src/lib/cc-agent-support.ts"() {
|
|
3295
3313
|
"use strict";
|
|
@@ -3587,7 +3605,7 @@ var init_notifications = __esm({
|
|
|
3587
3605
|
// src/lib/keychain.ts
|
|
3588
3606
|
import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
3589
3607
|
import { existsSync as existsSync13, statSync as statSync2 } from "fs";
|
|
3590
|
-
import { execSync as
|
|
3608
|
+
import { execSync as execSync5 } from "child_process";
|
|
3591
3609
|
import path14 from "path";
|
|
3592
3610
|
import os11 from "os";
|
|
3593
3611
|
function getKeyDir() {
|
|
@@ -3604,13 +3622,13 @@ function linuxSecretAvailable() {
|
|
|
3604
3622
|
if (process.platform !== "linux") return false;
|
|
3605
3623
|
if (linuxSecretAvailability !== null) return linuxSecretAvailability;
|
|
3606
3624
|
try {
|
|
3607
|
-
|
|
3625
|
+
execSync5("command -v secret-tool >/dev/null 2>&1", { timeout: 1e3 });
|
|
3608
3626
|
} catch {
|
|
3609
3627
|
linuxSecretAvailability = false;
|
|
3610
3628
|
return false;
|
|
3611
3629
|
}
|
|
3612
3630
|
try {
|
|
3613
|
-
|
|
3631
|
+
execSync5("secret-tool search --all exe-os probe >/dev/null 2>&1", { timeout: 1e3 });
|
|
3614
3632
|
linuxSecretAvailability = true;
|
|
3615
3633
|
} catch {
|
|
3616
3634
|
linuxSecretAvailability = false;
|
|
@@ -3634,7 +3652,7 @@ function macKeychainGet(service = SERVICE) {
|
|
|
3634
3652
|
if (!nativeKeychainAllowed()) return null;
|
|
3635
3653
|
if (process.platform !== "darwin") return null;
|
|
3636
3654
|
try {
|
|
3637
|
-
return
|
|
3655
|
+
return execSync5(
|
|
3638
3656
|
`security find-generic-password -s "${service}" -a "${ACCOUNT}" -w 2>/dev/null`,
|
|
3639
3657
|
{ encoding: "utf-8", timeout: 5e3 }
|
|
3640
3658
|
).trim();
|
|
@@ -3647,13 +3665,13 @@ function macKeychainSet(value, service = SERVICE) {
|
|
|
3647
3665
|
if (process.platform !== "darwin") return false;
|
|
3648
3666
|
try {
|
|
3649
3667
|
try {
|
|
3650
|
-
|
|
3668
|
+
execSync5(
|
|
3651
3669
|
`security delete-generic-password -s "${service}" -a "${ACCOUNT}" 2>/dev/null`,
|
|
3652
3670
|
{ timeout: 5e3 }
|
|
3653
3671
|
);
|
|
3654
3672
|
} catch {
|
|
3655
3673
|
}
|
|
3656
|
-
|
|
3674
|
+
execSync5(
|
|
3657
3675
|
`security add-generic-password -s "${service}" -a "${ACCOUNT}" -w "${value}"`,
|
|
3658
3676
|
{ timeout: 5e3 }
|
|
3659
3677
|
);
|
|
@@ -3666,7 +3684,7 @@ function macKeychainDelete(service = SERVICE) {
|
|
|
3666
3684
|
if (!nativeKeychainAllowed()) return false;
|
|
3667
3685
|
if (process.platform !== "darwin") return false;
|
|
3668
3686
|
try {
|
|
3669
|
-
|
|
3687
|
+
execSync5(
|
|
3670
3688
|
`security delete-generic-password -s "${service}" -a "${ACCOUNT}" 2>/dev/null`,
|
|
3671
3689
|
{ timeout: 5e3 }
|
|
3672
3690
|
);
|
|
@@ -3678,7 +3696,7 @@ function macKeychainDelete(service = SERVICE) {
|
|
|
3678
3696
|
function linuxSecretGet(service = SERVICE) {
|
|
3679
3697
|
if (!linuxSecretAvailable()) return null;
|
|
3680
3698
|
try {
|
|
3681
|
-
return
|
|
3699
|
+
return execSync5(
|
|
3682
3700
|
`secret-tool lookup service "${service}" account "${ACCOUNT}" 2>/dev/null`,
|
|
3683
3701
|
{ encoding: "utf-8", timeout: 5e3 }
|
|
3684
3702
|
).trim();
|
|
@@ -3689,7 +3707,7 @@ function linuxSecretGet(service = SERVICE) {
|
|
|
3689
3707
|
function linuxSecretSet(value, service = SERVICE) {
|
|
3690
3708
|
if (!linuxSecretAvailable()) return false;
|
|
3691
3709
|
try {
|
|
3692
|
-
|
|
3710
|
+
execSync5(
|
|
3693
3711
|
`echo -n "${value}" | secret-tool store --label="exe-os master key" service "${service}" account "${ACCOUNT}" 2>/dev/null`,
|
|
3694
3712
|
{ timeout: 5e3 }
|
|
3695
3713
|
);
|
|
@@ -3702,7 +3720,7 @@ function linuxSecretDelete(service = SERVICE) {
|
|
|
3702
3720
|
if (!nativeKeychainAllowed()) return false;
|
|
3703
3721
|
if (process.platform !== "linux") return false;
|
|
3704
3722
|
try {
|
|
3705
|
-
|
|
3723
|
+
execSync5(
|
|
3706
3724
|
`secret-tool clear service "${service}" account "${ACCOUNT}" 2>/dev/null`,
|
|
3707
3725
|
{ timeout: 5e3 }
|
|
3708
3726
|
);
|
|
@@ -4639,6 +4657,24 @@ var init_platform_procedures = __esm({
|
|
|
4639
4657
|
priority: "p0",
|
|
4640
4658
|
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."
|
|
4641
4659
|
},
|
|
4660
|
+
{
|
|
4661
|
+
title: "Bug report status check \u2014 surface available fixes on boot",
|
|
4662
|
+
domain: "support",
|
|
4663
|
+
priority: "p1",
|
|
4664
|
+
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."
|
|
4665
|
+
},
|
|
4666
|
+
{
|
|
4667
|
+
title: "Feature request triage \u2014 upstream feature vs local customization",
|
|
4668
|
+
domain: "support",
|
|
4669
|
+
priority: "p0",
|
|
4670
|
+
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."
|
|
4671
|
+
},
|
|
4672
|
+
{
|
|
4673
|
+
title: "Feature request status check \u2014 surface shipped features on boot",
|
|
4674
|
+
domain: "support",
|
|
4675
|
+
priority: "p1",
|
|
4676
|
+
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."
|
|
4677
|
+
},
|
|
4642
4678
|
// --- Operations ---
|
|
4643
4679
|
{
|
|
4644
4680
|
title: "Managers must supervise deployed workers",
|