@askexenow/exe-os 0.9.69 → 0.9.71
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/stack-manifests/v0.9.json +96 -16
- package/dist/bin/agentic-ontology-backfill.js +33 -0
- package/dist/bin/agentic-reflection-backfill.js +33 -0
- package/dist/bin/agentic-semantic-label.js +33 -0
- package/dist/bin/backfill-conversations.js +33 -0
- package/dist/bin/backfill-responses.js +33 -0
- package/dist/bin/backfill-vectors.js +33 -0
- package/dist/bin/bulk-sync-postgres.js +33 -0
- package/dist/bin/cleanup-stale-review-tasks.js +33 -0
- package/dist/bin/cli.js +1284 -178
- package/dist/bin/exe-agent.js +6 -0
- package/dist/bin/exe-assign.js +33 -0
- package/dist/bin/exe-boot.js +33 -0
- package/dist/bin/exe-call.js +6 -0
- package/dist/bin/exe-cloud.js +33 -0
- package/dist/bin/exe-dispatch.js +33 -0
- package/dist/bin/exe-doctor.js +33 -0
- package/dist/bin/exe-export-behaviors.js +33 -0
- package/dist/bin/exe-forget.js +33 -0
- package/dist/bin/exe-gateway.js +178 -110
- package/dist/bin/exe-heartbeat.js +33 -0
- package/dist/bin/exe-kill.js +33 -0
- package/dist/bin/exe-launch-agent.js +33 -0
- package/dist/bin/exe-new-employee.js +6 -0
- package/dist/bin/exe-pending-messages.js +33 -0
- package/dist/bin/exe-pending-notifications.js +33 -0
- package/dist/bin/exe-pending-reviews.js +33 -0
- package/dist/bin/exe-rename.js +40 -4
- package/dist/bin/exe-review.js +33 -0
- package/dist/bin/exe-search.js +33 -0
- package/dist/bin/exe-session-cleanup.js +33 -0
- package/dist/bin/exe-start-codex.js +33 -0
- package/dist/bin/exe-start-opencode.js +33 -0
- package/dist/bin/exe-status.js +33 -0
- package/dist/bin/exe-team.js +33 -0
- package/dist/bin/git-sweep.js +33 -0
- package/dist/bin/graph-backfill.js +177 -110
- package/dist/bin/graph-export.js +33 -0
- package/dist/bin/intercom-check.js +33 -0
- package/dist/bin/registry-proxy.js +207 -0
- package/dist/bin/scan-tasks.js +33 -0
- package/dist/bin/setup.js +33 -0
- package/dist/bin/shard-migrate.js +33 -0
- package/dist/bin/stack-update.js +128 -0
- package/dist/gateway/index.js +178 -110
- package/dist/hooks/bug-report-worker.js +33 -0
- package/dist/hooks/codex-stop-task-finalizer.js +33 -0
- package/dist/hooks/commit-complete.js +33 -0
- package/dist/hooks/error-recall.js +33 -0
- package/dist/hooks/ingest.js +33 -0
- package/dist/hooks/instructions-loaded.js +33 -0
- package/dist/hooks/notification.js +33 -0
- package/dist/hooks/post-compact.js +33 -0
- package/dist/hooks/post-tool-combined.js +698 -17
- package/dist/hooks/pre-compact.js +33 -0
- package/dist/hooks/pre-tool-use.js +33 -0
- package/dist/hooks/prompt-submit.js +314 -0
- package/dist/hooks/session-end.js +33 -0
- package/dist/hooks/session-start.js +33 -0
- package/dist/hooks/stop.js +279 -12
- package/dist/hooks/subagent-stop.js +33 -0
- package/dist/hooks/summary-worker.js +33 -0
- package/dist/index.js +178 -110
- package/dist/lib/cloud-sync.js +27 -0
- package/dist/lib/database.js +27 -0
- package/dist/lib/db.js +27 -0
- package/dist/lib/device-registry.js +27 -0
- package/dist/lib/employee-templates.js +6 -0
- package/dist/lib/exe-daemon.js +639 -259
- package/dist/lib/hybrid-search.js +33 -0
- package/dist/lib/registry-proxy.js +162 -0
- package/dist/lib/schedules.js +33 -0
- package/dist/lib/store.js +33 -0
- package/dist/mcp/server.js +561 -244
- package/dist/runtime/index.js +33 -0
- package/dist/tui/App.js +33 -0
- package/package.json +3 -2
- package/stack.release.json +6 -4
- package/stack.release.schema.json +89 -18
package/dist/hooks/stop.js
CHANGED
|
@@ -1386,8 +1386,8 @@ function findPackageRoot() {
|
|
|
1386
1386
|
function getAvailableMemoryGB() {
|
|
1387
1387
|
if (process.platform === "darwin") {
|
|
1388
1388
|
try {
|
|
1389
|
-
const { execSync:
|
|
1390
|
-
const vmstat =
|
|
1389
|
+
const { execSync: execSync7 } = __require("child_process");
|
|
1390
|
+
const vmstat = execSync7("vm_stat", { encoding: "utf8" });
|
|
1391
1391
|
const pageSize = 16384;
|
|
1392
1392
|
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
1393
1393
|
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
@@ -2769,6 +2769,33 @@ async function ensureSchema() {
|
|
|
2769
2769
|
CREATE INDEX IF NOT EXISTS idx_chat_history_session
|
|
2770
2770
|
ON chat_history(session_id, id);
|
|
2771
2771
|
`);
|
|
2772
|
+
await client.executeMultiple(`
|
|
2773
|
+
CREATE TABLE IF NOT EXISTS session_events (
|
|
2774
|
+
id TEXT PRIMARY KEY,
|
|
2775
|
+
agent_id TEXT NOT NULL,
|
|
2776
|
+
agent_role TEXT NOT NULL,
|
|
2777
|
+
session_id TEXT NOT NULL,
|
|
2778
|
+
session_scope TEXT,
|
|
2779
|
+
project_name TEXT NOT NULL,
|
|
2780
|
+
event_index INTEGER NOT NULL,
|
|
2781
|
+
event_type TEXT NOT NULL,
|
|
2782
|
+
tool_name TEXT,
|
|
2783
|
+
tool_use_id TEXT,
|
|
2784
|
+
content TEXT NOT NULL,
|
|
2785
|
+
payload_json TEXT,
|
|
2786
|
+
has_error INTEGER NOT NULL DEFAULT 0,
|
|
2787
|
+
created_at TEXT NOT NULL
|
|
2788
|
+
);
|
|
2789
|
+
|
|
2790
|
+
CREATE INDEX IF NOT EXISTS idx_session_events_agent_time
|
|
2791
|
+
ON session_events(agent_id, created_at DESC);
|
|
2792
|
+
|
|
2793
|
+
CREATE INDEX IF NOT EXISTS idx_session_events_session_index
|
|
2794
|
+
ON session_events(session_id, event_index);
|
|
2795
|
+
|
|
2796
|
+
CREATE INDEX IF NOT EXISTS idx_session_events_scope_agent_time
|
|
2797
|
+
ON session_events(session_scope, agent_id, created_at DESC);
|
|
2798
|
+
`);
|
|
2772
2799
|
await client.executeMultiple(`
|
|
2773
2800
|
CREATE TABLE IF NOT EXISTS workspaces (
|
|
2774
2801
|
id TEXT PRIMARY KEY,
|
|
@@ -3519,6 +3546,15 @@ function sessionScopeFilter(sessionScope, tableAlias) {
|
|
|
3519
3546
|
args: [scope]
|
|
3520
3547
|
};
|
|
3521
3548
|
}
|
|
3549
|
+
function strictSessionScopeFilter(sessionScope, tableAlias) {
|
|
3550
|
+
const scope = sessionScope !== void 0 ? sessionScope : getCurrentSessionScope();
|
|
3551
|
+
if (!scope) return { sql: "", args: [] };
|
|
3552
|
+
const col = tableAlias ? `${tableAlias}.session_scope` : "session_scope";
|
|
3553
|
+
return {
|
|
3554
|
+
sql: ` AND ${col} = ?`,
|
|
3555
|
+
args: [scope]
|
|
3556
|
+
};
|
|
3557
|
+
}
|
|
3522
3558
|
var init_task_scope = __esm({
|
|
3523
3559
|
"src/lib/task-scope.ts"() {
|
|
3524
3560
|
"use strict";
|
|
@@ -4600,6 +4636,12 @@ var init_platform_procedures = __esm({
|
|
|
4600
4636
|
priority: "p0",
|
|
4601
4637
|
content: "exe-build-adv is MANDATORY for ALL work touching 3+ files. Run /exe-build-adv --auto BEFORE implementation. Pipeline: Spec \u2192 AC \u2192 Tests \u2192 Evaluate \u2192 Fix. No multi-file feature ships without pipeline artifacts. No exceptions \u2014 managers reject work without them."
|
|
4602
4638
|
},
|
|
4639
|
+
{
|
|
4640
|
+
title: "Code context first for repository orientation",
|
|
4641
|
+
domain: "workflow",
|
|
4642
|
+
priority: "p1",
|
|
4643
|
+
content: "Before broad repo exploration, symbol tracing, blast-radius review, or codebase Q&A, agents should use the consolidated code_context MCP tool instead of manual grep/read loops. Use action=index or stats to refresh/check the index; action=search with query, limit, offset, languages, paths, refresh_index for fresh multi-language code/doc search; action=trace for symbol imports/dependents; action=blast_radius for impact analysis before edits. CLI parity exists via exe-os code-context init|index|status|stats|search|doctor. Keep code_context separate from durable employee memory: promote only validated decisions, procedures, or lessons into store_memory/commit_memory."
|
|
4644
|
+
},
|
|
4603
4645
|
{
|
|
4604
4646
|
title: "Commit discipline \u2014 never leave verified work floating",
|
|
4605
4647
|
domain: "workflow",
|
|
@@ -5886,9 +5928,179 @@ var init_fast_db_init = __esm({
|
|
|
5886
5928
|
}
|
|
5887
5929
|
});
|
|
5888
5930
|
|
|
5931
|
+
// src/lib/project-name.ts
|
|
5932
|
+
import { execSync as execSync6 } from "child_process";
|
|
5933
|
+
import path16 from "path";
|
|
5934
|
+
function getProjectName(cwd) {
|
|
5935
|
+
const dir = cwd ?? process.cwd();
|
|
5936
|
+
if (_cached2 && _cachedCwd === dir) return _cached2;
|
|
5937
|
+
try {
|
|
5938
|
+
let repoRoot;
|
|
5939
|
+
try {
|
|
5940
|
+
const gitCommonDir = execSync6("git rev-parse --path-format=absolute --git-common-dir", {
|
|
5941
|
+
cwd: dir,
|
|
5942
|
+
encoding: "utf8",
|
|
5943
|
+
timeout: 2e3,
|
|
5944
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
5945
|
+
}).trim();
|
|
5946
|
+
repoRoot = path16.dirname(gitCommonDir);
|
|
5947
|
+
} catch {
|
|
5948
|
+
repoRoot = execSync6("git rev-parse --show-toplevel", {
|
|
5949
|
+
cwd: dir,
|
|
5950
|
+
encoding: "utf8",
|
|
5951
|
+
timeout: 2e3,
|
|
5952
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
5953
|
+
}).trim();
|
|
5954
|
+
}
|
|
5955
|
+
_cached2 = path16.basename(repoRoot);
|
|
5956
|
+
_cachedCwd = dir;
|
|
5957
|
+
return _cached2;
|
|
5958
|
+
} catch {
|
|
5959
|
+
_cached2 = path16.basename(dir);
|
|
5960
|
+
_cachedCwd = dir;
|
|
5961
|
+
return _cached2;
|
|
5962
|
+
}
|
|
5963
|
+
}
|
|
5964
|
+
var _cached2, _cachedCwd;
|
|
5965
|
+
var init_project_name = __esm({
|
|
5966
|
+
"src/lib/project-name.ts"() {
|
|
5967
|
+
"use strict";
|
|
5968
|
+
_cached2 = null;
|
|
5969
|
+
_cachedCwd = null;
|
|
5970
|
+
}
|
|
5971
|
+
});
|
|
5972
|
+
|
|
5973
|
+
// src/lib/session-events.ts
|
|
5974
|
+
var session_events_exports = {};
|
|
5975
|
+
__export(session_events_exports, {
|
|
5976
|
+
ensureSessionEventsTable: () => ensureSessionEventsTable,
|
|
5977
|
+
listRecentSessionEvents: () => listRecentSessionEvents,
|
|
5978
|
+
recordSessionEvent: () => recordSessionEvent
|
|
5979
|
+
});
|
|
5980
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
5981
|
+
async function ensureSessionEventsTable(client) {
|
|
5982
|
+
await client.execute(`
|
|
5983
|
+
CREATE TABLE IF NOT EXISTS session_events (
|
|
5984
|
+
id TEXT PRIMARY KEY,
|
|
5985
|
+
agent_id TEXT NOT NULL,
|
|
5986
|
+
agent_role TEXT NOT NULL,
|
|
5987
|
+
session_id TEXT NOT NULL,
|
|
5988
|
+
session_scope TEXT,
|
|
5989
|
+
project_name TEXT NOT NULL,
|
|
5990
|
+
event_index INTEGER NOT NULL,
|
|
5991
|
+
event_type TEXT NOT NULL,
|
|
5992
|
+
tool_name TEXT,
|
|
5993
|
+
tool_use_id TEXT,
|
|
5994
|
+
content TEXT NOT NULL,
|
|
5995
|
+
payload_json TEXT,
|
|
5996
|
+
has_error INTEGER NOT NULL DEFAULT 0,
|
|
5997
|
+
created_at TEXT NOT NULL
|
|
5998
|
+
)
|
|
5999
|
+
`);
|
|
6000
|
+
await client.execute(`
|
|
6001
|
+
CREATE INDEX IF NOT EXISTS idx_session_events_agent_time
|
|
6002
|
+
ON session_events(agent_id, created_at DESC)
|
|
6003
|
+
`);
|
|
6004
|
+
await client.execute(`
|
|
6005
|
+
CREATE INDEX IF NOT EXISTS idx_session_events_session_index
|
|
6006
|
+
ON session_events(session_id, event_index)
|
|
6007
|
+
`);
|
|
6008
|
+
await client.execute(`
|
|
6009
|
+
CREATE INDEX IF NOT EXISTS idx_session_events_scope_agent_time
|
|
6010
|
+
ON session_events(session_scope, agent_id, created_at DESC)
|
|
6011
|
+
`);
|
|
6012
|
+
}
|
|
6013
|
+
async function recordSessionEvent(client, input2) {
|
|
6014
|
+
if (!input2.content || input2.content.trim().length === 0) return;
|
|
6015
|
+
await ensureSessionEventsTable(client);
|
|
6016
|
+
const maxResult = await client.execute({
|
|
6017
|
+
sql: "SELECT COALESCE(MAX(event_index), 0) AS max_index FROM session_events WHERE session_id = ?",
|
|
6018
|
+
args: [input2.sessionId]
|
|
6019
|
+
});
|
|
6020
|
+
const currentMax = Number(maxResult.rows[0]?.max_index ?? 0);
|
|
6021
|
+
const eventIndex = Number.isFinite(currentMax) ? currentMax + 1 : 1;
|
|
6022
|
+
await client.execute({
|
|
6023
|
+
sql: `INSERT INTO session_events (
|
|
6024
|
+
id, agent_id, agent_role, session_id, session_scope, project_name,
|
|
6025
|
+
event_index, event_type, tool_name, tool_use_id, content,
|
|
6026
|
+
payload_json, has_error, created_at
|
|
6027
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
6028
|
+
args: [
|
|
6029
|
+
randomUUID4(),
|
|
6030
|
+
input2.agentId,
|
|
6031
|
+
input2.agentRole,
|
|
6032
|
+
input2.sessionId,
|
|
6033
|
+
input2.sessionScope ?? getCurrentSessionScope(),
|
|
6034
|
+
input2.projectName ?? getProjectName(input2.cwd),
|
|
6035
|
+
eventIndex,
|
|
6036
|
+
input2.eventType,
|
|
6037
|
+
input2.toolName ?? null,
|
|
6038
|
+
input2.toolUseId ?? null,
|
|
6039
|
+
input2.content,
|
|
6040
|
+
input2.payloadJson ?? null,
|
|
6041
|
+
input2.hasError ? 1 : 0,
|
|
6042
|
+
input2.timestamp ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
6043
|
+
]
|
|
6044
|
+
});
|
|
6045
|
+
}
|
|
6046
|
+
async function listRecentSessionEvents(client, options) {
|
|
6047
|
+
await ensureSessionEventsTable(client);
|
|
6048
|
+
const conditions = ["agent_id = ?"];
|
|
6049
|
+
const args = [options.agentId];
|
|
6050
|
+
if (options.sessionId) {
|
|
6051
|
+
conditions.push("session_id = ?");
|
|
6052
|
+
args.push(options.sessionId);
|
|
6053
|
+
}
|
|
6054
|
+
if (options.eventType) {
|
|
6055
|
+
conditions.push("event_type = ?");
|
|
6056
|
+
args.push(options.eventType);
|
|
6057
|
+
}
|
|
6058
|
+
if (options.projectName && options.projectName !== "all") {
|
|
6059
|
+
conditions.push("project_name = ?");
|
|
6060
|
+
args.push(options.projectName);
|
|
6061
|
+
}
|
|
6062
|
+
const scope = strictSessionScopeFilter(options.sessionScope);
|
|
6063
|
+
const where = `WHERE ${conditions.join(" AND ")}${scope.sql}`;
|
|
6064
|
+
args.push(...scope.args);
|
|
6065
|
+
args.push(Math.min(Math.max(options.limit ?? 20, 1), 100));
|
|
6066
|
+
const result = await client.execute({
|
|
6067
|
+
sql: `SELECT id, agent_id, agent_role, session_id, session_scope,
|
|
6068
|
+
project_name, event_index, event_type, tool_name, tool_use_id,
|
|
6069
|
+
content, payload_json, has_error, created_at
|
|
6070
|
+
FROM session_events
|
|
6071
|
+
${where}
|
|
6072
|
+
ORDER BY created_at DESC, event_index DESC
|
|
6073
|
+
LIMIT ?`,
|
|
6074
|
+
args
|
|
6075
|
+
});
|
|
6076
|
+
return result.rows.map((row) => ({
|
|
6077
|
+
id: String(row.id),
|
|
6078
|
+
agentId: String(row.agent_id),
|
|
6079
|
+
agentRole: String(row.agent_role),
|
|
6080
|
+
sessionId: String(row.session_id),
|
|
6081
|
+
sessionScope: row.session_scope == null ? null : String(row.session_scope),
|
|
6082
|
+
projectName: String(row.project_name),
|
|
6083
|
+
eventIndex: Number(row.event_index),
|
|
6084
|
+
eventType: String(row.event_type),
|
|
6085
|
+
toolName: row.tool_name == null ? null : String(row.tool_name),
|
|
6086
|
+
toolUseId: row.tool_use_id == null ? null : String(row.tool_use_id),
|
|
6087
|
+
content: String(row.content),
|
|
6088
|
+
payloadJson: row.payload_json == null ? null : String(row.payload_json),
|
|
6089
|
+
hasError: Number(row.has_error) === 1,
|
|
6090
|
+
createdAt: String(row.created_at)
|
|
6091
|
+
}));
|
|
6092
|
+
}
|
|
6093
|
+
var init_session_events = __esm({
|
|
6094
|
+
"src/lib/session-events.ts"() {
|
|
6095
|
+
"use strict";
|
|
6096
|
+
init_task_scope();
|
|
6097
|
+
init_project_name();
|
|
6098
|
+
}
|
|
6099
|
+
});
|
|
6100
|
+
|
|
5889
6101
|
// src/lib/memory-queue.ts
|
|
5890
6102
|
import { appendFileSync as appendFileSync2, readFileSync as readFileSync11, renameSync as renameSync5, unlinkSync as unlinkSync4, existsSync as existsSync14, statSync as statSync4 } from "fs";
|
|
5891
|
-
import
|
|
6103
|
+
import path17 from "path";
|
|
5892
6104
|
function enqueueMemory(entry) {
|
|
5893
6105
|
appendFileSync2(QUEUE_PATH2, JSON.stringify(entry) + "\n");
|
|
5894
6106
|
}
|
|
@@ -5897,7 +6109,7 @@ var init_memory_queue = __esm({
|
|
|
5897
6109
|
"src/lib/memory-queue.ts"() {
|
|
5898
6110
|
"use strict";
|
|
5899
6111
|
init_config();
|
|
5900
|
-
QUEUE_PATH2 =
|
|
6112
|
+
QUEUE_PATH2 = path17.join(EXE_AI_DIR, "memory-queue.jsonl");
|
|
5901
6113
|
PROCESSING_PATH = QUEUE_PATH2 + ".processing";
|
|
5902
6114
|
TTL_MS2 = 24 * 60 * 60 * 1e3;
|
|
5903
6115
|
}
|
|
@@ -5963,7 +6175,7 @@ init_config();
|
|
|
5963
6175
|
init_config();
|
|
5964
6176
|
import { spawn as spawn2 } from "child_process";
|
|
5965
6177
|
import { existsSync as existsSync15, openSync as openSync2, closeSync as closeSync2 } from "fs";
|
|
5966
|
-
import
|
|
6178
|
+
import path18 from "path";
|
|
5967
6179
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
5968
6180
|
|
|
5969
6181
|
// src/lib/active-agent.ts
|
|
@@ -6084,7 +6296,7 @@ if (!process.env.AGENT_ID) {
|
|
|
6084
6296
|
if (!loadConfigSync().autoIngestion) {
|
|
6085
6297
|
process.exit(0);
|
|
6086
6298
|
}
|
|
6087
|
-
var WORKER_LOG_PATH =
|
|
6299
|
+
var WORKER_LOG_PATH = path18.join(EXE_AI_DIR, "workers.log");
|
|
6088
6300
|
function openWorkerLog() {
|
|
6089
6301
|
try {
|
|
6090
6302
|
return openSync2(WORKER_LOG_PATH, "a");
|
|
@@ -6122,13 +6334,13 @@ process.stdin.setEncoding("utf8");
|
|
|
6122
6334
|
process.stdin.on("data", (chunk) => {
|
|
6123
6335
|
if (input.length < MAX_INPUT_SIZE) input += chunk;
|
|
6124
6336
|
});
|
|
6125
|
-
process.stdin.on("end", () => {
|
|
6337
|
+
process.stdin.on("end", async () => {
|
|
6126
6338
|
try {
|
|
6127
6339
|
if (process.env.EXE_DEBUG_HOOKS || process.env.EXE_RUNTIME === "codex") {
|
|
6128
6340
|
try {
|
|
6129
|
-
const debugPath =
|
|
6341
|
+
const debugPath = path18.join(EXE_AI_DIR, "logs", "hook-stdin-stop.log");
|
|
6130
6342
|
const { mkdirSync: mkdirSync8, writeFileSync: writeFileSync8 } = __require("fs");
|
|
6131
|
-
mkdirSync8(
|
|
6343
|
+
mkdirSync8(path18.dirname(debugPath), { recursive: true });
|
|
6132
6344
|
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
6133
6345
|
const snippet = input.length > 500 ? input.slice(0, 500) + "...[truncated]" : input;
|
|
6134
6346
|
writeFileSync8(debugPath, `[${ts}] len=${input.length} ${snippet}
|
|
@@ -6138,11 +6350,11 @@ process.stdin.on("end", () => {
|
|
|
6138
6350
|
}
|
|
6139
6351
|
const data = JSON.parse(input);
|
|
6140
6352
|
const agent = getActiveAgent();
|
|
6141
|
-
const message = data.last_assistant_message
|
|
6353
|
+
const message = data.last_assistant_message || readLastAssistantMessageFromTranscript(data.transcript_path) || "";
|
|
6142
6354
|
const cwd = data.cwd ?? process.cwd();
|
|
6143
6355
|
if (process.env.EXE_RUNTIME === "codex" && !canCoordinate(agent.agentId, agent.agentRole)) {
|
|
6144
|
-
const codexFinalizerPath =
|
|
6145
|
-
|
|
6356
|
+
const codexFinalizerPath = path18.resolve(
|
|
6357
|
+
path18.dirname(fileURLToPath3(import.meta.url)),
|
|
6146
6358
|
"codex-stop-task-finalizer.js"
|
|
6147
6359
|
);
|
|
6148
6360
|
spawnDetachedWorker(codexFinalizerPath, {
|
|
@@ -6156,6 +6368,21 @@ process.stdin.on("end", () => {
|
|
|
6156
6368
|
if (!message || message.length < MIN_LENGTH) {
|
|
6157
6369
|
process.exit(0);
|
|
6158
6370
|
}
|
|
6371
|
+
try {
|
|
6372
|
+
const { fastDbInit: fastDbInit2 } = await Promise.resolve().then(() => (init_fast_db_init(), fast_db_init_exports));
|
|
6373
|
+
const { recordSessionEvent: recordSessionEvent2 } = await Promise.resolve().then(() => (init_session_events(), session_events_exports));
|
|
6374
|
+
const client = await fastDbInit2();
|
|
6375
|
+
await recordSessionEvent2(client, {
|
|
6376
|
+
agentId: agent.agentId,
|
|
6377
|
+
agentRole: agent.agentRole,
|
|
6378
|
+
sessionId: data.session_id,
|
|
6379
|
+
eventType: "assistant_response",
|
|
6380
|
+
content: message.slice(0, 2e4),
|
|
6381
|
+
cwd,
|
|
6382
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
6383
|
+
});
|
|
6384
|
+
} catch {
|
|
6385
|
+
}
|
|
6159
6386
|
const CAPACITY_SIGNALS = /context[- ]?full|hit capacity|conversation is too long|maximum context length|context window.*(?:limit|exceed|full)/i;
|
|
6160
6387
|
if (!canCoordinate(agent.agentId, agent.agentRole) && CAPACITY_SIGNALS.test(message)) {
|
|
6161
6388
|
Promise.resolve().then(() => (init_fast_db_init(), fast_db_init_exports)).then(({ fastDbInit: fastDbInit2 }) => fastDbInit2()).then(async (client) => {
|
|
@@ -6229,3 +6456,43 @@ process.stdin.on("end", () => {
|
|
|
6229
6456
|
}
|
|
6230
6457
|
process.exit(0);
|
|
6231
6458
|
});
|
|
6459
|
+
function readLastAssistantMessageFromTranscript(transcriptPath) {
|
|
6460
|
+
if (!transcriptPath) return null;
|
|
6461
|
+
try {
|
|
6462
|
+
const { readFileSync: readFileSync12 } = __require("fs");
|
|
6463
|
+
const text = readFileSync12(transcriptPath, "utf8");
|
|
6464
|
+
const lines = text.trim().split("\n").reverse();
|
|
6465
|
+
for (const line of lines) {
|
|
6466
|
+
try {
|
|
6467
|
+
const event = JSON.parse(line);
|
|
6468
|
+
const message = extractAssistantText(event);
|
|
6469
|
+
if (message) return message;
|
|
6470
|
+
} catch {
|
|
6471
|
+
}
|
|
6472
|
+
}
|
|
6473
|
+
} catch {
|
|
6474
|
+
return null;
|
|
6475
|
+
}
|
|
6476
|
+
return null;
|
|
6477
|
+
}
|
|
6478
|
+
function extractAssistantText(event) {
|
|
6479
|
+
const obj = event;
|
|
6480
|
+
if (obj.type !== "assistant" && obj.role !== "assistant") return null;
|
|
6481
|
+
const message = obj.message ?? obj;
|
|
6482
|
+
const content = message.content;
|
|
6483
|
+
if (typeof content === "string") return content.trim() || null;
|
|
6484
|
+
if (Array.isArray(content)) {
|
|
6485
|
+
const parts = content.map((part) => {
|
|
6486
|
+
if (typeof part === "string") return part;
|
|
6487
|
+
if (part && typeof part === "object") {
|
|
6488
|
+
const p = part;
|
|
6489
|
+
if (typeof p.text === "string") return p.text;
|
|
6490
|
+
if (typeof p.content === "string") return p.content;
|
|
6491
|
+
}
|
|
6492
|
+
return "";
|
|
6493
|
+
}).filter(Boolean);
|
|
6494
|
+
const joined = parts.join("\n").trim();
|
|
6495
|
+
return joined || null;
|
|
6496
|
+
}
|
|
6497
|
+
return null;
|
|
6498
|
+
}
|
|
@@ -2741,6 +2741,33 @@ async function ensureSchema() {
|
|
|
2741
2741
|
CREATE INDEX IF NOT EXISTS idx_chat_history_session
|
|
2742
2742
|
ON chat_history(session_id, id);
|
|
2743
2743
|
`);
|
|
2744
|
+
await client.executeMultiple(`
|
|
2745
|
+
CREATE TABLE IF NOT EXISTS session_events (
|
|
2746
|
+
id TEXT PRIMARY KEY,
|
|
2747
|
+
agent_id TEXT NOT NULL,
|
|
2748
|
+
agent_role TEXT NOT NULL,
|
|
2749
|
+
session_id TEXT NOT NULL,
|
|
2750
|
+
session_scope TEXT,
|
|
2751
|
+
project_name TEXT NOT NULL,
|
|
2752
|
+
event_index INTEGER NOT NULL,
|
|
2753
|
+
event_type TEXT NOT NULL,
|
|
2754
|
+
tool_name TEXT,
|
|
2755
|
+
tool_use_id TEXT,
|
|
2756
|
+
content TEXT NOT NULL,
|
|
2757
|
+
payload_json TEXT,
|
|
2758
|
+
has_error INTEGER NOT NULL DEFAULT 0,
|
|
2759
|
+
created_at TEXT NOT NULL
|
|
2760
|
+
);
|
|
2761
|
+
|
|
2762
|
+
CREATE INDEX IF NOT EXISTS idx_session_events_agent_time
|
|
2763
|
+
ON session_events(agent_id, created_at DESC);
|
|
2764
|
+
|
|
2765
|
+
CREATE INDEX IF NOT EXISTS idx_session_events_session_index
|
|
2766
|
+
ON session_events(session_id, event_index);
|
|
2767
|
+
|
|
2768
|
+
CREATE INDEX IF NOT EXISTS idx_session_events_scope_agent_time
|
|
2769
|
+
ON session_events(session_scope, agent_id, created_at DESC);
|
|
2770
|
+
`);
|
|
2744
2771
|
await client.executeMultiple(`
|
|
2745
2772
|
CREATE TABLE IF NOT EXISTS workspaces (
|
|
2746
2773
|
id TEXT PRIMARY KEY,
|
|
@@ -4572,6 +4599,12 @@ var init_platform_procedures = __esm({
|
|
|
4572
4599
|
priority: "p0",
|
|
4573
4600
|
content: "exe-build-adv is MANDATORY for ALL work touching 3+ files. Run /exe-build-adv --auto BEFORE implementation. Pipeline: Spec \u2192 AC \u2192 Tests \u2192 Evaluate \u2192 Fix. No multi-file feature ships without pipeline artifacts. No exceptions \u2014 managers reject work without them."
|
|
4574
4601
|
},
|
|
4602
|
+
{
|
|
4603
|
+
title: "Code context first for repository orientation",
|
|
4604
|
+
domain: "workflow",
|
|
4605
|
+
priority: "p1",
|
|
4606
|
+
content: "Before broad repo exploration, symbol tracing, blast-radius review, or codebase Q&A, agents should use the consolidated code_context MCP tool instead of manual grep/read loops. Use action=index or stats to refresh/check the index; action=search with query, limit, offset, languages, paths, refresh_index for fresh multi-language code/doc search; action=trace for symbol imports/dependents; action=blast_radius for impact analysis before edits. CLI parity exists via exe-os code-context init|index|status|stats|search|doctor. Keep code_context separate from durable employee memory: promote only validated decisions, procedures, or lessons into store_memory/commit_memory."
|
|
4607
|
+
},
|
|
4575
4608
|
{
|
|
4576
4609
|
title: "Commit discipline \u2014 never leave verified work floating",
|
|
4577
4610
|
domain: "workflow",
|
|
@@ -2508,6 +2508,33 @@ async function ensureSchema() {
|
|
|
2508
2508
|
CREATE INDEX IF NOT EXISTS idx_chat_history_session
|
|
2509
2509
|
ON chat_history(session_id, id);
|
|
2510
2510
|
`);
|
|
2511
|
+
await client.executeMultiple(`
|
|
2512
|
+
CREATE TABLE IF NOT EXISTS session_events (
|
|
2513
|
+
id TEXT PRIMARY KEY,
|
|
2514
|
+
agent_id TEXT NOT NULL,
|
|
2515
|
+
agent_role TEXT NOT NULL,
|
|
2516
|
+
session_id TEXT NOT NULL,
|
|
2517
|
+
session_scope TEXT,
|
|
2518
|
+
project_name TEXT NOT NULL,
|
|
2519
|
+
event_index INTEGER NOT NULL,
|
|
2520
|
+
event_type TEXT NOT NULL,
|
|
2521
|
+
tool_name TEXT,
|
|
2522
|
+
tool_use_id TEXT,
|
|
2523
|
+
content TEXT NOT NULL,
|
|
2524
|
+
payload_json TEXT,
|
|
2525
|
+
has_error INTEGER NOT NULL DEFAULT 0,
|
|
2526
|
+
created_at TEXT NOT NULL
|
|
2527
|
+
);
|
|
2528
|
+
|
|
2529
|
+
CREATE INDEX IF NOT EXISTS idx_session_events_agent_time
|
|
2530
|
+
ON session_events(agent_id, created_at DESC);
|
|
2531
|
+
|
|
2532
|
+
CREATE INDEX IF NOT EXISTS idx_session_events_session_index
|
|
2533
|
+
ON session_events(session_id, event_index);
|
|
2534
|
+
|
|
2535
|
+
CREATE INDEX IF NOT EXISTS idx_session_events_scope_agent_time
|
|
2536
|
+
ON session_events(session_scope, agent_id, created_at DESC);
|
|
2537
|
+
`);
|
|
2511
2538
|
await client.executeMultiple(`
|
|
2512
2539
|
CREATE TABLE IF NOT EXISTS workspaces (
|
|
2513
2540
|
id TEXT PRIMARY KEY,
|
|
@@ -4171,6 +4198,12 @@ var init_platform_procedures = __esm({
|
|
|
4171
4198
|
priority: "p0",
|
|
4172
4199
|
content: "exe-build-adv is MANDATORY for ALL work touching 3+ files. Run /exe-build-adv --auto BEFORE implementation. Pipeline: Spec \u2192 AC \u2192 Tests \u2192 Evaluate \u2192 Fix. No multi-file feature ships without pipeline artifacts. No exceptions \u2014 managers reject work without them."
|
|
4173
4200
|
},
|
|
4201
|
+
{
|
|
4202
|
+
title: "Code context first for repository orientation",
|
|
4203
|
+
domain: "workflow",
|
|
4204
|
+
priority: "p1",
|
|
4205
|
+
content: "Before broad repo exploration, symbol tracing, blast-radius review, or codebase Q&A, agents should use the consolidated code_context MCP tool instead of manual grep/read loops. Use action=index or stats to refresh/check the index; action=search with query, limit, offset, languages, paths, refresh_index for fresh multi-language code/doc search; action=trace for symbol imports/dependents; action=blast_radius for impact analysis before edits. CLI parity exists via exe-os code-context init|index|status|stats|search|doctor. Keep code_context separate from durable employee memory: promote only validated decisions, procedures, or lessons into store_memory/commit_memory."
|
|
4206
|
+
},
|
|
4174
4207
|
{
|
|
4175
4208
|
title: "Commit discipline \u2014 never leave verified work floating",
|
|
4176
4209
|
domain: "workflow",
|