@askexenow/exe-os 0.9.86 → 0.9.88
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/deploy/compose/docker-compose.yml +3 -3
- package/dist/bin/age-ontology-load.js +8 -2
- package/dist/bin/agentic-ontology-backfill.js +29 -0
- package/dist/bin/agentic-reflection-backfill.js +29 -0
- package/dist/bin/agentic-semantic-label.js +29 -0
- package/dist/bin/backfill-conversations.js +30 -0
- package/dist/bin/backfill-responses.js +30 -0
- package/dist/bin/backfill-vectors.js +30 -0
- package/dist/bin/bulk-sync-postgres.js +47 -1
- package/dist/bin/cc-doctor.js +3 -2
- package/dist/bin/cleanup-stale-review-tasks.js +30 -0
- package/dist/bin/cli.js +357 -19
- package/dist/bin/exe-agent.js +19 -0
- package/dist/bin/exe-assign.js +30 -0
- package/dist/bin/exe-boot.js +157 -4
- package/dist/bin/exe-call.js +20 -0
- package/dist/bin/exe-cloud.js +156 -3
- package/dist/bin/exe-dispatch.js +30 -1
- package/dist/bin/exe-doctor.js +30 -0
- package/dist/bin/exe-export-behaviors.js +29 -0
- package/dist/bin/exe-forget.js +30 -0
- package/dist/bin/exe-gateway.js +150 -35
- package/dist/bin/exe-healthcheck.js +2 -1
- package/dist/bin/exe-heartbeat.js +30 -0
- package/dist/bin/exe-kill.js +29 -0
- package/dist/bin/exe-launch-agent.js +29 -0
- package/dist/bin/exe-new-employee.js +37 -4
- package/dist/bin/exe-pending-messages.js +29 -0
- package/dist/bin/exe-pending-notifications.js +30 -0
- package/dist/bin/exe-pending-reviews.js +30 -0
- package/dist/bin/exe-rename.js +30 -0
- package/dist/bin/exe-review.js +30 -0
- package/dist/bin/exe-search.js +30 -0
- package/dist/bin/exe-session-cleanup.js +30 -1
- package/dist/bin/exe-settings.js +3 -0
- package/dist/bin/exe-start-codex.js +31 -2
- package/dist/bin/exe-start-opencode.js +31 -2
- package/dist/bin/exe-status.js +30 -0
- package/dist/bin/exe-team.js +30 -0
- package/dist/bin/git-sweep.js +30 -1
- package/dist/bin/graph-backfill.js +29 -0
- package/dist/bin/graph-export.js +29 -0
- package/dist/bin/graph-layer-benchmark.js +9 -1
- package/dist/bin/install.js +9 -0
- package/dist/bin/intercom-check.js +31 -1
- package/dist/bin/list-providers.js +1 -0
- package/dist/bin/postgres-agentic-reflection-backfill.js +7 -1
- package/dist/bin/postgres-agentic-semantic-backfill.js +7 -1
- package/dist/bin/registry-proxy.js +1 -0
- package/dist/bin/scan-tasks.js +31 -1
- package/dist/bin/setup.js +165 -9
- package/dist/bin/shard-migrate.js +29 -0
- package/dist/bin/stack-update.js +24 -7
- package/dist/bin/update.js +5 -0
- package/dist/gateway/index.js +30 -1
- package/dist/hooks/bug-report-worker.js +30 -1
- package/dist/hooks/codex-stop-task-finalizer.js +30 -1
- package/dist/hooks/commit-complete.js +30 -1
- package/dist/hooks/error-recall.js +29 -0
- package/dist/hooks/ingest.js +29 -0
- package/dist/hooks/instructions-loaded.js +29 -0
- package/dist/hooks/notification.js +29 -0
- package/dist/hooks/post-compact.js +29 -0
- package/dist/hooks/post-tool-combined.js +29 -0
- package/dist/hooks/pre-compact.js +30 -1
- package/dist/hooks/pre-tool-use.js +29 -0
- package/dist/hooks/prompt-submit.js +30 -1
- package/dist/hooks/session-end.js +30 -1
- package/dist/hooks/session-start.js +29 -0
- package/dist/hooks/stop.js +29 -0
- package/dist/hooks/subagent-stop.js +29 -0
- package/dist/hooks/summary-worker.js +155 -3
- package/dist/index.js +30 -1
- package/dist/lib/cloud-sync.js +136 -2
- package/dist/lib/consolidation.js +1 -0
- package/dist/lib/database.js +11 -0
- package/dist/lib/db.js +11 -0
- package/dist/lib/device-registry.js +11 -0
- package/dist/lib/employee-templates.js +19 -0
- package/dist/lib/exe-daemon.js +1455 -208
- package/dist/lib/hybrid-search.js +29 -0
- package/dist/lib/identity-templates.js +6 -2
- package/dist/lib/identity.js +1 -0
- package/dist/lib/messaging.js +2 -1
- package/dist/lib/reminders.js +1 -0
- package/dist/lib/schedules.js +29 -0
- package/dist/lib/skill-learning.js +1 -0
- package/dist/lib/store.js +29 -0
- package/dist/lib/tasks.js +2 -1
- package/dist/lib/tmux-routing.js +2 -1
- package/dist/lib/token-spend.js +1 -0
- package/dist/mcp/server.js +1278 -165
- package/dist/mcp/tools/complete-reminder.js +1 -0
- package/dist/mcp/tools/create-reminder.js +1 -0
- package/dist/mcp/tools/create-task.js +8 -3
- package/dist/mcp/tools/deactivate-behavior.js +1 -0
- package/dist/mcp/tools/list-reminders.js +1 -0
- package/dist/mcp/tools/list-tasks.js +1 -0
- package/dist/mcp/tools/send-message.js +2 -1
- package/dist/mcp/tools/update-task.js +2 -1
- package/dist/runtime/index.js +30 -1
- package/dist/tui/App.js +30 -1
- package/package.json +2 -2
package/dist/bin/exe-doctor.js
CHANGED
|
@@ -2745,6 +2745,7 @@ __export(database_exports, {
|
|
|
2745
2745
|
isInitialized: () => isInitialized,
|
|
2746
2746
|
setExternalClient: () => setExternalClient
|
|
2747
2747
|
});
|
|
2748
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
2748
2749
|
import { createClient as createClient2 } from "@libsql/client";
|
|
2749
2750
|
async function initDatabase(config) {
|
|
2750
2751
|
if (_walCheckpointTimer) {
|
|
@@ -2786,6 +2787,16 @@ async function initDatabase(config) {
|
|
|
2786
2787
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
2787
2788
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
2788
2789
|
}
|
|
2790
|
+
try {
|
|
2791
|
+
chmodSync2(config.dbPath, 384);
|
|
2792
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
2793
|
+
try {
|
|
2794
|
+
chmodSync2(config.dbPath + suffix, 384);
|
|
2795
|
+
} catch {
|
|
2796
|
+
}
|
|
2797
|
+
}
|
|
2798
|
+
} catch {
|
|
2799
|
+
}
|
|
2789
2800
|
}
|
|
2790
2801
|
function isInitialized() {
|
|
2791
2802
|
return _adapterClient !== null || _client !== null;
|
|
@@ -4474,6 +4485,24 @@ var init_platform_procedures = __esm({
|
|
|
4474
4485
|
priority: "p0",
|
|
4475
4486
|
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."
|
|
4476
4487
|
},
|
|
4488
|
+
{
|
|
4489
|
+
title: "Bug report status check \u2014 surface available fixes on boot",
|
|
4490
|
+
domain: "support",
|
|
4491
|
+
priority: "p1",
|
|
4492
|
+
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."
|
|
4493
|
+
},
|
|
4494
|
+
{
|
|
4495
|
+
title: "Feature request triage \u2014 upstream feature vs local customization",
|
|
4496
|
+
domain: "support",
|
|
4497
|
+
priority: "p0",
|
|
4498
|
+
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."
|
|
4499
|
+
},
|
|
4500
|
+
{
|
|
4501
|
+
title: "Feature request status check \u2014 surface shipped features on boot",
|
|
4502
|
+
domain: "support",
|
|
4503
|
+
priority: "p1",
|
|
4504
|
+
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."
|
|
4505
|
+
},
|
|
4477
4506
|
// --- Operations ---
|
|
4478
4507
|
{
|
|
4479
4508
|
title: "Managers must supervise deployed workers",
|
|
@@ -5897,6 +5926,7 @@ import { fileURLToPath } from "url";
|
|
|
5897
5926
|
function isMainModule(importMetaUrl) {
|
|
5898
5927
|
if (process.argv[1] == null) return false;
|
|
5899
5928
|
if (process.argv[1].includes("mcp/server")) return false;
|
|
5929
|
+
if (process.argv[1].includes("exe-daemon")) return false;
|
|
5900
5930
|
try {
|
|
5901
5931
|
const scriptPath = realpathSync(process.argv[1]);
|
|
5902
5932
|
const modulePath = realpathSync(fileURLToPath(importMetaUrl));
|
|
@@ -1778,6 +1778,7 @@ __export(database_exports, {
|
|
|
1778
1778
|
isInitialized: () => isInitialized,
|
|
1779
1779
|
setExternalClient: () => setExternalClient
|
|
1780
1780
|
});
|
|
1781
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
1781
1782
|
import { createClient } from "@libsql/client";
|
|
1782
1783
|
async function initDatabase(config) {
|
|
1783
1784
|
if (_walCheckpointTimer) {
|
|
@@ -1819,6 +1820,16 @@ async function initDatabase(config) {
|
|
|
1819
1820
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
1820
1821
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
1821
1822
|
}
|
|
1823
|
+
try {
|
|
1824
|
+
chmodSync2(config.dbPath, 384);
|
|
1825
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
1826
|
+
try {
|
|
1827
|
+
chmodSync2(config.dbPath + suffix, 384);
|
|
1828
|
+
} catch {
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
} catch {
|
|
1832
|
+
}
|
|
1822
1833
|
}
|
|
1823
1834
|
function isInitialized() {
|
|
1824
1835
|
return _adapterClient !== null || _client !== null;
|
|
@@ -4230,6 +4241,24 @@ var init_platform_procedures = __esm({
|
|
|
4230
4241
|
priority: "p0",
|
|
4231
4242
|
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."
|
|
4232
4243
|
},
|
|
4244
|
+
{
|
|
4245
|
+
title: "Bug report status check \u2014 surface available fixes on boot",
|
|
4246
|
+
domain: "support",
|
|
4247
|
+
priority: "p1",
|
|
4248
|
+
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."
|
|
4249
|
+
},
|
|
4250
|
+
{
|
|
4251
|
+
title: "Feature request triage \u2014 upstream feature vs local customization",
|
|
4252
|
+
domain: "support",
|
|
4253
|
+
priority: "p0",
|
|
4254
|
+
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."
|
|
4255
|
+
},
|
|
4256
|
+
{
|
|
4257
|
+
title: "Feature request status check \u2014 surface shipped features on boot",
|
|
4258
|
+
domain: "support",
|
|
4259
|
+
priority: "p1",
|
|
4260
|
+
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."
|
|
4261
|
+
},
|
|
4233
4262
|
// --- Operations ---
|
|
4234
4263
|
{
|
|
4235
4264
|
title: "Managers must supervise deployed workers",
|
package/dist/bin/exe-forget.js
CHANGED
|
@@ -1702,6 +1702,7 @@ __export(database_exports, {
|
|
|
1702
1702
|
isInitialized: () => isInitialized,
|
|
1703
1703
|
setExternalClient: () => setExternalClient
|
|
1704
1704
|
});
|
|
1705
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
1705
1706
|
import { createClient } from "@libsql/client";
|
|
1706
1707
|
async function initDatabase(config) {
|
|
1707
1708
|
if (_walCheckpointTimer) {
|
|
@@ -1743,6 +1744,16 @@ async function initDatabase(config) {
|
|
|
1743
1744
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
1744
1745
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
1745
1746
|
}
|
|
1747
|
+
try {
|
|
1748
|
+
chmodSync2(config.dbPath, 384);
|
|
1749
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
1750
|
+
try {
|
|
1751
|
+
chmodSync2(config.dbPath + suffix, 384);
|
|
1752
|
+
} catch {
|
|
1753
|
+
}
|
|
1754
|
+
}
|
|
1755
|
+
} catch {
|
|
1756
|
+
}
|
|
1746
1757
|
}
|
|
1747
1758
|
function isInitialized() {
|
|
1748
1759
|
return _adapterClient !== null || _client !== null;
|
|
@@ -4154,6 +4165,24 @@ var init_platform_procedures = __esm({
|
|
|
4154
4165
|
priority: "p0",
|
|
4155
4166
|
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."
|
|
4156
4167
|
},
|
|
4168
|
+
{
|
|
4169
|
+
title: "Bug report status check \u2014 surface available fixes on boot",
|
|
4170
|
+
domain: "support",
|
|
4171
|
+
priority: "p1",
|
|
4172
|
+
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."
|
|
4173
|
+
},
|
|
4174
|
+
{
|
|
4175
|
+
title: "Feature request triage \u2014 upstream feature vs local customization",
|
|
4176
|
+
domain: "support",
|
|
4177
|
+
priority: "p0",
|
|
4178
|
+
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."
|
|
4179
|
+
},
|
|
4180
|
+
{
|
|
4181
|
+
title: "Feature request status check \u2014 surface shipped features on boot",
|
|
4182
|
+
domain: "support",
|
|
4183
|
+
priority: "p1",
|
|
4184
|
+
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."
|
|
4185
|
+
},
|
|
4157
4186
|
// --- Operations ---
|
|
4158
4187
|
{
|
|
4159
4188
|
title: "Managers must supervise deployed workers",
|
|
@@ -5764,6 +5793,7 @@ import { fileURLToPath as fileURLToPath2 } from "url";
|
|
|
5764
5793
|
function isMainModule(importMetaUrl) {
|
|
5765
5794
|
if (process.argv[1] == null) return false;
|
|
5766
5795
|
if (process.argv[1].includes("mcp/server")) return false;
|
|
5796
|
+
if (process.argv[1].includes("exe-daemon")) return false;
|
|
5767
5797
|
try {
|
|
5768
5798
|
const scriptPath = realpathSync(process.argv[1]);
|
|
5769
5799
|
const modulePath = realpathSync(fileURLToPath2(importMetaUrl));
|
package/dist/bin/exe-gateway.js
CHANGED
|
@@ -26,6 +26,21 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
26
26
|
};
|
|
27
27
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
28
|
|
|
29
|
+
// src/lib/pg-ssl.ts
|
|
30
|
+
var pg_ssl_exports = {};
|
|
31
|
+
__export(pg_ssl_exports, {
|
|
32
|
+
pgSslConfig: () => pgSslConfig
|
|
33
|
+
});
|
|
34
|
+
function pgSslConfig() {
|
|
35
|
+
if (process.env.EXE_DB_SSL_DISABLED === "true") return {};
|
|
36
|
+
return { ssl: { rejectUnauthorized: process.env.EXE_DB_SSL_ALLOW_SELFSIGNED !== "true" } };
|
|
37
|
+
}
|
|
38
|
+
var init_pg_ssl = __esm({
|
|
39
|
+
"src/lib/pg-ssl.ts"() {
|
|
40
|
+
"use strict";
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
29
44
|
// src/lib/state-bus.ts
|
|
30
45
|
var StateBus, orgBus;
|
|
31
46
|
var init_state_bus = __esm({
|
|
@@ -1664,7 +1679,7 @@ var init_memory = __esm({
|
|
|
1664
1679
|
});
|
|
1665
1680
|
|
|
1666
1681
|
// src/lib/daemon-auth.ts
|
|
1667
|
-
import
|
|
1682
|
+
import crypto2 from "crypto";
|
|
1668
1683
|
import path6 from "path";
|
|
1669
1684
|
import { existsSync as existsSync5, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
|
|
1670
1685
|
function normalizeToken(token) {
|
|
@@ -1683,7 +1698,7 @@ function readDaemonToken() {
|
|
|
1683
1698
|
function ensureDaemonToken(seed) {
|
|
1684
1699
|
const existing = readDaemonToken();
|
|
1685
1700
|
if (existing) return existing;
|
|
1686
|
-
const token = normalizeToken(seed) ??
|
|
1701
|
+
const token = normalizeToken(seed) ?? crypto2.randomBytes(32).toString("hex");
|
|
1687
1702
|
ensurePrivateDirSync(EXE_AI_DIR);
|
|
1688
1703
|
writeFileSync3(DAEMON_TOKEN_PATH, `${token}
|
|
1689
1704
|
`, "utf8");
|
|
@@ -2358,6 +2373,7 @@ __export(database_exports, {
|
|
|
2358
2373
|
isInitialized: () => isInitialized,
|
|
2359
2374
|
setExternalClient: () => setExternalClient
|
|
2360
2375
|
});
|
|
2376
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
2361
2377
|
import { createClient } from "@libsql/client";
|
|
2362
2378
|
async function initDatabase(config2) {
|
|
2363
2379
|
if (_walCheckpointTimer) {
|
|
@@ -2399,6 +2415,16 @@ async function initDatabase(config2) {
|
|
|
2399
2415
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
2400
2416
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
2401
2417
|
}
|
|
2418
|
+
try {
|
|
2419
|
+
chmodSync2(config2.dbPath, 384);
|
|
2420
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
2421
|
+
try {
|
|
2422
|
+
chmodSync2(config2.dbPath + suffix, 384);
|
|
2423
|
+
} catch {
|
|
2424
|
+
}
|
|
2425
|
+
}
|
|
2426
|
+
} catch {
|
|
2427
|
+
}
|
|
2402
2428
|
}
|
|
2403
2429
|
function isInitialized() {
|
|
2404
2430
|
return _adapterClient !== null || _client !== null;
|
|
@@ -3960,7 +3986,7 @@ async function tryKeytar() {
|
|
|
3960
3986
|
}
|
|
3961
3987
|
function deriveMachineKey() {
|
|
3962
3988
|
try {
|
|
3963
|
-
const
|
|
3989
|
+
const crypto11 = __require("crypto");
|
|
3964
3990
|
const material = [
|
|
3965
3991
|
os6.hostname(),
|
|
3966
3992
|
os6.userInfo().username,
|
|
@@ -3969,7 +3995,7 @@ function deriveMachineKey() {
|
|
|
3969
3995
|
// Machine ID on Linux (stable across reboots)
|
|
3970
3996
|
process.platform === "linux" ? readMachineId() : ""
|
|
3971
3997
|
].join("|");
|
|
3972
|
-
return
|
|
3998
|
+
return crypto11.createHash("sha256").update(material).digest();
|
|
3973
3999
|
} catch {
|
|
3974
4000
|
return null;
|
|
3975
4001
|
}
|
|
@@ -3983,9 +4009,9 @@ function readMachineId() {
|
|
|
3983
4009
|
}
|
|
3984
4010
|
}
|
|
3985
4011
|
function encryptWithMachineKey(plaintext, machineKey) {
|
|
3986
|
-
const
|
|
3987
|
-
const iv =
|
|
3988
|
-
const cipher =
|
|
4012
|
+
const crypto11 = __require("crypto");
|
|
4013
|
+
const iv = crypto11.randomBytes(12);
|
|
4014
|
+
const cipher = crypto11.createCipheriv("aes-256-gcm", machineKey, iv);
|
|
3989
4015
|
let encrypted = cipher.update(plaintext, "utf-8", "base64");
|
|
3990
4016
|
encrypted += cipher.final("base64");
|
|
3991
4017
|
const authTag = cipher.getAuthTag().toString("base64");
|
|
@@ -3994,13 +4020,13 @@ function encryptWithMachineKey(plaintext, machineKey) {
|
|
|
3994
4020
|
function decryptWithMachineKey(encrypted, machineKey) {
|
|
3995
4021
|
if (!encrypted.startsWith(ENCRYPTED_PREFIX)) return null;
|
|
3996
4022
|
try {
|
|
3997
|
-
const
|
|
4023
|
+
const crypto11 = __require("crypto");
|
|
3998
4024
|
const parts = encrypted.slice(ENCRYPTED_PREFIX.length).split(":");
|
|
3999
4025
|
if (parts.length !== 3) return null;
|
|
4000
4026
|
const [ivB64, tagB64, cipherB64] = parts;
|
|
4001
4027
|
const iv = Buffer.from(ivB64, "base64");
|
|
4002
4028
|
const authTag = Buffer.from(tagB64, "base64");
|
|
4003
|
-
const decipher =
|
|
4029
|
+
const decipher = crypto11.createDecipheriv("aes-256-gcm", machineKey, iv);
|
|
4004
4030
|
decipher.setAuthTag(authTag);
|
|
4005
4031
|
let decrypted = decipher.update(cipherB64, "base64", "utf-8");
|
|
4006
4032
|
decrypted += decipher.final("utf-8");
|
|
@@ -4823,6 +4849,24 @@ var init_platform_procedures = __esm({
|
|
|
4823
4849
|
priority: "p0",
|
|
4824
4850
|
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."
|
|
4825
4851
|
},
|
|
4852
|
+
{
|
|
4853
|
+
title: "Bug report status check \u2014 surface available fixes on boot",
|
|
4854
|
+
domain: "support",
|
|
4855
|
+
priority: "p1",
|
|
4856
|
+
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."
|
|
4857
|
+
},
|
|
4858
|
+
{
|
|
4859
|
+
title: "Feature request triage \u2014 upstream feature vs local customization",
|
|
4860
|
+
domain: "support",
|
|
4861
|
+
priority: "p0",
|
|
4862
|
+
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."
|
|
4863
|
+
},
|
|
4864
|
+
{
|
|
4865
|
+
title: "Feature request status check \u2014 surface shipped features on boot",
|
|
4866
|
+
domain: "support",
|
|
4867
|
+
priority: "p1",
|
|
4868
|
+
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."
|
|
4869
|
+
},
|
|
4826
4870
|
// --- Operations ---
|
|
4827
4871
|
{
|
|
4828
4872
|
title: "Managers must supervise deployed workers",
|
|
@@ -6434,13 +6478,13 @@ __export(graph_rag_exports, {
|
|
|
6434
6478
|
resolveAlias: () => resolveAlias,
|
|
6435
6479
|
storeExtraction: () => storeExtraction
|
|
6436
6480
|
});
|
|
6437
|
-
import
|
|
6481
|
+
import crypto3 from "crypto";
|
|
6438
6482
|
function normalizeEntityName(name) {
|
|
6439
6483
|
return name.replace(/\s*\([^)]*\)\s*/g, "").trim().toLowerCase();
|
|
6440
6484
|
}
|
|
6441
6485
|
function entityId(name, type) {
|
|
6442
6486
|
const normalized = normalizeEntityName(name);
|
|
6443
|
-
return
|
|
6487
|
+
return crypto3.createHash("sha256").update(`${normalized}::${type.toLowerCase()}`).digest("hex").slice(0, 16);
|
|
6444
6488
|
}
|
|
6445
6489
|
async function resolveAlias(client, name) {
|
|
6446
6490
|
const normalized = normalizeEntityName(name);
|
|
@@ -6741,7 +6785,7 @@ async function storeExtraction(client, extraction, memoryId, timestamp) {
|
|
|
6741
6785
|
const targetAlias = await resolveAlias(client, r.target);
|
|
6742
6786
|
const sourceId = sourceAlias ?? entityId(r.source, r.sourceType);
|
|
6743
6787
|
const targetId = targetAlias ?? entityId(r.target, r.targetType);
|
|
6744
|
-
const relId =
|
|
6788
|
+
const relId = crypto3.randomUUID().slice(0, 16);
|
|
6745
6789
|
try {
|
|
6746
6790
|
await client.execute({
|
|
6747
6791
|
sql: `INSERT OR IGNORE INTO entities (id, name, type, first_seen, last_seen)
|
|
@@ -6804,7 +6848,7 @@ async function storeExtraction(client, extraction, memoryId, timestamp) {
|
|
|
6804
6848
|
}
|
|
6805
6849
|
}
|
|
6806
6850
|
for (const h of extraction.hyperedges) {
|
|
6807
|
-
const hId =
|
|
6851
|
+
const hId = crypto3.randomUUID().slice(0, 16);
|
|
6808
6852
|
try {
|
|
6809
6853
|
await client.execute({
|
|
6810
6854
|
sql: `INSERT OR IGNORE INTO hyperedges (id, label, relation, confidence, timestamp)
|
|
@@ -6868,7 +6912,7 @@ async function extractBatch(client, batchSize = 50, model = "claude-haiku-4-5-20
|
|
|
6868
6912
|
totalEntities += stored.entitiesStored;
|
|
6869
6913
|
totalRelationships += stored.relationshipsStored;
|
|
6870
6914
|
}
|
|
6871
|
-
const contentHash =
|
|
6915
|
+
const contentHash = crypto3.createHash("sha256").update(rawContent).digest("hex").slice(0, 32);
|
|
6872
6916
|
await client.execute({
|
|
6873
6917
|
sql: "UPDATE memories SET graph_extracted = 1, content_hash = ?, graph_extracted_hash = ? WHERE id = ?",
|
|
6874
6918
|
args: [contentHash, contentHash, memoryId]
|
|
@@ -9708,7 +9752,7 @@ function readQueue() {
|
|
|
9708
9752
|
function writeQueue(queue) {
|
|
9709
9753
|
ensureDir();
|
|
9710
9754
|
const tmp = `${QUEUE_PATH}.tmp`;
|
|
9711
|
-
writeFileSync6(tmp, JSON.stringify(queue, null, 2));
|
|
9755
|
+
writeFileSync6(tmp, JSON.stringify(queue, null, 2), { mode: 384 });
|
|
9712
9756
|
renameSync4(tmp, QUEUE_PATH);
|
|
9713
9757
|
}
|
|
9714
9758
|
function queueIntercom(targetSession, reason) {
|
|
@@ -9983,7 +10027,7 @@ var init_task_scope = __esm({
|
|
|
9983
10027
|
});
|
|
9984
10028
|
|
|
9985
10029
|
// src/lib/notifications.ts
|
|
9986
|
-
import
|
|
10030
|
+
import crypto5 from "crypto";
|
|
9987
10031
|
import path16 from "path";
|
|
9988
10032
|
import os12 from "os";
|
|
9989
10033
|
import {
|
|
@@ -9996,7 +10040,7 @@ import {
|
|
|
9996
10040
|
async function writeNotification(notification) {
|
|
9997
10041
|
try {
|
|
9998
10042
|
const client = getClient();
|
|
9999
|
-
const id =
|
|
10043
|
+
const id = crypto5.randomUUID();
|
|
10000
10044
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
10001
10045
|
const sessionScope = notification.sessionScope === void 0 ? getCurrentSessionScope() : notification.sessionScope;
|
|
10002
10046
|
await client.execute({
|
|
@@ -10040,7 +10084,7 @@ var init_notifications = __esm({
|
|
|
10040
10084
|
});
|
|
10041
10085
|
|
|
10042
10086
|
// src/lib/session-kill-telemetry.ts
|
|
10043
|
-
import
|
|
10087
|
+
import crypto6 from "crypto";
|
|
10044
10088
|
async function recordSessionKill(input) {
|
|
10045
10089
|
try {
|
|
10046
10090
|
const client = getClient();
|
|
@@ -10050,7 +10094,7 @@ async function recordSessionKill(input) {
|
|
|
10050
10094
|
ticks_idle, estimated_tokens_saved)
|
|
10051
10095
|
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
|
10052
10096
|
args: [
|
|
10053
|
-
|
|
10097
|
+
crypto6.randomUUID(),
|
|
10054
10098
|
input.sessionName,
|
|
10055
10099
|
input.agentId,
|
|
10056
10100
|
(/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -10178,7 +10222,7 @@ var init_session_scope = __esm({
|
|
|
10178
10222
|
});
|
|
10179
10223
|
|
|
10180
10224
|
// src/lib/tasks-crud.ts
|
|
10181
|
-
import
|
|
10225
|
+
import crypto7 from "crypto";
|
|
10182
10226
|
import path18 from "path";
|
|
10183
10227
|
import os13 from "os";
|
|
10184
10228
|
import { execSync as execSync7 } from "child_process";
|
|
@@ -10299,7 +10343,7 @@ async function resolveTask(client, identifier, scopeSession) {
|
|
|
10299
10343
|
}
|
|
10300
10344
|
async function createTaskCore(input) {
|
|
10301
10345
|
const client = getClient();
|
|
10302
|
-
const id =
|
|
10346
|
+
const id = crypto7.randomUUID();
|
|
10303
10347
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
10304
10348
|
const slug = slugify(input.title);
|
|
10305
10349
|
let earlySessionScope = null;
|
|
@@ -11264,10 +11308,10 @@ var init_tasks_notify = __esm({
|
|
|
11264
11308
|
});
|
|
11265
11309
|
|
|
11266
11310
|
// src/lib/behaviors.ts
|
|
11267
|
-
import
|
|
11311
|
+
import crypto8 from "crypto";
|
|
11268
11312
|
async function storeBehavior(opts) {
|
|
11269
11313
|
const client = getClient();
|
|
11270
|
-
const id =
|
|
11314
|
+
const id = crypto8.randomUUID();
|
|
11271
11315
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
11272
11316
|
let vector = null;
|
|
11273
11317
|
try {
|
|
@@ -11303,7 +11347,7 @@ __export(skill_learning_exports, {
|
|
|
11303
11347
|
storeTrajectory: () => storeTrajectory,
|
|
11304
11348
|
sweepTrajectories: () => sweepTrajectories
|
|
11305
11349
|
});
|
|
11306
|
-
import
|
|
11350
|
+
import crypto9 from "crypto";
|
|
11307
11351
|
async function extractTrajectory(taskId, agentId) {
|
|
11308
11352
|
const client = getClient();
|
|
11309
11353
|
const result = await client.execute({
|
|
@@ -11332,11 +11376,11 @@ async function extractTrajectory(taskId, agentId) {
|
|
|
11332
11376
|
return signature;
|
|
11333
11377
|
}
|
|
11334
11378
|
function hashSignature(signature) {
|
|
11335
|
-
return
|
|
11379
|
+
return crypto9.createHash("sha256").update(signature.join("|")).digest("hex").slice(0, 16);
|
|
11336
11380
|
}
|
|
11337
11381
|
async function storeTrajectory(opts) {
|
|
11338
11382
|
const client = getClient();
|
|
11339
|
-
const id =
|
|
11383
|
+
const id = crypto9.randomUUID();
|
|
11340
11384
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
11341
11385
|
const signatureHash = hashSignature(opts.signature);
|
|
11342
11386
|
await client.execute({
|
|
@@ -12907,10 +12951,10 @@ __export(messaging_exports, {
|
|
|
12907
12951
|
sendMessage: () => sendMessage,
|
|
12908
12952
|
setWsClientSend: () => setWsClientSend
|
|
12909
12953
|
});
|
|
12910
|
-
import
|
|
12954
|
+
import crypto10 from "crypto";
|
|
12911
12955
|
function generateUlid() {
|
|
12912
12956
|
const timestamp = Date.now().toString(36).padStart(10, "0");
|
|
12913
|
-
const random =
|
|
12957
|
+
const random = crypto10.randomBytes(10).toString("hex").slice(0, 16);
|
|
12914
12958
|
return (timestamp + random).toUpperCase();
|
|
12915
12959
|
}
|
|
12916
12960
|
function rowToMessage(row) {
|
|
@@ -13531,6 +13575,7 @@ import os16 from "os";
|
|
|
13531
13575
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
13532
13576
|
|
|
13533
13577
|
// src/gateway/webhook-server.ts
|
|
13578
|
+
import crypto from "crypto";
|
|
13534
13579
|
import {
|
|
13535
13580
|
createServer
|
|
13536
13581
|
} from "http";
|
|
@@ -13878,7 +13923,7 @@ var ReadOnlySqlRunner = class {
|
|
|
13878
13923
|
this.config = config2;
|
|
13879
13924
|
}
|
|
13880
13925
|
async run(sql, maxRows) {
|
|
13881
|
-
const databaseUrl = this.config.databaseUrl ?? process.env.EXE_GATEWAY_SQL_DATABASE_URL ?? process.env.EXE_COMPANY_BRAIN_SQL_DATABASE_URL ?? process.env.DATABASE_URL;
|
|
13926
|
+
const databaseUrl = this.config.databaseUrl ?? process.env.EXE_GATEWAY_SQL_DATABASE_URL ?? process.env.MCP_READONLY_DATABASE_URL ?? process.env.EXE_COMPANY_BRAIN_SQL_DATABASE_URL ?? process.env.DATABASE_URL;
|
|
13882
13927
|
if (!databaseUrl) {
|
|
13883
13928
|
throw new Error("Read-only SQL is not configured. Set EXE_GATEWAY_SQL_DATABASE_URL or DATABASE_URL.");
|
|
13884
13929
|
}
|
|
@@ -13886,7 +13931,8 @@ var ReadOnlySqlRunner = class {
|
|
|
13886
13931
|
const limit = clampRows(maxRows ?? this.config.maxRows ?? DEFAULT_MAX_ROWS);
|
|
13887
13932
|
const timeoutMs = this.config.statementTimeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
13888
13933
|
const wrappedSql = `SELECT * FROM (${cleaned}) AS exe_readonly_sql LIMIT ${limit + 1}`;
|
|
13889
|
-
const
|
|
13934
|
+
const { pgSslConfig: pgSslConfig2 } = await Promise.resolve().then(() => (init_pg_ssl(), pg_ssl_exports));
|
|
13935
|
+
const client = new Client({ connectionString: databaseUrl, ...pgSslConfig2() });
|
|
13890
13936
|
const start = Date.now();
|
|
13891
13937
|
try {
|
|
13892
13938
|
await client.connect();
|
|
@@ -13949,6 +13995,61 @@ function clampRows(value) {
|
|
|
13949
13995
|
// src/gateway/webhook-server.ts
|
|
13950
13996
|
var DEFAULT_HOST = process.env.EXE_WEBHOOK_HOST || "127.0.0.1";
|
|
13951
13997
|
var BODY_SIZE_LIMIT = 1048576;
|
|
13998
|
+
function verifyWebhookSignature(rawBody, signature, secret, toleranceSec = 300) {
|
|
13999
|
+
if (!signature) return false;
|
|
14000
|
+
const dotIdx = signature.indexOf(".");
|
|
14001
|
+
if (dotIdx < 0) return false;
|
|
14002
|
+
const timestampStr = signature.slice(0, dotIdx);
|
|
14003
|
+
const hash = signature.slice(dotIdx + 1);
|
|
14004
|
+
const timestamp = parseInt(timestampStr, 10);
|
|
14005
|
+
if (isNaN(timestamp)) return false;
|
|
14006
|
+
if (Math.abs(Date.now() / 1e3 - timestamp) > toleranceSec) return false;
|
|
14007
|
+
const expected = crypto.createHmac("sha256", secret).update(`${timestamp}.${rawBody}`).digest("hex");
|
|
14008
|
+
if (hash.length !== expected.length) return false;
|
|
14009
|
+
return crypto.timingSafeEqual(
|
|
14010
|
+
Buffer.from(hash, "hex"),
|
|
14011
|
+
Buffer.from(expected, "hex")
|
|
14012
|
+
);
|
|
14013
|
+
}
|
|
14014
|
+
function readRawBody(req) {
|
|
14015
|
+
return new Promise((resolve, reject) => {
|
|
14016
|
+
const chunks = [];
|
|
14017
|
+
let size = 0;
|
|
14018
|
+
let done = false;
|
|
14019
|
+
req.on("data", (chunk) => {
|
|
14020
|
+
size += chunk.length;
|
|
14021
|
+
if (size > BODY_SIZE_LIMIT) {
|
|
14022
|
+
if (!done) {
|
|
14023
|
+
done = true;
|
|
14024
|
+
req.resume();
|
|
14025
|
+
reject(new Error("Body too large"));
|
|
14026
|
+
}
|
|
14027
|
+
return;
|
|
14028
|
+
}
|
|
14029
|
+
chunks.push(chunk);
|
|
14030
|
+
});
|
|
14031
|
+
req.on("end", () => {
|
|
14032
|
+
if (done) return;
|
|
14033
|
+
done = true;
|
|
14034
|
+
const raw = Buffer.concat(chunks).toString("utf-8");
|
|
14035
|
+
if (!raw) {
|
|
14036
|
+
resolve({ raw: "", parsed: {} });
|
|
14037
|
+
return;
|
|
14038
|
+
}
|
|
14039
|
+
try {
|
|
14040
|
+
resolve({ raw, parsed: JSON.parse(raw) });
|
|
14041
|
+
} catch {
|
|
14042
|
+
reject(new Error("Invalid JSON"));
|
|
14043
|
+
}
|
|
14044
|
+
});
|
|
14045
|
+
req.on("error", (err) => {
|
|
14046
|
+
if (!done) {
|
|
14047
|
+
done = true;
|
|
14048
|
+
reject(err);
|
|
14049
|
+
}
|
|
14050
|
+
});
|
|
14051
|
+
});
|
|
14052
|
+
}
|
|
13952
14053
|
var WebhookServer = class {
|
|
13953
14054
|
constructor(config2, queryHandler = new QueryHandler()) {
|
|
13954
14055
|
this.config = config2;
|
|
@@ -14092,13 +14193,26 @@ var WebhookServer = class {
|
|
|
14092
14193
|
}
|
|
14093
14194
|
async handleWebhookPost(req, res, url) {
|
|
14094
14195
|
let body;
|
|
14196
|
+
let rawBody = "";
|
|
14095
14197
|
let parseError = null;
|
|
14096
14198
|
try {
|
|
14097
|
-
|
|
14199
|
+
const result = await readRawBody(req);
|
|
14200
|
+
rawBody = result.raw;
|
|
14201
|
+
body = result.parsed;
|
|
14098
14202
|
} catch (err) {
|
|
14099
14203
|
parseError = err instanceof Error ? err : new Error(String(err));
|
|
14100
14204
|
}
|
|
14101
|
-
if (this.config.
|
|
14205
|
+
if (this.config.webhookSigningSecret) {
|
|
14206
|
+
const sig = req.headers["x-webhook-signature"];
|
|
14207
|
+
if (!verifyWebhookSignature(
|
|
14208
|
+
rawBody,
|
|
14209
|
+
sig,
|
|
14210
|
+
this.config.webhookSigningSecret
|
|
14211
|
+
)) {
|
|
14212
|
+
sendJson(res, 401, { error: "Invalid webhook signature" });
|
|
14213
|
+
return;
|
|
14214
|
+
}
|
|
14215
|
+
} else if (this.config.authToken && !this.verifyAuth(req)) {
|
|
14102
14216
|
sendJson(res, 401, { error: "Unauthorized" });
|
|
14103
14217
|
return;
|
|
14104
14218
|
}
|
|
@@ -14142,6 +14256,7 @@ var WebhookServer = class {
|
|
|
14142
14256
|
if (!expectedToken) return false;
|
|
14143
14257
|
const authHeader = req.headers.authorization ?? "";
|
|
14144
14258
|
if (authHeader === `Bearer ${expectedToken}`) return true;
|
|
14259
|
+
if (process.env.NODE_ENV === "production") return false;
|
|
14145
14260
|
const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
14146
14261
|
return url.searchParams.get("token") === expectedToken;
|
|
14147
14262
|
}
|
|
@@ -14265,11 +14380,11 @@ init_crm_bridge();
|
|
|
14265
14380
|
|
|
14266
14381
|
// src/lib/pipeline-router.ts
|
|
14267
14382
|
init_database();
|
|
14268
|
-
import
|
|
14383
|
+
import crypto4 from "crypto";
|
|
14269
14384
|
async function sinkConversationStore(msg, agentResponse, agentName) {
|
|
14270
14385
|
try {
|
|
14271
14386
|
const client = getClient();
|
|
14272
|
-
const id =
|
|
14387
|
+
const id = crypto4.randomUUID();
|
|
14273
14388
|
const mediaJson = msg.media ? JSON.stringify(msg.media) : null;
|
|
14274
14389
|
await client.execute({
|
|
14275
14390
|
sql: `INSERT INTO conversations
|
|
@@ -14319,7 +14434,7 @@ async function sinkMemory(msg, agentResponse, agentName) {
|
|
|
14319
14434
|
].filter(Boolean).join("\n");
|
|
14320
14435
|
const vector = await embed2(rawText);
|
|
14321
14436
|
await writeMemory2({
|
|
14322
|
-
id:
|
|
14437
|
+
id: crypto4.randomUUID(),
|
|
14323
14438
|
agent_id: agentName ?? "gateway",
|
|
14324
14439
|
agent_role: "gateway",
|
|
14325
14440
|
session_id: `gateway-${msg.platform}`,
|
|
@@ -12,6 +12,7 @@ import { fileURLToPath } from "url";
|
|
|
12
12
|
function isMainModule(importMetaUrl) {
|
|
13
13
|
if (process.argv[1] == null) return false;
|
|
14
14
|
if (process.argv[1].includes("mcp/server")) return false;
|
|
15
|
+
if (process.argv[1].includes("exe-daemon")) return false;
|
|
15
16
|
try {
|
|
16
17
|
const scriptPath = realpathSync(process.argv[1]);
|
|
17
18
|
const modulePath = realpathSync(fileURLToPath(importMetaUrl));
|
|
@@ -587,7 +588,7 @@ function runHealthCheck() {
|
|
|
587
588
|
const failed = results.filter((r) => !r.pass).length;
|
|
588
589
|
return { results, passed, failed };
|
|
589
590
|
}
|
|
590
|
-
if (isMainModule(import.meta.url)) {
|
|
591
|
+
if (isMainModule(import.meta.url) && (process.argv[1] ?? "").includes("exe-healthcheck")) {
|
|
591
592
|
const { results, passed, failed } = runHealthCheck();
|
|
592
593
|
console.log("\n exe-os Health Check\n");
|
|
593
594
|
for (const r of results) {
|