@askexenow/exe-os 0.9.198 → 0.9.199
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/cloudflared/config.yml.example +3 -0
- package/deploy/compose/init-db.sql +4 -0
- package/deploy/stack-manifests/v0.9.json +5 -0
- package/dist/{backfill-metadata-KYCN4I7C.js → backfill-metadata-RL7T4XGY.js} +1 -1
- package/dist/bin/agentic-ontology-backfill.js +1 -1
- package/dist/bin/agentic-reflection-backfill.js +1 -1
- package/dist/bin/agentic-semantic-label.js +1 -1
- package/dist/bin/backfill-conversations.js +1 -1
- package/dist/bin/backfill-responses.js +1 -1
- package/dist/bin/backfill-vectors.js +2 -2
- package/dist/bin/bulk-sync-postgres.js +1 -1
- package/dist/bin/cleanup-stale-review-tasks.js +2 -2
- package/dist/bin/cli.js +10 -10
- package/dist/bin/exe-agent.js +8 -8
- package/dist/bin/exe-assign.js +1 -1
- package/dist/bin/exe-boot.js +4 -4
- package/dist/bin/exe-call.js +1 -1
- package/dist/bin/exe-dispatch.js +2 -2
- package/dist/bin/exe-doctor.js +1 -1
- package/dist/bin/exe-export-behaviors.js +2 -2
- package/dist/bin/exe-forget.js +3 -3
- package/dist/bin/exe-gateway.js +4 -4
- package/dist/bin/exe-heartbeat.js +2 -2
- package/dist/bin/exe-kill.js +3 -3
- package/dist/bin/exe-launch-agent.js +3 -9
- package/dist/bin/exe-new-employee.js +2 -2
- package/dist/bin/exe-pending-messages.js +3 -3
- package/dist/bin/exe-pending-notifications.js +2 -2
- package/dist/bin/exe-pending-reviews.js +2 -2
- package/dist/bin/exe-rename.js +1 -1
- package/dist/bin/exe-review.js +3 -3
- package/dist/bin/exe-search.js +2 -2
- package/dist/bin/exe-session-cleanup.js +5 -5
- package/dist/bin/exe-start-codex.js +2 -2
- package/dist/bin/exe-start-opencode.js +2 -2
- package/dist/bin/exe-status.js +3 -3
- package/dist/bin/exe-team.js +1 -1
- package/dist/bin/generate-hook-manifest.js +30 -0
- package/dist/bin/git-sweep.js +2 -2
- package/dist/bin/graph-backfill.js +1 -1
- package/dist/bin/graph-export.js +2 -2
- package/dist/bin/import-history.js +1 -1
- package/dist/bin/install.js +3 -3
- package/dist/bin/intercom-check.js +3 -3
- package/dist/bin/scan-tasks.js +2 -2
- package/dist/bin/setup.js +1 -1
- package/dist/bin/shard-migrate.js +1 -1
- package/dist/browser-sanitizer-Q3GWRYKI.js +229 -0
- package/dist/browser-session-store-TSD4PCY7.js +232 -0
- package/dist/{capacity-monitor-H7D43IUQ.js → capacity-monitor-2TRPP3AX.js} +2 -2
- package/dist/{catchup-brief-PTVQRBQK.js → catchup-brief-74ORL525.js} +3 -3
- package/dist/{chunk-BM4X3WHU.js → chunk-2DWKMJPE.js} +1 -1
- package/dist/{chunk-EMUQSTJL.js → chunk-2HEXCZGP.js} +1 -1
- package/dist/{chunk-HX4ULQ3E.js → chunk-5YVGHP2B.js} +11 -11
- package/dist/{chunk-5RT7IBY4.js → chunk-6BJ5GZD4.js} +3 -3
- package/dist/{chunk-BUN6JIDP.js → chunk-ACOQS4ZL.js} +1 -1
- package/dist/{chunk-HH4UGDJH.js → chunk-CGAYSKQF.js} +2 -2
- package/dist/{chunk-ADI4Z63O.js → chunk-DNEOEKWA.js} +2 -2
- package/dist/{chunk-62DAMAFL.js → chunk-FDD7KX7Q.js} +3 -3
- package/dist/{chunk-7AJST6LP.js → chunk-FXVTLBBA.js} +1 -1
- package/dist/{chunk-CGDA6NJI.js → chunk-IFFVONU6.js} +1 -1
- package/dist/{chunk-VGBQKQHJ.js → chunk-JDGCEOT4.js} +1 -1
- package/dist/{chunk-2EVDBTCZ.js → chunk-JDHB6I4O.js} +1 -1
- package/dist/{chunk-FL4PEEWL.js → chunk-JQLWMZZJ.js} +1 -1
- package/dist/{chunk-CHZMPZJ3.js → chunk-JRLSQFIE.js} +44 -44
- package/dist/{chunk-34ENR4JM.js → chunk-KRYEHI4V.js} +2 -2
- package/dist/{chunk-WP6P3LSI.js → chunk-MABQMUCQ.js} +9 -26
- package/dist/chunk-MNNWWEVJ.js +58 -0
- package/dist/{chunk-LLEB3QLI.js → chunk-MWGAC2ER.js} +1 -1
- package/dist/{chunk-UTDZUTRN.js → chunk-OF6TXNOC.js} +1 -1
- package/dist/{chunk-HH2QED73.js → chunk-OYU7TCBG.js} +1 -1
- package/dist/{chunk-UTUYZCQA.js → chunk-PHIQW2IU.js} +3 -3
- package/dist/{chunk-FXYOH3NG.js → chunk-RUKOGGQG.js} +1 -1
- package/dist/{chunk-FC3U23FN.js → chunk-WSYFZZCP.js} +2 -2
- package/dist/{chunk-QCNSCSCH.js → chunk-YZIUQ77U.js} +2 -2
- package/dist/{chunk-IUC2332K.js → chunk-ZAF4GJTD.js} +4 -4
- package/dist/{chunk-Q4WJJBOP.js → chunk-ZLP5TNRU.js} +1 -1
- package/dist/{crm-webhook-LRLN55LB.js → crm-webhook-OFWPEK33.js} +2 -2
- package/dist/{cto-delegation-gate-2FZN5SUY.js → cto-delegation-gate-7PGS5IN4.js} +1 -1
- package/dist/{daemon-orchestration-ZBSS6VZR.js → daemon-orchestration-MP3PPX7Q.js} +3 -3
- package/dist/{exe-export-4ZJTQRRE.js → exe-export-QMGWH3PL.js} +1 -1
- package/dist/{exe-import-JI3FTSWZ.js → exe-import-7NNKSCKI.js} +1 -1
- package/dist/{fast-db-init-URP3KJAE.js → fast-db-init-DAZZ7ZUP.js} +1 -1
- package/dist/gateway/index.js +5 -5
- package/dist/{git-task-sweep-GPPNL2DK.js → git-task-sweep-SLANXCSW.js} +2 -2
- package/dist/hooks/bug-report-worker.js +3 -3
- package/dist/hooks/codex-stop-task-finalizer.js +3 -3
- package/dist/hooks/commit-complete.js +4 -4
- package/dist/hooks/error-recall.js +2 -2
- package/dist/hooks/ingest.js +2 -2
- package/dist/hooks/instructions-loaded.js +1 -1
- package/dist/hooks/manifest.json +25 -0
- package/dist/hooks/notification.js +1 -1
- package/dist/hooks/post-compact.js +2 -2
- package/dist/hooks/post-tool-combined.js +2 -2
- package/dist/hooks/pre-compact.js +3 -3
- package/dist/hooks/pre-tool-use.js +6 -6
- package/dist/hooks/prompt-submit.js +8 -8
- package/dist/hooks/session-end.js +18 -4
- package/dist/hooks/session-start.js +17 -4
- package/dist/hooks/stop.js +5 -5
- package/dist/hooks/subagent-stop.js +2 -2
- package/dist/hooks/summary-worker.js +5 -5
- package/dist/index.js +10 -10
- package/dist/{installer-4SH2HTIU.js → installer-CWKEI7SE.js} +2 -2
- package/dist/{installer-BTOQSNZI.js → installer-DWVZFKAH.js} +4 -4
- package/dist/{installer-MWOEIXKV.js → installer-GSA2KOSE.js} +2 -2
- package/dist/lib/consolidation.js +2 -2
- package/dist/lib/embed-worker.js +81 -14
- package/dist/lib/employee-templates.js +1 -1
- package/dist/lib/exe-daemon.js +62 -13
- package/dist/lib/hybrid-search.js +2 -2
- package/dist/lib/messaging.js +2 -2
- package/dist/lib/schedules.js +2 -2
- package/dist/lib/store.js +1 -1
- package/dist/lib/tasks.js +2 -2
- package/dist/lib/tmux-routing.js +1 -1
- package/dist/mcp/register-tools.js +26 -26
- package/dist/mcp/server.js +29 -29
- package/dist/mcp/tools/create-task.js +3 -3
- package/dist/mcp/tools/list-tasks.js +3 -3
- package/dist/mcp/tools/send-message.js +3 -3
- package/dist/mcp/tools/update-task.js +3 -3
- package/dist/{notifications-GENT3AWZ.js → notifications-WYNI5OG6.js} +1 -1
- package/dist/{orchestrator-A72IFTWK.js → orchestrator-FRFCMLW3.js} +2 -2
- package/dist/{reranker-JJRY3V3V.js → reranker-2ZWUZRUF.js} +1 -1
- package/dist/{review-polling-UJ4P3BIG.js → review-polling-ADP5YFHW.js} +2 -2
- package/dist/runtime/index.js +11 -11
- package/dist/{session-events-GWEVYXPJ.js → session-events-JA3MCMZK.js} +2 -2
- package/dist/{session-scope-DKE6OPV5.js → session-scope-LXQKQDIS.js} +1 -1
- package/dist/{setup-wizard-B4WDA4KT.js → setup-wizard-GRR4F4TX.js} +1 -1
- package/dist/{task-enforcement-QYS2QEEO.js → task-enforcement-KSLBFILH.js} +1 -1
- package/dist/{task-scope-OS66ZD7O.js → task-scope-AI62AIPT.js} +1 -1
- package/dist/{tasks-crud-DJH4NZC2.js → tasks-crud-IEOK55IV.js} +1 -1
- package/dist/{tasks-review-Z6PA4AF5.js → tasks-review-ID7V6RSR.js} +1 -1
- package/dist/tui/App.js +8 -8
- package/dist/{tui-data-JI4URSHX.js → tui-data-HIFVW2PE.js} +1 -1
- package/dist/{worker-gate-DIILYSRZ.js → worker-gate-F3L7XDMJ.js} +1 -1
- package/dist/{workflow-engine-PJ5YSMRL.js → workflow-engine-H5KTDDJG.js} +2 -2
- package/package.json +3 -3
- package/release-notes.json +116 -119
- package/dist/chunk-WZTQUBIE.js +0 -125
- package/dist/{chunk-42QSXHKN.js → chunk-4X7CMJDN.js} +0 -0
- package/dist/{chunk-ZGPURQ4J.js → chunk-54MZI4PK.js} +0 -0
- package/dist/{chunk-TF2BZTXF.js → chunk-7WUBXLK2.js} +3 -3
- /package/dist/{chunk-SSRRHKIO.js → chunk-MQLMIY6U.js} +0 -0
- /package/dist/{chunk-M4UP7VWO.js → chunk-NF4AEKQK.js} +0 -0
- /package/dist/{chunk-LZU4HY4C.js → chunk-XNXTN5XZ.js} +0 -0
- /package/dist/{core-memory-UHWYIN2A.js → core-memory-VQKCHGFX.js} +0 -0
- /package/dist/{exe-key-4EUOGKBN.js → exe-key-QZ5GWV6D.js} +0 -0
- /package/dist/{skill-refinement-2U2UCV2H.js → skill-refinement-3UVLBCZD.js} +0 -0
|
@@ -6,7 +6,7 @@ import "../chunk-OGQX7HLN.js";
|
|
|
6
6
|
import {
|
|
7
7
|
disposeStore,
|
|
8
8
|
initStore
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-4X7CMJDN.js";
|
|
10
10
|
import "../chunk-CHCA3ZM2.js";
|
|
11
11
|
import "../chunk-OO5CPMT3.js";
|
|
12
12
|
import {
|
|
@@ -180,7 +180,7 @@ async function main() {
|
|
|
180
180
|
} catch {
|
|
181
181
|
}
|
|
182
182
|
try {
|
|
183
|
-
const { verifyOpenCodeHooks, runOpenCodeInstaller } = await import("../installer-
|
|
183
|
+
const { verifyOpenCodeHooks, runOpenCodeInstaller } = await import("../installer-GSA2KOSE.js");
|
|
184
184
|
if (!verifyOpenCodeHooks()) {
|
|
185
185
|
process.stderr.write("[exe-start-opencode] hooks missing \u2014 registering now\n");
|
|
186
186
|
await runOpenCodeInstaller();
|
package/dist/bin/exe-status.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
status
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
6
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-KRYEHI4V.js";
|
|
5
|
+
import "../chunk-NF4AEKQK.js";
|
|
6
|
+
import "../chunk-MABQMUCQ.js";
|
|
7
7
|
import "../chunk-RN6XYY7U.js";
|
|
8
8
|
import "../chunk-QI4IXJN7.js";
|
|
9
9
|
import "../chunk-64WZEXXA.js";
|
package/dist/bin/exe-team.js
CHANGED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/bin/generate-hook-manifest.ts
|
|
4
|
+
import { createHash } from "crypto";
|
|
5
|
+
import { readFileSync, writeFileSync, readdirSync, existsSync } from "fs";
|
|
6
|
+
import path from "path";
|
|
7
|
+
import { fileURLToPath } from "url";
|
|
8
|
+
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
var HOOKS_DIR = path.resolve(__dirname, "..", "hooks");
|
|
10
|
+
var MANIFEST_PATH = path.join(HOOKS_DIR, "manifest.json");
|
|
11
|
+
function main() {
|
|
12
|
+
if (!existsSync(HOOKS_DIR)) {
|
|
13
|
+
console.error(`[generate-hook-manifest] Hooks directory not found: ${HOOKS_DIR}`);
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
const files = readdirSync(HOOKS_DIR).filter((f) => f.endsWith(".js"));
|
|
17
|
+
const hashes = {};
|
|
18
|
+
for (const file of files) {
|
|
19
|
+
const content = readFileSync(path.join(HOOKS_DIR, file));
|
|
20
|
+
hashes[file] = createHash("sha256").update(content).digest("hex");
|
|
21
|
+
}
|
|
22
|
+
const manifest = {
|
|
23
|
+
version: 1,
|
|
24
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
25
|
+
hashes
|
|
26
|
+
};
|
|
27
|
+
writeFileSync(MANIFEST_PATH, JSON.stringify(manifest, null, 2) + "\n");
|
|
28
|
+
console.log(`[generate-hook-manifest] Written ${files.length} hashes to ${MANIFEST_PATH}`);
|
|
29
|
+
}
|
|
30
|
+
main();
|
package/dist/bin/git-sweep.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
sweepTasks
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-DNEOEKWA.js";
|
|
5
|
+
import "../chunk-MABQMUCQ.js";
|
|
6
6
|
import "../chunk-RN6XYY7U.js";
|
|
7
7
|
import "../chunk-QI4IXJN7.js";
|
|
8
8
|
import "../chunk-64WZEXXA.js";
|
package/dist/bin/graph-export.js
CHANGED
|
@@ -5,10 +5,10 @@ import {
|
|
|
5
5
|
} from "../chunk-46SQTBQW.js";
|
|
6
6
|
import {
|
|
7
7
|
fastDbInit
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-NF4AEKQK.js";
|
|
9
9
|
import {
|
|
10
10
|
disposeStore
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-4X7CMJDN.js";
|
|
12
12
|
import "../chunk-CHCA3ZM2.js";
|
|
13
13
|
import "../chunk-OO5CPMT3.js";
|
|
14
14
|
import "../chunk-MP2AFCGL.js";
|
package/dist/bin/install.js
CHANGED
|
@@ -6,9 +6,9 @@ import {
|
|
|
6
6
|
setupGhostty,
|
|
7
7
|
setupTmux,
|
|
8
8
|
setupWezterm
|
|
9
|
-
} from "../chunk-
|
|
10
|
-
import "../chunk-QPSUK5HA.js";
|
|
9
|
+
} from "../chunk-7WUBXLK2.js";
|
|
11
10
|
import "../chunk-GNHN5HRQ.js";
|
|
11
|
+
import "../chunk-QPSUK5HA.js";
|
|
12
12
|
import {
|
|
13
13
|
generateSessionWrappers
|
|
14
14
|
} from "../chunk-ZHMQDTGE.js";
|
|
@@ -329,7 +329,7 @@ if (args.includes("--commands-only")) {
|
|
|
329
329
|
}
|
|
330
330
|
try {
|
|
331
331
|
execSync("which codex", { encoding: "utf8", timeout: 5e3 });
|
|
332
|
-
const { runCodexInstaller } = await import("../installer-
|
|
332
|
+
const { runCodexInstaller } = await import("../installer-DWVZFKAH.js");
|
|
333
333
|
await runCodexInstaller();
|
|
334
334
|
} catch {
|
|
335
335
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
fastDbInit
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-NF4AEKQK.js";
|
|
5
5
|
import "../chunk-MLKGABMK.js";
|
|
6
6
|
|
|
7
7
|
// src/bin/intercom-check.ts
|
|
@@ -17,7 +17,7 @@ async function main() {
|
|
|
17
17
|
}
|
|
18
18
|
if (isCoordinator) {
|
|
19
19
|
try {
|
|
20
|
-
const { listPendingReviews, cleanupOrphanedReviews, formatAge, isStale } = await import("../tasks-review-
|
|
20
|
+
const { listPendingReviews, cleanupOrphanedReviews, formatAge, isStale } = await import("../tasks-review-ID7V6RSR.js");
|
|
21
21
|
const { extractRootExe } = await import("../lib/tmux-routing.js");
|
|
22
22
|
let sessionScope = process.env.EXE_SESSION ? extractRootExe(process.env.EXE_SESSION) ?? void 0 : void 0;
|
|
23
23
|
if (!sessionScope) {
|
|
@@ -115,7 +115,7 @@ async function main() {
|
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
try {
|
|
118
|
-
const { readUnreadNotifications, markAsRead } = await import("../notifications-
|
|
118
|
+
const { readUnreadNotifications, markAsRead } = await import("../notifications-WYNI5OG6.js");
|
|
119
119
|
const { resolveExeSession } = await import("../lib/tmux-routing.js");
|
|
120
120
|
const sessionScope = resolveExeSession();
|
|
121
121
|
const notifications = await readUnreadNotifications(agent, sessionScope);
|
package/dist/bin/scan-tasks.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
queryTaskRows
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-MABQMUCQ.js";
|
|
5
5
|
import "../chunk-RN6XYY7U.js";
|
|
6
6
|
import "../chunk-QI4IXJN7.js";
|
|
7
7
|
import "../chunk-64WZEXXA.js";
|
|
@@ -72,7 +72,7 @@ function checkMcpHealth() {
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
async function scanFromDb(agentId, tmuxSession, projectName) {
|
|
75
|
-
const { fastDbInit } = await import("../fast-db-init-
|
|
75
|
+
const { fastDbInit } = await import("../fast-db-init-DAZZ7ZUP.js");
|
|
76
76
|
try {
|
|
77
77
|
await fastDbInit();
|
|
78
78
|
} catch (err) {
|
package/dist/bin/setup.js
CHANGED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import "./chunk-MLKGABMK.js";
|
|
2
|
+
|
|
3
|
+
// src/lib/browser-sanitizer.ts
|
|
4
|
+
import crypto from "crypto";
|
|
5
|
+
var _canaries = /* @__PURE__ */ new Map();
|
|
6
|
+
function getCanaryToken(agentId) {
|
|
7
|
+
let canary = _canaries.get(agentId);
|
|
8
|
+
if (!canary) {
|
|
9
|
+
canary = crypto.randomBytes(16).toString("hex");
|
|
10
|
+
_canaries.set(agentId, canary);
|
|
11
|
+
}
|
|
12
|
+
return canary;
|
|
13
|
+
}
|
|
14
|
+
function clearCanaryToken(agentId) {
|
|
15
|
+
_canaries.delete(agentId);
|
|
16
|
+
}
|
|
17
|
+
function checkCanary(content, agentId) {
|
|
18
|
+
const canary = _canaries.get(agentId);
|
|
19
|
+
if (!canary) return { injectionDetected: false };
|
|
20
|
+
const idx = content.indexOf(canary);
|
|
21
|
+
if (idx === -1) return { injectionDetected: false };
|
|
22
|
+
const start = Math.max(0, idx - 50);
|
|
23
|
+
const end = Math.min(content.length, idx + canary.length + 50);
|
|
24
|
+
return {
|
|
25
|
+
injectionDetected: true,
|
|
26
|
+
foundAt: idx,
|
|
27
|
+
context: content.slice(start, end)
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
var INVISIBLE_CHARS_PATTERN = new RegExp(
|
|
31
|
+
[
|
|
32
|
+
"\\u200B",
|
|
33
|
+
// Zero-width space
|
|
34
|
+
"\\u200C",
|
|
35
|
+
// Zero-width non-joiner
|
|
36
|
+
"\\u200D",
|
|
37
|
+
// Zero-width joiner
|
|
38
|
+
"\\u200E",
|
|
39
|
+
// Left-to-right mark
|
|
40
|
+
"\\u200F",
|
|
41
|
+
// Right-to-left mark
|
|
42
|
+
"\\u2060",
|
|
43
|
+
// Word joiner
|
|
44
|
+
"\\u2061",
|
|
45
|
+
// Function application
|
|
46
|
+
"\\u2062",
|
|
47
|
+
// Invisible times
|
|
48
|
+
"\\u2063",
|
|
49
|
+
// Invisible separator
|
|
50
|
+
"\\u2064",
|
|
51
|
+
// Invisible plus
|
|
52
|
+
"\\uFEFF",
|
|
53
|
+
// BOM / zero-width no-break space
|
|
54
|
+
"\\u00AD",
|
|
55
|
+
// Soft hyphen
|
|
56
|
+
"\\u034F",
|
|
57
|
+
// Combining grapheme joiner
|
|
58
|
+
"\\u061C",
|
|
59
|
+
// Arabic letter mark
|
|
60
|
+
"\\u115F",
|
|
61
|
+
// Hangul choseong filler
|
|
62
|
+
"\\u1160",
|
|
63
|
+
// Hangul jungseong filler
|
|
64
|
+
"\\u17B4",
|
|
65
|
+
// Khmer vowel inherent aq
|
|
66
|
+
"\\u17B5",
|
|
67
|
+
// Khmer vowel inherent aa
|
|
68
|
+
"\\u180E",
|
|
69
|
+
// Mongolian vowel separator
|
|
70
|
+
"\\u2000",
|
|
71
|
+
// En quad (sometimes abused)
|
|
72
|
+
"\\u2001",
|
|
73
|
+
// Em quad
|
|
74
|
+
"\\u2002",
|
|
75
|
+
// En space
|
|
76
|
+
"\\u2003",
|
|
77
|
+
// Em space
|
|
78
|
+
"\\u2004",
|
|
79
|
+
// Three-per-em space
|
|
80
|
+
"\\u2005",
|
|
81
|
+
// Four-per-em space
|
|
82
|
+
"\\u2006",
|
|
83
|
+
// Six-per-em space
|
|
84
|
+
"\\u2007",
|
|
85
|
+
// Figure space
|
|
86
|
+
"\\u2008",
|
|
87
|
+
// Punctuation space
|
|
88
|
+
"\\u2009",
|
|
89
|
+
// Thin space
|
|
90
|
+
"\\u200A",
|
|
91
|
+
// Hair space
|
|
92
|
+
"\\u202A",
|
|
93
|
+
// Left-to-right embedding
|
|
94
|
+
"\\u202B",
|
|
95
|
+
// Right-to-left embedding
|
|
96
|
+
"\\u202C",
|
|
97
|
+
// Pop directional formatting
|
|
98
|
+
"\\u202D",
|
|
99
|
+
// Left-to-right override
|
|
100
|
+
"\\u202E",
|
|
101
|
+
// Right-to-left override
|
|
102
|
+
"\\u2066",
|
|
103
|
+
// Left-to-right isolate
|
|
104
|
+
"\\u2067",
|
|
105
|
+
// Right-to-left isolate
|
|
106
|
+
"\\u2068",
|
|
107
|
+
// First strong isolate
|
|
108
|
+
"\\u2069",
|
|
109
|
+
// Pop directional isolate
|
|
110
|
+
"\\uFFA0",
|
|
111
|
+
// Halfwidth Hangul filler
|
|
112
|
+
"\\uFFF9",
|
|
113
|
+
// Interlinear annotation anchor
|
|
114
|
+
"\\uFFFA",
|
|
115
|
+
// Interlinear annotation separator
|
|
116
|
+
"\\uFFFB"
|
|
117
|
+
// Interlinear annotation terminator
|
|
118
|
+
].join("|"),
|
|
119
|
+
"g"
|
|
120
|
+
);
|
|
121
|
+
var HTML_COMMENT_PATTERN = /<!--[\s\S]*?-->/g;
|
|
122
|
+
var HIDDEN_ELEMENT_PATTERNS = [
|
|
123
|
+
// display:none elements
|
|
124
|
+
/<[^>]+style\s*=\s*"[^"]*display\s*:\s*none[^"]*"[^>]*>[\s\S]*?<\/[^>]+>/gi,
|
|
125
|
+
/<[^>]+style\s*=\s*'[^']*display\s*:\s*none[^']*'[^>]*>[\s\S]*?<\/[^>]+>/gi,
|
|
126
|
+
// visibility:hidden elements
|
|
127
|
+
/<[^>]+style\s*=\s*"[^"]*visibility\s*:\s*hidden[^"]*"[^>]*>[\s\S]*?<\/[^>]+>/gi,
|
|
128
|
+
/<[^>]+style\s*=\s*'[^']*visibility\s*:\s*hidden[^']*'[^>]*>[\s\S]*?<\/[^>]+>/gi,
|
|
129
|
+
// opacity:0 elements
|
|
130
|
+
/<[^>]+style\s*=\s*"[^"]*opacity\s*:\s*0[^"]*"[^>]*>[\s\S]*?<\/[^>]+>/gi,
|
|
131
|
+
/<[^>]+style\s*=\s*'[^']*opacity\s*:\s*0[^']*'[^>]*>[\s\S]*?<\/[^>]+>/gi,
|
|
132
|
+
// Hidden attribute
|
|
133
|
+
/<[^>]+\bhidden\b[^>]*>[\s\S]*?<\/[^>]+>/gi,
|
|
134
|
+
// aria-hidden="true" (sometimes used to hide injection text)
|
|
135
|
+
/<[^>]+aria-hidden\s*=\s*"true"[^>]*>[\s\S]*?<\/[^>]+>/gi,
|
|
136
|
+
// Absolute positioning off-screen (common injection technique)
|
|
137
|
+
/<[^>]+style\s*=\s*"[^"]*position\s*:\s*absolute[^"]*left\s*:\s*-\d{4,}[^"]*"[^>]*>[\s\S]*?<\/[^>]+>/gi,
|
|
138
|
+
/<[^>]+style\s*=\s*"[^"]*position\s*:\s*absolute[^"]*top\s*:\s*-\d{4,}[^"]*"[^>]*>[\s\S]*?<\/[^>]+>/gi
|
|
139
|
+
];
|
|
140
|
+
var SUSPICIOUS_DATA_ATTRS = /\s+data-(?:prompt|instruction|system|ai-instruction|llm-prompt|agent-instruction|hidden-prompt|inject|command|role|context|persona)\s*=\s*"[^"]*"/gi;
|
|
141
|
+
var SCRIPT_STYLE_PATTERN = /<(?:script|style)\b[^>]*>[\s\S]*?<\/(?:script|style)>/gi;
|
|
142
|
+
var NOSCRIPT_PATTERN = /<noscript\b[^>]*>[\s\S]*?<\/noscript>/gi;
|
|
143
|
+
function sanitizeBrowserContent(rawContent, options = {}) {
|
|
144
|
+
const {
|
|
145
|
+
stripHidden = true,
|
|
146
|
+
stripComments = true,
|
|
147
|
+
stripInvisible = true,
|
|
148
|
+
stripScripts = true,
|
|
149
|
+
stripSuspiciousAttrs = true,
|
|
150
|
+
stripNoscript = true,
|
|
151
|
+
agentId
|
|
152
|
+
} = options;
|
|
153
|
+
let content = rawContent;
|
|
154
|
+
let strippedCount = 0;
|
|
155
|
+
const strippedCategories = [];
|
|
156
|
+
let injectionDetected = false;
|
|
157
|
+
let warning;
|
|
158
|
+
if (agentId) {
|
|
159
|
+
const canaryResult = checkCanary(content, agentId);
|
|
160
|
+
if (canaryResult.injectionDetected) {
|
|
161
|
+
injectionDetected = true;
|
|
162
|
+
warning = `\u26A0\uFE0F PROMPT INJECTION DETECTED: Page content contains your session canary token at offset ${canaryResult.foundAt}. This page may be attempting to extract or manipulate your system prompt. Context: "${canaryResult.context}"`;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (stripScripts) {
|
|
166
|
+
const before = content.length;
|
|
167
|
+
content = content.replace(SCRIPT_STYLE_PATTERN, "");
|
|
168
|
+
if (content.length < before) {
|
|
169
|
+
strippedCount++;
|
|
170
|
+
strippedCategories.push("scripts/styles");
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
if (stripHidden) {
|
|
174
|
+
const before = content.length;
|
|
175
|
+
for (const pattern of HIDDEN_ELEMENT_PATTERNS) {
|
|
176
|
+
content = content.replace(pattern, "");
|
|
177
|
+
}
|
|
178
|
+
if (content.length < before) {
|
|
179
|
+
strippedCount++;
|
|
180
|
+
strippedCategories.push("hidden-elements");
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (stripComments) {
|
|
184
|
+
const before = content.length;
|
|
185
|
+
content = content.replace(HTML_COMMENT_PATTERN, "");
|
|
186
|
+
if (content.length < before) {
|
|
187
|
+
strippedCount++;
|
|
188
|
+
strippedCategories.push("html-comments");
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (stripInvisible) {
|
|
192
|
+
const before = content.length;
|
|
193
|
+
content = content.replace(INVISIBLE_CHARS_PATTERN, "");
|
|
194
|
+
if (content.length < before) {
|
|
195
|
+
strippedCount++;
|
|
196
|
+
strippedCategories.push("invisible-chars");
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (stripSuspiciousAttrs) {
|
|
200
|
+
const before = content.length;
|
|
201
|
+
content = content.replace(SUSPICIOUS_DATA_ATTRS, "");
|
|
202
|
+
if (content.length < before) {
|
|
203
|
+
strippedCount++;
|
|
204
|
+
strippedCategories.push("suspicious-data-attrs");
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (stripNoscript) {
|
|
208
|
+
const before = content.length;
|
|
209
|
+
content = content.replace(NOSCRIPT_PATTERN, "");
|
|
210
|
+
if (content.length < before) {
|
|
211
|
+
strippedCount++;
|
|
212
|
+
strippedCategories.push("noscript");
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
content = content.replace(/\n{3,}/g, "\n\n").trim();
|
|
216
|
+
return {
|
|
217
|
+
content,
|
|
218
|
+
injectionDetected,
|
|
219
|
+
strippedCount,
|
|
220
|
+
strippedCategories,
|
|
221
|
+
warning
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
export {
|
|
225
|
+
checkCanary,
|
|
226
|
+
clearCanaryToken,
|
|
227
|
+
getCanaryToken,
|
|
228
|
+
sanitizeBrowserContent
|
|
229
|
+
};
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import {
|
|
2
|
+
enforcePrivateFileSync,
|
|
3
|
+
ensurePrivateDirSync
|
|
4
|
+
} from "./chunk-LYH5HE24.js";
|
|
5
|
+
import "./chunk-MLKGABMK.js";
|
|
6
|
+
|
|
7
|
+
// src/lib/browser-session-store.ts
|
|
8
|
+
import crypto from "crypto";
|
|
9
|
+
import path from "path";
|
|
10
|
+
import os from "os";
|
|
11
|
+
import {
|
|
12
|
+
existsSync,
|
|
13
|
+
readFileSync,
|
|
14
|
+
writeFileSync,
|
|
15
|
+
unlinkSync,
|
|
16
|
+
readdirSync,
|
|
17
|
+
statSync
|
|
18
|
+
} from "fs";
|
|
19
|
+
var ALGORITHM = "aes-256-gcm";
|
|
20
|
+
var IV_LENGTH = 12;
|
|
21
|
+
var TAG_LENGTH = 16;
|
|
22
|
+
var HKDF_INFO = "exe-browser-cookies-v1";
|
|
23
|
+
var DEFAULT_TTL_MS = 30 * 60 * 1e3;
|
|
24
|
+
var _jarCache = /* @__PURE__ */ new Map();
|
|
25
|
+
var _cookieKey = null;
|
|
26
|
+
function initCookieCrypto(masterKey) {
|
|
27
|
+
if (masterKey.length !== 32) {
|
|
28
|
+
throw new Error(`Master key must be 32 bytes, got ${masterKey.length}`);
|
|
29
|
+
}
|
|
30
|
+
_cookieKey = Buffer.from(
|
|
31
|
+
crypto.hkdfSync("sha256", masterKey, "", HKDF_INFO, 32)
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
function isCookieCryptoInitialized() {
|
|
35
|
+
return _cookieKey !== null;
|
|
36
|
+
}
|
|
37
|
+
function encrypt(data) {
|
|
38
|
+
if (!_cookieKey) {
|
|
39
|
+
return "plain:" + Buffer.from(data, "utf-8").toString("base64");
|
|
40
|
+
}
|
|
41
|
+
const iv = crypto.randomBytes(IV_LENGTH);
|
|
42
|
+
const cipher = crypto.createCipheriv(ALGORITHM, _cookieKey, iv);
|
|
43
|
+
const encrypted = Buffer.concat([
|
|
44
|
+
cipher.update(Buffer.from(data, "utf-8")),
|
|
45
|
+
cipher.final()
|
|
46
|
+
]);
|
|
47
|
+
const tag = cipher.getAuthTag();
|
|
48
|
+
return "enc:" + Buffer.concat([iv, encrypted, tag]).toString("base64");
|
|
49
|
+
}
|
|
50
|
+
function decrypt(ciphertext) {
|
|
51
|
+
if (ciphertext.startsWith("plain:")) {
|
|
52
|
+
return Buffer.from(ciphertext.slice(6), "base64").toString("utf-8");
|
|
53
|
+
}
|
|
54
|
+
if (!ciphertext.startsWith("enc:")) {
|
|
55
|
+
throw new Error("Unknown cookie store format");
|
|
56
|
+
}
|
|
57
|
+
if (!_cookieKey) {
|
|
58
|
+
throw new Error("Cookie crypto not initialized but encrypted data found");
|
|
59
|
+
}
|
|
60
|
+
const combined = Buffer.from(ciphertext.slice(4), "base64");
|
|
61
|
+
if (combined.length < IV_LENGTH + TAG_LENGTH) {
|
|
62
|
+
throw new Error("Cookie data too short");
|
|
63
|
+
}
|
|
64
|
+
const iv = combined.subarray(0, IV_LENGTH);
|
|
65
|
+
const tag = combined.subarray(combined.length - TAG_LENGTH);
|
|
66
|
+
const encrypted = combined.subarray(IV_LENGTH, combined.length - TAG_LENGTH);
|
|
67
|
+
const decipher = crypto.createDecipheriv(ALGORITHM, _cookieKey, iv);
|
|
68
|
+
decipher.setAuthTag(tag);
|
|
69
|
+
return Buffer.concat([
|
|
70
|
+
decipher.update(encrypted),
|
|
71
|
+
decipher.final()
|
|
72
|
+
]).toString("utf-8");
|
|
73
|
+
}
|
|
74
|
+
function getStoreDir() {
|
|
75
|
+
const base = process.env.EXE_OS_DIR ?? path.join(os.homedir(), ".exe-os");
|
|
76
|
+
return path.join(base, "browser-sessions");
|
|
77
|
+
}
|
|
78
|
+
function getJarPath(agentId, sessionKey) {
|
|
79
|
+
const safe = (s) => s.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
80
|
+
return path.join(getStoreDir(), `${safe(agentId)}-${safe(sessionKey)}.cookies.enc`);
|
|
81
|
+
}
|
|
82
|
+
function jarCacheKey(agentId, sessionKey) {
|
|
83
|
+
return `${agentId}:${sessionKey}`;
|
|
84
|
+
}
|
|
85
|
+
function getTtlMs() {
|
|
86
|
+
const envTtl = process.env.EXE_BROWSER_SESSION_TTL;
|
|
87
|
+
if (envTtl) {
|
|
88
|
+
const parsed = parseInt(envTtl, 10);
|
|
89
|
+
if (!isNaN(parsed) && parsed > 0) return parsed * 1e3;
|
|
90
|
+
}
|
|
91
|
+
return DEFAULT_TTL_MS;
|
|
92
|
+
}
|
|
93
|
+
function loadCookieJar(agentId, sessionKey) {
|
|
94
|
+
const cacheKey = jarCacheKey(agentId, sessionKey);
|
|
95
|
+
const cached = _jarCache.get(cacheKey);
|
|
96
|
+
if (cached) {
|
|
97
|
+
const ttl = getTtlMs();
|
|
98
|
+
if (Date.now() - cached.lastAccessed > ttl) {
|
|
99
|
+
clearCookieJar(agentId, sessionKey);
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
return cached;
|
|
103
|
+
}
|
|
104
|
+
const jarPath = getJarPath(agentId, sessionKey);
|
|
105
|
+
if (!existsSync(jarPath)) return null;
|
|
106
|
+
try {
|
|
107
|
+
const raw = readFileSync(jarPath, "utf-8");
|
|
108
|
+
const jar = JSON.parse(decrypt(raw));
|
|
109
|
+
const ttl = getTtlMs();
|
|
110
|
+
if (Date.now() - jar.lastAccessed > ttl) {
|
|
111
|
+
clearCookieJar(agentId, sessionKey);
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
115
|
+
jar.cookies = jar.cookies.filter((c) => !c.expires || c.expires > now);
|
|
116
|
+
_jarCache.set(cacheKey, jar);
|
|
117
|
+
return jar;
|
|
118
|
+
} catch {
|
|
119
|
+
try {
|
|
120
|
+
unlinkSync(jarPath);
|
|
121
|
+
} catch {
|
|
122
|
+
}
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function saveCookieJar(agentId, sessionKey, cookies) {
|
|
127
|
+
const cacheKey = jarCacheKey(agentId, sessionKey);
|
|
128
|
+
const existing = loadCookieJar(agentId, sessionKey);
|
|
129
|
+
const now = Date.now();
|
|
130
|
+
const cookieMap = /* @__PURE__ */ new Map();
|
|
131
|
+
if (existing) {
|
|
132
|
+
for (const c of existing.cookies) {
|
|
133
|
+
cookieMap.set(`${c.domain}:${c.path}:${c.name}`, c);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
for (const c of cookies) {
|
|
137
|
+
cookieMap.set(`${c.domain}:${c.path}:${c.name}`, c);
|
|
138
|
+
}
|
|
139
|
+
const nowSec = Math.floor(now / 1e3);
|
|
140
|
+
const merged = [...cookieMap.values()].filter(
|
|
141
|
+
(c) => !c.expires || c.expires > nowSec
|
|
142
|
+
);
|
|
143
|
+
const jar = {
|
|
144
|
+
agentId,
|
|
145
|
+
sessionKey,
|
|
146
|
+
cookies: merged,
|
|
147
|
+
lastAccessed: now,
|
|
148
|
+
createdAt: existing?.createdAt ?? now
|
|
149
|
+
};
|
|
150
|
+
const storeDir = getStoreDir();
|
|
151
|
+
ensurePrivateDirSync(storeDir);
|
|
152
|
+
const jarPath = getJarPath(agentId, sessionKey);
|
|
153
|
+
const encrypted = encrypt(JSON.stringify(jar));
|
|
154
|
+
writeFileSync(jarPath, encrypted, "utf-8");
|
|
155
|
+
enforcePrivateFileSync(jarPath);
|
|
156
|
+
_jarCache.set(cacheKey, jar);
|
|
157
|
+
}
|
|
158
|
+
function getCookiesForUrl(agentId, sessionKey, url) {
|
|
159
|
+
const jar = loadCookieJar(agentId, sessionKey);
|
|
160
|
+
if (!jar || jar.cookies.length === 0) return [];
|
|
161
|
+
let hostname;
|
|
162
|
+
try {
|
|
163
|
+
hostname = new URL(url).hostname;
|
|
164
|
+
} catch {
|
|
165
|
+
return [];
|
|
166
|
+
}
|
|
167
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
168
|
+
return jar.cookies.filter((c) => {
|
|
169
|
+
if (c.expires && c.expires <= now) return false;
|
|
170
|
+
const cookieDomain = c.domain.startsWith(".") ? c.domain.slice(1) : c.domain;
|
|
171
|
+
return hostname === cookieDomain || hostname.endsWith("." + cookieDomain);
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
function clearCookieJar(agentId, sessionKey) {
|
|
175
|
+
const cacheKey = jarCacheKey(agentId, sessionKey);
|
|
176
|
+
_jarCache.delete(cacheKey);
|
|
177
|
+
const jarPath = getJarPath(agentId, sessionKey);
|
|
178
|
+
try {
|
|
179
|
+
if (existsSync(jarPath)) unlinkSync(jarPath);
|
|
180
|
+
} catch {
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
function cleanupExpiredJars() {
|
|
184
|
+
const storeDir = getStoreDir();
|
|
185
|
+
if (!existsSync(storeDir)) return 0;
|
|
186
|
+
const ttl = getTtlMs();
|
|
187
|
+
const now = Date.now();
|
|
188
|
+
let cleaned = 0;
|
|
189
|
+
try {
|
|
190
|
+
const files = readdirSync(storeDir).filter((f) => f.endsWith(".cookies.enc"));
|
|
191
|
+
for (const file of files) {
|
|
192
|
+
const filePath = path.join(storeDir, file);
|
|
193
|
+
try {
|
|
194
|
+
const stat = statSync(filePath);
|
|
195
|
+
if (now - stat.mtimeMs > ttl) {
|
|
196
|
+
unlinkSync(filePath);
|
|
197
|
+
cleaned++;
|
|
198
|
+
}
|
|
199
|
+
} catch {
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
} catch {
|
|
203
|
+
}
|
|
204
|
+
return cleaned;
|
|
205
|
+
}
|
|
206
|
+
function touchCookieJar(agentId, sessionKey) {
|
|
207
|
+
const cacheKey = jarCacheKey(agentId, sessionKey);
|
|
208
|
+
const cached = _jarCache.get(cacheKey);
|
|
209
|
+
if (cached) {
|
|
210
|
+
cached.lastAccessed = Date.now();
|
|
211
|
+
const jarPath = getJarPath(agentId, sessionKey);
|
|
212
|
+
try {
|
|
213
|
+
if (existsSync(jarPath)) {
|
|
214
|
+
const raw = readFileSync(jarPath, "utf-8");
|
|
215
|
+
const jar = JSON.parse(decrypt(raw));
|
|
216
|
+
jar.lastAccessed = Date.now();
|
|
217
|
+
writeFileSync(jarPath, encrypt(JSON.stringify(jar)), "utf-8");
|
|
218
|
+
}
|
|
219
|
+
} catch {
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
export {
|
|
224
|
+
cleanupExpiredJars,
|
|
225
|
+
clearCookieJar,
|
|
226
|
+
getCookiesForUrl,
|
|
227
|
+
initCookieCrypto,
|
|
228
|
+
isCookieCryptoInitialized,
|
|
229
|
+
loadCookieJar,
|
|
230
|
+
saveCookieJar,
|
|
231
|
+
touchCookieJar
|
|
232
|
+
};
|
|
@@ -8,9 +8,9 @@ import {
|
|
|
8
8
|
isAtCapacity,
|
|
9
9
|
isWithinRelaunchCooldown,
|
|
10
10
|
pollCapacityDead
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-ZLP5TNRU.js";
|
|
12
12
|
import "./chunk-WRCETUYE.js";
|
|
13
|
-
import "./chunk-
|
|
13
|
+
import "./chunk-MABQMUCQ.js";
|
|
14
14
|
import "./chunk-RN6XYY7U.js";
|
|
15
15
|
import "./chunk-QI4IXJN7.js";
|
|
16
16
|
import "./chunk-64WZEXXA.js";
|