@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
|
@@ -994,7 +994,7 @@ __export(exe_daemon_client_exports, {
|
|
|
994
994
|
});
|
|
995
995
|
import net from "net";
|
|
996
996
|
import os4 from "os";
|
|
997
|
-
import { spawn } from "child_process";
|
|
997
|
+
import { spawn, execSync as execSync4 } from "child_process";
|
|
998
998
|
import { randomUUID } from "crypto";
|
|
999
999
|
import { existsSync as existsSync5, unlinkSync as unlinkSync3, readFileSync as readFileSync5, openSync, closeSync, statSync } from "fs";
|
|
1000
1000
|
import path6 from "path";
|
|
@@ -1024,6 +1024,14 @@ function handleData(chunk) {
|
|
|
1024
1024
|
}
|
|
1025
1025
|
}
|
|
1026
1026
|
}
|
|
1027
|
+
function isZombie(pid) {
|
|
1028
|
+
try {
|
|
1029
|
+
const state = execSync4(`ps -p ${pid} -o state=`, { encoding: "utf8", timeout: 2e3 }).trim();
|
|
1030
|
+
return state.startsWith("Z");
|
|
1031
|
+
} catch {
|
|
1032
|
+
return false;
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1027
1035
|
function cleanupStaleFiles() {
|
|
1028
1036
|
if (existsSync5(PID_PATH)) {
|
|
1029
1037
|
try {
|
|
@@ -1031,7 +1039,11 @@ function cleanupStaleFiles() {
|
|
|
1031
1039
|
if (pid > 0) {
|
|
1032
1040
|
try {
|
|
1033
1041
|
process.kill(pid, 0);
|
|
1034
|
-
|
|
1042
|
+
if (!isZombie(pid)) {
|
|
1043
|
+
return;
|
|
1044
|
+
}
|
|
1045
|
+
process.stderr.write(`[exed-client] PID ${pid} is a zombie \u2014 cleaning up stale files
|
|
1046
|
+
`);
|
|
1035
1047
|
} catch {
|
|
1036
1048
|
}
|
|
1037
1049
|
}
|
|
@@ -1059,8 +1071,8 @@ function findPackageRoot() {
|
|
|
1059
1071
|
function getAvailableMemoryGB() {
|
|
1060
1072
|
if (process.platform === "darwin") {
|
|
1061
1073
|
try {
|
|
1062
|
-
const { execSync:
|
|
1063
|
-
const vmstat =
|
|
1074
|
+
const { execSync: execSync6 } = __require("child_process");
|
|
1075
|
+
const vmstat = execSync6("vm_stat", { encoding: "utf8" });
|
|
1064
1076
|
const pageSize = 16384;
|
|
1065
1077
|
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
1066
1078
|
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
@@ -3050,6 +3062,12 @@ async function disposeDatabase() {
|
|
|
3050
3062
|
clearInterval(_walCheckpointTimer);
|
|
3051
3063
|
_walCheckpointTimer = null;
|
|
3052
3064
|
}
|
|
3065
|
+
if (_client) {
|
|
3066
|
+
try {
|
|
3067
|
+
await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
3068
|
+
} catch {
|
|
3069
|
+
}
|
|
3070
|
+
}
|
|
3053
3071
|
if (_daemonClient) {
|
|
3054
3072
|
_daemonClient.close();
|
|
3055
3073
|
_daemonClient = null;
|
|
@@ -3086,7 +3104,7 @@ var init_database = __esm({
|
|
|
3086
3104
|
// src/lib/keychain.ts
|
|
3087
3105
|
import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
3088
3106
|
import { existsSync as existsSync7, statSync as statSync2 } from "fs";
|
|
3089
|
-
import { execSync as
|
|
3107
|
+
import { execSync as execSync5 } from "child_process";
|
|
3090
3108
|
import path8 from "path";
|
|
3091
3109
|
import os5 from "os";
|
|
3092
3110
|
function getKeyDir() {
|
|
@@ -3103,13 +3121,13 @@ function linuxSecretAvailable() {
|
|
|
3103
3121
|
if (process.platform !== "linux") return false;
|
|
3104
3122
|
if (linuxSecretAvailability !== null) return linuxSecretAvailability;
|
|
3105
3123
|
try {
|
|
3106
|
-
|
|
3124
|
+
execSync5("command -v secret-tool >/dev/null 2>&1", { timeout: 1e3 });
|
|
3107
3125
|
} catch {
|
|
3108
3126
|
linuxSecretAvailability = false;
|
|
3109
3127
|
return false;
|
|
3110
3128
|
}
|
|
3111
3129
|
try {
|
|
3112
|
-
|
|
3130
|
+
execSync5("secret-tool search --all exe-os probe >/dev/null 2>&1", { timeout: 1e3 });
|
|
3113
3131
|
linuxSecretAvailability = true;
|
|
3114
3132
|
} catch {
|
|
3115
3133
|
linuxSecretAvailability = false;
|
|
@@ -3133,7 +3151,7 @@ function macKeychainGet(service = SERVICE) {
|
|
|
3133
3151
|
if (!nativeKeychainAllowed()) return null;
|
|
3134
3152
|
if (process.platform !== "darwin") return null;
|
|
3135
3153
|
try {
|
|
3136
|
-
return
|
|
3154
|
+
return execSync5(
|
|
3137
3155
|
`security find-generic-password -s "${service}" -a "${ACCOUNT}" -w 2>/dev/null`,
|
|
3138
3156
|
{ encoding: "utf-8", timeout: 5e3 }
|
|
3139
3157
|
).trim();
|
|
@@ -3146,13 +3164,13 @@ function macKeychainSet(value, service = SERVICE) {
|
|
|
3146
3164
|
if (process.platform !== "darwin") return false;
|
|
3147
3165
|
try {
|
|
3148
3166
|
try {
|
|
3149
|
-
|
|
3167
|
+
execSync5(
|
|
3150
3168
|
`security delete-generic-password -s "${service}" -a "${ACCOUNT}" 2>/dev/null`,
|
|
3151
3169
|
{ timeout: 5e3 }
|
|
3152
3170
|
);
|
|
3153
3171
|
} catch {
|
|
3154
3172
|
}
|
|
3155
|
-
|
|
3173
|
+
execSync5(
|
|
3156
3174
|
`security add-generic-password -s "${service}" -a "${ACCOUNT}" -w "${value}"`,
|
|
3157
3175
|
{ timeout: 5e3 }
|
|
3158
3176
|
);
|
|
@@ -3165,7 +3183,7 @@ function macKeychainDelete(service = SERVICE) {
|
|
|
3165
3183
|
if (!nativeKeychainAllowed()) return false;
|
|
3166
3184
|
if (process.platform !== "darwin") return false;
|
|
3167
3185
|
try {
|
|
3168
|
-
|
|
3186
|
+
execSync5(
|
|
3169
3187
|
`security delete-generic-password -s "${service}" -a "${ACCOUNT}" 2>/dev/null`,
|
|
3170
3188
|
{ timeout: 5e3 }
|
|
3171
3189
|
);
|
|
@@ -3177,7 +3195,7 @@ function macKeychainDelete(service = SERVICE) {
|
|
|
3177
3195
|
function linuxSecretGet(service = SERVICE) {
|
|
3178
3196
|
if (!linuxSecretAvailable()) return null;
|
|
3179
3197
|
try {
|
|
3180
|
-
return
|
|
3198
|
+
return execSync5(
|
|
3181
3199
|
`secret-tool lookup service "${service}" account "${ACCOUNT}" 2>/dev/null`,
|
|
3182
3200
|
{ encoding: "utf-8", timeout: 5e3 }
|
|
3183
3201
|
).trim();
|
|
@@ -3188,7 +3206,7 @@ function linuxSecretGet(service = SERVICE) {
|
|
|
3188
3206
|
function linuxSecretSet(value, service = SERVICE) {
|
|
3189
3207
|
if (!linuxSecretAvailable()) return false;
|
|
3190
3208
|
try {
|
|
3191
|
-
|
|
3209
|
+
execSync5(
|
|
3192
3210
|
`echo -n "${value}" | secret-tool store --label="exe-os master key" service "${service}" account "${ACCOUNT}" 2>/dev/null`,
|
|
3193
3211
|
{ timeout: 5e3 }
|
|
3194
3212
|
);
|
|
@@ -3201,7 +3219,7 @@ function linuxSecretDelete(service = SERVICE) {
|
|
|
3201
3219
|
if (!nativeKeychainAllowed()) return false;
|
|
3202
3220
|
if (process.platform !== "linux") return false;
|
|
3203
3221
|
try {
|
|
3204
|
-
|
|
3222
|
+
execSync5(
|
|
3205
3223
|
`secret-tool clear service "${service}" account "${ACCOUNT}" 2>/dev/null`,
|
|
3206
3224
|
{ timeout: 5e3 }
|
|
3207
3225
|
);
|
|
@@ -4138,6 +4156,24 @@ var init_platform_procedures = __esm({
|
|
|
4138
4156
|
priority: "p0",
|
|
4139
4157
|
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."
|
|
4140
4158
|
},
|
|
4159
|
+
{
|
|
4160
|
+
title: "Bug report status check \u2014 surface available fixes on boot",
|
|
4161
|
+
domain: "support",
|
|
4162
|
+
priority: "p1",
|
|
4163
|
+
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."
|
|
4164
|
+
},
|
|
4165
|
+
{
|
|
4166
|
+
title: "Feature request triage \u2014 upstream feature vs local customization",
|
|
4167
|
+
domain: "support",
|
|
4168
|
+
priority: "p0",
|
|
4169
|
+
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."
|
|
4170
|
+
},
|
|
4171
|
+
{
|
|
4172
|
+
title: "Feature request status check \u2014 surface shipped features on boot",
|
|
4173
|
+
domain: "support",
|
|
4174
|
+
priority: "p1",
|
|
4175
|
+
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."
|
|
4176
|
+
},
|
|
4141
4177
|
// --- Operations ---
|
|
4142
4178
|
{
|
|
4143
4179
|
title: "Managers must supervise deployed workers",
|
|
@@ -994,7 +994,7 @@ __export(exe_daemon_client_exports, {
|
|
|
994
994
|
});
|
|
995
995
|
import net from "net";
|
|
996
996
|
import os4 from "os";
|
|
997
|
-
import { spawn } from "child_process";
|
|
997
|
+
import { spawn, execSync as execSync4 } from "child_process";
|
|
998
998
|
import { randomUUID } from "crypto";
|
|
999
999
|
import { existsSync as existsSync5, unlinkSync as unlinkSync3, readFileSync as readFileSync5, openSync, closeSync, statSync } from "fs";
|
|
1000
1000
|
import path6 from "path";
|
|
@@ -1024,6 +1024,14 @@ function handleData(chunk) {
|
|
|
1024
1024
|
}
|
|
1025
1025
|
}
|
|
1026
1026
|
}
|
|
1027
|
+
function isZombie(pid) {
|
|
1028
|
+
try {
|
|
1029
|
+
const state = execSync4(`ps -p ${pid} -o state=`, { encoding: "utf8", timeout: 2e3 }).trim();
|
|
1030
|
+
return state.startsWith("Z");
|
|
1031
|
+
} catch {
|
|
1032
|
+
return false;
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1027
1035
|
function cleanupStaleFiles() {
|
|
1028
1036
|
if (existsSync5(PID_PATH)) {
|
|
1029
1037
|
try {
|
|
@@ -1031,7 +1039,11 @@ function cleanupStaleFiles() {
|
|
|
1031
1039
|
if (pid > 0) {
|
|
1032
1040
|
try {
|
|
1033
1041
|
process.kill(pid, 0);
|
|
1034
|
-
|
|
1042
|
+
if (!isZombie(pid)) {
|
|
1043
|
+
return;
|
|
1044
|
+
}
|
|
1045
|
+
process.stderr.write(`[exed-client] PID ${pid} is a zombie \u2014 cleaning up stale files
|
|
1046
|
+
`);
|
|
1035
1047
|
} catch {
|
|
1036
1048
|
}
|
|
1037
1049
|
}
|
|
@@ -1059,8 +1071,8 @@ function findPackageRoot() {
|
|
|
1059
1071
|
function getAvailableMemoryGB() {
|
|
1060
1072
|
if (process.platform === "darwin") {
|
|
1061
1073
|
try {
|
|
1062
|
-
const { execSync:
|
|
1063
|
-
const vmstat =
|
|
1074
|
+
const { execSync: execSync6 } = __require("child_process");
|
|
1075
|
+
const vmstat = execSync6("vm_stat", { encoding: "utf8" });
|
|
1064
1076
|
const pageSize = 16384;
|
|
1065
1077
|
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
1066
1078
|
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
@@ -3050,6 +3062,12 @@ async function disposeDatabase() {
|
|
|
3050
3062
|
clearInterval(_walCheckpointTimer);
|
|
3051
3063
|
_walCheckpointTimer = null;
|
|
3052
3064
|
}
|
|
3065
|
+
if (_client) {
|
|
3066
|
+
try {
|
|
3067
|
+
await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
3068
|
+
} catch {
|
|
3069
|
+
}
|
|
3070
|
+
}
|
|
3053
3071
|
if (_daemonClient) {
|
|
3054
3072
|
_daemonClient.close();
|
|
3055
3073
|
_daemonClient = null;
|
|
@@ -3086,7 +3104,7 @@ var init_database = __esm({
|
|
|
3086
3104
|
// src/lib/keychain.ts
|
|
3087
3105
|
import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
3088
3106
|
import { existsSync as existsSync6, statSync as statSync2 } from "fs";
|
|
3089
|
-
import { execSync as
|
|
3107
|
+
import { execSync as execSync5 } from "child_process";
|
|
3090
3108
|
import path7 from "path";
|
|
3091
3109
|
import os5 from "os";
|
|
3092
3110
|
function getKeyDir() {
|
|
@@ -3103,13 +3121,13 @@ function linuxSecretAvailable() {
|
|
|
3103
3121
|
if (process.platform !== "linux") return false;
|
|
3104
3122
|
if (linuxSecretAvailability !== null) return linuxSecretAvailability;
|
|
3105
3123
|
try {
|
|
3106
|
-
|
|
3124
|
+
execSync5("command -v secret-tool >/dev/null 2>&1", { timeout: 1e3 });
|
|
3107
3125
|
} catch {
|
|
3108
3126
|
linuxSecretAvailability = false;
|
|
3109
3127
|
return false;
|
|
3110
3128
|
}
|
|
3111
3129
|
try {
|
|
3112
|
-
|
|
3130
|
+
execSync5("secret-tool search --all exe-os probe >/dev/null 2>&1", { timeout: 1e3 });
|
|
3113
3131
|
linuxSecretAvailability = true;
|
|
3114
3132
|
} catch {
|
|
3115
3133
|
linuxSecretAvailability = false;
|
|
@@ -3133,7 +3151,7 @@ function macKeychainGet(service = SERVICE) {
|
|
|
3133
3151
|
if (!nativeKeychainAllowed()) return null;
|
|
3134
3152
|
if (process.platform !== "darwin") return null;
|
|
3135
3153
|
try {
|
|
3136
|
-
return
|
|
3154
|
+
return execSync5(
|
|
3137
3155
|
`security find-generic-password -s "${service}" -a "${ACCOUNT}" -w 2>/dev/null`,
|
|
3138
3156
|
{ encoding: "utf-8", timeout: 5e3 }
|
|
3139
3157
|
).trim();
|
|
@@ -3146,13 +3164,13 @@ function macKeychainSet(value, service = SERVICE) {
|
|
|
3146
3164
|
if (process.platform !== "darwin") return false;
|
|
3147
3165
|
try {
|
|
3148
3166
|
try {
|
|
3149
|
-
|
|
3167
|
+
execSync5(
|
|
3150
3168
|
`security delete-generic-password -s "${service}" -a "${ACCOUNT}" 2>/dev/null`,
|
|
3151
3169
|
{ timeout: 5e3 }
|
|
3152
3170
|
);
|
|
3153
3171
|
} catch {
|
|
3154
3172
|
}
|
|
3155
|
-
|
|
3173
|
+
execSync5(
|
|
3156
3174
|
`security add-generic-password -s "${service}" -a "${ACCOUNT}" -w "${value}"`,
|
|
3157
3175
|
{ timeout: 5e3 }
|
|
3158
3176
|
);
|
|
@@ -3165,7 +3183,7 @@ function macKeychainDelete(service = SERVICE) {
|
|
|
3165
3183
|
if (!nativeKeychainAllowed()) return false;
|
|
3166
3184
|
if (process.platform !== "darwin") return false;
|
|
3167
3185
|
try {
|
|
3168
|
-
|
|
3186
|
+
execSync5(
|
|
3169
3187
|
`security delete-generic-password -s "${service}" -a "${ACCOUNT}" 2>/dev/null`,
|
|
3170
3188
|
{ timeout: 5e3 }
|
|
3171
3189
|
);
|
|
@@ -3177,7 +3195,7 @@ function macKeychainDelete(service = SERVICE) {
|
|
|
3177
3195
|
function linuxSecretGet(service = SERVICE) {
|
|
3178
3196
|
if (!linuxSecretAvailable()) return null;
|
|
3179
3197
|
try {
|
|
3180
|
-
return
|
|
3198
|
+
return execSync5(
|
|
3181
3199
|
`secret-tool lookup service "${service}" account "${ACCOUNT}" 2>/dev/null`,
|
|
3182
3200
|
{ encoding: "utf-8", timeout: 5e3 }
|
|
3183
3201
|
).trim();
|
|
@@ -3188,7 +3206,7 @@ function linuxSecretGet(service = SERVICE) {
|
|
|
3188
3206
|
function linuxSecretSet(value, service = SERVICE) {
|
|
3189
3207
|
if (!linuxSecretAvailable()) return false;
|
|
3190
3208
|
try {
|
|
3191
|
-
|
|
3209
|
+
execSync5(
|
|
3192
3210
|
`echo -n "${value}" | secret-tool store --label="exe-os master key" service "${service}" account "${ACCOUNT}" 2>/dev/null`,
|
|
3193
3211
|
{ timeout: 5e3 }
|
|
3194
3212
|
);
|
|
@@ -3201,7 +3219,7 @@ function linuxSecretDelete(service = SERVICE) {
|
|
|
3201
3219
|
if (!nativeKeychainAllowed()) return false;
|
|
3202
3220
|
if (process.platform !== "linux") return false;
|
|
3203
3221
|
try {
|
|
3204
|
-
|
|
3222
|
+
execSync5(
|
|
3205
3223
|
`secret-tool clear service "${service}" account "${ACCOUNT}" 2>/dev/null`,
|
|
3206
3224
|
{ timeout: 5e3 }
|
|
3207
3225
|
);
|
|
@@ -4138,6 +4156,24 @@ var init_platform_procedures = __esm({
|
|
|
4138
4156
|
priority: "p0",
|
|
4139
4157
|
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."
|
|
4140
4158
|
},
|
|
4159
|
+
{
|
|
4160
|
+
title: "Bug report status check \u2014 surface available fixes on boot",
|
|
4161
|
+
domain: "support",
|
|
4162
|
+
priority: "p1",
|
|
4163
|
+
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."
|
|
4164
|
+
},
|
|
4165
|
+
{
|
|
4166
|
+
title: "Feature request triage \u2014 upstream feature vs local customization",
|
|
4167
|
+
domain: "support",
|
|
4168
|
+
priority: "p0",
|
|
4169
|
+
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."
|
|
4170
|
+
},
|
|
4171
|
+
{
|
|
4172
|
+
title: "Feature request status check \u2014 surface shipped features on boot",
|
|
4173
|
+
domain: "support",
|
|
4174
|
+
priority: "p1",
|
|
4175
|
+
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."
|
|
4176
|
+
},
|
|
4141
4177
|
// --- Operations ---
|
|
4142
4178
|
{
|
|
4143
4179
|
title: "Managers must supervise deployed workers",
|
|
@@ -1289,7 +1289,7 @@ __export(exe_daemon_client_exports, {
|
|
|
1289
1289
|
});
|
|
1290
1290
|
import net from "net";
|
|
1291
1291
|
import os6 from "os";
|
|
1292
|
-
import { spawn } from "child_process";
|
|
1292
|
+
import { spawn, execSync as execSync5 } from "child_process";
|
|
1293
1293
|
import { randomUUID } from "crypto";
|
|
1294
1294
|
import { existsSync as existsSync7, unlinkSync as unlinkSync3, readFileSync as readFileSync7, openSync, closeSync, statSync } from "fs";
|
|
1295
1295
|
import path9 from "path";
|
|
@@ -1319,6 +1319,14 @@ function handleData(chunk) {
|
|
|
1319
1319
|
}
|
|
1320
1320
|
}
|
|
1321
1321
|
}
|
|
1322
|
+
function isZombie(pid) {
|
|
1323
|
+
try {
|
|
1324
|
+
const state = execSync5(`ps -p ${pid} -o state=`, { encoding: "utf8", timeout: 2e3 }).trim();
|
|
1325
|
+
return state.startsWith("Z");
|
|
1326
|
+
} catch {
|
|
1327
|
+
return false;
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1322
1330
|
function cleanupStaleFiles() {
|
|
1323
1331
|
if (existsSync7(PID_PATH)) {
|
|
1324
1332
|
try {
|
|
@@ -1326,7 +1334,11 @@ function cleanupStaleFiles() {
|
|
|
1326
1334
|
if (pid > 0) {
|
|
1327
1335
|
try {
|
|
1328
1336
|
process.kill(pid, 0);
|
|
1329
|
-
|
|
1337
|
+
if (!isZombie(pid)) {
|
|
1338
|
+
return;
|
|
1339
|
+
}
|
|
1340
|
+
process.stderr.write(`[exed-client] PID ${pid} is a zombie \u2014 cleaning up stale files
|
|
1341
|
+
`);
|
|
1330
1342
|
} catch {
|
|
1331
1343
|
}
|
|
1332
1344
|
}
|
|
@@ -1354,8 +1366,8 @@ function findPackageRoot() {
|
|
|
1354
1366
|
function getAvailableMemoryGB() {
|
|
1355
1367
|
if (process.platform === "darwin") {
|
|
1356
1368
|
try {
|
|
1357
|
-
const { execSync:
|
|
1358
|
-
const vmstat =
|
|
1369
|
+
const { execSync: execSync7 } = __require("child_process");
|
|
1370
|
+
const vmstat = execSync7("vm_stat", { encoding: "utf8" });
|
|
1359
1371
|
const pageSize = 16384;
|
|
1360
1372
|
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
1361
1373
|
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
@@ -3345,6 +3357,12 @@ async function disposeDatabase() {
|
|
|
3345
3357
|
clearInterval(_walCheckpointTimer);
|
|
3346
3358
|
_walCheckpointTimer = null;
|
|
3347
3359
|
}
|
|
3360
|
+
if (_client) {
|
|
3361
|
+
try {
|
|
3362
|
+
await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
3363
|
+
} catch {
|
|
3364
|
+
}
|
|
3365
|
+
}
|
|
3348
3366
|
if (_daemonClient) {
|
|
3349
3367
|
_daemonClient.close();
|
|
3350
3368
|
_daemonClient = null;
|
|
@@ -3524,7 +3542,7 @@ var init_task_scope = __esm({
|
|
|
3524
3542
|
// src/lib/keychain.ts
|
|
3525
3543
|
import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
3526
3544
|
import { existsSync as existsSync12, statSync as statSync2 } from "fs";
|
|
3527
|
-
import { execSync as
|
|
3545
|
+
import { execSync as execSync6 } from "child_process";
|
|
3528
3546
|
import path14 from "path";
|
|
3529
3547
|
import os10 from "os";
|
|
3530
3548
|
function getKeyDir() {
|
|
@@ -3541,13 +3559,13 @@ function linuxSecretAvailable() {
|
|
|
3541
3559
|
if (process.platform !== "linux") return false;
|
|
3542
3560
|
if (linuxSecretAvailability !== null) return linuxSecretAvailability;
|
|
3543
3561
|
try {
|
|
3544
|
-
|
|
3562
|
+
execSync6("command -v secret-tool >/dev/null 2>&1", { timeout: 1e3 });
|
|
3545
3563
|
} catch {
|
|
3546
3564
|
linuxSecretAvailability = false;
|
|
3547
3565
|
return false;
|
|
3548
3566
|
}
|
|
3549
3567
|
try {
|
|
3550
|
-
|
|
3568
|
+
execSync6("secret-tool search --all exe-os probe >/dev/null 2>&1", { timeout: 1e3 });
|
|
3551
3569
|
linuxSecretAvailability = true;
|
|
3552
3570
|
} catch {
|
|
3553
3571
|
linuxSecretAvailability = false;
|
|
@@ -3571,7 +3589,7 @@ function macKeychainGet(service = SERVICE) {
|
|
|
3571
3589
|
if (!nativeKeychainAllowed()) return null;
|
|
3572
3590
|
if (process.platform !== "darwin") return null;
|
|
3573
3591
|
try {
|
|
3574
|
-
return
|
|
3592
|
+
return execSync6(
|
|
3575
3593
|
`security find-generic-password -s "${service}" -a "${ACCOUNT}" -w 2>/dev/null`,
|
|
3576
3594
|
{ encoding: "utf-8", timeout: 5e3 }
|
|
3577
3595
|
).trim();
|
|
@@ -3584,13 +3602,13 @@ function macKeychainSet(value, service = SERVICE) {
|
|
|
3584
3602
|
if (process.platform !== "darwin") return false;
|
|
3585
3603
|
try {
|
|
3586
3604
|
try {
|
|
3587
|
-
|
|
3605
|
+
execSync6(
|
|
3588
3606
|
`security delete-generic-password -s "${service}" -a "${ACCOUNT}" 2>/dev/null`,
|
|
3589
3607
|
{ timeout: 5e3 }
|
|
3590
3608
|
);
|
|
3591
3609
|
} catch {
|
|
3592
3610
|
}
|
|
3593
|
-
|
|
3611
|
+
execSync6(
|
|
3594
3612
|
`security add-generic-password -s "${service}" -a "${ACCOUNT}" -w "${value}"`,
|
|
3595
3613
|
{ timeout: 5e3 }
|
|
3596
3614
|
);
|
|
@@ -3603,7 +3621,7 @@ function macKeychainDelete(service = SERVICE) {
|
|
|
3603
3621
|
if (!nativeKeychainAllowed()) return false;
|
|
3604
3622
|
if (process.platform !== "darwin") return false;
|
|
3605
3623
|
try {
|
|
3606
|
-
|
|
3624
|
+
execSync6(
|
|
3607
3625
|
`security delete-generic-password -s "${service}" -a "${ACCOUNT}" 2>/dev/null`,
|
|
3608
3626
|
{ timeout: 5e3 }
|
|
3609
3627
|
);
|
|
@@ -3615,7 +3633,7 @@ function macKeychainDelete(service = SERVICE) {
|
|
|
3615
3633
|
function linuxSecretGet(service = SERVICE) {
|
|
3616
3634
|
if (!linuxSecretAvailable()) return null;
|
|
3617
3635
|
try {
|
|
3618
|
-
return
|
|
3636
|
+
return execSync6(
|
|
3619
3637
|
`secret-tool lookup service "${service}" account "${ACCOUNT}" 2>/dev/null`,
|
|
3620
3638
|
{ encoding: "utf-8", timeout: 5e3 }
|
|
3621
3639
|
).trim();
|
|
@@ -3626,7 +3644,7 @@ function linuxSecretGet(service = SERVICE) {
|
|
|
3626
3644
|
function linuxSecretSet(value, service = SERVICE) {
|
|
3627
3645
|
if (!linuxSecretAvailable()) return false;
|
|
3628
3646
|
try {
|
|
3629
|
-
|
|
3647
|
+
execSync6(
|
|
3630
3648
|
`echo -n "${value}" | secret-tool store --label="exe-os master key" service "${service}" account "${ACCOUNT}" 2>/dev/null`,
|
|
3631
3649
|
{ timeout: 5e3 }
|
|
3632
3650
|
);
|
|
@@ -3639,7 +3657,7 @@ function linuxSecretDelete(service = SERVICE) {
|
|
|
3639
3657
|
if (!nativeKeychainAllowed()) return false;
|
|
3640
3658
|
if (process.platform !== "linux") return false;
|
|
3641
3659
|
try {
|
|
3642
|
-
|
|
3660
|
+
execSync6(
|
|
3643
3661
|
`secret-tool clear service "${service}" account "${ACCOUNT}" 2>/dev/null`,
|
|
3644
3662
|
{ timeout: 5e3 }
|
|
3645
3663
|
);
|
|
@@ -4576,6 +4594,24 @@ var init_platform_procedures = __esm({
|
|
|
4576
4594
|
priority: "p0",
|
|
4577
4595
|
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."
|
|
4578
4596
|
},
|
|
4597
|
+
{
|
|
4598
|
+
title: "Bug report status check \u2014 surface available fixes on boot",
|
|
4599
|
+
domain: "support",
|
|
4600
|
+
priority: "p1",
|
|
4601
|
+
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."
|
|
4602
|
+
},
|
|
4603
|
+
{
|
|
4604
|
+
title: "Feature request triage \u2014 upstream feature vs local customization",
|
|
4605
|
+
domain: "support",
|
|
4606
|
+
priority: "p0",
|
|
4607
|
+
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."
|
|
4608
|
+
},
|
|
4609
|
+
{
|
|
4610
|
+
title: "Feature request status check \u2014 surface shipped features on boot",
|
|
4611
|
+
domain: "support",
|
|
4612
|
+
priority: "p1",
|
|
4613
|
+
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."
|
|
4614
|
+
},
|
|
4579
4615
|
// --- Operations ---
|
|
4580
4616
|
{
|
|
4581
4617
|
title: "Managers must supervise deployed workers",
|