@event4u/agent-config 9.27.0 → 9.28.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/AGENTS.md +12 -11
- package/CHANGELOG.md +99 -0
- package/README.md +1 -1
- package/dist/agent-src/commands/analyze/conformance.md +24 -0
- package/dist/agent-src/contexts/execution/orchestration-telemetry.md +10 -3
- package/dist/agent-src/rules/artifact-engagement-recording.md +4 -1
- package/dist/agent-src/rules/autonomous-execution.md +1 -1
- package/dist/agent-src/rules/brand-source-of-truth.md +33 -6
- package/dist/agent-src/rules/context-hygiene.md +3 -1
- package/dist/agent-src/rules/council-availability.md +93 -0
- package/dist/agent-src/rules/cross-source-consistency.md +3 -0
- package/dist/agent-src/rules/delegation-policy.md +29 -5
- package/dist/agent-src/rules/design-fidelity.md +3 -0
- package/dist/agent-src/rules/evaluator-independence.md +2 -1
- package/dist/agent-src/rules/external-code-graph-interop.md +2 -1
- package/dist/agent-src/rules/finance-safety-floor.md +1 -1
- package/dist/agent-src/rules/git-history-discipline.md +1 -1
- package/dist/agent-src/rules/history-discipline.md +3 -1
- package/dist/agent-src/rules/legal-safety-floor.md +1 -1
- package/dist/agent-src/rules/no-pr-progress-comments.md +3 -1
- package/dist/agent-src/rules/onboarding-gate.md +3 -1
- package/dist/agent-src/rules/roadmap-ci-steps-policy.md +4 -1
- package/dist/agent-src/rules/role-mode-adherence.md +1 -1
- package/dist/agent-src/rules/scale-discipline.md +3 -1
- package/dist/agent-src/rules/self-repair-loop.md +103 -0
- package/dist/agent-src/rules/session-canary.md +2 -1
- package/dist/agent-src/rules/strategy-safety-floor.md +1 -1
- package/dist/agent-src/rules/token-budget-discipline.md +3 -1
- package/dist/agent-src/rules/tool-safety.md +5 -1
- package/dist/agent-src/skills/adversarial-review/SKILL.md +1 -1
- package/dist/agent-src/skills/analysis-autonomous-mode/SKILL.md +1 -1
- package/dist/agent-src/skills/performance-analysis/SKILL.md +1 -1
- package/dist/agent-src/skills/persona-improvement/SKILL.md +1 -1
- package/dist/agent-src/skills/project-analyzer/SKILL.md +1 -1
- package/dist/agent-src/skills/security-audit/SKILL.md +1 -1
- package/dist/agent-src/skills/sequential-thinking/SKILL.md +1 -1
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +1 -1
- package/dist/agent-src/skills/universal-project-analysis/SKILL.md +1 -1
- package/dist/agent-src/templates/AGENTS.md +6 -10
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/cli/registry.js +7 -0
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli-delegate/chunk-22GCIJ2O.js +270 -0
- package/dist/cli-delegate/{chunk-BCPIOAGV.js → chunk-2BE5I2MN.js} +8 -8
- package/dist/cli-delegate/{chunk-AIIUU73N.js → chunk-7OMQCH4V.js} +1 -1
- package/dist/cli-delegate/{chunk-HJ6DAJHR.js → chunk-GB2FSUEE.js} +57 -7
- package/dist/cli-delegate/{chunk-WR6GTRHJ.js → chunk-JXARCGVN.js} +3 -3
- package/dist/cli-delegate/{chunk-3KJIMFTB.js → chunk-PQSAQKHW.js} +466 -304
- package/dist/cli-delegate/chunk-REKCMYOU.js +2991 -0
- package/dist/cli-delegate/cmd_analyze_session.js +1 -1
- package/dist/cli-delegate/cmd_brand_status.js +134 -0
- package/dist/cli-delegate/cmd_conformance.js +7 -7
- package/dist/cli-delegate/cmd_converge.js +3 -3
- package/dist/cli-delegate/cmd_doctor.js +4 -4
- package/dist/cli-delegate/cmd_explain.js +80 -330
- package/dist/cli-delegate/cmd_export.js +5 -5
- package/dist/cli-delegate/cmd_fleet.js +3 -3
- package/dist/cli-delegate/cmd_handoff.js +2 -2
- package/dist/cli-delegate/cmd_mcp_available.js +433 -0
- package/dist/cli-delegate/cmd_migrate.js +3 -3
- package/dist/cli-delegate/cmd_packs_active.js +153 -0
- package/dist/cli-delegate/cmd_preflight.js +1 -1
- package/dist/cli-delegate/cmd_prune.js +5 -5
- package/dist/cli-delegate/cmd_route_audit.js +8 -8
- package/dist/cli-delegate/cmd_route_explain.js +4 -4
- package/dist/cli-delegate/cmd_settings_get.js +272 -0
- package/dist/cli-delegate/cmd_settings_migrate.js +5 -5
- package/dist/cli-delegate/cmd_settings_set.js +7 -2967
- package/dist/cli-delegate/cmd_sync.js +5 -5
- package/dist/cli-delegate/cmd_uninstall.js +5 -5
- package/dist/cli-delegate/cmd_update.js +4 -4
- package/dist/cli-delegate/cmd_upgrade.js +4 -4
- package/dist/cli-delegate/cmd_validate.js +5 -5
- package/dist/cli-delegate/cmd_versions.js +4 -4
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +100 -40
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +3 -3
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +7 -5
- package/dist/discovery/trust-report.md +11 -11
- package/dist/discovery/workspaces.json +6 -4
- package/dist/hooks/dispatch.js +9004 -6132
- package/dist/install/install.mjs +697 -507
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +127 -20
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/agent_settings.js +80 -15
- package/dist/scripts/_lib/agent_settings.js.map +1 -1
- package/docs/contracts/settings-classes.md +29 -8
- package/docs/guidelines/agent-infra/memory-access.md +14 -3
- package/package.json +1 -1
- package/src/agent-src/templates/AGENTS.md +6 -10
- package/src/config/budgets.yml +29 -0
- package/src/config/evaluator-budgets.json +4 -4
- package/src/config/gate-coverage.yml +26 -0
- package/src/scripts/_cli/cmd_brand_status.ts +174 -0
- package/src/scripts/_cli/cmd_mcp_available.ts +266 -0
- package/src/scripts/_cli/cmd_packs_active.ts +225 -0
- package/src/scripts/_cli/cmd_settings_get.ts +324 -0
- package/src/scripts/_dispatch.bash +57 -0
- package/src/scripts/_lib/agent_settings.ts +82 -16
- package/src/scripts/_lib/carrier_divergence.ts +135 -0
- package/src/scripts/_lib/host_capability.ts +84 -1
- package/src/scripts/_lib/prompt_shape.ts +88 -0
- package/src/scripts/_lib/review_skipped_record.ts +102 -0
- package/src/scripts/_lib/rule_layer_overlap.ts +254 -0
- package/src/scripts/_lib/self_repair.ts +342 -0
- package/src/scripts/_lib/self_repair_store.ts +100 -0
- package/src/scripts/_lib/transcript_entry.ts +80 -0
- package/src/scripts/check_branch_freshness.ts +255 -0
- package/src/scripts/check_council_config_location.ts +125 -1
- package/src/scripts/check_standing_rule_delivery.ts +314 -0
- package/src/scripts/config/profiles.ts +13 -3
- package/src/scripts/conformance_scan.ts +272 -24
- package/src/scripts/council_availability_hook.ts +188 -0
- package/src/scripts/council_cli.ts +126 -7
- package/src/scripts/hook_manifest.yaml +107 -26
- package/src/scripts/hooks/block_no_verify.ts +39 -2
- package/src/scripts/hooks/block_unauthorized_git.ts +156 -7
- package/src/scripts/hooks/concern_registry.ts +10 -0
- package/src/scripts/hooks/delegation_nudge_hook.ts +450 -0
- package/src/scripts/hooks/end_review_nudge_hook.ts +726 -0
- package/src/scripts/hooks/orchestration_record_hook.ts +342 -0
- package/src/scripts/install.ts +151 -0
- package/src/scripts/language_mirror_hook.ts +30 -37
- package/src/scripts/measure_scope_dedup.ts +19 -13
- package/src/scripts/onboarding_gate_hook.ts +40 -1
- package/src/scripts/orchestration_record.ts +4 -1
- package/src/scripts/preamble_byte_census.ts +9 -20
- package/src/scripts/report_carrier_divergence.ts +364 -0
- package/src/scripts/report_skill_activation.ts +257 -0
- package/src/scripts/report_skill_obligation_violations.ts +579 -0
- package/src/scripts/routing_doctor.ts +77 -6
- package/src/scripts/self_repair_cli.ts +240 -0
- package/src/scripts/self_repair_hook.ts +241 -0
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "./chunk-DVRS2KVR.js";
|
|
6
6
|
import {
|
|
7
7
|
main
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-JXARCGVN.js";
|
|
9
9
|
import {
|
|
10
10
|
RULE_SOURCE_REL
|
|
11
11
|
} from "./chunk-BKO2AZ7Z.js";
|
|
@@ -48,7 +48,7 @@ import {
|
|
|
48
48
|
import {
|
|
49
49
|
find_project_root_with_anchor,
|
|
50
50
|
load_agent_settings
|
|
51
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-GB2FSUEE.js";
|
|
52
52
|
import {
|
|
53
53
|
event4u_root,
|
|
54
54
|
legacy_xdg_root,
|
|
@@ -266,9 +266,9 @@ function subtract_pointers(doc, entries) {
|
|
|
266
266
|
// src/scripts/install.ts
|
|
267
267
|
import { spawn, spawnSync } from "node:child_process";
|
|
268
268
|
import * as crypto3 from "node:crypto";
|
|
269
|
-
import * as
|
|
269
|
+
import * as fs6 from "node:fs";
|
|
270
270
|
import * as os2 from "node:os";
|
|
271
|
-
import * as
|
|
271
|
+
import * as path5 from "node:path";
|
|
272
272
|
import process2 from "node:process";
|
|
273
273
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
274
274
|
|
|
@@ -388,28 +388,127 @@ function is_claude_builtin_name(slug) {
|
|
|
388
388
|
return CLAUDE_CODE_BUILTIN_NAMES.has(slug.toLowerCase());
|
|
389
389
|
}
|
|
390
390
|
|
|
391
|
+
// src/scripts/_lib/rule_layer_overlap.ts
|
|
392
|
+
import * as fs from "node:fs";
|
|
393
|
+
import * as path from "node:path";
|
|
394
|
+
var INSTALLER_PROVENANCE_KEYS = ["package", "source_path"];
|
|
395
|
+
function stripProvenance(text) {
|
|
396
|
+
const lines = text.split("\n");
|
|
397
|
+
if (lines[0]?.trim() !== "---") return text;
|
|
398
|
+
let close = -1;
|
|
399
|
+
for (let i = 1; i < lines.length; i++) {
|
|
400
|
+
if (lines[i]?.trim() === "---") {
|
|
401
|
+
close = i;
|
|
402
|
+
break;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
if (close === -1) return text;
|
|
406
|
+
const kept = [];
|
|
407
|
+
for (let i = 0; i < lines.length; i++) {
|
|
408
|
+
if (i > 0 && i < close) {
|
|
409
|
+
const key = /^([A-Za-z_][A-Za-z0-9_-]*):/.exec(lines[i] ?? "")?.[1];
|
|
410
|
+
if (key !== void 0 && INSTALLER_PROVENANCE_KEYS.includes(key)) continue;
|
|
411
|
+
}
|
|
412
|
+
kept.push(lines[i] ?? "");
|
|
413
|
+
}
|
|
414
|
+
return kept.join("\n");
|
|
415
|
+
}
|
|
416
|
+
function only_in(a, b) {
|
|
417
|
+
return [...a.keys()].filter((k) => !b.has(k)).sort();
|
|
418
|
+
}
|
|
419
|
+
function compareLayers(global_layer, project_layer) {
|
|
420
|
+
const overlap = [...global_layer.keys()].filter((k) => project_layer.has(k)).sort();
|
|
421
|
+
const duplicate = [];
|
|
422
|
+
const divergent = [];
|
|
423
|
+
let redundant_chars = 0;
|
|
424
|
+
for (const name of overlap) {
|
|
425
|
+
const g = stripProvenance(global_layer.get(name) ?? "");
|
|
426
|
+
const p = stripProvenance(project_layer.get(name) ?? "");
|
|
427
|
+
if (g === p) {
|
|
428
|
+
duplicate.push(name);
|
|
429
|
+
redundant_chars += (project_layer.get(name) ?? "").length;
|
|
430
|
+
} else {
|
|
431
|
+
divergent.push(name);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
return {
|
|
435
|
+
schema_version: 1,
|
|
436
|
+
overlap,
|
|
437
|
+
duplicate,
|
|
438
|
+
divergent,
|
|
439
|
+
global_only: only_in(global_layer, project_layer),
|
|
440
|
+
project_only: only_in(project_layer, global_layer),
|
|
441
|
+
redundant_chars
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
function readRuleLayer(dir) {
|
|
445
|
+
let names;
|
|
446
|
+
try {
|
|
447
|
+
names = fs.readdirSync(dir);
|
|
448
|
+
} catch {
|
|
449
|
+
return null;
|
|
450
|
+
}
|
|
451
|
+
const files = /* @__PURE__ */ new Map();
|
|
452
|
+
for (const name of names.filter((n) => n.endsWith(".md")).sort()) {
|
|
453
|
+
try {
|
|
454
|
+
files.set(name, fs.readFileSync(path.join(dir, name), "utf-8"));
|
|
455
|
+
} catch {
|
|
456
|
+
continue;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
return { dir, files };
|
|
460
|
+
}
|
|
461
|
+
function claudeMdExcludesGlob(dir) {
|
|
462
|
+
return `${path.resolve(dir).replace(/\/+$/, "")}/**`;
|
|
463
|
+
}
|
|
464
|
+
function mergeClaudeMdExcludes(existing, entry) {
|
|
465
|
+
if (!Array.isArray(existing)) return [entry];
|
|
466
|
+
if (existing.includes(entry)) return [...existing];
|
|
467
|
+
return [...existing, entry];
|
|
468
|
+
}
|
|
469
|
+
function decideLayerAction(report, choice, global_dir, project_dir) {
|
|
470
|
+
const refresh_required = report.divergent.length > 0;
|
|
471
|
+
const skew = refresh_required ? ` ${report.divergent.length} shared rule(s) differ in body \u2014 refresh before suppressing, or obligations only the suppressed copy carries are lost.` : "";
|
|
472
|
+
if (choice === "both-acknowledged") {
|
|
473
|
+
return {
|
|
474
|
+
write: "both",
|
|
475
|
+
suppress_dir: null,
|
|
476
|
+
refresh_required,
|
|
477
|
+
note: `Keeping both rule layers by request: ${report.overlap.length} shared rule(s), ${report.redundant_chars} chars delivered twice per session. Nothing suppressed, nothing deleted.${skew}`
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
const keep = choice === "global" ? global_dir : project_dir;
|
|
481
|
+
const drop = choice === "global" ? project_dir : global_dir;
|
|
482
|
+
return {
|
|
483
|
+
write: choice,
|
|
484
|
+
suppress_dir: drop,
|
|
485
|
+
refresh_required,
|
|
486
|
+
note: `Keeping ${choice} rule layer (${keep}); suppressing ${drop} via claudeMdExcludes \u2014 recovers ${report.redundant_chars} chars per session. No file is deleted or rewritten.${skew}`
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
|
|
391
490
|
// src/scripts/_lib/install_drift.ts
|
|
392
491
|
var import_yaml = __toESM(require_dist(), 1);
|
|
393
492
|
import * as crypto from "node:crypto";
|
|
394
|
-
import * as
|
|
493
|
+
import * as fs2 from "node:fs";
|
|
395
494
|
import * as os from "node:os";
|
|
396
|
-
import * as
|
|
495
|
+
import * as path2 from "node:path";
|
|
397
496
|
function expanduser(p) {
|
|
398
497
|
if (p === "~") {
|
|
399
498
|
return os.homedir();
|
|
400
499
|
}
|
|
401
500
|
if (p.startsWith("~/") || process.platform === "win32" && p.startsWith("~\\")) {
|
|
402
|
-
return
|
|
501
|
+
return path2.join(os.homedir(), p.slice(2));
|
|
403
502
|
}
|
|
404
503
|
return p;
|
|
405
504
|
}
|
|
406
505
|
function resolve_entry_path(project_root, raw) {
|
|
407
506
|
const p = expanduser(raw);
|
|
408
|
-
return
|
|
507
|
+
return path2.isAbsolute(p) ? p : path2.join(project_root, p);
|
|
409
508
|
}
|
|
410
509
|
function sha256_of_file(p) {
|
|
411
510
|
try {
|
|
412
|
-
return crypto.createHash("sha256").update(
|
|
511
|
+
return crypto.createHash("sha256").update(fs2.readFileSync(p)).digest("hex");
|
|
413
512
|
} catch {
|
|
414
513
|
return null;
|
|
415
514
|
}
|
|
@@ -418,7 +517,7 @@ function collect_drift(project_root, env) {
|
|
|
418
517
|
const target = manifest_path(project_root, env);
|
|
419
518
|
let text;
|
|
420
519
|
try {
|
|
421
|
-
text =
|
|
520
|
+
text = fs2.readFileSync(target, "utf-8");
|
|
422
521
|
} catch {
|
|
423
522
|
return null;
|
|
424
523
|
}
|
|
@@ -463,7 +562,7 @@ function collect_drift(project_root, env) {
|
|
|
463
562
|
continue;
|
|
464
563
|
}
|
|
465
564
|
const resolved = resolve_entry_path(project_root, raw_path);
|
|
466
|
-
if (!
|
|
565
|
+
if (!fs2.existsSync(resolved)) {
|
|
467
566
|
out.push({
|
|
468
567
|
tool_id,
|
|
469
568
|
path: resolved,
|
|
@@ -517,8 +616,8 @@ function format_drift_report(entries) {
|
|
|
517
616
|
|
|
518
617
|
// src/scripts/_lib/claude_desktop_bundler.ts
|
|
519
618
|
import * as crypto2 from "node:crypto";
|
|
520
|
-
import * as
|
|
521
|
-
import * as
|
|
619
|
+
import * as fs3 from "node:fs";
|
|
620
|
+
import * as path3 from "node:path";
|
|
522
621
|
|
|
523
622
|
// src/scripts/_lib/zip_min.ts
|
|
524
623
|
import * as zlib from "node:zlib";
|
|
@@ -625,7 +724,7 @@ function _is_excluded(rel_parts) {
|
|
|
625
724
|
}
|
|
626
725
|
function _is_dir(p) {
|
|
627
726
|
try {
|
|
628
|
-
return
|
|
727
|
+
return fs3.statSync(p).isDirectory();
|
|
629
728
|
} catch {
|
|
630
729
|
return false;
|
|
631
730
|
}
|
|
@@ -637,12 +736,12 @@ function _compare_rel_parts(a, b) {
|
|
|
637
736
|
}
|
|
638
737
|
function _walk_skill_files(skill_dir) {
|
|
639
738
|
const out = [];
|
|
640
|
-
const resolved =
|
|
739
|
+
const resolved = fs3.realpathSync(skill_dir);
|
|
641
740
|
const walk = (root, relRoot) => {
|
|
642
741
|
const dirNames = [];
|
|
643
742
|
const fileNames = [];
|
|
644
|
-
for (const dirent of
|
|
645
|
-
const full =
|
|
743
|
+
for (const dirent of fs3.readdirSync(root, { withFileTypes: true })) {
|
|
744
|
+
const full = path3.join(root, dirent.name);
|
|
646
745
|
const isDir2 = dirent.isDirectory() || dirent.isSymbolicLink() && _is_dir(full);
|
|
647
746
|
if (isDir2) {
|
|
648
747
|
dirNames.push(dirent.name);
|
|
@@ -655,13 +754,13 @@ function _walk_skill_files(skill_dir) {
|
|
|
655
754
|
if (_is_excluded(rel_parts)) {
|
|
656
755
|
continue;
|
|
657
756
|
}
|
|
658
|
-
out.push([
|
|
757
|
+
out.push([path3.join(root, fname), rel_parts]);
|
|
659
758
|
}
|
|
660
759
|
for (const dname of dirNames) {
|
|
661
760
|
if (_is_excluded([dname])) {
|
|
662
761
|
continue;
|
|
663
762
|
}
|
|
664
|
-
walk(
|
|
763
|
+
walk(path3.join(root, dname), [...relRoot, dname]);
|
|
665
764
|
}
|
|
666
765
|
};
|
|
667
766
|
walk(resolved, []);
|
|
@@ -674,53 +773,53 @@ function _manifest_digest(files) {
|
|
|
674
773
|
const rel = rel_parts.join("/");
|
|
675
774
|
h.update(Buffer.from(rel, "utf-8"));
|
|
676
775
|
h.update(Buffer.from([0]));
|
|
677
|
-
h.update(crypto2.createHash("sha256").update(
|
|
776
|
+
h.update(crypto2.createHash("sha256").update(fs3.readFileSync(abs_path)).digest());
|
|
678
777
|
h.update(Buffer.from([0]));
|
|
679
778
|
}
|
|
680
779
|
return h.digest("hex");
|
|
681
780
|
}
|
|
682
781
|
function _atomic_write_zip(zip_path, files) {
|
|
683
|
-
|
|
684
|
-
const stem =
|
|
685
|
-
const tmp_path =
|
|
686
|
-
|
|
782
|
+
fs3.mkdirSync(path3.dirname(zip_path), { recursive: true });
|
|
783
|
+
const stem = path3.basename(zip_path, path3.extname(zip_path));
|
|
784
|
+
const tmp_path = path3.join(
|
|
785
|
+
path3.dirname(zip_path),
|
|
687
786
|
`.${stem}.${crypto2.randomBytes(6).toString("hex")}.zip.tmp`
|
|
688
787
|
);
|
|
689
788
|
try {
|
|
690
789
|
const entries = files.map(([abs_path, rel_parts]) => ({
|
|
691
790
|
name: rel_parts.join("/"),
|
|
692
|
-
data:
|
|
791
|
+
data: fs3.readFileSync(abs_path)
|
|
693
792
|
}));
|
|
694
|
-
|
|
695
|
-
|
|
793
|
+
fs3.writeFileSync(tmp_path, zip_write_sync(entries));
|
|
794
|
+
fs3.renameSync(tmp_path, zip_path);
|
|
696
795
|
} finally {
|
|
697
|
-
if (
|
|
698
|
-
|
|
796
|
+
if (fs3.existsSync(tmp_path)) {
|
|
797
|
+
fs3.unlinkSync(tmp_path);
|
|
699
798
|
}
|
|
700
799
|
}
|
|
701
800
|
}
|
|
702
801
|
function _write_if_changed(dest_dir, slug, files, force, written) {
|
|
703
802
|
const digest = _manifest_digest(files);
|
|
704
|
-
const zip_path =
|
|
705
|
-
const digest_path =
|
|
706
|
-
const recorded =
|
|
707
|
-
if (!force && recorded === digest &&
|
|
803
|
+
const zip_path = path3.join(dest_dir, `${slug}.zip`);
|
|
804
|
+
const digest_path = path3.join(dest_dir, `${slug}.sha256`);
|
|
805
|
+
const recorded = fs3.existsSync(digest_path) ? fs3.readFileSync(digest_path, "utf-8").trim() : "";
|
|
806
|
+
if (!force && recorded === digest && fs3.existsSync(zip_path)) {
|
|
708
807
|
return;
|
|
709
808
|
}
|
|
710
809
|
_atomic_write_zip(zip_path, files);
|
|
711
|
-
|
|
810
|
+
fs3.writeFileSync(digest_path, digest + "\n", "utf-8");
|
|
712
811
|
written.push(zip_path);
|
|
713
812
|
}
|
|
714
813
|
function build_skill_bundles(package_root, dest_dir, force = false, curation = null) {
|
|
715
|
-
const skills_root =
|
|
814
|
+
const skills_root = path3.join(package_root, "dist/agent-src", "skills");
|
|
716
815
|
if (!_is_dir(skills_root)) {
|
|
717
816
|
return [];
|
|
718
817
|
}
|
|
719
|
-
|
|
818
|
+
fs3.mkdirSync(dest_dir, { recursive: true });
|
|
720
819
|
const written = [];
|
|
721
|
-
for (const name of
|
|
722
|
-
const entry =
|
|
723
|
-
const isSymlink2 =
|
|
820
|
+
for (const name of fs3.readdirSync(skills_root).sort()) {
|
|
821
|
+
const entry = path3.join(skills_root, name);
|
|
822
|
+
const isSymlink2 = fs3.lstatSync(entry).isSymbolicLink();
|
|
724
823
|
if (!(_is_dir(entry) || isSymlink2)) {
|
|
725
824
|
continue;
|
|
726
825
|
}
|
|
@@ -728,8 +827,8 @@ function build_skill_bundles(package_root, dest_dir, force = false, curation = n
|
|
|
728
827
|
if (curation !== null && !curation.includes(skill_name)) {
|
|
729
828
|
continue;
|
|
730
829
|
}
|
|
731
|
-
const skill_md =
|
|
732
|
-
if (!
|
|
830
|
+
const skill_md = path3.join(entry, "SKILL.md");
|
|
831
|
+
if (!fs3.existsSync(skill_md)) {
|
|
733
832
|
continue;
|
|
734
833
|
}
|
|
735
834
|
const files = _walk_skill_files(entry);
|
|
@@ -741,15 +840,15 @@ function build_skill_bundles(package_root, dest_dir, force = false, curation = n
|
|
|
741
840
|
return written;
|
|
742
841
|
}
|
|
743
842
|
function _command_slug(source_file, commands_root) {
|
|
744
|
-
const rel =
|
|
745
|
-
const noExt = rel.slice(0, rel.length -
|
|
746
|
-
return noExt.split(
|
|
843
|
+
const rel = path3.relative(commands_root, source_file);
|
|
844
|
+
const noExt = rel.slice(0, rel.length - path3.extname(rel).length);
|
|
845
|
+
return noExt.split(path3.sep).join("-");
|
|
747
846
|
}
|
|
748
847
|
function _iter_command_files(commands_root) {
|
|
749
848
|
const found = [];
|
|
750
849
|
const walk = (dir) => {
|
|
751
|
-
for (const dirent of
|
|
752
|
-
const full =
|
|
850
|
+
for (const dirent of fs3.readdirSync(dir, { withFileTypes: true })) {
|
|
851
|
+
const full = path3.join(dir, dirent.name);
|
|
753
852
|
if (dirent.isDirectory() || dirent.isSymbolicLink() && _is_dir(full)) {
|
|
754
853
|
walk(full);
|
|
755
854
|
} else if (dirent.name.endsWith(".md")) {
|
|
@@ -759,21 +858,21 @@ function _iter_command_files(commands_root) {
|
|
|
759
858
|
};
|
|
760
859
|
walk(commands_root);
|
|
761
860
|
found.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
|
|
762
|
-
return found.filter((source_file) =>
|
|
861
|
+
return found.filter((source_file) => path3.basename(source_file) !== "AGENTS.md");
|
|
763
862
|
}
|
|
764
863
|
function build_command_bundles(package_root, dest_dir, force = false, curation = null) {
|
|
765
|
-
const commands_root =
|
|
864
|
+
const commands_root = path3.join(package_root, "dist/agent-src", "commands");
|
|
766
865
|
if (!_is_dir(commands_root)) {
|
|
767
866
|
return [];
|
|
768
867
|
}
|
|
769
|
-
const skills_root =
|
|
868
|
+
const skills_root = path3.join(package_root, "dist/agent-src", "skills");
|
|
770
869
|
let skill_names = /* @__PURE__ */ new Set();
|
|
771
870
|
if (_is_dir(skills_root)) {
|
|
772
871
|
skill_names = new Set(
|
|
773
|
-
|
|
872
|
+
fs3.readdirSync(skills_root).filter((name) => _is_dir(path3.join(skills_root, name)))
|
|
774
873
|
);
|
|
775
874
|
}
|
|
776
|
-
|
|
875
|
+
fs3.mkdirSync(dest_dir, { recursive: true });
|
|
777
876
|
const written = [];
|
|
778
877
|
for (const source_file of _iter_command_files(commands_root)) {
|
|
779
878
|
const slug = _command_slug(source_file, commands_root);
|
|
@@ -783,7 +882,7 @@ function build_command_bundles(package_root, dest_dir, force = false, curation =
|
|
|
783
882
|
if (curation !== null && !curation.includes(slug)) {
|
|
784
883
|
continue;
|
|
785
884
|
}
|
|
786
|
-
const files = [[
|
|
885
|
+
const files = [[fs3.realpathSync(source_file), ["SKILL.md"]]];
|
|
787
886
|
_write_if_changed(dest_dir, slug, files, force, written);
|
|
788
887
|
}
|
|
789
888
|
return written;
|
|
@@ -2144,8 +2243,8 @@ var zodToJsonSchema = (schema, options) => {
|
|
|
2144
2243
|
};
|
|
2145
2244
|
|
|
2146
2245
|
// src/scripts/_lib/module_detection.ts
|
|
2147
|
-
import * as
|
|
2148
|
-
import * as
|
|
2246
|
+
import * as fs4 from "node:fs";
|
|
2247
|
+
import * as path4 from "node:path";
|
|
2149
2248
|
var _SKIP_DIRS = /* @__PURE__ */ new Set([".module-template", ".example"]);
|
|
2150
2249
|
var _RULES = [
|
|
2151
2250
|
["app/Modules", "laravel-hmvc", "App\\Modules\\{ModuleName}"],
|
|
@@ -2159,14 +2258,14 @@ var _RULES = [
|
|
|
2159
2258
|
];
|
|
2160
2259
|
function _isDir(p) {
|
|
2161
2260
|
try {
|
|
2162
|
-
return
|
|
2261
|
+
return fs4.statSync(p).isDirectory();
|
|
2163
2262
|
} catch {
|
|
2164
2263
|
return false;
|
|
2165
2264
|
}
|
|
2166
2265
|
}
|
|
2167
2266
|
function _isFile(p) {
|
|
2168
2267
|
try {
|
|
2169
|
-
return
|
|
2268
|
+
return fs4.statSync(p).isFile();
|
|
2170
2269
|
} catch {
|
|
2171
2270
|
return false;
|
|
2172
2271
|
}
|
|
@@ -2180,13 +2279,13 @@ function _isUpperChar(ch) {
|
|
|
2180
2279
|
function _list_module_subdirs(root) {
|
|
2181
2280
|
let entries;
|
|
2182
2281
|
try {
|
|
2183
|
-
entries =
|
|
2282
|
+
entries = fs4.readdirSync(root).sort();
|
|
2184
2283
|
} catch {
|
|
2185
2284
|
return [];
|
|
2186
2285
|
}
|
|
2187
2286
|
const out = [];
|
|
2188
2287
|
for (const name of entries) {
|
|
2189
|
-
if (!_isDir(
|
|
2288
|
+
if (!_isDir(path4.join(root, name))) {
|
|
2190
2289
|
continue;
|
|
2191
2290
|
}
|
|
2192
2291
|
if (name.startsWith(".")) {
|
|
@@ -2208,11 +2307,11 @@ function _score_confidence(stack, root, subdirs) {
|
|
|
2208
2307
|
return capitalized.length > 0 ? "high" : "medium";
|
|
2209
2308
|
}
|
|
2210
2309
|
if (stack === "node-monorepo") {
|
|
2211
|
-
const withPkgJson = subdirs.filter((name) => _isFile(
|
|
2310
|
+
const withPkgJson = subdirs.filter((name) => _isFile(path4.join(root, name, "package.json")));
|
|
2212
2311
|
return withPkgJson.length > 0 ? "high" : "medium";
|
|
2213
2312
|
}
|
|
2214
2313
|
if (stack === "python-src") {
|
|
2215
|
-
const withInit = subdirs.filter((name) => _isFile(
|
|
2314
|
+
const withInit = subdirs.filter((name) => _isFile(path4.join(root, name, "__init__.py")));
|
|
2216
2315
|
return withInit.length > 0 ? "high" : "medium";
|
|
2217
2316
|
}
|
|
2218
2317
|
if (stack === "go-internal") {
|
|
@@ -2224,7 +2323,7 @@ function detect_module_roots(project_root) {
|
|
|
2224
2323
|
const high = [];
|
|
2225
2324
|
const medium = [];
|
|
2226
2325
|
for (const [rel_path, stack, namespace_template] of _RULES) {
|
|
2227
|
-
const abs_path =
|
|
2326
|
+
const abs_path = path4.join(project_root, rel_path);
|
|
2228
2327
|
if (!_isDir(abs_path)) {
|
|
2229
2328
|
continue;
|
|
2230
2329
|
}
|
|
@@ -2246,7 +2345,7 @@ function detect_module_roots(project_root) {
|
|
|
2246
2345
|
}
|
|
2247
2346
|
|
|
2248
2347
|
// src/scripts/_lib/model_tier.ts
|
|
2249
|
-
import
|
|
2348
|
+
import fs5 from "node:fs";
|
|
2250
2349
|
var TIER_TO_CLAUDE_MODEL = {
|
|
2251
2350
|
high: "opus",
|
|
2252
2351
|
medium: "sonnet",
|
|
@@ -2254,8 +2353,8 @@ var TIER_TO_CLAUDE_MODEL = {
|
|
|
2254
2353
|
};
|
|
2255
2354
|
var MODEL_TIER_RE = /^model_tier:\s*"?([a-z]+)"?\s*$/m;
|
|
2256
2355
|
function read_model_tier(skill_md) {
|
|
2257
|
-
if (!
|
|
2258
|
-
const text =
|
|
2356
|
+
if (!fs5.existsSync(skill_md)) return null;
|
|
2357
|
+
const text = fs5.readFileSync(skill_md).toString("utf-8");
|
|
2259
2358
|
if (!text.startsWith("---\n")) return null;
|
|
2260
2359
|
const end = text.indexOf("\n---\n", 4);
|
|
2261
2360
|
if (end === -1) return null;
|
|
@@ -2289,34 +2388,34 @@ var ArgparseExit = class extends Error {
|
|
|
2289
2388
|
function expanduser2(p) {
|
|
2290
2389
|
if (p === "~") return os2.homedir();
|
|
2291
2390
|
if (p.startsWith("~/") || p.startsWith("~\\")) {
|
|
2292
|
-
return
|
|
2391
|
+
return path5.join(os2.homedir(), p.slice(2));
|
|
2293
2392
|
}
|
|
2294
2393
|
return p;
|
|
2295
2394
|
}
|
|
2296
2395
|
function resolvePath(p) {
|
|
2297
2396
|
try {
|
|
2298
|
-
return
|
|
2397
|
+
return fs6.realpathSync(path5.resolve(p));
|
|
2299
2398
|
} catch {
|
|
2300
|
-
return
|
|
2399
|
+
return path5.resolve(p);
|
|
2301
2400
|
}
|
|
2302
2401
|
}
|
|
2303
2402
|
function isFile(p) {
|
|
2304
2403
|
try {
|
|
2305
|
-
return
|
|
2404
|
+
return fs6.statSync(p).isFile();
|
|
2306
2405
|
} catch {
|
|
2307
2406
|
return false;
|
|
2308
2407
|
}
|
|
2309
2408
|
}
|
|
2310
2409
|
function isDir(p) {
|
|
2311
2410
|
try {
|
|
2312
|
-
return
|
|
2411
|
+
return fs6.statSync(p).isDirectory();
|
|
2313
2412
|
} catch {
|
|
2314
2413
|
return false;
|
|
2315
2414
|
}
|
|
2316
2415
|
}
|
|
2317
2416
|
function pathExists(p) {
|
|
2318
2417
|
try {
|
|
2319
|
-
|
|
2418
|
+
fs6.statSync(p);
|
|
2320
2419
|
return true;
|
|
2321
2420
|
} catch {
|
|
2322
2421
|
return false;
|
|
@@ -2324,24 +2423,24 @@ function pathExists(p) {
|
|
|
2324
2423
|
}
|
|
2325
2424
|
function isSymlink(p) {
|
|
2326
2425
|
try {
|
|
2327
|
-
return
|
|
2426
|
+
return fs6.lstatSync(p).isSymbolicLink();
|
|
2328
2427
|
} catch {
|
|
2329
2428
|
return false;
|
|
2330
2429
|
}
|
|
2331
2430
|
}
|
|
2332
2431
|
function readText(p) {
|
|
2333
|
-
return
|
|
2432
|
+
return fs6.readFileSync(p, "utf-8");
|
|
2334
2433
|
}
|
|
2335
2434
|
function writeText(p, content) {
|
|
2336
|
-
|
|
2435
|
+
fs6.writeFileSync(p, content, "utf-8");
|
|
2337
2436
|
}
|
|
2338
2437
|
function mkdirp(p) {
|
|
2339
|
-
|
|
2438
|
+
fs6.mkdirSync(p, { recursive: true });
|
|
2340
2439
|
}
|
|
2341
2440
|
function sortedGlobStems(directory, suffix) {
|
|
2342
2441
|
let entries;
|
|
2343
2442
|
try {
|
|
2344
|
-
entries =
|
|
2443
|
+
entries = fs6.readdirSync(directory);
|
|
2345
2444
|
} catch {
|
|
2346
2445
|
return [];
|
|
2347
2446
|
}
|
|
@@ -2361,7 +2460,7 @@ function sortedGlobStems(directory, suffix) {
|
|
|
2361
2460
|
function countZips(directory) {
|
|
2362
2461
|
if (!isDir(directory)) return 0;
|
|
2363
2462
|
let n = 0;
|
|
2364
|
-
for (const name of
|
|
2463
|
+
for (const name of fs6.readdirSync(directory)) {
|
|
2365
2464
|
if (name.endsWith(".zip")) n += 1;
|
|
2366
2465
|
}
|
|
2367
2466
|
return n;
|
|
@@ -2369,35 +2468,35 @@ function countZips(directory) {
|
|
|
2369
2468
|
function sha256OfFile(p) {
|
|
2370
2469
|
let data;
|
|
2371
2470
|
try {
|
|
2372
|
-
data =
|
|
2471
|
+
data = fs6.readFileSync(p);
|
|
2373
2472
|
} catch {
|
|
2374
2473
|
return null;
|
|
2375
2474
|
}
|
|
2376
2475
|
return crypto3.createHash("sha256").update(data).digest("hex");
|
|
2377
2476
|
}
|
|
2378
2477
|
function atomicWrite0644(target, body, prefix) {
|
|
2379
|
-
const dir =
|
|
2380
|
-
const tmpName =
|
|
2478
|
+
const dir = path5.dirname(target);
|
|
2479
|
+
const tmpName = path5.join(
|
|
2381
2480
|
dir,
|
|
2382
2481
|
`${prefix}${process2.pid}.${crypto3.randomBytes(6).toString("hex")}.yml.tmp`
|
|
2383
2482
|
);
|
|
2384
2483
|
let fd = null;
|
|
2385
2484
|
try {
|
|
2386
|
-
fd =
|
|
2387
|
-
|
|
2388
|
-
|
|
2485
|
+
fd = fs6.openSync(tmpName, "wx", 420);
|
|
2486
|
+
fs6.writeFileSync(fd, body, "utf-8");
|
|
2487
|
+
fs6.closeSync(fd);
|
|
2389
2488
|
fd = null;
|
|
2390
|
-
|
|
2391
|
-
|
|
2489
|
+
fs6.chmodSync(tmpName, 420);
|
|
2490
|
+
fs6.renameSync(tmpName, target);
|
|
2392
2491
|
} catch (err) {
|
|
2393
2492
|
if (fd !== null) {
|
|
2394
2493
|
try {
|
|
2395
|
-
|
|
2494
|
+
fs6.closeSync(fd);
|
|
2396
2495
|
} catch {
|
|
2397
2496
|
}
|
|
2398
2497
|
}
|
|
2399
2498
|
try {
|
|
2400
|
-
|
|
2499
|
+
fs6.unlinkSync(tmpName);
|
|
2401
2500
|
} catch {
|
|
2402
2501
|
}
|
|
2403
2502
|
throw err;
|
|
@@ -2521,12 +2620,12 @@ var LEGACY_SETTINGS_FILE = ".agent-settings";
|
|
|
2521
2620
|
var LEGACY_BACKUP_FILE = ".agent-settings.backup.key-value";
|
|
2522
2621
|
var SETTINGS_SUBDIR = ["agents", "settings"];
|
|
2523
2622
|
function _canonical_settings_target(project_root) {
|
|
2524
|
-
return
|
|
2623
|
+
return path5.join(project_root, ...SETTINGS_SUBDIR, SETTINGS_FILE);
|
|
2525
2624
|
}
|
|
2526
2625
|
function _resolve_settings_read(project_root) {
|
|
2527
2626
|
const canonical = _canonical_settings_target(project_root);
|
|
2528
2627
|
if (pathExists(canonical)) return canonical;
|
|
2529
|
-
const legacy =
|
|
2628
|
+
const legacy = path5.join(project_root, SETTINGS_FILE);
|
|
2530
2629
|
if (pathExists(legacy)) return legacy;
|
|
2531
2630
|
return canonical;
|
|
2532
2631
|
}
|
|
@@ -2590,9 +2689,9 @@ function fail(msg) {
|
|
|
2590
2689
|
throw new SystemExitError(1);
|
|
2591
2690
|
}
|
|
2592
2691
|
function detect_package_root(project_root) {
|
|
2593
|
-
const npm_path =
|
|
2692
|
+
const npm_path = path5.join(project_root, "node_modules", "@event4u", "agent-config");
|
|
2594
2693
|
if (isDir(npm_path)) return resolvePath(npm_path);
|
|
2595
|
-
if (pathExists(
|
|
2694
|
+
if (pathExists(path5.join(project_root, "src", "config", "profiles", "minimal.ini"))) {
|
|
2596
2695
|
return project_root;
|
|
2597
2696
|
}
|
|
2598
2697
|
fail(
|
|
@@ -2600,12 +2699,12 @@ function detect_package_root(project_root) {
|
|
|
2600
2699
|
);
|
|
2601
2700
|
}
|
|
2602
2701
|
function detect_package_type(package_root) {
|
|
2603
|
-
if (package_root.split(
|
|
2702
|
+
if (package_root.split(path5.sep).includes("node_modules")) return "npm";
|
|
2604
2703
|
return "local";
|
|
2605
2704
|
}
|
|
2606
2705
|
function detect_package_type_for_project(project_root, package_root) {
|
|
2607
2706
|
const npm_path = resolvePath(
|
|
2608
|
-
|
|
2707
|
+
path5.join(project_root, "node_modules", "@event4u", "agent-config")
|
|
2609
2708
|
);
|
|
2610
2709
|
const package_resolved = resolvePath(package_root);
|
|
2611
2710
|
if (package_resolved === npm_path) return "npm";
|
|
@@ -2625,7 +2724,7 @@ function ensure_directory(p) {
|
|
|
2625
2724
|
mkdirp(p);
|
|
2626
2725
|
}
|
|
2627
2726
|
function write_file(p, content) {
|
|
2628
|
-
ensure_directory(
|
|
2727
|
+
ensure_directory(path5.dirname(p));
|
|
2629
2728
|
writeText(p, content);
|
|
2630
2729
|
}
|
|
2631
2730
|
function read_json_file(p) {
|
|
@@ -2796,7 +2895,7 @@ function _append_unknown_legacy(rendered, legacy_values, unknown_keys) {
|
|
|
2796
2895
|
return rendered + "\n" + suffix;
|
|
2797
2896
|
}
|
|
2798
2897
|
function _migrate_legacy_if_present(project_root, template_body) {
|
|
2799
|
-
const legacy_target =
|
|
2898
|
+
const legacy_target = path5.join(project_root, LEGACY_SETTINGS_FILE);
|
|
2800
2899
|
if (!isFile(legacy_target)) return null;
|
|
2801
2900
|
const legacy_text = readText(legacy_target);
|
|
2802
2901
|
const [values, unknown] = _parse_legacy_settings(legacy_text);
|
|
@@ -2811,9 +2910,9 @@ function _migrate_legacy_if_present(project_root, template_body) {
|
|
|
2811
2910
|
}
|
|
2812
2911
|
}
|
|
2813
2912
|
rendered = _append_unknown_legacy(rendered, values, unknown);
|
|
2814
|
-
const backup_target =
|
|
2913
|
+
const backup_target = path5.join(project_root, LEGACY_BACKUP_FILE);
|
|
2815
2914
|
writeText(backup_target, legacy_text);
|
|
2816
|
-
|
|
2915
|
+
fs6.unlinkSync(legacy_target);
|
|
2817
2916
|
info(`Migrated legacy ${LEGACY_SETTINGS_FILE} \u2192 ${SETTINGS_FILE}`);
|
|
2818
2917
|
info(`Backup saved to ${LEGACY_BACKUP_FILE}`);
|
|
2819
2918
|
if (unknown.length > 0) {
|
|
@@ -2848,7 +2947,7 @@ function _render_template(template, profile_values) {
|
|
|
2848
2947
|
return body;
|
|
2849
2948
|
}
|
|
2850
2949
|
function _load_valid_user_types(package_root) {
|
|
2851
|
-
const directory =
|
|
2950
|
+
const directory = path5.join(package_root, USER_TYPES_DIR);
|
|
2852
2951
|
if (!isDir(directory)) return [];
|
|
2853
2952
|
return sortedGlobStems(directory, ".yml");
|
|
2854
2953
|
}
|
|
@@ -2905,8 +3004,8 @@ function splitlinesKeepends(text) {
|
|
|
2905
3004
|
}
|
|
2906
3005
|
function ensure_agent_settings(project_root, package_root, profile, force, user_type = "", packs = null) {
|
|
2907
3006
|
const target = _canonical_settings_target(project_root);
|
|
2908
|
-
const profile_source =
|
|
2909
|
-
const template_source =
|
|
3007
|
+
const profile_source = path5.join(package_root, "src", "config", "profiles", `${profile}.ini`);
|
|
3008
|
+
const template_source = path5.join(package_root, "src", "config", "agent-settings.template.yml");
|
|
2910
3009
|
if (!pathExists(profile_source)) fail(`Missing profile preset: ${profile_source}`);
|
|
2911
3010
|
if (!pathExists(template_source)) fail(`Missing settings template: ${template_source}`);
|
|
2912
3011
|
const template = readText(template_source);
|
|
@@ -2920,21 +3019,21 @@ function ensure_agent_settings(project_root, package_root, profile, force, user_
|
|
|
2920
3019
|
if (profile_values["rule_loading_tier"] !== profile) {
|
|
2921
3020
|
const got = "rule_loading_tier" in profile_values ? `'${profile_values["rule_loading_tier"]}'` : "None";
|
|
2922
3021
|
fail(
|
|
2923
|
-
`Profile preset ${
|
|
3022
|
+
`Profile preset ${path5.basename(profile_source)} has rule_loading_tier=${got} but --profile=${profile}`
|
|
2924
3023
|
);
|
|
2925
3024
|
}
|
|
2926
3025
|
profile_values["user_type"] = _validate_user_type(package_root, user_type);
|
|
2927
3026
|
let template_body = _render_template(template, profile_values);
|
|
2928
3027
|
template_body = _inject_packs(template_body, packs ?? []);
|
|
2929
|
-
const legacy_root =
|
|
3028
|
+
const legacy_root = path5.join(project_root, SETTINGS_FILE);
|
|
2930
3029
|
if (isFile(legacy_root) && !pathExists(target)) {
|
|
2931
|
-
mkdirp(
|
|
3030
|
+
mkdirp(path5.dirname(target));
|
|
2932
3031
|
writeText(target, readText(legacy_root));
|
|
2933
|
-
|
|
3032
|
+
fs6.unlinkSync(legacy_root);
|
|
2934
3033
|
success(`Migrated ${SETTINGS_FILE} \u2192 agents/settings/${SETTINGS_FILE} (ADR-038)`);
|
|
2935
3034
|
return;
|
|
2936
3035
|
}
|
|
2937
|
-
const legacy_target =
|
|
3036
|
+
const legacy_target = path5.join(project_root, LEGACY_SETTINGS_FILE);
|
|
2938
3037
|
if (isFile(legacy_target) && pathExists(target)) {
|
|
2939
3038
|
warn(
|
|
2940
3039
|
`Both ${SETTINGS_FILE} and legacy ${LEGACY_SETTINGS_FILE} exist. Skipping migration to avoid overwriting ${SETTINGS_FILE}. Delete one of them manually and re-run.`
|
|
@@ -2951,7 +3050,7 @@ function ensure_agent_settings(project_root, package_root, profile, force, user_
|
|
|
2951
3050
|
skip(`${SETTINGS_FILE} already exists`);
|
|
2952
3051
|
return;
|
|
2953
3052
|
}
|
|
2954
|
-
mkdirp(
|
|
3053
|
+
mkdirp(path5.dirname(target));
|
|
2955
3054
|
write_file(target, template_body);
|
|
2956
3055
|
const user_type_value = profile_values["user_type"] ?? "";
|
|
2957
3056
|
const suffix = user_type_value ? `, user_type=${user_type_value}` : "";
|
|
@@ -2964,7 +3063,7 @@ function ensure_vscode_bridge(project_root, package_type, force) {
|
|
|
2964
3063
|
const plugin_path = plugin_paths[package_type] ?? "./plugin/agent-config";
|
|
2965
3064
|
const bridge = { "chat.pluginLocations": { [plugin_path]: true } };
|
|
2966
3065
|
merge_json_file(
|
|
2967
|
-
|
|
3066
|
+
path5.join(project_root, ".vscode", "settings.json"),
|
|
2968
3067
|
bridge,
|
|
2969
3068
|
force,
|
|
2970
3069
|
".vscode/settings.json"
|
|
@@ -2973,14 +3072,14 @@ function ensure_vscode_bridge(project_root, package_type, force) {
|
|
|
2973
3072
|
function ensure_augment_bridge(project_root, force) {
|
|
2974
3073
|
const bridge = { enabledPlugins: { "agent-config@event4u": true } };
|
|
2975
3074
|
return merge_json_file(
|
|
2976
|
-
|
|
3075
|
+
path5.join(project_root, ".augment", "settings.json"),
|
|
2977
3076
|
bridge,
|
|
2978
3077
|
force,
|
|
2979
3078
|
".augment/settings.json"
|
|
2980
3079
|
);
|
|
2981
3080
|
}
|
|
2982
|
-
var AUGMENT_USER_DIR =
|
|
2983
|
-
var AUGMENT_USER_HOOKS_DIR =
|
|
3081
|
+
var AUGMENT_USER_DIR = path5.join(os2.homedir(), ".augment");
|
|
3082
|
+
var AUGMENT_USER_HOOKS_DIR = path5.join(AUGMENT_USER_DIR, "hooks");
|
|
2984
3083
|
var AUGMENT_DISPATCHER_TRAMPOLINE = "augment-dispatcher.sh";
|
|
2985
3084
|
var AUGMENT_LEGACY_TRAMPOLINES = [
|
|
2986
3085
|
"augment-chat-history.sh",
|
|
@@ -2996,29 +3095,29 @@ var AUGMENT_DISPATCHER_BINDINGS = [
|
|
|
2996
3095
|
["post_tool_use", "PostToolUse"]
|
|
2997
3096
|
];
|
|
2998
3097
|
function _deploy_augment_trampoline(package_root, name, force) {
|
|
2999
|
-
const src =
|
|
3098
|
+
const src = path5.join(package_root, "scripts", "hooks", name);
|
|
3000
3099
|
if (!pathExists(src)) {
|
|
3001
3100
|
skip(`augment trampoline missing in package: ${src}`);
|
|
3002
3101
|
return null;
|
|
3003
3102
|
}
|
|
3004
3103
|
mkdirp(AUGMENT_USER_HOOKS_DIR);
|
|
3005
|
-
const dst =
|
|
3104
|
+
const dst = path5.join(AUGMENT_USER_HOOKS_DIR, name);
|
|
3006
3105
|
const src_text = readText(src);
|
|
3007
3106
|
if (pathExists(dst) && readText(dst) === src_text && !force) {
|
|
3008
3107
|
skip(`~/.augment/hooks/${name} already up to date`);
|
|
3009
3108
|
} else {
|
|
3010
3109
|
writeText(dst, src_text);
|
|
3011
|
-
|
|
3110
|
+
fs6.chmodSync(dst, 493);
|
|
3012
3111
|
success(`~/.augment/hooks/${name} installed`);
|
|
3013
3112
|
}
|
|
3014
3113
|
return dst;
|
|
3015
3114
|
}
|
|
3016
3115
|
function _remove_legacy_augment_trampolines() {
|
|
3017
3116
|
for (const name of AUGMENT_LEGACY_TRAMPOLINES) {
|
|
3018
|
-
const legacy =
|
|
3117
|
+
const legacy = path5.join(AUGMENT_USER_HOOKS_DIR, name);
|
|
3019
3118
|
try {
|
|
3020
3119
|
if (isFile(legacy)) {
|
|
3021
|
-
|
|
3120
|
+
fs6.unlinkSync(legacy);
|
|
3022
3121
|
skip(`removed legacy ~/.augment/hooks/${name}`);
|
|
3023
3122
|
}
|
|
3024
3123
|
} catch {
|
|
@@ -3037,7 +3136,7 @@ function ensure_augment_user_hooks(package_root, force) {
|
|
|
3037
3136
|
}
|
|
3038
3137
|
const settings_patch = { hooks: per_event };
|
|
3039
3138
|
return merge_json_file(
|
|
3040
|
-
|
|
3139
|
+
path5.join(AUGMENT_USER_DIR, "settings.json"),
|
|
3041
3140
|
settings_patch,
|
|
3042
3141
|
force,
|
|
3043
3142
|
"~/.augment/settings.json"
|
|
@@ -3062,7 +3161,7 @@ function _heal_legacy_claude_plugin_ids(p) {
|
|
|
3062
3161
|
return removed;
|
|
3063
3162
|
}
|
|
3064
3163
|
function ensure_claude_bridge(project_root, force) {
|
|
3065
|
-
const target =
|
|
3164
|
+
const target = path5.join(project_root, ".claude", "settings.json");
|
|
3066
3165
|
const healed = _heal_legacy_claude_plugin_ids(target);
|
|
3067
3166
|
for (const pid of healed) {
|
|
3068
3167
|
success(`.claude/settings.json: removed stale plugin id \`${pid}\``);
|
|
@@ -3087,29 +3186,29 @@ function ensure_cursor_bridge(project_root, force) {
|
|
|
3087
3186
|
}
|
|
3088
3187
|
const bridge = { version: 1, hooks };
|
|
3089
3188
|
return merge_json_file(
|
|
3090
|
-
|
|
3189
|
+
path5.join(project_root, ".cursor", "hooks.json"),
|
|
3091
3190
|
bridge,
|
|
3092
3191
|
force,
|
|
3093
3192
|
".cursor/hooks.json"
|
|
3094
3193
|
);
|
|
3095
3194
|
}
|
|
3096
|
-
var CURSOR_USER_DIR =
|
|
3097
|
-
var CURSOR_USER_HOOKS_DIR =
|
|
3195
|
+
var CURSOR_USER_DIR = path5.join(os2.homedir(), ".cursor");
|
|
3196
|
+
var CURSOR_USER_HOOKS_DIR = path5.join(CURSOR_USER_DIR, "hooks");
|
|
3098
3197
|
var CURSOR_DISPATCHER_TRAMPOLINE = "cursor-dispatcher.sh";
|
|
3099
3198
|
function ensure_cursor_user_hooks(package_root, force) {
|
|
3100
|
-
const src =
|
|
3199
|
+
const src = path5.join(package_root, "scripts", "hooks", CURSOR_DISPATCHER_TRAMPOLINE);
|
|
3101
3200
|
if (!pathExists(src)) {
|
|
3102
3201
|
skip(`cursor trampoline missing in package: ${src}`);
|
|
3103
3202
|
return [];
|
|
3104
3203
|
}
|
|
3105
3204
|
mkdirp(CURSOR_USER_HOOKS_DIR);
|
|
3106
|
-
const dst =
|
|
3205
|
+
const dst = path5.join(CURSOR_USER_HOOKS_DIR, CURSOR_DISPATCHER_TRAMPOLINE);
|
|
3107
3206
|
const src_text = readText(src);
|
|
3108
3207
|
if (pathExists(dst) && readText(dst) === src_text && !force) {
|
|
3109
3208
|
skip(`~/.cursor/hooks/${CURSOR_DISPATCHER_TRAMPOLINE} already up to date`);
|
|
3110
3209
|
} else {
|
|
3111
3210
|
writeText(dst, src_text);
|
|
3112
|
-
|
|
3211
|
+
fs6.chmodSync(dst, 493);
|
|
3113
3212
|
success(`~/.cursor/hooks/${CURSOR_DISPATCHER_TRAMPOLINE} installed`);
|
|
3114
3213
|
}
|
|
3115
3214
|
const hooks = {};
|
|
@@ -3118,7 +3217,7 @@ function ensure_cursor_user_hooks(package_root, force) {
|
|
|
3118
3217
|
}
|
|
3119
3218
|
const settings_patch = { version: 1, hooks };
|
|
3120
3219
|
return merge_json_file(
|
|
3121
|
-
|
|
3220
|
+
path5.join(CURSOR_USER_DIR, "hooks.json"),
|
|
3122
3221
|
settings_patch,
|
|
3123
3222
|
force,
|
|
3124
3223
|
"~/.cursor/hooks.json"
|
|
@@ -3161,12 +3260,12 @@ exit 0
|
|
|
3161
3260
|
`;
|
|
3162
3261
|
}
|
|
3163
3262
|
function ensure_cline_bridge(project_root, force) {
|
|
3164
|
-
const hooks_dir =
|
|
3263
|
+
const hooks_dir = path5.join(project_root, ".clinerules", "hooks");
|
|
3165
3264
|
mkdirp(hooks_dir);
|
|
3166
3265
|
const workspace_quoted = shlexQuote(resolvePath(project_root));
|
|
3167
3266
|
let written = 0;
|
|
3168
3267
|
for (const [ac_event, native_event] of CLINE_DISPATCHER_BINDINGS) {
|
|
3169
|
-
const target =
|
|
3268
|
+
const target = path5.join(hooks_dir, native_event);
|
|
3170
3269
|
const body = clineProjectHookBody(native_event, ac_event, workspace_quoted);
|
|
3171
3270
|
if (pathExists(target) && readText(target) === body && !force) {
|
|
3172
3271
|
continue;
|
|
@@ -3176,7 +3275,7 @@ function ensure_cline_bridge(project_root, force) {
|
|
|
3176
3275
|
continue;
|
|
3177
3276
|
}
|
|
3178
3277
|
writeText(target, body);
|
|
3179
|
-
|
|
3278
|
+
fs6.chmodSync(target, 493);
|
|
3180
3279
|
written += 1;
|
|
3181
3280
|
}
|
|
3182
3281
|
if (written) {
|
|
@@ -3185,27 +3284,27 @@ function ensure_cline_bridge(project_root, force) {
|
|
|
3185
3284
|
skip(".clinerules/hooks/ already up to date");
|
|
3186
3285
|
}
|
|
3187
3286
|
}
|
|
3188
|
-
var CLINE_USER_DIR =
|
|
3287
|
+
var CLINE_USER_DIR = path5.join(os2.homedir(), "Documents", "Cline", "Hooks");
|
|
3189
3288
|
var CLINE_DISPATCHER_TRAMPOLINE = "cline-dispatcher.sh";
|
|
3190
3289
|
function ensure_cline_user_hooks(package_root, force) {
|
|
3191
|
-
const src =
|
|
3290
|
+
const src = path5.join(package_root, "scripts", "hooks", CLINE_DISPATCHER_TRAMPOLINE);
|
|
3192
3291
|
if (!pathExists(src)) {
|
|
3193
3292
|
skip(`cline trampoline missing in package: ${src}`);
|
|
3194
3293
|
return;
|
|
3195
3294
|
}
|
|
3196
3295
|
mkdirp(CLINE_USER_DIR);
|
|
3197
|
-
const trampoline =
|
|
3296
|
+
const trampoline = path5.join(CLINE_USER_DIR, CLINE_DISPATCHER_TRAMPOLINE);
|
|
3198
3297
|
const src_text = readText(src);
|
|
3199
3298
|
if (pathExists(trampoline) && readText(trampoline) === src_text && !force) {
|
|
3200
3299
|
skip(`~/Documents/Cline/Hooks/${CLINE_DISPATCHER_TRAMPOLINE} already up to date`);
|
|
3201
3300
|
} else {
|
|
3202
3301
|
writeText(trampoline, src_text);
|
|
3203
|
-
|
|
3302
|
+
fs6.chmodSync(trampoline, 493);
|
|
3204
3303
|
success(`~/Documents/Cline/Hooks/${CLINE_DISPATCHER_TRAMPOLINE} installed`);
|
|
3205
3304
|
}
|
|
3206
3305
|
const trampoline_quoted = shlexQuote(trampoline);
|
|
3207
3306
|
for (const [ac_event, native_event] of CLINE_DISPATCHER_BINDINGS) {
|
|
3208
|
-
const wrapper =
|
|
3307
|
+
const wrapper = path5.join(CLINE_USER_DIR, native_event);
|
|
3209
3308
|
const body = `#!/usr/bin/env bash
|
|
3210
3309
|
# Generated by event4u/agent-config install.py \u2014 DO NOT EDIT.
|
|
3211
3310
|
# User-scope Cline hook for ${native_event} \u2192 agent-config ${ac_event}.
|
|
@@ -3215,7 +3314,7 @@ exec ${trampoline_quoted} ${ac_event} ${native_event}
|
|
|
3215
3314
|
continue;
|
|
3216
3315
|
}
|
|
3217
3316
|
writeText(wrapper, body);
|
|
3218
|
-
|
|
3317
|
+
fs6.chmodSync(wrapper, 493);
|
|
3219
3318
|
}
|
|
3220
3319
|
}
|
|
3221
3320
|
var WINDSURF_DISPATCHER_BINDINGS = [
|
|
@@ -3236,29 +3335,29 @@ function ensure_windsurf_bridge(project_root, force) {
|
|
|
3236
3335
|
}
|
|
3237
3336
|
const bridge = { hooks };
|
|
3238
3337
|
return merge_json_file(
|
|
3239
|
-
|
|
3338
|
+
path5.join(project_root, ".windsurf", "hooks.json"),
|
|
3240
3339
|
bridge,
|
|
3241
3340
|
force,
|
|
3242
3341
|
".windsurf/hooks.json"
|
|
3243
3342
|
);
|
|
3244
3343
|
}
|
|
3245
|
-
var WINDSURF_USER_DIR =
|
|
3246
|
-
var WINDSURF_USER_HOOKS_DIR =
|
|
3344
|
+
var WINDSURF_USER_DIR = path5.join(os2.homedir(), ".codeium", "windsurf");
|
|
3345
|
+
var WINDSURF_USER_HOOKS_DIR = path5.join(WINDSURF_USER_DIR, "hooks");
|
|
3247
3346
|
var WINDSURF_DISPATCHER_TRAMPOLINE = "windsurf-dispatcher.sh";
|
|
3248
3347
|
function ensure_windsurf_user_hooks(package_root, force) {
|
|
3249
|
-
const src =
|
|
3348
|
+
const src = path5.join(package_root, "scripts", "hooks", WINDSURF_DISPATCHER_TRAMPOLINE);
|
|
3250
3349
|
if (!pathExists(src)) {
|
|
3251
3350
|
skip(`windsurf trampoline missing in package: ${src}`);
|
|
3252
3351
|
return [];
|
|
3253
3352
|
}
|
|
3254
3353
|
mkdirp(WINDSURF_USER_HOOKS_DIR);
|
|
3255
|
-
const dst =
|
|
3354
|
+
const dst = path5.join(WINDSURF_USER_HOOKS_DIR, WINDSURF_DISPATCHER_TRAMPOLINE);
|
|
3256
3355
|
const src_text = readText(src);
|
|
3257
3356
|
if (pathExists(dst) && readText(dst) === src_text && !force) {
|
|
3258
3357
|
skip(`~/.codeium/windsurf/hooks/${WINDSURF_DISPATCHER_TRAMPOLINE} already up to date`);
|
|
3259
3358
|
} else {
|
|
3260
3359
|
writeText(dst, src_text);
|
|
3261
|
-
|
|
3360
|
+
fs6.chmodSync(dst, 493);
|
|
3262
3361
|
success(`~/.codeium/windsurf/hooks/${WINDSURF_DISPATCHER_TRAMPOLINE} installed`);
|
|
3263
3362
|
}
|
|
3264
3363
|
const hooks = {};
|
|
@@ -3270,7 +3369,7 @@ function ensure_windsurf_user_hooks(package_root, force) {
|
|
|
3270
3369
|
}
|
|
3271
3370
|
const settings_patch = { hooks };
|
|
3272
3371
|
return merge_json_file(
|
|
3273
|
-
|
|
3372
|
+
path5.join(WINDSURF_USER_DIR, "hooks.json"),
|
|
3274
3373
|
settings_patch,
|
|
3275
3374
|
force,
|
|
3276
3375
|
"~/.codeium/windsurf/hooks.json"
|
|
@@ -3299,43 +3398,43 @@ function _gemini_hooks_dict(command_factory) {
|
|
|
3299
3398
|
function ensure_gemini_bridge(project_root, force) {
|
|
3300
3399
|
const bridge = { hooks: _gemini_hooks_dict(_gemini_dispatch_command) };
|
|
3301
3400
|
return merge_json_file(
|
|
3302
|
-
|
|
3401
|
+
path5.join(project_root, ".gemini", "settings.json"),
|
|
3303
3402
|
bridge,
|
|
3304
3403
|
force,
|
|
3305
3404
|
".gemini/settings.json"
|
|
3306
3405
|
);
|
|
3307
3406
|
}
|
|
3308
|
-
var GEMINI_USER_DIR =
|
|
3309
|
-
var GEMINI_USER_HOOKS_DIR =
|
|
3407
|
+
var GEMINI_USER_DIR = path5.join(os2.homedir(), ".gemini");
|
|
3408
|
+
var GEMINI_USER_HOOKS_DIR = path5.join(GEMINI_USER_DIR, "hooks");
|
|
3310
3409
|
var GEMINI_DISPATCHER_TRAMPOLINE = "gemini-dispatcher.sh";
|
|
3311
3410
|
function ensure_gemini_user_hooks(package_root, force) {
|
|
3312
|
-
const src =
|
|
3411
|
+
const src = path5.join(package_root, "scripts", "hooks", GEMINI_DISPATCHER_TRAMPOLINE);
|
|
3313
3412
|
if (!pathExists(src)) {
|
|
3314
3413
|
skip(`gemini trampoline missing in package: ${src}`);
|
|
3315
3414
|
return [];
|
|
3316
3415
|
}
|
|
3317
3416
|
mkdirp(GEMINI_USER_HOOKS_DIR);
|
|
3318
|
-
const dst =
|
|
3417
|
+
const dst = path5.join(GEMINI_USER_HOOKS_DIR, GEMINI_DISPATCHER_TRAMPOLINE);
|
|
3319
3418
|
const src_text = readText(src);
|
|
3320
3419
|
if (pathExists(dst) && readText(dst) === src_text && !force) {
|
|
3321
3420
|
skip(`~/.gemini/hooks/${GEMINI_DISPATCHER_TRAMPOLINE} already up to date`);
|
|
3322
3421
|
} else {
|
|
3323
3422
|
writeText(dst, src_text);
|
|
3324
|
-
|
|
3423
|
+
fs6.chmodSync(dst, 493);
|
|
3325
3424
|
success(`~/.gemini/hooks/${GEMINI_DISPATCHER_TRAMPOLINE} installed`);
|
|
3326
3425
|
}
|
|
3327
3426
|
const settings_patch = {
|
|
3328
3427
|
hooks: _gemini_hooks_dict((ac_event, native) => `${dst} ${ac_event} ${native}`)
|
|
3329
3428
|
};
|
|
3330
3429
|
return merge_json_file(
|
|
3331
|
-
|
|
3430
|
+
path5.join(GEMINI_USER_DIR, "settings.json"),
|
|
3332
3431
|
settings_patch,
|
|
3333
3432
|
force,
|
|
3334
3433
|
"~/.gemini/settings.json"
|
|
3335
3434
|
);
|
|
3336
3435
|
}
|
|
3337
3436
|
function ensure_copilot_bridge(project_root, force) {
|
|
3338
|
-
const target =
|
|
3437
|
+
const target = path5.join(project_root, ".github", "plugin", "marketplace.json");
|
|
3339
3438
|
const bridge = {
|
|
3340
3439
|
marketplace: {
|
|
3341
3440
|
name: "event4u-agent-marketplace",
|
|
@@ -3378,7 +3477,7 @@ See \`docs/setup/per-ide/roocode.md\` for the full activation guide.
|
|
|
3378
3477
|
Run \`./agent-config --help\` for available commands.
|
|
3379
3478
|
`;
|
|
3380
3479
|
function ensure_roocode_bridge(project_root, force) {
|
|
3381
|
-
const target =
|
|
3480
|
+
const target = path5.join(project_root, ".roo", "rules", "agent-config.md");
|
|
3382
3481
|
if (pathExists(target) && !force) {
|
|
3383
3482
|
skip(".roo/rules/agent-config.md already exists");
|
|
3384
3483
|
return;
|
|
@@ -3400,7 +3499,7 @@ To wire Claude Desktop to this project's rules, run:
|
|
|
3400
3499
|
Canonical rule and skill source: \`.augment/\` (see \`AGENTS.md\`).
|
|
3401
3500
|
`;
|
|
3402
3501
|
function ensure_claude_desktop_bridge(project_root, force) {
|
|
3403
|
-
const target =
|
|
3502
|
+
const target = path5.join(project_root, ".claude-desktop", "agent-config.md");
|
|
3404
3503
|
if (pathExists(target) && !force) {
|
|
3405
3504
|
skip(".claude-desktop/agent-config.md already exists");
|
|
3406
3505
|
return;
|
|
@@ -3425,7 +3524,7 @@ Or pass \`--read .aider/agent-config.md\` on the command line.
|
|
|
3425
3524
|
Canonical rule and skill source: \`.augment/\` (see \`AGENTS.md\`).
|
|
3426
3525
|
`;
|
|
3427
3526
|
function ensure_aider_bridge(project_root, force) {
|
|
3428
|
-
const target =
|
|
3527
|
+
const target = path5.join(project_root, ".aider", "agent-config.md");
|
|
3429
3528
|
if (pathExists(target) && !force) {
|
|
3430
3529
|
skip(".aider/agent-config.md already exists");
|
|
3431
3530
|
return;
|
|
@@ -3444,7 +3543,7 @@ developers where the rules and skills live.
|
|
|
3444
3543
|
Canonical rule and skill source: \`.augment/\` (see project \`AGENTS.md\`).
|
|
3445
3544
|
`;
|
|
3446
3545
|
function ensure_codex_bridge(project_root, force) {
|
|
3447
|
-
const target =
|
|
3546
|
+
const target = path5.join(project_root, ".codex", "agent-config.md");
|
|
3448
3547
|
if (pathExists(target) && !force) {
|
|
3449
3548
|
skip(".codex/agent-config.md already exists");
|
|
3450
3549
|
return;
|
|
@@ -3462,7 +3561,7 @@ rules per session. The canonical rule and skill source lives under
|
|
|
3462
3561
|
orientation).
|
|
3463
3562
|
`;
|
|
3464
3563
|
function ensure_continue_bridge(project_root, force) {
|
|
3465
|
-
const target =
|
|
3564
|
+
const target = path5.join(project_root, ".continue", "rules", "agent-config.md");
|
|
3466
3565
|
if (pathExists(target) && !force) {
|
|
3467
3566
|
skip(".continue/rules/agent-config.md already exists");
|
|
3468
3567
|
return;
|
|
@@ -3493,7 +3592,7 @@ orientation).
|
|
|
3493
3592
|
See \`docs/setup/per-ide/kilocode.md\` for the full activation guide.
|
|
3494
3593
|
`;
|
|
3495
3594
|
function ensure_kilocode_bridge(project_root, force) {
|
|
3496
|
-
const target =
|
|
3595
|
+
const target = path5.join(project_root, ".kilocode", "rules", "agent-config.md");
|
|
3497
3596
|
if (pathExists(target) && !force) {
|
|
3498
3597
|
skip(".kilocode/rules/agent-config.md already exists");
|
|
3499
3598
|
return;
|
|
@@ -3520,7 +3619,7 @@ canonical source (or symlink it):
|
|
|
3520
3619
|
Canonical rule and skill source: \`.augment/\` (see \`AGENTS.md\`).
|
|
3521
3620
|
`;
|
|
3522
3621
|
function ensure_zed_bridge(project_root, force) {
|
|
3523
|
-
const target =
|
|
3622
|
+
const target = path5.join(project_root, ".zed", "agent-config.md");
|
|
3524
3623
|
if (pathExists(target) && !force) {
|
|
3525
3624
|
skip(".zed/agent-config.md already exists");
|
|
3526
3625
|
return;
|
|
@@ -3541,7 +3640,7 @@ rules into your JetBrains profile.
|
|
|
3541
3640
|
Canonical rule and skill source: \`.augment/\` (see \`AGENTS.md\`).
|
|
3542
3641
|
`;
|
|
3543
3642
|
function ensure_jetbrains_bridge(project_root, force) {
|
|
3544
|
-
const target =
|
|
3643
|
+
const target = path5.join(project_root, ".jetbrains", "agent-config.md");
|
|
3545
3644
|
if (pathExists(target) && !force) {
|
|
3546
3645
|
skip(".jetbrains/agent-config.md already exists");
|
|
3547
3646
|
return;
|
|
@@ -3572,7 +3671,7 @@ session. The canonical rule and skill source lives under \`.augment/\`
|
|
|
3572
3671
|
See \`docs/setup/per-ide/kiro.md\` for the full activation guide.
|
|
3573
3672
|
`;
|
|
3574
3673
|
function ensure_kiro_bridge(project_root, force) {
|
|
3575
|
-
const target =
|
|
3674
|
+
const target = path5.join(project_root, ".kiro", "steering", "agent-config.md");
|
|
3576
3675
|
if (pathExists(target) && !force) {
|
|
3577
3676
|
skip(".kiro/steering/agent-config.md already exists");
|
|
3578
3677
|
return;
|
|
@@ -3598,35 +3697,35 @@ var SMOKE_BRIDGE_PATHS = {
|
|
|
3598
3697
|
};
|
|
3599
3698
|
function dirHasEntries(p) {
|
|
3600
3699
|
try {
|
|
3601
|
-
return
|
|
3700
|
+
return fs6.readdirSync(p).length > 0;
|
|
3602
3701
|
} catch {
|
|
3603
3702
|
return false;
|
|
3604
3703
|
}
|
|
3605
3704
|
}
|
|
3606
3705
|
function _resolve_tsx_invocation(scriptPath, scriptArgs) {
|
|
3607
3706
|
const binName = process2.platform === "win32" ? "tsx.cmd" : "tsx";
|
|
3608
|
-
let dir =
|
|
3707
|
+
let dir = path5.dirname(scriptPath);
|
|
3609
3708
|
for (; ; ) {
|
|
3610
|
-
const candidate =
|
|
3709
|
+
const candidate = path5.join(dir, "node_modules", ".bin", binName);
|
|
3611
3710
|
if (isFile(candidate)) {
|
|
3612
3711
|
return { command: candidate, args: [scriptPath, ...scriptArgs] };
|
|
3613
3712
|
}
|
|
3614
|
-
const parent =
|
|
3713
|
+
const parent = path5.dirname(dir);
|
|
3615
3714
|
if (parent === dir) break;
|
|
3616
3715
|
dir = parent;
|
|
3617
3716
|
}
|
|
3618
3717
|
return { command: "npx", args: ["tsx", scriptPath, ...scriptArgs] };
|
|
3619
3718
|
}
|
|
3620
3719
|
function _smoke_test_hooks(project_root, package_root) {
|
|
3621
|
-
const dispatcher =
|
|
3622
|
-
const manifest =
|
|
3720
|
+
const dispatcher = path5.join(package_root, "scripts", "hooks", "dispatch_hook.ts");
|
|
3721
|
+
const manifest = path5.join(package_root, "scripts", "hook_manifest.yaml");
|
|
3623
3722
|
if (!isFile(dispatcher) || !isFile(manifest)) return 0;
|
|
3624
3723
|
const failed = [];
|
|
3625
3724
|
const skipped = [];
|
|
3626
3725
|
const passed = [];
|
|
3627
3726
|
for (const [platform, native] of SMOKE_PROBE_EVENTS) {
|
|
3628
3727
|
const rel_bridge = SMOKE_BRIDGE_PATHS[platform] ?? "";
|
|
3629
|
-
const bridge_path = rel_bridge ?
|
|
3728
|
+
const bridge_path = rel_bridge ? path5.join(project_root, rel_bridge) : null;
|
|
3630
3729
|
const bridge_present = Boolean(
|
|
3631
3730
|
bridge_path && (isFile(bridge_path) || isDir(bridge_path) && dirHasEntries(bridge_path))
|
|
3632
3731
|
);
|
|
@@ -3826,9 +3925,9 @@ To remove this marker, delete this file.
|
|
|
3826
3925
|
`;
|
|
3827
3926
|
}
|
|
3828
3927
|
var _CLAUDE_DESKTOP_BUNDLES_SUBPATH = "claude-desktop/bundles";
|
|
3829
|
-
var GLOBAL_ROOT =
|
|
3830
|
-
var GLOBAL_USER_SETTINGS_PATH =
|
|
3831
|
-
var GLOBAL_AGENT_SETTINGS_PATH =
|
|
3928
|
+
var GLOBAL_ROOT = path5.join(os2.homedir(), ".event4u", "agent-config");
|
|
3929
|
+
var GLOBAL_USER_SETTINGS_PATH = path5.join(GLOBAL_ROOT, ".agent-user.yml");
|
|
3930
|
+
var GLOBAL_AGENT_SETTINGS_PATH = path5.join(GLOBAL_ROOT, ".agent-settings.yml");
|
|
3832
3931
|
function _bridge_marker(tool_id, scope) {
|
|
3833
3932
|
if (scope === "global") return USER_SCOPE_PATHS[tool_id] ?? "";
|
|
3834
3933
|
return PROJECT_BRIDGE_MARKERS[tool_id] ?? "";
|
|
@@ -3877,7 +3976,7 @@ function _load_yaml_doc(p) {
|
|
|
3877
3976
|
return _isPlainObject(data) ? data : {};
|
|
3878
3977
|
}
|
|
3879
3978
|
function _load_default_settings(package_root) {
|
|
3880
|
-
const template_source =
|
|
3979
|
+
const template_source = path5.join(package_root, "src", "config", "agent-settings.template.yml");
|
|
3881
3980
|
if (!pathExists(template_source)) return {};
|
|
3882
3981
|
let text;
|
|
3883
3982
|
try {
|
|
@@ -3889,6 +3988,58 @@ function _load_default_settings(package_root) {
|
|
|
3889
3988
|
const data = yamlSafeLoad(rendered);
|
|
3890
3989
|
return _isPlainObject(data) ? data : {};
|
|
3891
3990
|
}
|
|
3991
|
+
var RULE_LAYER_CHOICES = ["global", "project", "both-acknowledged"];
|
|
3992
|
+
function _suppress_rule_layer(project_root, suppress_dir) {
|
|
3993
|
+
const target = path5.join(project_root, ".claude", "settings.local.json");
|
|
3994
|
+
const existing = pathExists(target) ? read_json_file(target) : {};
|
|
3995
|
+
let real_dir = suppress_dir;
|
|
3996
|
+
try {
|
|
3997
|
+
real_dir = fs6.realpathSync(suppress_dir);
|
|
3998
|
+
} catch {
|
|
3999
|
+
real_dir = suppress_dir;
|
|
4000
|
+
}
|
|
4001
|
+
const entry = claudeMdExcludesGlob(real_dir);
|
|
4002
|
+
const merged = mergeClaudeMdExcludes(existing["claudeMdExcludes"], entry);
|
|
4003
|
+
if (JSON.stringify(existing["claudeMdExcludes"] ?? null) === JSON.stringify(merged)) return;
|
|
4004
|
+
write_json_file(target, { ...existing, claudeMdExcludes: merged });
|
|
4005
|
+
success(`.claude/settings.local.json: claudeMdExcludes += ${entry}`);
|
|
4006
|
+
}
|
|
4007
|
+
function _gate_rule_layer_overlap(project_root, layer, dry_run) {
|
|
4008
|
+
const global_dir = path5.join(os2.homedir(), ".claude", "rules");
|
|
4009
|
+
const project_dir = path5.join(project_root, ".claude", "rules");
|
|
4010
|
+
const g = readRuleLayer(global_dir);
|
|
4011
|
+
const p = readRuleLayer(project_dir);
|
|
4012
|
+
if (g === null || p === null) return true;
|
|
4013
|
+
const report = compareLayers(g.files, p.files);
|
|
4014
|
+
if (report.overlap.length === 0) return true;
|
|
4015
|
+
if (layer === null) {
|
|
4016
|
+
warn(
|
|
4017
|
+
`rule layers overlap: ${report.overlap.length} rule(s) are in BOTH ${global_dir} and ${project_dir}, so Claude Code loads them twice (${report.redundant_chars} chars of standing context per session).`
|
|
4018
|
+
);
|
|
4019
|
+
info("Pick which layer owns the corpus \u2014 no file is deleted either way:");
|
|
4020
|
+
info(` --layer=global keep ${global_dir}, suppress the project one`);
|
|
4021
|
+
info(` --layer=project keep ${project_dir}, suppress the global one`);
|
|
4022
|
+
info(" --layer=both-acknowledged keep both and pay the doubled context knowingly");
|
|
4023
|
+
return false;
|
|
4024
|
+
}
|
|
4025
|
+
const action = decideLayerAction(
|
|
4026
|
+
report,
|
|
4027
|
+
layer,
|
|
4028
|
+
global_dir,
|
|
4029
|
+
project_dir
|
|
4030
|
+
);
|
|
4031
|
+
if (action.refresh_required && action.suppress_dir !== null) {
|
|
4032
|
+
warn(
|
|
4033
|
+
`${report.divergent.length} shared rule(s) differ in body between the two layers (${report.divergent.slice(0, 5).join(", ")}${report.divergent.length > 5 ? ", \u2026" : ""}). Suppressing a layer now would drop whatever only that copy carries. Re-run the projection first, or pass --layer=both-acknowledged.`
|
|
4034
|
+
);
|
|
4035
|
+
return false;
|
|
4036
|
+
}
|
|
4037
|
+
info(action.note);
|
|
4038
|
+
if (action.suppress_dir !== null && !dry_run) {
|
|
4039
|
+
_suppress_rule_layer(project_root, action.suppress_dir);
|
|
4040
|
+
}
|
|
4041
|
+
return true;
|
|
4042
|
+
}
|
|
3892
4043
|
function _resolve_scope(opts, detected, detect_reason, custom_path) {
|
|
3893
4044
|
if (opts.scope === "project") return "project";
|
|
3894
4045
|
if (opts.scope === "global") return "global";
|
|
@@ -3965,9 +4116,9 @@ function detect_scope(cwd) {
|
|
|
3965
4116
|
if (pathExists(_resolve_settings_read(cwd))) {
|
|
3966
4117
|
return ["project", `existing ${SETTINGS_FILE}`];
|
|
3967
4118
|
}
|
|
3968
|
-
const has_manifest = SCOPE_DETECT_MANIFESTS.find((m) => pathExists(
|
|
3969
|
-
const has_ai_dir = SCOPE_DETECT_AI_DIRS.find((d) => isDir(
|
|
3970
|
-
const has_ai_file = SCOPE_DETECT_AI_FILES.find((f) => pathExists(
|
|
4119
|
+
const has_manifest = SCOPE_DETECT_MANIFESTS.find((m) => pathExists(path5.join(cwd, m))) ?? null;
|
|
4120
|
+
const has_ai_dir = SCOPE_DETECT_AI_DIRS.find((d) => isDir(path5.join(cwd, d))) ?? null;
|
|
4121
|
+
const has_ai_file = SCOPE_DETECT_AI_FILES.find((f) => pathExists(path5.join(cwd, f))) ?? null;
|
|
3971
4122
|
if (has_manifest && (has_ai_dir || has_ai_file)) {
|
|
3972
4123
|
const marker = has_ai_dir || has_ai_file;
|
|
3973
4124
|
return ["prompt", `manifest (${has_manifest}) + AI-tool config (${marker})`];
|
|
@@ -3988,7 +4139,7 @@ function readLineSyncRaw(promptText) {
|
|
|
3988
4139
|
for (; ; ) {
|
|
3989
4140
|
let n;
|
|
3990
4141
|
try {
|
|
3991
|
-
n =
|
|
4142
|
+
n = fs6.readSync(0, buf, 0, 1, null);
|
|
3992
4143
|
} catch (err) {
|
|
3993
4144
|
const code = err.code;
|
|
3994
4145
|
if (code === "EAGAIN") {
|
|
@@ -4063,8 +4214,8 @@ function _files_by_tool_from_bridges(tools, project_root, scope) {
|
|
|
4063
4214
|
const marker = _bridge_marker(tool_id, scope);
|
|
4064
4215
|
if (!marker) continue;
|
|
4065
4216
|
let marker_path = marker;
|
|
4066
|
-
if (!
|
|
4067
|
-
marker_path =
|
|
4217
|
+
if (!path5.isAbsolute(marker_path)) {
|
|
4218
|
+
marker_path = path5.join(project_root, marker_path);
|
|
4068
4219
|
}
|
|
4069
4220
|
out[tool_id] = [_file_entry(marker_path, "bridge", false)];
|
|
4070
4221
|
}
|
|
@@ -4103,26 +4254,26 @@ function _update_installed_tools_manifest(project_root, tools, scope, force, fil
|
|
|
4103
4254
|
}
|
|
4104
4255
|
write_manifest(target, version, entries);
|
|
4105
4256
|
if (!state.QUIET) {
|
|
4106
|
-
const rel = isRelativeTo(target, project_root) ?
|
|
4257
|
+
const rel = isRelativeTo(target, project_root) ? path5.relative(project_root, target) : target;
|
|
4107
4258
|
info(`Manifest updated: ${rel}`);
|
|
4108
4259
|
}
|
|
4109
4260
|
return 0;
|
|
4110
4261
|
}
|
|
4111
4262
|
function isRelativeTo(child, parent) {
|
|
4112
|
-
const rel =
|
|
4113
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
4263
|
+
const rel = path5.relative(parent, child);
|
|
4264
|
+
return rel === "" || !rel.startsWith("..") && !path5.isAbsolute(rel);
|
|
4114
4265
|
}
|
|
4115
4266
|
function _resolve_package_root_for_global() {
|
|
4116
4267
|
const here = resolvePath(_HERE);
|
|
4117
|
-
const candidate =
|
|
4118
|
-
if (!pathExists(
|
|
4268
|
+
const candidate = path5.dirname(path5.dirname(path5.dirname(here)));
|
|
4269
|
+
if (!pathExists(path5.join(candidate, "src", "config", "profiles", "minimal.ini"))) {
|
|
4119
4270
|
fail(
|
|
4120
4271
|
`Could not locate agent-config package root from ${here}. Expected src/config/profiles/minimal.ini at the parent directory.`
|
|
4121
4272
|
);
|
|
4122
4273
|
}
|
|
4123
4274
|
return candidate;
|
|
4124
4275
|
}
|
|
4125
|
-
var CONSUMER_BRIDGE_MARKER_RELPATH =
|
|
4276
|
+
var CONSUMER_BRIDGE_MARKER_RELPATH = path5.join("agents", ".event4u-bridge.yml");
|
|
4126
4277
|
var MIGRATE_LEGACY_YAML_FILES = [".agent-settings.yml", ".agent-user.yml"];
|
|
4127
4278
|
var MIGRATE_LEGACY_TOOL_DIRS = [".augment", ".claude", ".cursor"];
|
|
4128
4279
|
var AGENT_CONFIG_PACKAGE_NAME = "@event4u/agent-config";
|
|
@@ -4130,7 +4281,7 @@ function _is_agent_config_source_repo(project_root) {
|
|
|
4130
4281
|
if (process2.env["AGENT_CONFIG_CONSUMER_MODE"] === "1") {
|
|
4131
4282
|
return [false, "consumer-mode-override"];
|
|
4132
4283
|
}
|
|
4133
|
-
const pkg_json =
|
|
4284
|
+
const pkg_json = path5.join(project_root, "package.json");
|
|
4134
4285
|
if (isFile(pkg_json)) {
|
|
4135
4286
|
let data = {};
|
|
4136
4287
|
try {
|
|
@@ -4142,18 +4293,18 @@ function _is_agent_config_source_repo(project_root) {
|
|
|
4142
4293
|
return [true, "package.json:name"];
|
|
4143
4294
|
}
|
|
4144
4295
|
}
|
|
4145
|
-
if (isDir(
|
|
4296
|
+
if (isDir(path5.join(project_root, ".agent-src.uncondensed"))) {
|
|
4146
4297
|
return [true, ".agent-src.uncondensed/"];
|
|
4147
4298
|
}
|
|
4148
|
-
const packages_dir =
|
|
4299
|
+
const packages_dir = path5.join(project_root, "packages");
|
|
4149
4300
|
if (isDir(packages_dir)) {
|
|
4150
|
-
for (const child of
|
|
4151
|
-
if (isDir(
|
|
4301
|
+
for (const child of fs6.readdirSync(packages_dir)) {
|
|
4302
|
+
if (isDir(path5.join(packages_dir, child, ".agent-src.uncondensed"))) {
|
|
4152
4303
|
return [true, `packages/${child}/.agent-src.uncondensed/`];
|
|
4153
4304
|
}
|
|
4154
4305
|
}
|
|
4155
4306
|
}
|
|
4156
|
-
const installer_self =
|
|
4307
|
+
const installer_self = path5.join(project_root, "scripts", "install.py");
|
|
4157
4308
|
try {
|
|
4158
4309
|
if (isFile(installer_self) && resolvePath(installer_self) === resolvePath(_HERE)) {
|
|
4159
4310
|
return [true, "src/scripts/install.py (self)"];
|
|
@@ -4173,17 +4324,17 @@ function _detect_legacy_for_migration(project_root) {
|
|
|
4173
4324
|
}
|
|
4174
4325
|
return [];
|
|
4175
4326
|
}
|
|
4176
|
-
if (isFile(
|
|
4327
|
+
if (isFile(path5.join(project_root, INSTALL_MODE_MARKER_REL))) return [];
|
|
4177
4328
|
const found = [];
|
|
4178
4329
|
for (const name of MIGRATE_LEGACY_YAML_FILES) {
|
|
4179
|
-
if (isFile(
|
|
4330
|
+
if (isFile(path5.join(project_root, name))) {
|
|
4180
4331
|
found.push(name);
|
|
4181
|
-
} else if (isFile(
|
|
4332
|
+
} else if (isFile(path5.join(project_root, "settings", name))) {
|
|
4182
4333
|
found.push(`settings/${name}`);
|
|
4183
4334
|
}
|
|
4184
4335
|
}
|
|
4185
4336
|
for (const name of MIGRATE_LEGACY_TOOL_DIRS) {
|
|
4186
|
-
const p =
|
|
4337
|
+
const p = path5.join(project_root, name);
|
|
4187
4338
|
if (isDir(p) && !isSymlink(p)) {
|
|
4188
4339
|
found.push(`${name}/`);
|
|
4189
4340
|
}
|
|
@@ -4195,7 +4346,7 @@ function _prompt_migrate_to_global(project_root, artefacts) {
|
|
|
4195
4346
|
process2.stdout.write("\n");
|
|
4196
4347
|
warn("Legacy project-local artefacts detected \u2014 pre-ADR-020 layout:");
|
|
4197
4348
|
for (const rel of artefacts) {
|
|
4198
|
-
info(` ${
|
|
4349
|
+
info(` ${path5.join(project_root, rel)}`);
|
|
4199
4350
|
}
|
|
4200
4351
|
info("The unified `agent-config migrate` sweeps these in one pass.");
|
|
4201
4352
|
info("The wizard recreates fresh config afterwards.");
|
|
@@ -4226,20 +4377,20 @@ function _run_migrate_to_global(project_root) {
|
|
|
4226
4377
|
function _format_global_root_for_marker(global_root) {
|
|
4227
4378
|
const home = resolvePath(os2.homedir());
|
|
4228
4379
|
const resolved = resolvePath(global_root);
|
|
4229
|
-
const rel =
|
|
4230
|
-
if (rel === "" || rel.startsWith("..") ||
|
|
4380
|
+
const rel = path5.relative(home, resolved);
|
|
4381
|
+
if (rel === "" || rel.startsWith("..") || path5.isAbsolute(rel)) {
|
|
4231
4382
|
return global_root;
|
|
4232
4383
|
}
|
|
4233
|
-
return `~/${rel.split(
|
|
4384
|
+
return `~/${rel.split(path5.sep).join("/")}`;
|
|
4234
4385
|
}
|
|
4235
4386
|
function _remove_legacy_consumer_bridge_marker(project_root, env = null) {
|
|
4236
4387
|
const env_map = env ?? process2.env;
|
|
4237
4388
|
if (env_map["AGENT_CONFIG_DEV_MODE"] === "1") return null;
|
|
4238
|
-
if (isDir(
|
|
4239
|
-
const target =
|
|
4389
|
+
if (isDir(path5.join(project_root, ".agent-src.uncondensed"))) return null;
|
|
4390
|
+
const target = path5.join(project_root, CONSUMER_BRIDGE_MARKER_RELPATH);
|
|
4240
4391
|
if (!isFile(target)) return null;
|
|
4241
4392
|
try {
|
|
4242
|
-
|
|
4393
|
+
fs6.rmSync(target);
|
|
4243
4394
|
} catch {
|
|
4244
4395
|
return null;
|
|
4245
4396
|
}
|
|
@@ -4253,7 +4404,7 @@ var PROJECT_ANCHOR_TOOLS = {
|
|
|
4253
4404
|
function _write_per_tool_project_anchors(project_root, tools, env = null, now = null) {
|
|
4254
4405
|
const env_map = env ?? process2.env;
|
|
4255
4406
|
if (env_map["AGENT_CONFIG_DEV_MODE"] === "1") return [];
|
|
4256
|
-
if (isDir(
|
|
4407
|
+
if (isDir(path5.join(project_root, ".agent-src.uncondensed"))) return [];
|
|
4257
4408
|
const global_root_str = _format_global_root_for_marker(
|
|
4258
4409
|
event4u_root(env_map)
|
|
4259
4410
|
);
|
|
@@ -4262,8 +4413,8 @@ function _write_per_tool_project_anchors(project_root, tools, env = null, now =
|
|
|
4262
4413
|
for (const tool_id of Object.keys(PROJECT_ANCHOR_TOOLS).sort()) {
|
|
4263
4414
|
const rel_path = PROJECT_ANCHOR_TOOLS[tool_id];
|
|
4264
4415
|
if (!tools.has(tool_id)) continue;
|
|
4265
|
-
const target =
|
|
4266
|
-
mkdirp(
|
|
4416
|
+
const target = path5.join(project_root, rel_path);
|
|
4417
|
+
mkdirp(path5.dirname(target));
|
|
4267
4418
|
const body = `# event4u/agent-config \u2014 per-tool project anchor (auto-written).
|
|
4268
4419
|
# Spec: docs/contracts/consumer-bridge.md \xA7 Per-tool anchor strategy.
|
|
4269
4420
|
# Tool: ${tool_id}. Resolves the global install directly \u2014 no
|
|
@@ -4281,7 +4432,7 @@ installed_at: ${stamp}
|
|
|
4281
4432
|
}
|
|
4282
4433
|
var PACKAGE_TAG_ID = "event4u/agent-config";
|
|
4283
4434
|
function _inject_package_tag(target, source, package_root) {
|
|
4284
|
-
if (
|
|
4435
|
+
if (path5.extname(target) !== ".md") return;
|
|
4285
4436
|
let text;
|
|
4286
4437
|
try {
|
|
4287
4438
|
text = readText(target);
|
|
@@ -4309,8 +4460,8 @@ function _inject_package_tag(target, source, package_root) {
|
|
|
4309
4460
|
resolved_src = source;
|
|
4310
4461
|
}
|
|
4311
4462
|
if (package_root !== null) {
|
|
4312
|
-
const rel =
|
|
4313
|
-
if (rel !== "" && !rel.startsWith("..") && !
|
|
4463
|
+
const rel = path5.relative(resolvePath(package_root), resolved_src);
|
|
4464
|
+
if (rel !== "" && !rel.startsWith("..") && !path5.isAbsolute(rel)) {
|
|
4314
4465
|
source_value = rel;
|
|
4315
4466
|
} else {
|
|
4316
4467
|
source_value = resolved_src;
|
|
@@ -4345,7 +4496,7 @@ function _escapes_package_root(resolved, package_root) {
|
|
|
4345
4496
|
if (package_root === null) return false;
|
|
4346
4497
|
let root;
|
|
4347
4498
|
try {
|
|
4348
|
-
root =
|
|
4499
|
+
root = fs6.realpathSync(package_root);
|
|
4349
4500
|
} catch {
|
|
4350
4501
|
return false;
|
|
4351
4502
|
}
|
|
@@ -4360,7 +4511,7 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
|
|
|
4360
4511
|
if (file_filter !== null && !file_filter(src)) return [0, 0, written_paths];
|
|
4361
4512
|
let resolved_src = src;
|
|
4362
4513
|
try {
|
|
4363
|
-
resolved_src =
|
|
4514
|
+
resolved_src = fs6.realpathSync(src);
|
|
4364
4515
|
} catch {
|
|
4365
4516
|
resolved_src = src;
|
|
4366
4517
|
}
|
|
@@ -4368,10 +4519,10 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
|
|
|
4368
4519
|
warn(`refused: ${src} dereferences outside the package root \u2014 not copied`);
|
|
4369
4520
|
return [0, 0, written_paths];
|
|
4370
4521
|
}
|
|
4371
|
-
mkdirp(
|
|
4522
|
+
mkdirp(path5.dirname(dest));
|
|
4372
4523
|
const decision = _resolve_file_conflict(dest, force);
|
|
4373
4524
|
if (decision === "skip") return [0, 1, written_paths];
|
|
4374
|
-
|
|
4525
|
+
fs6.copyFileSync(src, dest);
|
|
4375
4526
|
_inject_package_tag(dest, src, package_root);
|
|
4376
4527
|
written_paths.push(dest);
|
|
4377
4528
|
return [1, 0, written_paths];
|
|
@@ -4379,11 +4530,11 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
|
|
|
4379
4530
|
mkdirp(dest);
|
|
4380
4531
|
const walk = (node) => {
|
|
4381
4532
|
const acc = [];
|
|
4382
|
-
const names =
|
|
4533
|
+
const names = fs6.readdirSync(node).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
|
|
4383
4534
|
for (const name of names) {
|
|
4384
|
-
const entry =
|
|
4535
|
+
const entry = path5.join(node, name);
|
|
4385
4536
|
acc.push(entry);
|
|
4386
|
-
const lst =
|
|
4537
|
+
const lst = fs6.lstatSync(entry);
|
|
4387
4538
|
if (lst.isDirectory() && !lst.isSymbolicLink()) {
|
|
4388
4539
|
acc.push(...walk(entry));
|
|
4389
4540
|
}
|
|
@@ -4391,9 +4542,9 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
|
|
|
4391
4542
|
return acc;
|
|
4392
4543
|
};
|
|
4393
4544
|
for (const entry of walk(src)) {
|
|
4394
|
-
const rel =
|
|
4395
|
-
const target =
|
|
4396
|
-
const lst =
|
|
4545
|
+
const rel = path5.relative(src, entry);
|
|
4546
|
+
const target = path5.join(dest, rel);
|
|
4547
|
+
const lst = fs6.lstatSync(entry);
|
|
4397
4548
|
if (lst.isDirectory() && !lst.isSymbolicLink()) {
|
|
4398
4549
|
mkdirp(target);
|
|
4399
4550
|
continue;
|
|
@@ -4401,8 +4552,8 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
|
|
|
4401
4552
|
let resolvedIsDir = false;
|
|
4402
4553
|
let resolved = entry;
|
|
4403
4554
|
try {
|
|
4404
|
-
resolved =
|
|
4405
|
-
resolvedIsDir =
|
|
4555
|
+
resolved = fs6.realpathSync(entry);
|
|
4556
|
+
resolvedIsDir = fs6.statSync(entry).isDirectory();
|
|
4406
4557
|
} catch {
|
|
4407
4558
|
resolvedIsDir = false;
|
|
4408
4559
|
}
|
|
@@ -4432,8 +4583,8 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
|
|
|
4432
4583
|
skipped += 1;
|
|
4433
4584
|
continue;
|
|
4434
4585
|
}
|
|
4435
|
-
mkdirp(
|
|
4436
|
-
|
|
4586
|
+
mkdirp(path5.dirname(target));
|
|
4587
|
+
fs6.copyFileSync(resolved, target);
|
|
4437
4588
|
_inject_package_tag(target, resolved, package_root);
|
|
4438
4589
|
written += 1;
|
|
4439
4590
|
written_paths.push(target);
|
|
@@ -4445,7 +4596,7 @@ function _claude_desktop_bundles_dir() {
|
|
|
4445
4596
|
}
|
|
4446
4597
|
function _write_claude_desktop_marker(_force, lockfile_path2, bundles_dir, bundle_count) {
|
|
4447
4598
|
const anchor = expanduser2(USER_SCOPE_PATHS["claude-desktop"]);
|
|
4448
|
-
const target =
|
|
4599
|
+
const target = path5.join(anchor, "agent-config.md");
|
|
4449
4600
|
mkdirp(anchor);
|
|
4450
4601
|
const body = claudeDesktopMarkerBody(lockfile_path2, anchor, bundles_dir, bundle_count);
|
|
4451
4602
|
writeText(target, body);
|
|
@@ -4469,23 +4620,23 @@ function _apply_claude_flat_command_wrappers(anchor, package_root, current_files
|
|
|
4469
4620
|
const wrapped = [];
|
|
4470
4621
|
const collisions = [];
|
|
4471
4622
|
const reserved = [];
|
|
4472
|
-
const commands_dir =
|
|
4623
|
+
const commands_dir = path5.join(anchor, "commands");
|
|
4473
4624
|
let flat_entries = [];
|
|
4474
4625
|
try {
|
|
4475
|
-
flat_entries =
|
|
4626
|
+
flat_entries = fs6.readdirSync(commands_dir).filter((f) => f.endsWith(".md"));
|
|
4476
4627
|
} catch {
|
|
4477
4628
|
}
|
|
4478
4629
|
for (const fname of flat_entries.sort()) {
|
|
4479
4630
|
const slug = fname.slice(0, -".md".length);
|
|
4480
4631
|
if (!is_claude_builtin_name(slug)) continue;
|
|
4481
|
-
|
|
4632
|
+
fs6.rmSync(path5.join(commands_dir, fname), { force: true });
|
|
4482
4633
|
current_files.delete(`commands/${fname}`);
|
|
4483
4634
|
reserved.push(slug);
|
|
4484
4635
|
}
|
|
4485
4636
|
const eligible = new Set(_CLAUDE_FLAT_WRAPPER_EXTRA);
|
|
4486
4637
|
try {
|
|
4487
4638
|
const manifest = JSON.parse(
|
|
4488
|
-
|
|
4639
|
+
fs6.readFileSync(path5.join(package_root, "dist", "discovery", "discovery-manifest.json"), "utf8")
|
|
4489
4640
|
);
|
|
4490
4641
|
for (const a of manifest.artefacts ?? []) {
|
|
4491
4642
|
if (a.category !== "command" || typeof a.slug !== "string") continue;
|
|
@@ -4496,22 +4647,22 @@ function _apply_claude_flat_command_wrappers(anchor, package_root, current_files
|
|
|
4496
4647
|
}
|
|
4497
4648
|
for (const slug of [...eligible].sort()) {
|
|
4498
4649
|
const flat_rel = `commands/${slug}.md`;
|
|
4499
|
-
const flat_abs =
|
|
4500
|
-
if (!
|
|
4501
|
-
const skill_dir =
|
|
4502
|
-
if (
|
|
4650
|
+
const flat_abs = path5.join(anchor, "commands", `${slug}.md`);
|
|
4651
|
+
if (!fs6.existsSync(flat_abs)) continue;
|
|
4652
|
+
const skill_dir = path5.join(anchor, "skills", slug);
|
|
4653
|
+
if (fs6.existsSync(skill_dir)) {
|
|
4503
4654
|
collisions.push(slug);
|
|
4504
4655
|
continue;
|
|
4505
4656
|
}
|
|
4506
|
-
let body =
|
|
4657
|
+
let body = fs6.readFileSync(flat_abs, "utf8");
|
|
4507
4658
|
if (body.startsWith("---\n") && !/^name:/m.test(body.split("\n---")[0] ?? "")) {
|
|
4508
4659
|
body = body.replace("---\n", `---
|
|
4509
4660
|
name: ${slug}
|
|
4510
4661
|
`);
|
|
4511
4662
|
}
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4663
|
+
fs6.mkdirSync(skill_dir, { recursive: true });
|
|
4664
|
+
fs6.writeFileSync(path5.join(skill_dir, "SKILL.md"), body, "utf8");
|
|
4665
|
+
fs6.rmSync(flat_abs, { force: true });
|
|
4515
4666
|
current_files.delete(flat_rel);
|
|
4516
4667
|
current_files.add(`skills/${slug}/SKILL.md`);
|
|
4517
4668
|
wrapped.push(slug);
|
|
@@ -4543,8 +4694,8 @@ function _deploy_global_content(tools, force, package_root, lockfile_path2) {
|
|
|
4543
4694
|
const written_paths = [];
|
|
4544
4695
|
let current_files = /* @__PURE__ */ new Set();
|
|
4545
4696
|
for (const [src_rel, dest_sub] of plan) {
|
|
4546
|
-
const src =
|
|
4547
|
-
const dest = dest_sub ?
|
|
4697
|
+
const src = path5.join(package_root, src_rel);
|
|
4698
|
+
const dest = dest_sub ? path5.join(anchor, dest_sub) : anchor;
|
|
4548
4699
|
const rule_filter = _rule_filter_for_source(src_rel, rule_scope);
|
|
4549
4700
|
const [w, s, paths] = _copy_dir_dereferencing_symlinks(
|
|
4550
4701
|
src,
|
|
@@ -4618,10 +4769,10 @@ function _deploy_global_content(tools, force, package_root, lockfile_path2) {
|
|
|
4618
4769
|
results[tool_id] = [written_total, skipped_total, "deployed", written_paths];
|
|
4619
4770
|
if (tool_id === "claude-code") {
|
|
4620
4771
|
try {
|
|
4621
|
-
const manifest =
|
|
4772
|
+
const manifest = path5.join(package_root, "src", "scripts", "hook_manifest.yaml");
|
|
4622
4773
|
const matrix = build_claude_hook_matrix(manifest);
|
|
4623
4774
|
const res = ensure_managed_hooks(
|
|
4624
|
-
|
|
4775
|
+
path5.join(anchor, "settings.json"),
|
|
4625
4776
|
matrix
|
|
4626
4777
|
);
|
|
4627
4778
|
if (!state.QUIET) {
|
|
@@ -4658,7 +4809,7 @@ function _preview_global_reap(tools, package_root) {
|
|
|
4658
4809
|
const anchor = expanduser2(anchor_raw);
|
|
4659
4810
|
let current_files = /* @__PURE__ */ new Set();
|
|
4660
4811
|
for (const [src_rel, dest_sub] of plan) {
|
|
4661
|
-
const src =
|
|
4812
|
+
const src = path5.join(package_root, src_rel);
|
|
4662
4813
|
current_files = setUnion(
|
|
4663
4814
|
current_files,
|
|
4664
4815
|
expected_deploy_files(
|
|
@@ -4692,14 +4843,14 @@ function _preview_global_reap(tools, package_root) {
|
|
|
4692
4843
|
function _verify_deploy_targets(anchor, plan) {
|
|
4693
4844
|
const missing = [];
|
|
4694
4845
|
for (const [, dest_sub] of plan) {
|
|
4695
|
-
const target = dest_sub ?
|
|
4846
|
+
const target = dest_sub ? path5.join(anchor, dest_sub) : anchor;
|
|
4696
4847
|
const label = dest_sub || ".";
|
|
4697
4848
|
if (!isDir(target)) {
|
|
4698
4849
|
missing.push(label);
|
|
4699
4850
|
continue;
|
|
4700
4851
|
}
|
|
4701
4852
|
try {
|
|
4702
|
-
const entries =
|
|
4853
|
+
const entries = fs6.readdirSync(target);
|
|
4703
4854
|
if (entries.length === 0) missing.push(label);
|
|
4704
4855
|
} catch {
|
|
4705
4856
|
missing.push(label);
|
|
@@ -4714,13 +4865,13 @@ function _prune_modules_by(deploy_results, is_pruned) {
|
|
|
4714
4865
|
const [written, skipped, status, paths] = deploy_results[tool_id];
|
|
4715
4866
|
const pruned_skill_dirs = /* @__PURE__ */ new Set();
|
|
4716
4867
|
for (const p of paths) {
|
|
4717
|
-
const parts = p.split(
|
|
4868
|
+
const parts = p.split(path5.sep);
|
|
4718
4869
|
if (parts.includes("skills")) {
|
|
4719
4870
|
const i = parts.indexOf("skills");
|
|
4720
4871
|
if (i + 1 < parts.length) {
|
|
4721
|
-
const skill_root = parts.slice(0, i + 2).join(
|
|
4872
|
+
const skill_root = parts.slice(0, i + 2).join(path5.sep);
|
|
4722
4873
|
if (!pruned_skill_dirs.has(skill_root)) {
|
|
4723
|
-
const skillmd =
|
|
4874
|
+
const skillmd = path5.join(skill_root, "SKILL.md");
|
|
4724
4875
|
if (pathExists(skillmd) && is_pruned(skillmd)) {
|
|
4725
4876
|
pruned_skill_dirs.add(skill_root);
|
|
4726
4877
|
}
|
|
@@ -4731,25 +4882,25 @@ function _prune_modules_by(deploy_results, is_pruned) {
|
|
|
4731
4882
|
const keep = [];
|
|
4732
4883
|
const delete_files = [];
|
|
4733
4884
|
for (const p of paths) {
|
|
4734
|
-
const parts = p.split(
|
|
4885
|
+
const parts = p.split(path5.sep);
|
|
4735
4886
|
let is_target = false;
|
|
4736
4887
|
if (parts.includes("skills")) {
|
|
4737
4888
|
const i = parts.indexOf("skills");
|
|
4738
|
-
if (i + 1 < parts.length && pruned_skill_dirs.has(parts.slice(0, i + 2).join(
|
|
4889
|
+
if (i + 1 < parts.length && pruned_skill_dirs.has(parts.slice(0, i + 2).join(path5.sep))) {
|
|
4739
4890
|
is_target = true;
|
|
4740
4891
|
}
|
|
4741
|
-
} else if (parts.includes("commands") &&
|
|
4892
|
+
} else if (parts.includes("commands") && path5.extname(p) === ".md" && is_pruned(p)) {
|
|
4742
4893
|
is_target = true;
|
|
4743
4894
|
}
|
|
4744
4895
|
(is_target ? delete_files : keep).push(p);
|
|
4745
4896
|
}
|
|
4746
4897
|
for (const d of pruned_skill_dirs) {
|
|
4747
|
-
|
|
4898
|
+
fs6.rmSync(d, { recursive: true, force: true });
|
|
4748
4899
|
}
|
|
4749
4900
|
for (const p of delete_files) {
|
|
4750
|
-
if (p.split(
|
|
4901
|
+
if (p.split(path5.sep).includes("commands") && pathExists(p)) {
|
|
4751
4902
|
try {
|
|
4752
|
-
|
|
4903
|
+
fs6.unlinkSync(p);
|
|
4753
4904
|
} catch {
|
|
4754
4905
|
}
|
|
4755
4906
|
}
|
|
@@ -4770,9 +4921,9 @@ function _resolve_global_settings_doc() {
|
|
|
4770
4921
|
}
|
|
4771
4922
|
function _resolve_global_settings_path() {
|
|
4772
4923
|
const root = event4u_root();
|
|
4773
|
-
const canonical =
|
|
4924
|
+
const canonical = path5.join(root, "settings", SETTINGS_FILE);
|
|
4774
4925
|
if (pathExists(canonical)) return canonical;
|
|
4775
|
-
const legacy =
|
|
4926
|
+
const legacy = path5.join(root, SETTINGS_FILE);
|
|
4776
4927
|
if (pathExists(legacy)) return legacy;
|
|
4777
4928
|
return null;
|
|
4778
4929
|
}
|
|
@@ -4883,7 +5034,7 @@ function install_global(tools, force, project_root = null, core_only = false) {
|
|
|
4883
5034
|
info(` schema_version=1, agent_config_version=${installed_version}`);
|
|
4884
5035
|
info(` tools=${merged_tools.join(",")}`);
|
|
4885
5036
|
}
|
|
4886
|
-
if (project_root !== null && pathExists(_resolve_settings_read(project_root)) && !isDir(
|
|
5037
|
+
if (project_root !== null && pathExists(_resolve_settings_read(project_root)) && !isDir(path5.join(project_root, ".agent-src.uncondensed"))) {
|
|
4887
5038
|
const drift = collect_drift(project_root);
|
|
4888
5039
|
if (!state.QUIET) {
|
|
4889
5040
|
process2.stdout.write("\n");
|
|
@@ -4983,19 +5134,19 @@ function install_global(tools, force, project_root = null, core_only = false) {
|
|
|
4983
5134
|
}
|
|
4984
5135
|
}
|
|
4985
5136
|
}
|
|
4986
|
-
if (project_root !== null && pathExists(_resolve_settings_read(project_root)) && !isDir(
|
|
5137
|
+
if (project_root !== null && pathExists(_resolve_settings_read(project_root)) && !isDir(path5.join(project_root, ".agent-src.uncondensed"))) {
|
|
4987
5138
|
const files_by_tool = _files_by_tool_from_deploy(deploy_results);
|
|
4988
5139
|
const rc = _update_installed_tools_manifest(project_root, tools, "global", force, files_by_tool);
|
|
4989
5140
|
if (rc !== 0) return rc;
|
|
4990
5141
|
const removed_marker = _remove_legacy_consumer_bridge_marker(project_root);
|
|
4991
5142
|
if (removed_marker !== null && !state.QUIET) {
|
|
4992
|
-
const rel = isRelativeTo(removed_marker, project_root) ?
|
|
5143
|
+
const rel = isRelativeTo(removed_marker, project_root) ? path5.relative(project_root, removed_marker) : removed_marker;
|
|
4993
5144
|
info(`Removed legacy bridge marker: ${rel}`);
|
|
4994
5145
|
}
|
|
4995
5146
|
const anchor_paths = _write_per_tool_project_anchors(project_root, tools);
|
|
4996
5147
|
if (anchor_paths.length > 0 && !state.QUIET) {
|
|
4997
5148
|
for (const p of anchor_paths) {
|
|
4998
|
-
const rel = isRelativeTo(p, project_root) ?
|
|
5149
|
+
const rel = isRelativeTo(p, project_root) ? path5.relative(project_root, p) : p;
|
|
4999
5150
|
info(`Project anchor written: ${rel}`);
|
|
5000
5151
|
}
|
|
5001
5152
|
}
|
|
@@ -5012,8 +5163,8 @@ function install_global(tools, force, project_root = null, core_only = false) {
|
|
|
5012
5163
|
}
|
|
5013
5164
|
return 0;
|
|
5014
5165
|
}
|
|
5015
|
-
var SETTINGS_SURFACE_REL =
|
|
5016
|
-
var SETTINGS_DELTA_REL =
|
|
5166
|
+
var SETTINGS_SURFACE_REL = path5.join("state", "settings-surface.json");
|
|
5167
|
+
var SETTINGS_DELTA_REL = path5.join("state", "settings-delta.json");
|
|
5017
5168
|
function _current_settings_surface(version) {
|
|
5018
5169
|
const jsonSchema = zodToJsonSchema(settingsSchema, {
|
|
5019
5170
|
name: "AgentSettings",
|
|
@@ -5024,20 +5175,20 @@ function _current_settings_surface(version) {
|
|
|
5024
5175
|
}
|
|
5025
5176
|
function _write_settings_surface_snapshot(installed_version) {
|
|
5026
5177
|
const root = event4u_root();
|
|
5027
|
-
const surface_path =
|
|
5028
|
-
const delta_path =
|
|
5178
|
+
const surface_path = path5.join(root, SETTINGS_SURFACE_REL);
|
|
5179
|
+
const delta_path = path5.join(root, SETTINGS_DELTA_REL);
|
|
5029
5180
|
const next = _current_settings_surface(installed_version);
|
|
5030
5181
|
let previous = null;
|
|
5031
5182
|
try {
|
|
5032
|
-
const parsed = JSON.parse(
|
|
5183
|
+
const parsed = JSON.parse(fs6.readFileSync(surface_path, "utf8"));
|
|
5033
5184
|
if (parsed !== null && typeof parsed === "object" && parsed.entries !== void 0) previous = parsed;
|
|
5034
5185
|
} catch {
|
|
5035
5186
|
}
|
|
5036
5187
|
if (previous !== null && previous.version !== next.version) {
|
|
5037
5188
|
const delta = computeSurfaceDelta(previous, next);
|
|
5038
5189
|
if (delta.changes.length > 0) {
|
|
5039
|
-
|
|
5040
|
-
|
|
5190
|
+
fs6.mkdirSync(path5.dirname(delta_path), { recursive: true, mode: 448 });
|
|
5191
|
+
fs6.writeFileSync(delta_path, `${JSON.stringify(delta, null, 2)}
|
|
5041
5192
|
`, { mode: 384 });
|
|
5042
5193
|
if (!state.QUIET) {
|
|
5043
5194
|
const counts = {};
|
|
@@ -5049,8 +5200,8 @@ function _write_settings_surface_snapshot(installed_version) {
|
|
|
5049
5200
|
}
|
|
5050
5201
|
}
|
|
5051
5202
|
}
|
|
5052
|
-
|
|
5053
|
-
|
|
5203
|
+
fs6.mkdirSync(path5.dirname(surface_path), { recursive: true, mode: 448 });
|
|
5204
|
+
fs6.writeFileSync(surface_path, `${JSON.stringify(next, null, 2)}
|
|
5054
5205
|
`, { mode: 384 });
|
|
5055
5206
|
}
|
|
5056
5207
|
function arrayStrEqual(a, b) {
|
|
@@ -5076,6 +5227,7 @@ var USAGE = `usage: ${PROG} [-h] [--profile PROFILE] [--user-type USER_TYPE] [--
|
|
|
5076
5227
|
[--tools TOOLS] [--ai AI] [--packs PACKS] [--core-only]
|
|
5077
5228
|
[--no-smoke] [--global]
|
|
5078
5229
|
[--scope {project,global,prompt,auto}]
|
|
5230
|
+
[--layer {global,project,both-acknowledged}]
|
|
5079
5231
|
[--custom-path CUSTOM_PATH] [--offline] [--minimal]
|
|
5080
5232
|
[--interactive] [--no-ui] [--dry-run]
|
|
5081
5233
|
[--apply-payload APPLY_PAYLOAD]
|
|
@@ -5109,7 +5261,8 @@ var _VALUE_FLAGS = {
|
|
|
5109
5261
|
"--packs": "packs",
|
|
5110
5262
|
"--scope": "scope",
|
|
5111
5263
|
"--custom-path": "custom_path",
|
|
5112
|
-
"--apply-payload": "apply_payload"
|
|
5264
|
+
"--apply-payload": "apply_payload",
|
|
5265
|
+
"--layer": "layer"
|
|
5113
5266
|
};
|
|
5114
5267
|
function _argError(msg) {
|
|
5115
5268
|
process2.stderr.write(USAGE);
|
|
@@ -5144,7 +5297,8 @@ function parse_options(argv) {
|
|
|
5144
5297
|
interactive: false,
|
|
5145
5298
|
no_ui: false,
|
|
5146
5299
|
dry_run: false,
|
|
5147
|
-
apply_payload: null
|
|
5300
|
+
apply_payload: null,
|
|
5301
|
+
layer: null
|
|
5148
5302
|
};
|
|
5149
5303
|
const positionals = [];
|
|
5150
5304
|
let i = 0;
|
|
@@ -5181,6 +5335,11 @@ function parse_options(argv) {
|
|
|
5181
5335
|
`argument --scope: invalid choice: '${value}' (choose from 'project', 'global', 'prompt', 'auto')`
|
|
5182
5336
|
);
|
|
5183
5337
|
}
|
|
5338
|
+
if (flag === "--layer" && !RULE_LAYER_CHOICES.includes(value)) {
|
|
5339
|
+
_argError(
|
|
5340
|
+
`argument --layer: invalid choice: '${value}' (choose from ${RULE_LAYER_CHOICES.map((c) => `'${c}'`).join(", ")})`
|
|
5341
|
+
);
|
|
5342
|
+
}
|
|
5184
5343
|
opts[valueDest] = value;
|
|
5185
5344
|
i += 1;
|
|
5186
5345
|
continue;
|
|
@@ -5262,13 +5421,13 @@ function _minimal_templates_root() {
|
|
|
5262
5421
|
const chain = [start];
|
|
5263
5422
|
let cur = start;
|
|
5264
5423
|
for (; ; ) {
|
|
5265
|
-
const parent =
|
|
5424
|
+
const parent = path5.dirname(cur);
|
|
5266
5425
|
if (parent === cur) break;
|
|
5267
5426
|
chain.push(parent);
|
|
5268
5427
|
cur = parent;
|
|
5269
5428
|
}
|
|
5270
5429
|
for (const ancestor of chain) {
|
|
5271
|
-
const candidate =
|
|
5430
|
+
const candidate = path5.join(ancestor, "src", "templates", "minimal");
|
|
5272
5431
|
if (isDir(candidate)) return candidate;
|
|
5273
5432
|
}
|
|
5274
5433
|
fail("Could not locate src/templates/minimal/ \u2014 package install is corrupt.");
|
|
@@ -5276,9 +5435,9 @@ function _minimal_templates_root() {
|
|
|
5276
5435
|
var INSTALL_MODE_MARKER_REL = "agents/.agent-state/install-mode.txt";
|
|
5277
5436
|
function _write_install_mode_marker(project_root, mode) {
|
|
5278
5437
|
if (mode !== "minimal" && mode !== "full") return;
|
|
5279
|
-
const marker =
|
|
5438
|
+
const marker = path5.join(project_root, INSTALL_MODE_MARKER_REL);
|
|
5280
5439
|
try {
|
|
5281
|
-
mkdirp(
|
|
5440
|
+
mkdirp(path5.dirname(marker));
|
|
5282
5441
|
writeText(marker, `${mode}
|
|
5283
5442
|
`);
|
|
5284
5443
|
} catch {
|
|
@@ -5287,7 +5446,7 @@ function _write_install_mode_marker(project_root, mode) {
|
|
|
5287
5446
|
function install_minimal(target_root_in, force, user_type = "") {
|
|
5288
5447
|
let target_root = resolvePath(target_root_in);
|
|
5289
5448
|
mkdirp(target_root);
|
|
5290
|
-
const parent =
|
|
5449
|
+
const parent = path5.dirname(target_root);
|
|
5291
5450
|
if (parent !== target_root) {
|
|
5292
5451
|
const existing = find_project_root_with_anchor(parent);
|
|
5293
5452
|
if (existing !== null && existing[0] !== target_root) {
|
|
@@ -5298,21 +5457,21 @@ function install_minimal(target_root_in, force, user_type = "") {
|
|
|
5298
5457
|
}
|
|
5299
5458
|
}
|
|
5300
5459
|
const templates = _minimal_templates_root();
|
|
5301
|
-
const settings_src =
|
|
5302
|
-
const overrides_gitkeep_src =
|
|
5303
|
-
const overrides_readme_src =
|
|
5460
|
+
const settings_src = path5.join(templates, SETTINGS_FILE);
|
|
5461
|
+
const overrides_gitkeep_src = path5.join(templates, "overrides-gitkeep");
|
|
5462
|
+
const overrides_readme_src = path5.join(templates, "agents-overrides-readme.md");
|
|
5304
5463
|
if (!isFile(settings_src)) fail(`Bundled minimal settings template missing under ${templates}`);
|
|
5305
5464
|
if (!isFile(overrides_gitkeep_src) || !isFile(overrides_readme_src)) {
|
|
5306
5465
|
fail(`Bundled overrides scaffold templates missing under ${templates}`);
|
|
5307
5466
|
}
|
|
5308
5467
|
info(`Minimal init \u2192 ${target_root}`);
|
|
5309
|
-
const overrides_root =
|
|
5468
|
+
const overrides_root = path5.join(target_root, "agents", "overrides");
|
|
5310
5469
|
mkdirp(overrides_root);
|
|
5311
5470
|
const gitkeep_body = readText(overrides_gitkeep_src);
|
|
5312
5471
|
for (const sub of ["rules", "skills", "commands"]) {
|
|
5313
|
-
const sub_dir =
|
|
5472
|
+
const sub_dir = path5.join(overrides_root, sub);
|
|
5314
5473
|
mkdirp(sub_dir);
|
|
5315
|
-
const gitkeep_dst =
|
|
5474
|
+
const gitkeep_dst = path5.join(sub_dir, ".gitkeep");
|
|
5316
5475
|
if (pathExists(gitkeep_dst) && !force) {
|
|
5317
5476
|
skip(`agents/overrides/${sub}/.gitkeep already exists (use --force to overwrite)`);
|
|
5318
5477
|
} else {
|
|
@@ -5320,7 +5479,7 @@ function install_minimal(target_root_in, force, user_type = "") {
|
|
|
5320
5479
|
success(`Wrote agents/overrides/${sub}/.gitkeep`);
|
|
5321
5480
|
}
|
|
5322
5481
|
}
|
|
5323
|
-
const readme_dst =
|
|
5482
|
+
const readme_dst = path5.join(overrides_root, "README.md");
|
|
5324
5483
|
if (pathExists(readme_dst) && !force) {
|
|
5325
5484
|
skip("agents/overrides/README.md already exists (use --force to overwrite)");
|
|
5326
5485
|
} else {
|
|
@@ -5338,14 +5497,14 @@ function install_minimal(target_root_in, force, user_type = "") {
|
|
|
5338
5497
|
personal:
|
|
5339
5498
|
user_type: ${user_type}
|
|
5340
5499
|
`;
|
|
5341
|
-
mkdirp(
|
|
5500
|
+
mkdirp(path5.dirname(settings_dst));
|
|
5342
5501
|
writeText(settings_dst, body);
|
|
5343
5502
|
success(`Wrote ${SETTINGS_FILE} (user_type=${user_type})`);
|
|
5344
5503
|
}
|
|
5345
5504
|
}
|
|
5346
5505
|
const removed_marker = _remove_legacy_consumer_bridge_marker(target_root);
|
|
5347
5506
|
if (removed_marker !== null) {
|
|
5348
|
-
const rel = isRelativeTo(removed_marker, target_root) ?
|
|
5507
|
+
const rel = isRelativeTo(removed_marker, target_root) ? path5.relative(target_root, removed_marker) : removed_marker;
|
|
5349
5508
|
success(`Removed legacy bridge marker: ${rel}`);
|
|
5350
5509
|
}
|
|
5351
5510
|
_write_install_mode_marker(target_root, "minimal");
|
|
@@ -5419,7 +5578,7 @@ function run_interactive_init(project_root, force) {
|
|
|
5419
5578
|
);
|
|
5420
5579
|
return 0;
|
|
5421
5580
|
}
|
|
5422
|
-
const target =
|
|
5581
|
+
const target = path5.join(project_root, _LOCAL_CONFIG_FILE);
|
|
5423
5582
|
if (pathExists(target) && !force) {
|
|
5424
5583
|
warn(
|
|
5425
5584
|
`${_LOCAL_CONFIG_FILE} already exists; re-run with --force to overwrite. Skipping interactive init.`
|
|
@@ -5446,7 +5605,7 @@ function run_interactive_init(project_root, force) {
|
|
|
5446
5605
|
warn(`Could not write ${target}: ${String(exc)}`);
|
|
5447
5606
|
return 1;
|
|
5448
5607
|
}
|
|
5449
|
-
success(`Wrote ${
|
|
5608
|
+
success(`Wrote ${path5.relative(project_root, target)} (${user_type} / ${stack} / ${verbosity})`);
|
|
5450
5609
|
return 0;
|
|
5451
5610
|
}
|
|
5452
5611
|
var _WIZARD_READY_RE = /^WIZARD_READY (http:\/\/(?:127\.0\.0\.1|localhost):\d+\/\S*)\r?$/;
|
|
@@ -5464,12 +5623,12 @@ function _wizard_should_launch(opts) {
|
|
|
5464
5623
|
return [true, ""];
|
|
5465
5624
|
}
|
|
5466
5625
|
function _wizard_cli_dist(_project_root) {
|
|
5467
|
-
const package_root =
|
|
5468
|
-
const cli =
|
|
5626
|
+
const package_root = path5.dirname(path5.dirname(path5.dirname(resolvePath(_HERE))));
|
|
5627
|
+
const cli = path5.join(package_root, "dist", "cli", "agent-config.js");
|
|
5469
5628
|
return pathExists(cli) ? cli : null;
|
|
5470
5629
|
}
|
|
5471
5630
|
function _server_info_path() {
|
|
5472
|
-
return
|
|
5631
|
+
return path5.join(os2.homedir(), ".event4u", "agent-config", "local-server.json");
|
|
5473
5632
|
}
|
|
5474
5633
|
function _pid_is_agent_config(pid) {
|
|
5475
5634
|
let res;
|
|
@@ -5486,7 +5645,7 @@ function _pid_is_agent_config(pid) {
|
|
|
5486
5645
|
}
|
|
5487
5646
|
function unlinkMissingOk(p) {
|
|
5488
5647
|
try {
|
|
5489
|
-
|
|
5648
|
+
fs6.unlinkSync(p);
|
|
5490
5649
|
} catch {
|
|
5491
5650
|
}
|
|
5492
5651
|
}
|
|
@@ -5564,14 +5723,14 @@ function _wizard_spawn(project_root, pass_project_root = true) {
|
|
|
5564
5723
|
}
|
|
5565
5724
|
function _wizard_run_sync(cmd, env, cli) {
|
|
5566
5725
|
const total = _WIZARD_TIMEOUTS.reduce((a, b) => a + b, 0);
|
|
5567
|
-
const log_path =
|
|
5726
|
+
const log_path = path5.join(
|
|
5568
5727
|
os2.tmpdir(),
|
|
5569
5728
|
`agent-config-wizard-${process2.pid}-${Date.now()}.log`
|
|
5570
5729
|
);
|
|
5571
5730
|
let child;
|
|
5572
5731
|
let log_fd = null;
|
|
5573
5732
|
try {
|
|
5574
|
-
log_fd =
|
|
5733
|
+
log_fd = fs6.openSync(log_path, "w");
|
|
5575
5734
|
child = spawn(cmd[0], cmd.slice(1), {
|
|
5576
5735
|
env,
|
|
5577
5736
|
detached: true,
|
|
@@ -5589,7 +5748,7 @@ function _wizard_run_sync(cmd, env, cli) {
|
|
|
5589
5748
|
} finally {
|
|
5590
5749
|
if (log_fd !== null) {
|
|
5591
5750
|
try {
|
|
5592
|
-
|
|
5751
|
+
fs6.closeSync(log_fd);
|
|
5593
5752
|
} catch {
|
|
5594
5753
|
}
|
|
5595
5754
|
}
|
|
@@ -5839,8 +5998,8 @@ function main2(argv) {
|
|
|
5839
5998
|
const target_root = resolvePath(
|
|
5840
5999
|
opts.custom_path || opts.project || process2.env["PROJECT_ROOT"] || process2.cwd()
|
|
5841
6000
|
);
|
|
5842
|
-
const minimal_package_root =
|
|
5843
|
-
|
|
6001
|
+
const minimal_package_root = path5.dirname(
|
|
6002
|
+
path5.dirname(path5.dirname(_minimal_templates_root()))
|
|
5844
6003
|
);
|
|
5845
6004
|
const validated_user_type = _validate_user_type(minimal_package_root, opts.user_type);
|
|
5846
6005
|
return install_minimal(target_root, opts.force, validated_user_type);
|
|
@@ -5854,6 +6013,9 @@ function main2(argv) {
|
|
|
5854
6013
|
let parsed_tools = _parse_tools(opts.tools);
|
|
5855
6014
|
const tools_was_all = _tools_was_all(opts.tools);
|
|
5856
6015
|
parsed_tools = _validate_scope(parsed_tools, scope, tools_was_all);
|
|
6016
|
+
if (parsed_tools.has("claude-code") && !_gate_rule_layer_overlap(detect_root, opts.layer, opts.dry_run)) {
|
|
6017
|
+
return 2;
|
|
6018
|
+
}
|
|
5857
6019
|
const wizard_handoff = _wizard_should_launch(opts)[0];
|
|
5858
6020
|
if (scope === "global") {
|
|
5859
6021
|
const artefacts = _detect_legacy_for_migration(detect_root);
|
|
@@ -5869,7 +6031,7 @@ function main2(argv) {
|
|
|
5869
6031
|
return rc2;
|
|
5870
6032
|
}
|
|
5871
6033
|
const project_root = custom_path || resolvePath(opts.project || process2.env["PROJECT_ROOT"] || process2.cwd());
|
|
5872
|
-
const is_first_run = !pathExists(
|
|
6034
|
+
const is_first_run = !pathExists(path5.join(project_root, SETTINGS_FILE));
|
|
5873
6035
|
const rc = _main_project_install(opts, project_root, parsed_tools, is_first_run);
|
|
5874
6036
|
if (rc === 0 && opts.interactive) {
|
|
5875
6037
|
run_interactive_init(project_root, opts.force);
|
|
@@ -5933,16 +6095,16 @@ function _team_setup_hint_line(project_root) {
|
|
|
5933
6095
|
return " \u2022 Claude Code team mode (optional cross-model review via the official codex plugin): run `agent-config doctor --check team` for setup status.";
|
|
5934
6096
|
}
|
|
5935
6097
|
function finalize_claude_model_tiers(project_root) {
|
|
5936
|
-
const claude_skills =
|
|
5937
|
-
const augment_skills =
|
|
6098
|
+
const claude_skills = path5.join(project_root, ".claude", "skills");
|
|
6099
|
+
const augment_skills = path5.join(project_root, ".augment", "skills");
|
|
5938
6100
|
if (!isDir(claude_skills) || !isDir(augment_skills)) return 0;
|
|
5939
6101
|
if (_read_consumer_auto_switch(project_root) !== "auto") return 0;
|
|
5940
6102
|
let rendered = 0;
|
|
5941
|
-
const entries =
|
|
6103
|
+
const entries = fs6.readdirSync(claude_skills).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
|
|
5942
6104
|
for (const name of entries) {
|
|
5943
|
-
const entry =
|
|
5944
|
-
const src_dir =
|
|
5945
|
-
const src_md =
|
|
6105
|
+
const entry = path5.join(claude_skills, name);
|
|
6106
|
+
const src_dir = path5.join(augment_skills, name);
|
|
6107
|
+
const src_md = path5.join(src_dir, "SKILL.md");
|
|
5946
6108
|
let tier;
|
|
5947
6109
|
try {
|
|
5948
6110
|
tier = read_model_tier(src_md);
|
|
@@ -5951,22 +6113,22 @@ function finalize_claude_model_tiers(project_root) {
|
|
|
5951
6113
|
}
|
|
5952
6114
|
if (tier === null || !(tier in TIER_TO_CLAUDE_MODEL) || !isDir(src_dir)) continue;
|
|
5953
6115
|
if (isSymlink(entry) || isFile(entry)) {
|
|
5954
|
-
|
|
6116
|
+
fs6.unlinkSync(entry);
|
|
5955
6117
|
} else if (isDir(entry)) {
|
|
5956
|
-
|
|
6118
|
+
fs6.rmSync(entry, { recursive: true, force: true });
|
|
5957
6119
|
}
|
|
5958
6120
|
mkdirp(entry);
|
|
5959
|
-
const srcFiles =
|
|
6121
|
+
const srcFiles = fs6.readdirSync(src_dir).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
|
|
5960
6122
|
for (const fname of srcFiles) {
|
|
5961
6123
|
if (fname === "SKILL.md") {
|
|
5962
6124
|
writeText(
|
|
5963
|
-
|
|
6125
|
+
path5.join(entry, "SKILL.md"),
|
|
5964
6126
|
render_native_model_md(readText(src_md), tier)
|
|
5965
6127
|
);
|
|
5966
6128
|
} else {
|
|
5967
|
-
|
|
5968
|
-
|
|
5969
|
-
|
|
6129
|
+
fs6.symlinkSync(
|
|
6130
|
+
path5.join("../../../.augment/skills", name, fname),
|
|
6131
|
+
path5.join(entry, fname)
|
|
5970
6132
|
);
|
|
5971
6133
|
}
|
|
5972
6134
|
}
|
|
@@ -5984,7 +6146,7 @@ function _main_project_install(opts, project_root, parsed_tools, is_first_run) {
|
|
|
5984
6146
|
let package_type;
|
|
5985
6147
|
if (opts.package) {
|
|
5986
6148
|
package_root = resolvePath(opts.package);
|
|
5987
|
-
if (!pathExists(
|
|
6149
|
+
if (!pathExists(path5.join(package_root, "src", "config", "profiles", "minimal.ini"))) {
|
|
5988
6150
|
fail(`Invalid --package path (missing src/config/profiles/minimal.ini): ${package_root}`);
|
|
5989
6151
|
}
|
|
5990
6152
|
package_type = detect_package_type_for_project(project_root, package_root);
|
|
@@ -6119,9 +6281,9 @@ function _main_project_install(opts, project_root, parsed_tools, is_first_run) {
|
|
|
6119
6281
|
function _resolvedArgv1() {
|
|
6120
6282
|
if (process2.argv[1] === void 0) return void 0;
|
|
6121
6283
|
try {
|
|
6122
|
-
return
|
|
6284
|
+
return fs6.realpathSync(path5.resolve(process2.argv[1]));
|
|
6123
6285
|
} catch {
|
|
6124
|
-
return
|
|
6286
|
+
return path5.resolve(process2.argv[1]);
|
|
6125
6287
|
}
|
|
6126
6288
|
}
|
|
6127
6289
|
var _argv1 = _resolvedArgv1();
|