@event4u/agent-config 9.31.0 → 9.33.0
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/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +146 -0
- package/dist/agent-src/commands/review/routing.md +3 -4
- package/dist/agent-src/contexts/communication/rules-auto/reply-close-mechanics.md +65 -0
- package/dist/agent-src/contexts/execution/host-capability-manifest.md +32 -1
- package/dist/agent-src/contexts/execution/orchestration-telemetry.md +3 -0
- package/dist/agent-src/rules/delegation-policy.md +17 -1
- package/dist/agent-src/scripts/roadmap_gates.ts +107 -3
- package/dist/agent-src/skills/docker/SKILL.md +11 -0
- package/dist/agent-src/skills/laravel/SKILL.md +11 -0
- package/dist/agent-src/skills/review-routing/SKILL.md +23 -6
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/scripts/ownership-map.example.yml +1 -1
- package/dist/agent-src/templates/scripts/work_engine/delivery_state.ts +6 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +332 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/refine.ts +106 -1
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.ts +50 -15
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +49 -15
- package/dist/agent-src/templates/scripts/work_engine/state.ts +74 -0
- package/dist/agent-src/templates/scripts/work_engine/state_io.ts +6 -0
- package/dist/cli/registry.js +4 -4
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli-delegate/chunk-2WELHO3P.js +582 -0
- package/dist/cli-delegate/chunk-HTIU3W56.js +66 -0
- package/dist/cli-delegate/{chunk-ITIQSGOQ.js → chunk-MA4GFWDY.js} +7 -4
- package/dist/cli-delegate/{chunk-2WCLVDWC.js → chunk-PMQ6Z3T3.js} +1642 -165
- package/dist/cli-delegate/chunk-PZWRPRWP.js +38 -0
- package/dist/cli-delegate/{chunk-PFBV6XRT.js → chunk-Q26HT4QT.js} +1 -63
- package/dist/cli-delegate/{chunk-LVRYBKTI.js → chunk-YPAWXXXR.js} +158 -0
- package/dist/cli-delegate/cmd_conformance.js +308 -227
- package/dist/cli-delegate/cmd_doctor.js +4 -2
- package/dist/cli-delegate/cmd_export.js +1 -1
- package/dist/cli-delegate/cmd_handoff.js +160 -58
- package/dist/cli-delegate/cmd_prune.js +1 -1
- package/dist/cli-delegate/cmd_session_recycle.js +30 -5
- package/dist/cli-delegate/cmd_settings_get.js +4 -2
- package/dist/cli-delegate/cmd_settings_migrate.js +1 -1
- package/dist/cli-delegate/cmd_settings_set.js +5 -3
- package/dist/cli-delegate/cmd_sync.js +1 -1
- package/dist/cli-delegate/cmd_uninstall.js +1 -1
- package/dist/cli-delegate/cmd_validate.js +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +8 -8
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +2 -2
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +2 -2
- package/dist/hooks/dispatch.js +1136 -690
- package/dist/install/install.mjs +7 -4
- package/dist/mcp/registry-manifest.json +2 -2
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +3688 -1159
- package/package.json +1 -1
- package/src/agent-src/scripts/roadmap_gates.ts +107 -3
- package/src/agent-src/templates/scripts/ownership-map.example.yml +1 -1
- package/src/agent-src/templates/scripts/work_engine/delivery_state.ts +6 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +332 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/refine.ts +106 -1
- package/src/agent-src/templates/scripts/work_engine/directives/backend/test.ts +50 -15
- package/src/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +49 -15
- package/src/agent-src/templates/scripts/work_engine/state.ts +74 -0
- package/src/agent-src/templates/scripts/work_engine/state_io.ts +6 -0
- package/src/config/cost-parity-budget.json +167 -0
- package/src/config/gate-coverage.yml +44 -5
- package/src/config/quorum-attendance-budget.json +39 -0
- package/src/scripts/_cli/cmd_doctor.ts +69 -1
- package/src/scripts/_cli/cmd_session_recycle.ts +44 -3
- package/src/scripts/_cli/handoff_generate.ts +36 -1
- package/src/scripts/_cli/handoff_sessions.ts +140 -9
- package/src/scripts/_dispatch.bash +5 -3
- package/src/scripts/_lib/carrier_divergence.ts +98 -27
- package/src/scripts/_lib/envelope_grounding.ts +206 -0
- package/src/scripts/_lib/host_capability.ts +79 -0
- package/src/scripts/_lib/orchestration_record.ts +45 -0
- package/src/scripts/_lib/session_eol.ts +85 -0
- package/src/scripts/_lib/subagent_capsule.ts +256 -1
- package/src/scripts/ai_council/clients.ts +31 -0
- package/src/scripts/ai_council/events_log.ts +128 -6
- package/src/scripts/ai_council/orchestrator.ts +12 -3
- package/src/scripts/ai_council/pricing.ts +48 -1
- package/src/scripts/ai_council/quorum.ts +20 -0
- package/src/scripts/ai_council/session.ts +11 -0
- package/src/scripts/ask_transport.ts +20 -1
- package/src/scripts/cache_realization_report.ts +38 -0
- package/src/scripts/check_release_highlights.ts +7 -1
- package/src/scripts/check_secret_leak.test.ts +43 -0
- package/src/scripts/check_secret_leak.ts +12 -0
- package/src/scripts/conformance_scan.ts +105 -0
- package/src/scripts/cost/track.mjs +39 -0
- package/src/scripts/cost_summary.ts +104 -1
- package/src/scripts/council_cli.ts +131 -13
- package/src/scripts/dispatch_economy_report.ts +5 -2
- package/src/scripts/handoff_context_hook.ts +66 -18
- package/src/scripts/hooks/session_eol_hook.ts +12 -12
- package/src/scripts/install.ts +20 -6
- package/src/scripts/lint_budget_ownership.ts +81 -0
- package/src/scripts/lint_skill_frontmatter_safety.ts +55 -1
- package/src/scripts/lint_workflow_paths.ts +384 -0
- package/src/scripts/preamble_byte_census.ts +9 -1
- package/src/scripts/report_carrier_divergence.ts +104 -29
- package/src/scripts/report_conformance_funnel.ts +51 -4
- package/src/scripts/routing_doctor.ts +25 -2
- package/src/scripts/schemas/dod.schema.json +45 -0
- package/src/scripts/schemas/subagent.schema.json +3 -2
- package/dist/cli-delegate/chunk-RVGBH4XK.js +0 -142
|
@@ -66,10 +66,12 @@ import {
|
|
|
66
66
|
_wizard_state_path,
|
|
67
67
|
main,
|
|
68
68
|
shutilWhich
|
|
69
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-PMQ6Z3T3.js";
|
|
70
70
|
import "./chunk-FTAISGDQ.js";
|
|
71
71
|
import "./chunk-EJITJBJX.js";
|
|
72
|
-
import "./chunk-
|
|
72
|
+
import "./chunk-Q26HT4QT.js";
|
|
73
|
+
import "./chunk-YPAWXXXR.js";
|
|
74
|
+
import "./chunk-PZWRPRWP.js";
|
|
73
75
|
import "./chunk-736JCWLM.js";
|
|
74
76
|
import "./chunk-63WSP6YZ.js";
|
|
75
77
|
import "./chunk-GRRPEPRN.js";
|
|
@@ -9,8 +9,13 @@ import {
|
|
|
9
9
|
RECYCLE_CONSUMED_REL,
|
|
10
10
|
RECYCLE_ENVELOPE_REL,
|
|
11
11
|
RECYCLE_MAX_AGE_HOURS,
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
collectRepoAnchor,
|
|
13
|
+
describeDrift,
|
|
14
|
+
hasBoundaryMarker,
|
|
15
|
+
scanEnvelopeDirectives,
|
|
16
|
+
validateRecycleEnvelope,
|
|
17
|
+
wrapAsPriorSessionData
|
|
18
|
+
} from "./chunk-2WELHO3P.js";
|
|
14
19
|
import "./chunk-3EWYC3YK.js";
|
|
15
20
|
import {
|
|
16
21
|
readHookStdin
|
|
@@ -18,7 +23,8 @@ import {
|
|
|
18
23
|
import {
|
|
19
24
|
_RAW_KEY_PREFIXES,
|
|
20
25
|
hardenedSpawnEnv
|
|
21
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-YPAWXXXR.js";
|
|
27
|
+
import "./chunk-PZWRPRWP.js";
|
|
22
28
|
import "./chunk-JEJABGKB.js";
|
|
23
29
|
import "./chunk-NDJLNC6Q.js";
|
|
24
30
|
import "./chunk-OY53J6II.js";
|
|
@@ -26,9 +32,9 @@ import "./chunk-J55WI3RR.js";
|
|
|
26
32
|
|
|
27
33
|
// src/scripts/_cli/cmd_handoff.ts
|
|
28
34
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
29
|
-
import * as
|
|
35
|
+
import * as fs5 from "node:fs";
|
|
30
36
|
import process4 from "node:process";
|
|
31
|
-
import * as
|
|
37
|
+
import * as path5 from "node:path";
|
|
32
38
|
import { fileURLToPath as fileURLToPath2, pathToFileURL } from "node:url";
|
|
33
39
|
|
|
34
40
|
// src/scripts/_cli/handoff_generate.ts
|
|
@@ -208,6 +214,15 @@ function _is_replay_mode() {
|
|
|
208
214
|
function _handoff_context_path(root) {
|
|
209
215
|
return process2.env.AGENT_HANDOFF_CONTEXT_FILE || path.join(root, HANDOFF_CONTEXT_REL);
|
|
210
216
|
}
|
|
217
|
+
function guardedInjection(block, reason) {
|
|
218
|
+
if (!hasBoundaryMarker(block)) {
|
|
219
|
+
return {
|
|
220
|
+
action: "discard",
|
|
221
|
+
reason: "refused: injected block carries no prior-session boundary marker"
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
return { action: "inject", reason, context: block };
|
|
225
|
+
}
|
|
211
226
|
function consume_handoff_context(root, now = /* @__PURE__ */ new Date()) {
|
|
212
227
|
const target = _handoff_context_path(root);
|
|
213
228
|
let text;
|
|
@@ -238,14 +253,12 @@ function consume_handoff_context(root, now = /* @__PURE__ */ new Date()) {
|
|
|
238
253
|
return { action: "discard", reason: `stale: ${ageHours.toFixed(1)}h > ${MAX_AGE_HOURS}h` };
|
|
239
254
|
}
|
|
240
255
|
const sourceSession = text.match(/^Source-Session: (.+)$/m)?.[1]?.trim() ?? "unknown";
|
|
241
|
-
const block =
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
"</handoff-context>"
|
|
246
|
-
].join("\n");
|
|
256
|
+
const block = wrapAsPriorSessionData(text, {
|
|
257
|
+
kind: `handoff session=${sourceSession}`,
|
|
258
|
+
source: HANDOFF_CONTEXT_REL
|
|
259
|
+
});
|
|
247
260
|
remove();
|
|
248
|
-
return
|
|
261
|
+
return guardedInjection(block, `handoff consumed (session=${sourceSession})`);
|
|
249
262
|
}
|
|
250
263
|
function consume_recycle_envelope(root, now = /* @__PURE__ */ new Date()) {
|
|
251
264
|
const target = process2.env.AGENT_RECYCLE_ENVELOPE_FILE || path.join(root, RECYCLE_ENVELOPE_REL);
|
|
@@ -297,16 +310,24 @@ function consume_recycle_envelope(root, now = /* @__PURE__ */ new Date()) {
|
|
|
297
310
|
consume();
|
|
298
311
|
return { action: "discard", reason: "recycle envelope workspace does not resolve" };
|
|
299
312
|
}
|
|
300
|
-
const
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
313
|
+
const drift = describeDrift(envelope, collectRepoAnchor(root));
|
|
314
|
+
const warnings = scanEnvelopeDirectives(envelope);
|
|
315
|
+
const focus = (process2.env.AGENT_RESUME_FOCUS ?? "").trim();
|
|
316
|
+
const block = wrapAsPriorSessionData(JSON.stringify(envelope, null, 2), {
|
|
317
|
+
kind: "recycle-envelope",
|
|
318
|
+
source: RECYCLE_ENVELOPE_REL,
|
|
319
|
+
warnings: [
|
|
320
|
+
...drift,
|
|
321
|
+
...focus ? [`FOCUS: attack "${focus}" first \u2014 the rest of this envelope is context.`] : [],
|
|
322
|
+
"Re-derive everything under not_carried_forward from source before trusting it.",
|
|
323
|
+
...warnings
|
|
324
|
+
]
|
|
325
|
+
});
|
|
308
326
|
consume();
|
|
309
|
-
return
|
|
327
|
+
return guardedInjection(
|
|
328
|
+
block,
|
|
329
|
+
warnings.length > 0 ? `recycle envelope consumed (${warnings.length} directive warning(s) surfaced)` : "recycle envelope consumed"
|
|
330
|
+
);
|
|
310
331
|
}
|
|
311
332
|
function main() {
|
|
312
333
|
let envelope = {};
|
|
@@ -365,6 +386,7 @@ var WORD_CAP = 1200;
|
|
|
365
386
|
var SNIPPET_CHARS = 200;
|
|
366
387
|
var DONE_SNIPPET_CHARS = 400;
|
|
367
388
|
var MAX_ERRORS = 5;
|
|
389
|
+
var MAX_ERROR_CHARS = 400;
|
|
368
390
|
var MAX_DECISIONS = 5;
|
|
369
391
|
var MAX_FILES = 15;
|
|
370
392
|
var FAILURE_RE = /\b(fail(ing|ed|ure)?|error|exit[= ][1-9]|red\b|broken)\b/i;
|
|
@@ -570,7 +592,11 @@ function build_handoff(session, options = {}) {
|
|
|
570
592
|
lastUser ? [`continue from the last user ask: ${_snippet(lastUser, SNIPPET_CHARS)}`] : []
|
|
571
593
|
);
|
|
572
594
|
const errors = _redact_items(
|
|
573
|
-
toolish.filter((t) => FAILURE_RE.test(t.text)).slice(-MAX_ERRORS).map((t) =>
|
|
595
|
+
toolish.filter((t) => FAILURE_RE.test(t.text)).slice(-MAX_ERRORS).map((t) => {
|
|
596
|
+
const line = t.text.split("\n").find((l) => FAILURE_RE.test(l))?.trim() ?? t.text.trim();
|
|
597
|
+
const prefix = t.tool ? `${t.tool}: ` : "";
|
|
598
|
+
return `${prefix}${line}`.slice(0, MAX_ERROR_CHARS);
|
|
599
|
+
})
|
|
574
600
|
);
|
|
575
601
|
const decisions = _redact_items(
|
|
576
602
|
assistants.filter((t) => DECISION_RE.test(t.text)).slice(-MAX_DECISIONS).map((t) => _snippet(t.text, SNIPPET_CHARS))
|
|
@@ -622,6 +648,14 @@ function build_handoff(session, options = {}) {
|
|
|
622
648
|
}
|
|
623
649
|
for (const s of sections) {
|
|
624
650
|
lines.push("", `## ${s.title}`, "");
|
|
651
|
+
if (s.title === "Resume pointer") {
|
|
652
|
+
lines.push(
|
|
653
|
+
"> Precision contract: identify code by signature or `path:line`, never by",
|
|
654
|
+
"> description; quote error strings verbatim; give every resume step its",
|
|
655
|
+
'> expected outcome, so "done" is checkable rather than felt.',
|
|
656
|
+
""
|
|
657
|
+
);
|
|
658
|
+
}
|
|
625
659
|
if (s.items.length === 0) {
|
|
626
660
|
if (s.verbatim && verbatim.withheldLines > 0) {
|
|
627
661
|
lines.push(`- [${verbatim.withheldLines} line(s) withheld by privacy floor]`);
|
|
@@ -670,11 +704,42 @@ function write_handoff(text, options = {}) {
|
|
|
670
704
|
}
|
|
671
705
|
|
|
672
706
|
// src/scripts/_cli/handoff_sessions.ts
|
|
673
|
-
import * as
|
|
707
|
+
import * as fs4 from "node:fs";
|
|
674
708
|
import * as os from "node:os";
|
|
709
|
+
import * as path4 from "node:path";
|
|
710
|
+
|
|
711
|
+
// src/scripts/_lib/session_eol.ts
|
|
712
|
+
import * as crypto from "node:crypto";
|
|
713
|
+
import * as fs3 from "node:fs";
|
|
675
714
|
import * as path3 from "node:path";
|
|
715
|
+
function eolStateDir(workspaceRoot) {
|
|
716
|
+
return path3.join(workspaceRoot, "agents", "runtime", "state", "session-eol");
|
|
717
|
+
}
|
|
718
|
+
function eolStateFile(workspaceRoot, sessionKey) {
|
|
719
|
+
return path3.join(eolStateDir(workspaceRoot), `${sessionKey}.json`);
|
|
720
|
+
}
|
|
721
|
+
function eolSessionKey(raw) {
|
|
722
|
+
return crypto.createHash("sha256").update(raw || "unknown-session").digest("hex");
|
|
723
|
+
}
|
|
724
|
+
function readEolCounters(workspaceRoot, sessionKey) {
|
|
725
|
+
try {
|
|
726
|
+
const raw = fs3.readFileSync(eolStateFile(workspaceRoot, sessionKey), "utf-8");
|
|
727
|
+
const parsed = JSON.parse(raw);
|
|
728
|
+
const counters = parsed["counters"];
|
|
729
|
+
if (typeof counters !== "object" || counters === null || Array.isArray(counters)) {
|
|
730
|
+
return null;
|
|
731
|
+
}
|
|
732
|
+
return counters;
|
|
733
|
+
} catch {
|
|
734
|
+
return null;
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
// src/scripts/_cli/handoff_sessions.ts
|
|
676
739
|
var DEFAULT_CAP = 15;
|
|
740
|
+
var FETCH_OVERSHOOT = 3;
|
|
677
741
|
var SUMMARY_SNIPPET_CHARS = 120;
|
|
742
|
+
var SUBSTANTIVE_TOKEN_FLOOR = 1e4;
|
|
678
743
|
function encode_project_path(cwd) {
|
|
679
744
|
return cwd.replace(/[/.]/g, "-");
|
|
680
745
|
}
|
|
@@ -690,7 +755,7 @@ function _summarize(first, last) {
|
|
|
690
755
|
}
|
|
691
756
|
function _read_lines2(file) {
|
|
692
757
|
try {
|
|
693
|
-
return
|
|
758
|
+
return fs4.readFileSync(file, "utf-8").split("\n");
|
|
694
759
|
} catch {
|
|
695
760
|
return [];
|
|
696
761
|
}
|
|
@@ -707,10 +772,10 @@ function _parse_json2(line) {
|
|
|
707
772
|
}
|
|
708
773
|
return null;
|
|
709
774
|
}
|
|
710
|
-
var CHAT_HISTORY_REL =
|
|
775
|
+
var CHAT_HISTORY_REL = path4.join("agents", "runtime", ".agent-chat-history");
|
|
711
776
|
function _chat_history_path(opts) {
|
|
712
777
|
if (opts.chatHistoryPath) return opts.chatHistoryPath;
|
|
713
|
-
return process.env.AGENT_CHAT_HISTORY_FILE ||
|
|
778
|
+
return process.env.AGENT_CHAT_HISTORY_FILE || path4.join(opts.cwd ?? process.cwd(), CHAT_HISTORY_REL);
|
|
714
779
|
}
|
|
715
780
|
function _chat_history_summaries(histPath) {
|
|
716
781
|
const bySession = /* @__PURE__ */ new Map();
|
|
@@ -795,19 +860,19 @@ function _scan_claude_transcript(file) {
|
|
|
795
860
|
return scan;
|
|
796
861
|
}
|
|
797
862
|
function _claude_transcript_sessions(opts, cap) {
|
|
798
|
-
const root = opts.claudeProjectsRoot ??
|
|
863
|
+
const root = opts.claudeProjectsRoot ?? path4.join(os.homedir(), ".claude", "projects");
|
|
799
864
|
const cwd = opts.cwd ?? process.cwd();
|
|
800
|
-
const projectDir =
|
|
865
|
+
const projectDir = path4.join(root, encode_project_path(cwd));
|
|
801
866
|
let names;
|
|
802
867
|
try {
|
|
803
|
-
names =
|
|
868
|
+
names = fs4.readdirSync(projectDir).filter((n) => n.endsWith(".jsonl"));
|
|
804
869
|
} catch {
|
|
805
870
|
return [];
|
|
806
871
|
}
|
|
807
872
|
const files = names.map((n) => {
|
|
808
|
-
const full =
|
|
873
|
+
const full = path4.join(projectDir, n);
|
|
809
874
|
try {
|
|
810
|
-
return { full, id:
|
|
875
|
+
return { full, id: path4.basename(n, ".jsonl"), mtime: fs4.statSync(full).mtimeMs };
|
|
811
876
|
} catch {
|
|
812
877
|
return null;
|
|
813
878
|
}
|
|
@@ -832,13 +897,13 @@ function _claude_transcript_sessions(opts, cap) {
|
|
|
832
897
|
function _codex_meta(file) {
|
|
833
898
|
let firstLine = "";
|
|
834
899
|
try {
|
|
835
|
-
const fd =
|
|
900
|
+
const fd = fs4.openSync(file, "r");
|
|
836
901
|
try {
|
|
837
902
|
const buf = Buffer.alloc(8192);
|
|
838
|
-
const n =
|
|
903
|
+
const n = fs4.readSync(fd, buf, 0, buf.length, 0);
|
|
839
904
|
firstLine = buf.toString("utf-8", 0, n).split("\n")[0] ?? "";
|
|
840
905
|
} finally {
|
|
841
|
-
|
|
906
|
+
fs4.closeSync(fd);
|
|
842
907
|
}
|
|
843
908
|
} catch {
|
|
844
909
|
return null;
|
|
@@ -863,17 +928,17 @@ function _codex_files(root) {
|
|
|
863
928
|
const dir = stack.pop();
|
|
864
929
|
let entries;
|
|
865
930
|
try {
|
|
866
|
-
entries =
|
|
931
|
+
entries = fs4.readdirSync(dir, { withFileTypes: true });
|
|
867
932
|
} catch {
|
|
868
933
|
continue;
|
|
869
934
|
}
|
|
870
935
|
for (const e of entries) {
|
|
871
|
-
const full =
|
|
936
|
+
const full = path4.join(dir, e.name);
|
|
872
937
|
if (e.isDirectory()) stack.push(full);
|
|
873
938
|
else if (e.isFile() && e.name.endsWith(".jsonl")) out.push(full);
|
|
874
939
|
}
|
|
875
940
|
}
|
|
876
|
-
return out.sort((a, b) =>
|
|
941
|
+
return out.sort((a, b) => path4.basename(a) < path4.basename(b) ? 1 : -1);
|
|
877
942
|
}
|
|
878
943
|
function _codex_prompt_text(rec) {
|
|
879
944
|
if (rec.type !== "event_msg") return null;
|
|
@@ -901,13 +966,13 @@ function _scan_codex_session(file) {
|
|
|
901
966
|
return scan;
|
|
902
967
|
}
|
|
903
968
|
function _matches_repo(sessionCwd, repoCwd) {
|
|
904
|
-
const norm = (p) =>
|
|
969
|
+
const norm = (p) => path4.resolve(p).replace(/\/+$/, "");
|
|
905
970
|
const a = norm(sessionCwd);
|
|
906
971
|
const b = norm(repoCwd);
|
|
907
|
-
return a === b || a.startsWith(b +
|
|
972
|
+
return a === b || a.startsWith(b + path4.sep);
|
|
908
973
|
}
|
|
909
974
|
function _codex_sessions(opts, cap) {
|
|
910
|
-
const root = opts.codexSessionsRoot ??
|
|
975
|
+
const root = opts.codexSessionsRoot ?? path4.join(os.homedir(), ".codex", "sessions");
|
|
911
976
|
const cwd = opts.cwd ?? process.cwd();
|
|
912
977
|
const matching = [];
|
|
913
978
|
for (const file of _codex_files(root)) {
|
|
@@ -937,21 +1002,58 @@ function _codex_sessions(opts, cap) {
|
|
|
937
1002
|
function _sort_key(s) {
|
|
938
1003
|
return s.endedAt ?? s.startedAt ?? "";
|
|
939
1004
|
}
|
|
1005
|
+
function is_substantive(counters) {
|
|
1006
|
+
if (counters === null) return true;
|
|
1007
|
+
if (!Number.isFinite(counters.assistant_records)) return true;
|
|
1008
|
+
if (counters.assistant_records < 1) return false;
|
|
1009
|
+
if (!Number.isFinite(counters.tool_calls)) return true;
|
|
1010
|
+
if (counters.tool_calls >= 1) return true;
|
|
1011
|
+
if (!Number.isFinite(counters.final_context_tokens)) return true;
|
|
1012
|
+
return counters.final_context_tokens >= SUBSTANTIVE_TOKEN_FLOOR;
|
|
1013
|
+
}
|
|
1014
|
+
function _derive_tag(id) {
|
|
1015
|
+
try {
|
|
1016
|
+
return derive_session_tag(id);
|
|
1017
|
+
} catch {
|
|
1018
|
+
return null;
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
function _counters_for(session, byTag, workspaceRoot) {
|
|
1022
|
+
const native = session.source === "chat-history" ? byTag.get(session.id) : session;
|
|
1023
|
+
const candidates = [
|
|
1024
|
+
...session.source === "chat-history" ? [] : [session.id],
|
|
1025
|
+
native?.id,
|
|
1026
|
+
native?.transcriptPath
|
|
1027
|
+
];
|
|
1028
|
+
for (const candidate of candidates) {
|
|
1029
|
+
if (!candidate) continue;
|
|
1030
|
+
const counters = readEolCounters(workspaceRoot, eolSessionKey(candidate));
|
|
1031
|
+
if (counters !== null) return counters;
|
|
1032
|
+
}
|
|
1033
|
+
return null;
|
|
1034
|
+
}
|
|
940
1035
|
function list_handoff_sessions(opts = {}) {
|
|
941
1036
|
const cap = opts.cap ?? DEFAULT_CAP;
|
|
1037
|
+
const workspaceRoot = opts.workspaceRoot ?? opts.cwd ?? process.cwd();
|
|
1038
|
+
const selfId = opts.selfSessionId === null ? null : opts.selfSessionId ?? process.env.AGENT_SESSION_ID ?? process.env.CLAUDE_CODE_SESSION_ID ?? null;
|
|
1039
|
+
const selfTag = selfId ? _derive_tag(selfId) : null;
|
|
942
1040
|
const primary = _chat_history_sessions(opts);
|
|
943
1041
|
const knownTags = new Set(primary.map((s) => s.id));
|
|
944
|
-
const
|
|
945
|
-
|
|
946
|
-
...
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
1042
|
+
const fetchCap = cap * FETCH_OVERSHOOT;
|
|
1043
|
+
const nativeAll = [
|
|
1044
|
+
..._claude_transcript_sessions(opts, fetchCap),
|
|
1045
|
+
..._codex_sessions(opts, fetchCap)
|
|
1046
|
+
];
|
|
1047
|
+
const byTag = /* @__PURE__ */ new Map();
|
|
1048
|
+
for (const s of nativeAll) {
|
|
1049
|
+
const tag = _derive_tag(s.id);
|
|
1050
|
+
if (tag) byTag.set(tag, s);
|
|
1051
|
+
}
|
|
1052
|
+
const native = nativeAll.filter((s) => {
|
|
1053
|
+
const tag = _derive_tag(s.id);
|
|
1054
|
+
return tag === null || !knownTags.has(tag);
|
|
953
1055
|
});
|
|
954
|
-
return [...primary, ...native].sort((a, b) => _sort_key(a) < _sort_key(b) ? 1 : _sort_key(a) > _sort_key(b) ? -1 : 0).slice(0, cap);
|
|
1056
|
+
return [...primary, ...native].filter((s) => s.id !== selfId && (selfTag === null || s.id !== selfTag)).filter((s) => is_substantive(_counters_for(s, byTag, workspaceRoot))).sort((a, b) => _sort_key(a) < _sort_key(b) ? 1 : _sort_key(a) > _sort_key(b) ? -1 : 0).slice(0, cap);
|
|
955
1057
|
}
|
|
956
1058
|
|
|
957
1059
|
// src/scripts/_cli/cmd_handoff.ts
|
|
@@ -1016,14 +1118,14 @@ function _default_runner(cmd) {
|
|
|
1016
1118
|
function _tty_read_line(prompt) {
|
|
1017
1119
|
try {
|
|
1018
1120
|
process4.stdout.write(prompt);
|
|
1019
|
-
const fd =
|
|
1121
|
+
const fd = fs5.openSync("/dev/tty", "rs");
|
|
1020
1122
|
try {
|
|
1021
1123
|
const buf = Buffer.alloc(1);
|
|
1022
1124
|
let line = "";
|
|
1023
1125
|
for (; ; ) {
|
|
1024
1126
|
let n = 0;
|
|
1025
1127
|
try {
|
|
1026
|
-
n =
|
|
1128
|
+
n = fs5.readSync(fd, buf, 0, 1, null);
|
|
1027
1129
|
} catch (exc) {
|
|
1028
1130
|
const code = exc.code;
|
|
1029
1131
|
if (code === "EAGAIN" || code === "EINTR") continue;
|
|
@@ -1036,7 +1138,7 @@ function _tty_read_line(prompt) {
|
|
|
1036
1138
|
}
|
|
1037
1139
|
return line;
|
|
1038
1140
|
} finally {
|
|
1039
|
-
|
|
1141
|
+
fs5.closeSync(fd);
|
|
1040
1142
|
}
|
|
1041
1143
|
} catch {
|
|
1042
1144
|
return null;
|
|
@@ -1130,7 +1232,7 @@ function main2(argv = null, options = {}) {
|
|
|
1130
1232
|
throw exc;
|
|
1131
1233
|
}
|
|
1132
1234
|
const envRoot = process4.env.AGENT_CONFIG_ROOT_OVERRIDE === "1" ? process4.env.AGENT_CONFIG_PROJECT_ROOT || null : null;
|
|
1133
|
-
const root =
|
|
1235
|
+
const root = path5.resolve(opts.root ?? envRoot ?? process4.cwd());
|
|
1134
1236
|
const sessions = list_handoff_sessions({ cwd: root });
|
|
1135
1237
|
if (opts.list) {
|
|
1136
1238
|
if (sessions.length === 0) {
|
|
@@ -1209,7 +1311,7 @@ ${PROG}: error: unknown --launch host '${opts.launch}' (claude | codex)
|
|
|
1209
1311
|
`);
|
|
1210
1312
|
return runner(adapter.build_argv(text));
|
|
1211
1313
|
}
|
|
1212
|
-
const existed =
|
|
1314
|
+
const existed = fs5.existsSync(handoff_target_path(root));
|
|
1213
1315
|
const target = write_handoff(text, { cwd: root });
|
|
1214
1316
|
if (existed) out("note: replaced an unconsumed handoff \u2014 only the most recent one persists.\n");
|
|
1215
1317
|
out(`handoff written: ${target}
|
|
@@ -1226,13 +1328,13 @@ function _isCliEntry() {
|
|
|
1226
1328
|
if (process4.argv[1] === void 0) {
|
|
1227
1329
|
return false;
|
|
1228
1330
|
}
|
|
1229
|
-
const argvUrl = pathToFileURL(
|
|
1331
|
+
const argvUrl = pathToFileURL(path5.resolve(process4.argv[1])).href;
|
|
1230
1332
|
if (import.meta.url === argvUrl) {
|
|
1231
1333
|
return true;
|
|
1232
1334
|
}
|
|
1233
1335
|
try {
|
|
1234
|
-
const here =
|
|
1235
|
-
const argv =
|
|
1336
|
+
const here = fs5.realpathSync(fileURLToPath2(import.meta.url));
|
|
1337
|
+
const argv = fs5.realpathSync(path5.resolve(process4.argv[1]));
|
|
1236
1338
|
return here === argv;
|
|
1237
1339
|
} catch {
|
|
1238
1340
|
return false;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
PROJECT_BRIDGE_MARKERS
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-MA4GFWDY.js";
|
|
5
5
|
import "./chunk-UVKNIJH2.js";
|
|
6
6
|
import "./chunk-DS6BLDMG.js";
|
|
7
7
|
import "./chunk-BKO2AZ7Z.js";
|
|
@@ -3,11 +3,13 @@ import {
|
|
|
3
3
|
CAPSULE_SCHEMA_VERSION,
|
|
4
4
|
RECYCLE_ENVELOPE_MAX_BYTES,
|
|
5
5
|
RECYCLE_ENVELOPE_REL,
|
|
6
|
+
collectGrounding,
|
|
6
7
|
validateRecycleEnvelope
|
|
7
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-2WELHO3P.js";
|
|
8
9
|
import {
|
|
9
10
|
atomic_write_json
|
|
10
11
|
} from "./chunk-EJITJBJX.js";
|
|
12
|
+
import "./chunk-PZWRPRWP.js";
|
|
11
13
|
import {
|
|
12
14
|
resolve_project_root
|
|
13
15
|
} from "./chunk-JEJABGKB.js";
|
|
@@ -32,7 +34,10 @@ function templateEnvelope() {
|
|
|
32
34
|
constraints: ["<binding constraint>"],
|
|
33
35
|
open_worker_envelopes: [],
|
|
34
36
|
artifact_paths: ["<path to a deliverable / note / evidence file>"],
|
|
35
|
-
assumptions: []
|
|
37
|
+
assumptions: [],
|
|
38
|
+
next_task: "<the ONE task this envelope is written for \u2014 select content for it>",
|
|
39
|
+
suggested_skills: ["<skill the successor should invoke>"],
|
|
40
|
+
failed_approaches: ['<tried X, failed because Y \u2014 or the single entry "none">']
|
|
36
41
|
};
|
|
37
42
|
}
|
|
38
43
|
function parseArgv(argv) {
|
|
@@ -41,6 +46,8 @@ function parseArgv(argv) {
|
|
|
41
46
|
const a = argv[i];
|
|
42
47
|
if (a === "--template") {
|
|
43
48
|
parsed.template = true;
|
|
49
|
+
} else if (a === "--verify") {
|
|
50
|
+
parsed.verify = true;
|
|
44
51
|
} else if (a === "--file") {
|
|
45
52
|
const value = argv[i + 1];
|
|
46
53
|
if (!value) return { ok: false, message: "--file requires a path" };
|
|
@@ -74,6 +81,16 @@ function runSessionRecycle(input, opts) {
|
|
|
74
81
|
envelope["written_at"] = (opts.now ?? /* @__PURE__ */ new Date()).toISOString();
|
|
75
82
|
}
|
|
76
83
|
if (envelope["workspace"] === void 0) envelope["workspace"] = projectRoot;
|
|
84
|
+
const grounding = collectGrounding(projectRoot);
|
|
85
|
+
for (const key of ["repo_identity", "branch", "head", "status_summary", "last_verify", "uncommitted_paths"]) {
|
|
86
|
+
delete envelope[key];
|
|
87
|
+
}
|
|
88
|
+
if (grounding.repo_identity !== null) envelope["repo_identity"] = grounding.repo_identity;
|
|
89
|
+
if (grounding.branch !== null) envelope["branch"] = grounding.branch;
|
|
90
|
+
if (grounding.head !== null) envelope["head"] = grounding.head;
|
|
91
|
+
if (grounding.status_summary !== null) envelope["status_summary"] = grounding.status_summary;
|
|
92
|
+
if (grounding.last_verify !== null) envelope["last_verify"] = grounding.last_verify;
|
|
93
|
+
envelope["uncommitted_paths"] = grounding.uncommitted_paths;
|
|
77
94
|
const violations = validateRecycleEnvelope(envelope);
|
|
78
95
|
if (violations.length > 0) {
|
|
79
96
|
return {
|
|
@@ -95,6 +112,10 @@ function runSessionRecycle(input, opts) {
|
|
|
95
112
|
]
|
|
96
113
|
};
|
|
97
114
|
}
|
|
115
|
+
if (opts.verify === true) {
|
|
116
|
+
out.push(`recycle envelope VALID \u2014 ${bytes} bytes, not written (--verify).`);
|
|
117
|
+
return { code: 0, out, err };
|
|
118
|
+
}
|
|
98
119
|
const target = path.join(projectRoot, RECYCLE_ENVELOPE_REL);
|
|
99
120
|
try {
|
|
100
121
|
atomic_write_json(target, envelope);
|
|
@@ -115,9 +136,10 @@ function main(argv = process.argv.slice(2)) {
|
|
|
115
136
|
const parsed = parseArgv(argv);
|
|
116
137
|
if (!parsed.ok) {
|
|
117
138
|
const usage = [
|
|
118
|
-
"usage: agent-config session:recycle [--file <envelope.json>] [--template]",
|
|
139
|
+
"usage: agent-config session:recycle [--file <envelope.json>] [--template] [--verify]",
|
|
119
140
|
" --file <path> read the envelope JSON from a file (default: stdin)",
|
|
120
|
-
" --template print a skeleton envelope and exit"
|
|
141
|
+
" --template print a skeleton envelope and exit",
|
|
142
|
+
" --verify validate only \u2014 same rejections, no write"
|
|
121
143
|
].join("\n");
|
|
122
144
|
if (parsed.message === "usage") {
|
|
123
145
|
process.stdout.write(`${usage}
|
|
@@ -149,7 +171,10 @@ ${usage}
|
|
|
149
171
|
`);
|
|
150
172
|
return 2;
|
|
151
173
|
}
|
|
152
|
-
const result = runSessionRecycle(input, {
|
|
174
|
+
const result = runSessionRecycle(input, {
|
|
175
|
+
cwd: process.cwd(),
|
|
176
|
+
...parsed.verify === true ? { verify: true } : {}
|
|
177
|
+
});
|
|
153
178
|
for (const line of result.out) process.stdout.write(`${line}
|
|
154
179
|
`);
|
|
155
180
|
for (const line of result.err) process.stderr.write(`${line}
|
|
@@ -3,9 +3,11 @@ import {
|
|
|
3
3
|
buildSettingsClassIndex,
|
|
4
4
|
classOfPath,
|
|
5
5
|
getSettingsLeaf,
|
|
6
|
-
load,
|
|
7
6
|
parseSettingsClassRows
|
|
8
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-HTIU3W56.js";
|
|
8
|
+
import {
|
|
9
|
+
load
|
|
10
|
+
} from "./chunk-Q26HT4QT.js";
|
|
9
11
|
import {
|
|
10
12
|
MERGEABLE_KEYS,
|
|
11
13
|
SETTINGS_CARVE_OUT,
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
buildSettingsClassIndex,
|
|
4
|
-
dump,
|
|
5
4
|
getSettingsLeaf,
|
|
6
|
-
load,
|
|
7
5
|
parseSettingsClassRows
|
|
8
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-HTIU3W56.js";
|
|
7
|
+
import {
|
|
8
|
+
dump,
|
|
9
|
+
load
|
|
10
|
+
} from "./chunk-Q26HT4QT.js";
|
|
9
11
|
import {
|
|
10
12
|
external_exports,
|
|
11
13
|
settingsSchema
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
main
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-MA4GFWDY.js";
|
|
5
5
|
import "./chunk-UVKNIJH2.js";
|
|
6
6
|
import "./chunk-DS6BLDMG.js";
|
|
7
7
|
import "./chunk-BKO2AZ7Z.js";
|
|
@@ -3,7 +3,7 @@ import { createRequire as __acCreateRequire } from 'node:module'; const require
|
|
|
3
3
|
import {
|
|
4
4
|
PROJECT_BRIDGE_MARKERS,
|
|
5
5
|
USER_SCOPE_PATHS
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-MA4GFWDY.js";
|
|
7
7
|
import "./chunk-UVKNIJH2.js";
|
|
8
8
|
import "./chunk-DS6BLDMG.js";
|
|
9
9
|
import "./chunk-BKO2AZ7Z.js";
|