@event4u/agent-config 12.0.0 → 13.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +273 -0
- package/README.md +1 -1
- package/agents/templates/.ai-council.yml.example +46 -3
- package/dist/agent-src/commands/cost/report.md +23 -0
- package/dist/agent-src/contexts/execution/subagent-routing.md +148 -33
- package/dist/agent-src/contexts/model-recommendations.md +6 -4
- package/dist/agent-src/contexts/subagent-configuration.md +69 -7
- package/dist/agent-src/rules/autonomous-execution.md +1 -1
- package/dist/agent-src/rules/design-fidelity.md +1 -1
- package/dist/agent-src/rules/design-review-after-ui-write.md +10 -5
- package/dist/agent-src/rules/evaluator-independence.md +27 -5
- package/dist/agent-src/rules/git-history-discipline.md +5 -1
- package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +1 -0
- package/dist/agent-src/rules/missing-skill-recovery.md +89 -0
- package/dist/agent-src/rules/ui-audit-gate.md +9 -4
- package/dist/agent-src/scripts/archive_completed_roadmaps.ts +33 -0
- package/dist/agent-src/scripts/roadmap_gates.ts +30 -2
- package/dist/agent-src/scripts/update_roadmap_progress.ts +47 -1
- package/dist/agent-src/skills/authz-review/SKILL.md +4 -0
- package/dist/agent-src/skills/design-system-capture/SKILL.md +4 -0
- package/dist/agent-src/skills/design-system-capture/references/snapshot-preference-order.md +77 -0
- package/dist/agent-src/skills/merge-conflicts/SKILL.md +4 -0
- package/dist/agent-src/skills/prompt-optimizer/SKILL.md +17 -1
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +11 -11
- package/dist/agent-src/skills/systematic-debugging/SKILL.md +4 -0
- package/dist/agent-src/skills/threat-modeling/SKILL.md +3 -0
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +41 -3
- package/dist/cli/registry.js +1 -0
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli-delegate/{chunk-NN4KW4HZ.js → chunk-3B72LSZL.js} +123 -2338
- package/dist/cli-delegate/{chunk-55WZN5VF.js → chunk-EVTY7ISR.js} +2 -2
- package/dist/cli-delegate/chunk-N7FEST6D.js +3895 -0
- package/dist/cli-delegate/{chunk-L565YFXH.js → chunk-XURJ4AQC.js} +566 -298
- package/dist/cli-delegate/cmd_conformance.js +4 -4
- package/dist/cli-delegate/cmd_doctor.js +2 -2
- package/dist/cli-delegate/cmd_export.js +2 -2
- package/dist/cli-delegate/cmd_handoff.js +1 -1
- package/dist/cli-delegate/cmd_prune.js +2 -2
- package/dist/cli-delegate/cmd_settings_migrate.js +2 -2
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +2 -2
- package/dist/cli-delegate/cmd_uninstall.js +2 -2
- package/dist/cli-delegate/cmd_validate.js +2 -2
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +44 -23
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +3 -3
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +6 -5
- package/dist/discovery/trust-report.md +2 -2
- package/dist/discovery/workspaces.json +5 -4
- package/dist/hooks/dispatch.js +10625 -8541
- package/dist/install/install.mjs +754 -484
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +1302 -167
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/model_tier.js +9 -0
- package/dist/scripts/_lib/model_tier.js.map +1 -1
- package/dist/scripts/condense.js +50 -0
- package/dist/scripts/condense.js.map +1 -1
- package/dist/server/schemas/settings.js +2 -2
- package/dist/server/schemas/settings.js.map +1 -1
- package/docs/MIGRATION.md +20 -1
- package/docs/guidelines/design-fidelity-mechanics.md +21 -0
- package/docs/guidelines/design-handover-extraction.md +87 -0
- package/docs/guidelines/prompt-templates.md +24 -1
- package/package.json +1 -1
- package/src/agent-src/scripts/archive_completed_roadmaps.ts +33 -0
- package/src/agent-src/scripts/roadmap_gates.ts +30 -2
- package/src/agent-src/scripts/update_roadmap_progress.ts +47 -1
- package/src/config/evaluator-budgets.json +9 -8
- package/src/config/gate-coverage.yml +63 -11
- package/src/config/gate-violation-baselines.json +12 -0
- package/src/config/hook-token-budget.json +15 -2
- package/src/config/preamble-payload-budget.json +28 -0
- package/src/scripts/_dispatch.bash +10 -0
- package/src/scripts/_lib/bench_ab_complexity.ts +439 -0
- package/src/scripts/_lib/bench_ab_safety_tier.ts +142 -0
- package/src/scripts/_lib/bench_ab_scoring_v2.ts +28 -3
- package/src/scripts/_lib/bench_ab_search_adherence.ts +423 -0
- package/src/scripts/_lib/bench_ab_size_claim.ts +206 -0
- package/src/scripts/_lib/bench_ab_workspace.ts +111 -0
- package/src/scripts/_lib/git_common_dir.ts +173 -0
- package/src/scripts/_lib/model_tier.ts +9 -0
- package/src/scripts/_lib/release_highlights.ts +108 -7
- package/src/scripts/_lib/skill_catalogue.ts +1115 -0
- package/src/scripts/_lib/tier_budget_routing.ts +31 -331
- package/src/scripts/ai_council/clients.ts +197 -18
- package/src/scripts/ai_council/config.ts +16 -1
- package/src/scripts/ai_council/low_impact.ts +14 -1
- package/src/scripts/ai_council/orchestrator.ts +14 -1
- package/src/scripts/ai_council/transport_resolver.ts +32 -2
- package/src/scripts/bench_ab_v2_complexity.ts +252 -0
- package/src/scripts/bench_ab_v2_run.ts +3 -42
- package/src/scripts/bench_ab_v2_safety.ts +296 -0
- package/src/scripts/bench_ab_v2_search.ts +343 -0
- package/src/scripts/bench_ab_v2_stats.ts +191 -0
- package/src/scripts/build_archive_index.ts +383 -0
- package/src/scripts/capture_skill_catalogue.ts +279 -317
- package/src/scripts/check_branch_freshness.ts +7 -1
- package/src/scripts/check_release_published.ts +6 -2
- package/src/scripts/check_release_trunk_sync.ts +18 -2
- package/src/scripts/check_source_size_budget.ts +428 -0
- package/src/scripts/check_suppression_hygiene.ts +5 -1
- package/src/scripts/condense.ts +50 -1
- package/src/scripts/cost/backfill_rates.mjs +298 -0
- package/src/scripts/cost/budget.mjs +12 -32
- package/src/scripts/cost_summary.ts +25 -0
- package/src/scripts/dispatch_r2_reviewer.ts +15 -5
- package/src/scripts/evidence_report.ts +15 -4
- package/src/scripts/external_sources_denylist.json +1 -0
- package/src/scripts/hook_manifest.yaml +75 -15
- package/src/scripts/hooks/concern_registry.ts +4 -0
- package/src/scripts/hooks/orchestration_record_hook.ts +21 -0
- package/src/scripts/hooks/skill_route_hook.ts +226 -0
- package/src/scripts/hooks/tool_result_bytes_hook.ts +219 -0
- package/src/scripts/hooks/ui_route_nudge_hook.ts +6 -3
- package/src/scripts/hot_context_hook.ts +13 -1
- package/src/scripts/install.ts +129 -0
- package/src/scripts/janitor.ts +77 -2
- package/src/scripts/lint_design_antipattern_parity.ts +40 -6
- package/src/scripts/lint_harvest_provenance.ts +35 -1
- package/src/scripts/lint_plan_risk_register.ts +22 -9
- package/src/scripts/lint_roadmap_blockers.ts +109 -6
- package/src/scripts/lint_rule_skill_pack_reach.ts +43 -0
- package/src/scripts/lint_scheduled_deprecations.ts +738 -0
- package/src/scripts/lint_skill_router_head.ts +21 -0
- package/src/scripts/mcp_server/consumer_tool_catalog.json +26 -3
- package/src/scripts/mcp_server/tool_catalog_source.ts +6 -24
- package/src/scripts/mcp_server/tools.ts +87 -0
- package/src/scripts/migration_status.ts +17 -1
- package/src/scripts/probe_review_binding_drift.ts +731 -0
- package/src/scripts/release.ts +100 -6
- package/src/scripts/routing_doctor.ts +50 -13
- package/src/scripts/schemas/command.schema.json +3 -3
- package/src/scripts/schemas/skill.schema.json +20 -2
- package/src/scripts/schemas/subagent.schema.json +2 -2
- package/src/scripts/session_eol_report.ts +81 -0
- package/src/scripts/trigger_coverage.ts +224 -3
- package/src/scripts/workspace_doctor.ts +464 -0
- package/src/scripts/worktree_cleanup_check.ts +2 -1
- package/src/server/schemas/settings.ts +2 -2
- package/dist/cli-delegate/chunk-AYKQGIBG.js +0 -1594
- package/src/config/budget-routing.json +0 -7
|
@@ -2,7 +2,7 @@ import { createRequire as __acCreateRequire } from 'node:module'; const require
|
|
|
2
2
|
import {
|
|
3
3
|
ZodFirstPartyTypeKind,
|
|
4
4
|
settingsSchema
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-EVTY7ISR.js";
|
|
6
6
|
import {
|
|
7
7
|
main
|
|
8
8
|
} from "./chunk-PPQO4NGR.js";
|
|
@@ -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 fs7 from "node:fs";
|
|
270
270
|
import * as os2 from "node:os";
|
|
271
|
-
import * as
|
|
271
|
+
import * as path6 from "node:path";
|
|
272
272
|
import process2 from "node:process";
|
|
273
273
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
274
274
|
|
|
@@ -614,10 +614,209 @@ function format_drift_report(entries) {
|
|
|
614
614
|
return lines.join("\n") + "\n";
|
|
615
615
|
}
|
|
616
616
|
|
|
617
|
-
// src/scripts/_lib/
|
|
618
|
-
import * as crypto2 from "node:crypto";
|
|
617
|
+
// src/scripts/_lib/skill_catalogue.ts
|
|
619
618
|
import * as fs3 from "node:fs";
|
|
620
619
|
import * as path3 from "node:path";
|
|
620
|
+
var OBSERVATION_LOG = path3.join(
|
|
621
|
+
"agents",
|
|
622
|
+
"evidence",
|
|
623
|
+
"metrics",
|
|
624
|
+
"skill-catalogue.jsonl"
|
|
625
|
+
);
|
|
626
|
+
function frontmatterOf(content) {
|
|
627
|
+
if (!content.startsWith("---")) return "";
|
|
628
|
+
const end = content.indexOf("\n---", 3);
|
|
629
|
+
if (end === -1) return "";
|
|
630
|
+
return content.slice(3, end);
|
|
631
|
+
}
|
|
632
|
+
function topLevelKeys(frontmatter) {
|
|
633
|
+
const keys = [];
|
|
634
|
+
for (const line of frontmatter.split("\n")) {
|
|
635
|
+
const match = /^([A-Za-z_][A-Za-z0-9_-]*):/.exec(line);
|
|
636
|
+
if (match) keys.push(match[1]);
|
|
637
|
+
}
|
|
638
|
+
return keys;
|
|
639
|
+
}
|
|
640
|
+
function descriptionOf(frontmatter) {
|
|
641
|
+
const lines = frontmatter.split("\n");
|
|
642
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
643
|
+
const match = /^description:\s*(.*)$/.exec(lines[i]);
|
|
644
|
+
if (!match) continue;
|
|
645
|
+
const rest = match[1].trim();
|
|
646
|
+
if (/^[|>][-+]?\d*$/.test(rest)) {
|
|
647
|
+
const body = [];
|
|
648
|
+
for (let j = i + 1; j < lines.length; j += 1) {
|
|
649
|
+
const line = lines[j];
|
|
650
|
+
if (line.trim() === "") {
|
|
651
|
+
body.push("");
|
|
652
|
+
continue;
|
|
653
|
+
}
|
|
654
|
+
if (!/^\s/.test(line)) break;
|
|
655
|
+
body.push(line.trim());
|
|
656
|
+
}
|
|
657
|
+
return body.join(" ").trim();
|
|
658
|
+
}
|
|
659
|
+
return rest.replace(/^["']|["']$/g, "");
|
|
660
|
+
}
|
|
661
|
+
return "";
|
|
662
|
+
}
|
|
663
|
+
function readProjectedCatalogue(root) {
|
|
664
|
+
const names = fs3.readdirSync(root).filter((n) => fs3.existsSync(path3.join(root, n, "SKILL.md"))).sort();
|
|
665
|
+
return names.map((name, index) => {
|
|
666
|
+
const content = fs3.readFileSync(path3.join(root, name, "SKILL.md"), "utf-8");
|
|
667
|
+
const frontmatter = frontmatterOf(content);
|
|
668
|
+
const description = descriptionOf(frontmatter);
|
|
669
|
+
return {
|
|
670
|
+
name,
|
|
671
|
+
position: index + 1,
|
|
672
|
+
hasDescription: description.length > 0,
|
|
673
|
+
descriptionLength: description.length,
|
|
674
|
+
description,
|
|
675
|
+
frontmatterKeys: topLevelKeys(frontmatter)
|
|
676
|
+
};
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
function truncationModeOf(record) {
|
|
680
|
+
return record.truncation_mode ?? "per-entry";
|
|
681
|
+
}
|
|
682
|
+
function markdownFilesUnder(root) {
|
|
683
|
+
if (!fs3.existsSync(root)) return [];
|
|
684
|
+
const out = [];
|
|
685
|
+
const walk = (dir) => {
|
|
686
|
+
for (const entry of fs3.readdirSync(dir, { withFileTypes: true })) {
|
|
687
|
+
const full = path3.join(dir, entry.name);
|
|
688
|
+
if (fs3.statSync(full).isDirectory()) walk(full);
|
|
689
|
+
else if (entry.name.endsWith(".md")) out.push(full);
|
|
690
|
+
}
|
|
691
|
+
};
|
|
692
|
+
walk(root);
|
|
693
|
+
return out;
|
|
694
|
+
}
|
|
695
|
+
function measureCatalogueVolume(host, root) {
|
|
696
|
+
const skillsRoot = path3.join(root, "skills");
|
|
697
|
+
const skills = fs3.existsSync(skillsRoot) ? readProjectedCatalogue(skillsRoot) : [];
|
|
698
|
+
const commandEntries = markdownFilesUnder(path3.join(root, "commands")).length;
|
|
699
|
+
return {
|
|
700
|
+
host,
|
|
701
|
+
root,
|
|
702
|
+
skillEntries: skills.length,
|
|
703
|
+
commandEntries,
|
|
704
|
+
artefacts: skills.length + commandEntries,
|
|
705
|
+
descriptionBytes: skills.reduce((sum, e) => sum + Buffer.byteLength(e.description), 0)
|
|
706
|
+
};
|
|
707
|
+
}
|
|
708
|
+
function _supersedes(candidate, incumbent) {
|
|
709
|
+
if (candidate.observed_at !== incumbent.observed_at) {
|
|
710
|
+
return candidate.observed_at > incumbent.observed_at;
|
|
711
|
+
}
|
|
712
|
+
return (candidate.dropped_count ?? 0) > (incumbent.dropped_count ?? 0);
|
|
713
|
+
}
|
|
714
|
+
function knownHostLimits(records) {
|
|
715
|
+
const out = /* @__PURE__ */ new Map();
|
|
716
|
+
const chosen = /* @__PURE__ */ new Map();
|
|
717
|
+
for (const record of records) {
|
|
718
|
+
if (truncationModeOf(record) !== "budget-strip-and-drop") continue;
|
|
719
|
+
if (typeof record.dropped_count !== "number") continue;
|
|
720
|
+
if (record.dropped_count <= 0) continue;
|
|
721
|
+
const previous = chosen.get(record.host);
|
|
722
|
+
if (previous !== void 0 && !_supersedes(record, previous)) continue;
|
|
723
|
+
chosen.set(record.host, record);
|
|
724
|
+
out.set(record.host, {
|
|
725
|
+
host: record.host,
|
|
726
|
+
droppedEntries: record.dropped_count,
|
|
727
|
+
projectedVolume: record.entries_total,
|
|
728
|
+
projectedSkills: record.projected_skill_count ?? null,
|
|
729
|
+
observedAt: record.observed_at
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
return out;
|
|
733
|
+
}
|
|
734
|
+
function catalogueLimitWarning(volume, limit) {
|
|
735
|
+
if (limit === void 0) return null;
|
|
736
|
+
if (limit.projectedSkills === null) return null;
|
|
737
|
+
if (volume.skillEntries < limit.projectedSkills) return null;
|
|
738
|
+
return `${volume.host}: deploying ${volume.skillEntries} skills. This host reported dropping ${limit.droppedEntries} entries from the model-visible list when last measured (${limit.observedAt}, at ${limit.projectedSkills} skills) \u2014 that much never reaches the model. Explain: \`agent-config exec capture_skill_catalogue --limits\``;
|
|
739
|
+
}
|
|
740
|
+
function migrationEligibility(host, resolvedMode, currentSkillCount, limits) {
|
|
741
|
+
if (resolvedMode === "scoped") return { eligible: false, reason: "already-scoped" };
|
|
742
|
+
const limit = limits.get(host);
|
|
743
|
+
if (limit === void 0) return { eligible: false, reason: "no-observation-for-host" };
|
|
744
|
+
if (limit.projectedSkills === null) return { eligible: false, reason: "observation-not-comparable" };
|
|
745
|
+
if (limit.droppedEntries <= 0) return { eligible: false, reason: "no-truncation-observed" };
|
|
746
|
+
if (currentSkillCount < limit.projectedSkills) {
|
|
747
|
+
return { eligible: false, reason: "below-observed-skill-volume" };
|
|
748
|
+
}
|
|
749
|
+
return {
|
|
750
|
+
eligible: true,
|
|
751
|
+
reason: "eligible",
|
|
752
|
+
droppedEntries: limit.droppedEntries,
|
|
753
|
+
observedAt: limit.observedAt
|
|
754
|
+
};
|
|
755
|
+
}
|
|
756
|
+
function migrationPromptLines(host, eligibility, settingsPath) {
|
|
757
|
+
return [
|
|
758
|
+
`${host}: ${eligibility.droppedEntries} catalogue entries never reach the model.`,
|
|
759
|
+
`Measured on this machine (${eligibility.observedAt}). This install is on \`legacy-all\`,`,
|
|
760
|
+
"which ships everything and lets the host drop what does not fit \u2014 silently.",
|
|
761
|
+
"",
|
|
762
|
+
"Scoping the projection to your active packs is the alternative. Nothing here",
|
|
763
|
+
"changes it for you: `projection.mode` is yours to set, by hand or in the GUI.",
|
|
764
|
+
"",
|
|
765
|
+
` edit ${settingsPath}`,
|
|
766
|
+
" projection:",
|
|
767
|
+
" mode: scoped",
|
|
768
|
+
"",
|
|
769
|
+
" or agent-config config (Settings \u2192 projection)",
|
|
770
|
+
"",
|
|
771
|
+
"Keeping `legacy-all` is a legitimate choice \u2014 this is a notification, not a gate."
|
|
772
|
+
];
|
|
773
|
+
}
|
|
774
|
+
function readObservationLog(logPath) {
|
|
775
|
+
if (!fs3.existsSync(logPath)) return [];
|
|
776
|
+
const out = [];
|
|
777
|
+
for (const line of fs3.readFileSync(logPath, "utf-8").split("\n")) {
|
|
778
|
+
const trimmed = line.trim();
|
|
779
|
+
if (trimmed.length === 0) continue;
|
|
780
|
+
try {
|
|
781
|
+
out.push(JSON.parse(trimmed));
|
|
782
|
+
} catch {
|
|
783
|
+
continue;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
return out;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
// src/shared/interactiveContext.ts
|
|
790
|
+
var CI_ENV_KEYS = ["CI", "GITHUB_ACTIONS", "AGENT_CONFIG_CI"];
|
|
791
|
+
function _flagSet(env, key) {
|
|
792
|
+
const raw = (env[key] ?? "").trim();
|
|
793
|
+
return raw !== "" && raw !== "0";
|
|
794
|
+
}
|
|
795
|
+
function nonInteractiveReason(probe) {
|
|
796
|
+
for (const key of CI_ENV_KEYS) {
|
|
797
|
+
if (_flagSet(probe.env, key)) {
|
|
798
|
+
return "ci";
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
if (_flagSet(probe.env, "AGENT_CONFIG_NO_UI")) {
|
|
802
|
+
return "no-ui-requested";
|
|
803
|
+
}
|
|
804
|
+
if (!probe.stdinTty || !probe.stdoutTty) {
|
|
805
|
+
return "not-a-tty";
|
|
806
|
+
}
|
|
807
|
+
if (probe.headless === true) {
|
|
808
|
+
return "headless";
|
|
809
|
+
}
|
|
810
|
+
return null;
|
|
811
|
+
}
|
|
812
|
+
function isInteractiveSession(probe) {
|
|
813
|
+
return nonInteractiveReason(probe) === null;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
// src/scripts/_lib/claude_desktop_bundler.ts
|
|
817
|
+
import * as crypto2 from "node:crypto";
|
|
818
|
+
import * as fs4 from "node:fs";
|
|
819
|
+
import * as path4 from "node:path";
|
|
621
820
|
|
|
622
821
|
// src/scripts/_lib/zip_min.ts
|
|
623
822
|
import * as zlib from "node:zlib";
|
|
@@ -724,7 +923,7 @@ function _is_excluded(rel_parts) {
|
|
|
724
923
|
}
|
|
725
924
|
function _is_dir(p) {
|
|
726
925
|
try {
|
|
727
|
-
return
|
|
926
|
+
return fs4.statSync(p).isDirectory();
|
|
728
927
|
} catch {
|
|
729
928
|
return false;
|
|
730
929
|
}
|
|
@@ -736,12 +935,12 @@ function _compare_rel_parts(a, b) {
|
|
|
736
935
|
}
|
|
737
936
|
function _walk_skill_files(skill_dir) {
|
|
738
937
|
const out = [];
|
|
739
|
-
const resolved =
|
|
938
|
+
const resolved = fs4.realpathSync(skill_dir);
|
|
740
939
|
const walk = (root, relRoot) => {
|
|
741
940
|
const dirNames = [];
|
|
742
941
|
const fileNames = [];
|
|
743
|
-
for (const dirent of
|
|
744
|
-
const full =
|
|
942
|
+
for (const dirent of fs4.readdirSync(root, { withFileTypes: true })) {
|
|
943
|
+
const full = path4.join(root, dirent.name);
|
|
745
944
|
const isDir2 = dirent.isDirectory() || dirent.isSymbolicLink() && _is_dir(full);
|
|
746
945
|
if (isDir2) {
|
|
747
946
|
dirNames.push(dirent.name);
|
|
@@ -754,13 +953,13 @@ function _walk_skill_files(skill_dir) {
|
|
|
754
953
|
if (_is_excluded(rel_parts)) {
|
|
755
954
|
continue;
|
|
756
955
|
}
|
|
757
|
-
out.push([
|
|
956
|
+
out.push([path4.join(root, fname), rel_parts]);
|
|
758
957
|
}
|
|
759
958
|
for (const dname of dirNames) {
|
|
760
959
|
if (_is_excluded([dname])) {
|
|
761
960
|
continue;
|
|
762
961
|
}
|
|
763
|
-
walk(
|
|
962
|
+
walk(path4.join(root, dname), [...relRoot, dname]);
|
|
764
963
|
}
|
|
765
964
|
};
|
|
766
965
|
walk(resolved, []);
|
|
@@ -773,53 +972,53 @@ function _manifest_digest(files) {
|
|
|
773
972
|
const rel = rel_parts.join("/");
|
|
774
973
|
h.update(Buffer.from(rel, "utf-8"));
|
|
775
974
|
h.update(Buffer.from([0]));
|
|
776
|
-
h.update(crypto2.createHash("sha256").update(
|
|
975
|
+
h.update(crypto2.createHash("sha256").update(fs4.readFileSync(abs_path)).digest());
|
|
777
976
|
h.update(Buffer.from([0]));
|
|
778
977
|
}
|
|
779
978
|
return h.digest("hex");
|
|
780
979
|
}
|
|
781
980
|
function _atomic_write_zip(zip_path, files) {
|
|
782
|
-
|
|
783
|
-
const stem =
|
|
784
|
-
const tmp_path =
|
|
785
|
-
|
|
981
|
+
fs4.mkdirSync(path4.dirname(zip_path), { recursive: true });
|
|
982
|
+
const stem = path4.basename(zip_path, path4.extname(zip_path));
|
|
983
|
+
const tmp_path = path4.join(
|
|
984
|
+
path4.dirname(zip_path),
|
|
786
985
|
`.${stem}.${crypto2.randomBytes(6).toString("hex")}.zip.tmp`
|
|
787
986
|
);
|
|
788
987
|
try {
|
|
789
988
|
const entries = files.map(([abs_path, rel_parts]) => ({
|
|
790
989
|
name: rel_parts.join("/"),
|
|
791
|
-
data:
|
|
990
|
+
data: fs4.readFileSync(abs_path)
|
|
792
991
|
}));
|
|
793
|
-
|
|
794
|
-
|
|
992
|
+
fs4.writeFileSync(tmp_path, zip_write_sync(entries));
|
|
993
|
+
fs4.renameSync(tmp_path, zip_path);
|
|
795
994
|
} finally {
|
|
796
|
-
if (
|
|
797
|
-
|
|
995
|
+
if (fs4.existsSync(tmp_path)) {
|
|
996
|
+
fs4.unlinkSync(tmp_path);
|
|
798
997
|
}
|
|
799
998
|
}
|
|
800
999
|
}
|
|
801
1000
|
function _write_if_changed(dest_dir, slug, files, force, written) {
|
|
802
1001
|
const digest = _manifest_digest(files);
|
|
803
|
-
const zip_path =
|
|
804
|
-
const digest_path =
|
|
805
|
-
const recorded =
|
|
806
|
-
if (!force && recorded === digest &&
|
|
1002
|
+
const zip_path = path4.join(dest_dir, `${slug}.zip`);
|
|
1003
|
+
const digest_path = path4.join(dest_dir, `${slug}.sha256`);
|
|
1004
|
+
const recorded = fs4.existsSync(digest_path) ? fs4.readFileSync(digest_path, "utf-8").trim() : "";
|
|
1005
|
+
if (!force && recorded === digest && fs4.existsSync(zip_path)) {
|
|
807
1006
|
return;
|
|
808
1007
|
}
|
|
809
1008
|
_atomic_write_zip(zip_path, files);
|
|
810
|
-
|
|
1009
|
+
fs4.writeFileSync(digest_path, digest + "\n", "utf-8");
|
|
811
1010
|
written.push(zip_path);
|
|
812
1011
|
}
|
|
813
1012
|
function build_skill_bundles(package_root, dest_dir, force = false, curation = null) {
|
|
814
|
-
const skills_root =
|
|
1013
|
+
const skills_root = path4.join(package_root, "dist/agent-src", "skills");
|
|
815
1014
|
if (!_is_dir(skills_root)) {
|
|
816
1015
|
return [];
|
|
817
1016
|
}
|
|
818
|
-
|
|
1017
|
+
fs4.mkdirSync(dest_dir, { recursive: true });
|
|
819
1018
|
const written = [];
|
|
820
|
-
for (const name of
|
|
821
|
-
const entry =
|
|
822
|
-
const isSymlink2 =
|
|
1019
|
+
for (const name of fs4.readdirSync(skills_root).sort()) {
|
|
1020
|
+
const entry = path4.join(skills_root, name);
|
|
1021
|
+
const isSymlink2 = fs4.lstatSync(entry).isSymbolicLink();
|
|
823
1022
|
if (!(_is_dir(entry) || isSymlink2)) {
|
|
824
1023
|
continue;
|
|
825
1024
|
}
|
|
@@ -827,8 +1026,8 @@ function build_skill_bundles(package_root, dest_dir, force = false, curation = n
|
|
|
827
1026
|
if (curation !== null && !curation.includes(skill_name)) {
|
|
828
1027
|
continue;
|
|
829
1028
|
}
|
|
830
|
-
const skill_md =
|
|
831
|
-
if (!
|
|
1029
|
+
const skill_md = path4.join(entry, "SKILL.md");
|
|
1030
|
+
if (!fs4.existsSync(skill_md)) {
|
|
832
1031
|
continue;
|
|
833
1032
|
}
|
|
834
1033
|
const files = _walk_skill_files(entry);
|
|
@@ -840,15 +1039,15 @@ function build_skill_bundles(package_root, dest_dir, force = false, curation = n
|
|
|
840
1039
|
return written;
|
|
841
1040
|
}
|
|
842
1041
|
function _command_slug(source_file, commands_root) {
|
|
843
|
-
const rel =
|
|
844
|
-
const noExt = rel.slice(0, rel.length -
|
|
845
|
-
return noExt.split(
|
|
1042
|
+
const rel = path4.relative(commands_root, source_file);
|
|
1043
|
+
const noExt = rel.slice(0, rel.length - path4.extname(rel).length);
|
|
1044
|
+
return noExt.split(path4.sep).join("-");
|
|
846
1045
|
}
|
|
847
1046
|
function _iter_command_files(commands_root) {
|
|
848
1047
|
const found = [];
|
|
849
1048
|
const walk = (dir) => {
|
|
850
|
-
for (const dirent of
|
|
851
|
-
const full =
|
|
1049
|
+
for (const dirent of fs4.readdirSync(dir, { withFileTypes: true })) {
|
|
1050
|
+
const full = path4.join(dir, dirent.name);
|
|
852
1051
|
if (dirent.isDirectory() || dirent.isSymbolicLink() && _is_dir(full)) {
|
|
853
1052
|
walk(full);
|
|
854
1053
|
} else if (dirent.name.endsWith(".md")) {
|
|
@@ -858,21 +1057,21 @@ function _iter_command_files(commands_root) {
|
|
|
858
1057
|
};
|
|
859
1058
|
walk(commands_root);
|
|
860
1059
|
found.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
|
|
861
|
-
return found.filter((source_file) =>
|
|
1060
|
+
return found.filter((source_file) => path4.basename(source_file) !== "AGENTS.md");
|
|
862
1061
|
}
|
|
863
1062
|
function build_command_bundles(package_root, dest_dir, force = false, curation = null) {
|
|
864
|
-
const commands_root =
|
|
1063
|
+
const commands_root = path4.join(package_root, "dist/agent-src", "commands");
|
|
865
1064
|
if (!_is_dir(commands_root)) {
|
|
866
1065
|
return [];
|
|
867
1066
|
}
|
|
868
|
-
const skills_root =
|
|
1067
|
+
const skills_root = path4.join(package_root, "dist/agent-src", "skills");
|
|
869
1068
|
let skill_names = /* @__PURE__ */ new Set();
|
|
870
1069
|
if (_is_dir(skills_root)) {
|
|
871
1070
|
skill_names = new Set(
|
|
872
|
-
|
|
1071
|
+
fs4.readdirSync(skills_root).filter((name) => _is_dir(path4.join(skills_root, name)))
|
|
873
1072
|
);
|
|
874
1073
|
}
|
|
875
|
-
|
|
1074
|
+
fs4.mkdirSync(dest_dir, { recursive: true });
|
|
876
1075
|
const written = [];
|
|
877
1076
|
for (const source_file of _iter_command_files(commands_root)) {
|
|
878
1077
|
const slug = _command_slug(source_file, commands_root);
|
|
@@ -882,7 +1081,7 @@ function build_command_bundles(package_root, dest_dir, force = false, curation =
|
|
|
882
1081
|
if (curation !== null && !curation.includes(slug)) {
|
|
883
1082
|
continue;
|
|
884
1083
|
}
|
|
885
|
-
const files = [[
|
|
1084
|
+
const files = [[fs4.realpathSync(source_file), ["SKILL.md"]]];
|
|
886
1085
|
_write_if_changed(dest_dir, slug, files, force, written);
|
|
887
1086
|
}
|
|
888
1087
|
return written;
|
|
@@ -2243,8 +2442,8 @@ var zodToJsonSchema = (schema, options) => {
|
|
|
2243
2442
|
};
|
|
2244
2443
|
|
|
2245
2444
|
// src/scripts/_lib/module_detection.ts
|
|
2246
|
-
import * as
|
|
2247
|
-
import * as
|
|
2445
|
+
import * as fs5 from "node:fs";
|
|
2446
|
+
import * as path5 from "node:path";
|
|
2248
2447
|
var _SKIP_DIRS = /* @__PURE__ */ new Set([".module-template", ".example"]);
|
|
2249
2448
|
var _RULES = [
|
|
2250
2449
|
["app/Modules", "laravel-hmvc", "App\\Modules\\{ModuleName}"],
|
|
@@ -2258,14 +2457,14 @@ var _RULES = [
|
|
|
2258
2457
|
];
|
|
2259
2458
|
function _isDir(p) {
|
|
2260
2459
|
try {
|
|
2261
|
-
return
|
|
2460
|
+
return fs5.statSync(p).isDirectory();
|
|
2262
2461
|
} catch {
|
|
2263
2462
|
return false;
|
|
2264
2463
|
}
|
|
2265
2464
|
}
|
|
2266
2465
|
function _isFile(p) {
|
|
2267
2466
|
try {
|
|
2268
|
-
return
|
|
2467
|
+
return fs5.statSync(p).isFile();
|
|
2269
2468
|
} catch {
|
|
2270
2469
|
return false;
|
|
2271
2470
|
}
|
|
@@ -2279,13 +2478,13 @@ function _isUpperChar(ch) {
|
|
|
2279
2478
|
function _list_module_subdirs(root) {
|
|
2280
2479
|
let entries;
|
|
2281
2480
|
try {
|
|
2282
|
-
entries =
|
|
2481
|
+
entries = fs5.readdirSync(root).sort();
|
|
2283
2482
|
} catch {
|
|
2284
2483
|
return [];
|
|
2285
2484
|
}
|
|
2286
2485
|
const out = [];
|
|
2287
2486
|
for (const name of entries) {
|
|
2288
|
-
if (!_isDir(
|
|
2487
|
+
if (!_isDir(path5.join(root, name))) {
|
|
2289
2488
|
continue;
|
|
2290
2489
|
}
|
|
2291
2490
|
if (name.startsWith(".")) {
|
|
@@ -2307,11 +2506,11 @@ function _score_confidence(stack, root, subdirs) {
|
|
|
2307
2506
|
return capitalized.length > 0 ? "high" : "medium";
|
|
2308
2507
|
}
|
|
2309
2508
|
if (stack === "node-monorepo") {
|
|
2310
|
-
const withPkgJson = subdirs.filter((name) => _isFile(
|
|
2509
|
+
const withPkgJson = subdirs.filter((name) => _isFile(path5.join(root, name, "package.json")));
|
|
2311
2510
|
return withPkgJson.length > 0 ? "high" : "medium";
|
|
2312
2511
|
}
|
|
2313
2512
|
if (stack === "python-src") {
|
|
2314
|
-
const withInit = subdirs.filter((name) => _isFile(
|
|
2513
|
+
const withInit = subdirs.filter((name) => _isFile(path5.join(root, name, "__init__.py")));
|
|
2315
2514
|
return withInit.length > 0 ? "high" : "medium";
|
|
2316
2515
|
}
|
|
2317
2516
|
if (stack === "go-internal") {
|
|
@@ -2323,7 +2522,7 @@ function detect_module_roots(project_root) {
|
|
|
2323
2522
|
const high = [];
|
|
2324
2523
|
const medium = [];
|
|
2325
2524
|
for (const [rel_path, stack, namespace_template] of _RULES) {
|
|
2326
|
-
const abs_path =
|
|
2525
|
+
const abs_path = path5.join(project_root, rel_path);
|
|
2327
2526
|
if (!_isDir(abs_path)) {
|
|
2328
2527
|
continue;
|
|
2329
2528
|
}
|
|
@@ -2345,16 +2544,17 @@ function detect_module_roots(project_root) {
|
|
|
2345
2544
|
}
|
|
2346
2545
|
|
|
2347
2546
|
// src/scripts/_lib/model_tier.ts
|
|
2348
|
-
import
|
|
2547
|
+
import fs6 from "node:fs";
|
|
2349
2548
|
var TIER_TO_CLAUDE_MODEL = {
|
|
2549
|
+
frontier: "fable",
|
|
2350
2550
|
high: "opus",
|
|
2351
2551
|
medium: "sonnet",
|
|
2352
2552
|
lite: "haiku"
|
|
2353
2553
|
};
|
|
2354
2554
|
var MODEL_TIER_RE = /^model_tier:\s*"?([a-z]+)"?\s*$/m;
|
|
2355
2555
|
function read_model_tier(skill_md) {
|
|
2356
|
-
if (!
|
|
2357
|
-
const text =
|
|
2556
|
+
if (!fs6.existsSync(skill_md)) return null;
|
|
2557
|
+
const text = fs6.readFileSync(skill_md).toString("utf-8");
|
|
2358
2558
|
if (!text.startsWith("---\n")) return null;
|
|
2359
2559
|
const end = text.indexOf("\n---\n", 4);
|
|
2360
2560
|
if (end === -1) return null;
|
|
@@ -2388,34 +2588,34 @@ var ArgparseExit = class extends Error {
|
|
|
2388
2588
|
function expanduser2(p) {
|
|
2389
2589
|
if (p === "~") return os2.homedir();
|
|
2390
2590
|
if (p.startsWith("~/") || p.startsWith("~\\")) {
|
|
2391
|
-
return
|
|
2591
|
+
return path6.join(os2.homedir(), p.slice(2));
|
|
2392
2592
|
}
|
|
2393
2593
|
return p;
|
|
2394
2594
|
}
|
|
2395
2595
|
function resolvePath(p) {
|
|
2396
2596
|
try {
|
|
2397
|
-
return
|
|
2597
|
+
return fs7.realpathSync(path6.resolve(p));
|
|
2398
2598
|
} catch {
|
|
2399
|
-
return
|
|
2599
|
+
return path6.resolve(p);
|
|
2400
2600
|
}
|
|
2401
2601
|
}
|
|
2402
2602
|
function isFile(p) {
|
|
2403
2603
|
try {
|
|
2404
|
-
return
|
|
2604
|
+
return fs7.statSync(p).isFile();
|
|
2405
2605
|
} catch {
|
|
2406
2606
|
return false;
|
|
2407
2607
|
}
|
|
2408
2608
|
}
|
|
2409
2609
|
function isDir(p) {
|
|
2410
2610
|
try {
|
|
2411
|
-
return
|
|
2611
|
+
return fs7.statSync(p).isDirectory();
|
|
2412
2612
|
} catch {
|
|
2413
2613
|
return false;
|
|
2414
2614
|
}
|
|
2415
2615
|
}
|
|
2416
2616
|
function pathExists(p) {
|
|
2417
2617
|
try {
|
|
2418
|
-
|
|
2618
|
+
fs7.statSync(p);
|
|
2419
2619
|
return true;
|
|
2420
2620
|
} catch {
|
|
2421
2621
|
return false;
|
|
@@ -2423,24 +2623,24 @@ function pathExists(p) {
|
|
|
2423
2623
|
}
|
|
2424
2624
|
function isSymlink(p) {
|
|
2425
2625
|
try {
|
|
2426
|
-
return
|
|
2626
|
+
return fs7.lstatSync(p).isSymbolicLink();
|
|
2427
2627
|
} catch {
|
|
2428
2628
|
return false;
|
|
2429
2629
|
}
|
|
2430
2630
|
}
|
|
2431
2631
|
function readText(p) {
|
|
2432
|
-
return
|
|
2632
|
+
return fs7.readFileSync(p, "utf-8");
|
|
2433
2633
|
}
|
|
2434
2634
|
function writeText(p, content) {
|
|
2435
|
-
|
|
2635
|
+
fs7.writeFileSync(p, content, "utf-8");
|
|
2436
2636
|
}
|
|
2437
2637
|
function mkdirp(p) {
|
|
2438
|
-
|
|
2638
|
+
fs7.mkdirSync(p, { recursive: true });
|
|
2439
2639
|
}
|
|
2440
2640
|
function sortedGlobStems(directory, suffix) {
|
|
2441
2641
|
let entries;
|
|
2442
2642
|
try {
|
|
2443
|
-
entries =
|
|
2643
|
+
entries = fs7.readdirSync(directory);
|
|
2444
2644
|
} catch {
|
|
2445
2645
|
return [];
|
|
2446
2646
|
}
|
|
@@ -2460,7 +2660,7 @@ function sortedGlobStems(directory, suffix) {
|
|
|
2460
2660
|
function countZips(directory) {
|
|
2461
2661
|
if (!isDir(directory)) return 0;
|
|
2462
2662
|
let n = 0;
|
|
2463
|
-
for (const name of
|
|
2663
|
+
for (const name of fs7.readdirSync(directory)) {
|
|
2464
2664
|
if (name.endsWith(".zip")) n += 1;
|
|
2465
2665
|
}
|
|
2466
2666
|
return n;
|
|
@@ -2468,35 +2668,35 @@ function countZips(directory) {
|
|
|
2468
2668
|
function sha256OfFile(p) {
|
|
2469
2669
|
let data;
|
|
2470
2670
|
try {
|
|
2471
|
-
data =
|
|
2671
|
+
data = fs7.readFileSync(p);
|
|
2472
2672
|
} catch {
|
|
2473
2673
|
return null;
|
|
2474
2674
|
}
|
|
2475
2675
|
return crypto3.createHash("sha256").update(data).digest("hex");
|
|
2476
2676
|
}
|
|
2477
2677
|
function atomicWrite0644(target, body, prefix) {
|
|
2478
|
-
const dir =
|
|
2479
|
-
const tmpName =
|
|
2678
|
+
const dir = path6.dirname(target);
|
|
2679
|
+
const tmpName = path6.join(
|
|
2480
2680
|
dir,
|
|
2481
2681
|
`${prefix}${process2.pid}.${crypto3.randomBytes(6).toString("hex")}.yml.tmp`
|
|
2482
2682
|
);
|
|
2483
2683
|
let fd = null;
|
|
2484
2684
|
try {
|
|
2485
|
-
fd =
|
|
2486
|
-
|
|
2487
|
-
|
|
2685
|
+
fd = fs7.openSync(tmpName, "wx", 420);
|
|
2686
|
+
fs7.writeFileSync(fd, body, "utf-8");
|
|
2687
|
+
fs7.closeSync(fd);
|
|
2488
2688
|
fd = null;
|
|
2489
|
-
|
|
2490
|
-
|
|
2689
|
+
fs7.chmodSync(tmpName, 420);
|
|
2690
|
+
fs7.renameSync(tmpName, target);
|
|
2491
2691
|
} catch (err) {
|
|
2492
2692
|
if (fd !== null) {
|
|
2493
2693
|
try {
|
|
2494
|
-
|
|
2694
|
+
fs7.closeSync(fd);
|
|
2495
2695
|
} catch {
|
|
2496
2696
|
}
|
|
2497
2697
|
}
|
|
2498
2698
|
try {
|
|
2499
|
-
|
|
2699
|
+
fs7.unlinkSync(tmpName);
|
|
2500
2700
|
} catch {
|
|
2501
2701
|
}
|
|
2502
2702
|
throw err;
|
|
@@ -2620,12 +2820,12 @@ var LEGACY_SETTINGS_FILE = ".agent-settings";
|
|
|
2620
2820
|
var LEGACY_BACKUP_FILE = ".agent-settings.backup.key-value";
|
|
2621
2821
|
var SETTINGS_SUBDIR = ["agents", "settings"];
|
|
2622
2822
|
function _canonical_settings_target(project_root) {
|
|
2623
|
-
return
|
|
2823
|
+
return path6.join(project_root, ...SETTINGS_SUBDIR, SETTINGS_FILE);
|
|
2624
2824
|
}
|
|
2625
2825
|
function _resolve_settings_read(project_root) {
|
|
2626
2826
|
const canonical = _canonical_settings_target(project_root);
|
|
2627
2827
|
if (pathExists(canonical)) return canonical;
|
|
2628
|
-
const legacy =
|
|
2828
|
+
const legacy = path6.join(project_root, SETTINGS_FILE);
|
|
2629
2829
|
if (pathExists(legacy)) return legacy;
|
|
2630
2830
|
return canonical;
|
|
2631
2831
|
}
|
|
@@ -2689,9 +2889,9 @@ function fail(msg) {
|
|
|
2689
2889
|
throw new SystemExitError(1);
|
|
2690
2890
|
}
|
|
2691
2891
|
function detect_package_root(project_root) {
|
|
2692
|
-
const npm_path =
|
|
2892
|
+
const npm_path = path6.join(project_root, "node_modules", "@event4u", "agent-config");
|
|
2693
2893
|
if (isDir(npm_path)) return resolvePath(npm_path);
|
|
2694
|
-
if (pathExists(
|
|
2894
|
+
if (pathExists(path6.join(project_root, "src", "config", "profiles", "minimal.ini"))) {
|
|
2695
2895
|
return project_root;
|
|
2696
2896
|
}
|
|
2697
2897
|
fail(
|
|
@@ -2699,12 +2899,12 @@ function detect_package_root(project_root) {
|
|
|
2699
2899
|
);
|
|
2700
2900
|
}
|
|
2701
2901
|
function detect_package_type(package_root) {
|
|
2702
|
-
if (package_root.split(
|
|
2902
|
+
if (package_root.split(path6.sep).includes("node_modules")) return "npm";
|
|
2703
2903
|
return "local";
|
|
2704
2904
|
}
|
|
2705
2905
|
function detect_package_type_for_project(project_root, package_root) {
|
|
2706
2906
|
const npm_path = resolvePath(
|
|
2707
|
-
|
|
2907
|
+
path6.join(project_root, "node_modules", "@event4u", "agent-config")
|
|
2708
2908
|
);
|
|
2709
2909
|
const package_resolved = resolvePath(package_root);
|
|
2710
2910
|
if (package_resolved === npm_path) return "npm";
|
|
@@ -2724,7 +2924,7 @@ function ensure_directory(p) {
|
|
|
2724
2924
|
mkdirp(p);
|
|
2725
2925
|
}
|
|
2726
2926
|
function write_file(p, content) {
|
|
2727
|
-
ensure_directory(
|
|
2927
|
+
ensure_directory(path6.dirname(p));
|
|
2728
2928
|
writeText(p, content);
|
|
2729
2929
|
}
|
|
2730
2930
|
function read_json_file(p) {
|
|
@@ -2895,7 +3095,7 @@ function _append_unknown_legacy(rendered, legacy_values, unknown_keys) {
|
|
|
2895
3095
|
return rendered + "\n" + suffix;
|
|
2896
3096
|
}
|
|
2897
3097
|
function _migrate_legacy_if_present(project_root, template_body) {
|
|
2898
|
-
const legacy_target =
|
|
3098
|
+
const legacy_target = path6.join(project_root, LEGACY_SETTINGS_FILE);
|
|
2899
3099
|
if (!isFile(legacy_target)) return null;
|
|
2900
3100
|
const legacy_text = readText(legacy_target);
|
|
2901
3101
|
const [values, unknown] = _parse_legacy_settings(legacy_text);
|
|
@@ -2910,9 +3110,9 @@ function _migrate_legacy_if_present(project_root, template_body) {
|
|
|
2910
3110
|
}
|
|
2911
3111
|
}
|
|
2912
3112
|
rendered = _append_unknown_legacy(rendered, values, unknown);
|
|
2913
|
-
const backup_target =
|
|
3113
|
+
const backup_target = path6.join(project_root, LEGACY_BACKUP_FILE);
|
|
2914
3114
|
writeText(backup_target, legacy_text);
|
|
2915
|
-
|
|
3115
|
+
fs7.unlinkSync(legacy_target);
|
|
2916
3116
|
info(`Migrated legacy ${LEGACY_SETTINGS_FILE} \u2192 ${SETTINGS_FILE}`);
|
|
2917
3117
|
info(`Backup saved to ${LEGACY_BACKUP_FILE}`);
|
|
2918
3118
|
if (unknown.length > 0) {
|
|
@@ -2947,7 +3147,7 @@ function _render_template(template, profile_values) {
|
|
|
2947
3147
|
return body;
|
|
2948
3148
|
}
|
|
2949
3149
|
function _load_valid_user_types(package_root) {
|
|
2950
|
-
const directory =
|
|
3150
|
+
const directory = path6.join(package_root, USER_TYPES_DIR);
|
|
2951
3151
|
if (!isDir(directory)) return [];
|
|
2952
3152
|
return sortedGlobStems(directory, ".yml");
|
|
2953
3153
|
}
|
|
@@ -3004,8 +3204,8 @@ function splitlinesKeepends(text) {
|
|
|
3004
3204
|
}
|
|
3005
3205
|
function ensure_agent_settings(project_root, package_root, profile, force, user_type = "", packs = null) {
|
|
3006
3206
|
const target = _canonical_settings_target(project_root);
|
|
3007
|
-
const profile_source =
|
|
3008
|
-
const template_source =
|
|
3207
|
+
const profile_source = path6.join(package_root, "src", "config", "profiles", `${profile}.ini`);
|
|
3208
|
+
const template_source = path6.join(package_root, "src", "config", "agent-settings.template.yml");
|
|
3009
3209
|
if (!pathExists(profile_source)) fail(`Missing profile preset: ${profile_source}`);
|
|
3010
3210
|
if (!pathExists(template_source)) fail(`Missing settings template: ${template_source}`);
|
|
3011
3211
|
const template = readText(template_source);
|
|
@@ -3019,21 +3219,21 @@ function ensure_agent_settings(project_root, package_root, profile, force, user_
|
|
|
3019
3219
|
if (profile_values["rule_loading_tier"] !== profile) {
|
|
3020
3220
|
const got = "rule_loading_tier" in profile_values ? `'${profile_values["rule_loading_tier"]}'` : "None";
|
|
3021
3221
|
fail(
|
|
3022
|
-
`Profile preset ${
|
|
3222
|
+
`Profile preset ${path6.basename(profile_source)} has rule_loading_tier=${got} but --profile=${profile}`
|
|
3023
3223
|
);
|
|
3024
3224
|
}
|
|
3025
3225
|
profile_values["user_type"] = _validate_user_type(package_root, user_type);
|
|
3026
3226
|
let template_body = _render_template(template, profile_values);
|
|
3027
3227
|
template_body = _inject_packs(template_body, packs ?? []);
|
|
3028
|
-
const legacy_root =
|
|
3228
|
+
const legacy_root = path6.join(project_root, SETTINGS_FILE);
|
|
3029
3229
|
if (isFile(legacy_root) && !pathExists(target)) {
|
|
3030
|
-
mkdirp(
|
|
3230
|
+
mkdirp(path6.dirname(target));
|
|
3031
3231
|
writeText(target, readText(legacy_root));
|
|
3032
|
-
|
|
3232
|
+
fs7.unlinkSync(legacy_root);
|
|
3033
3233
|
success(`Migrated ${SETTINGS_FILE} \u2192 agents/settings/${SETTINGS_FILE} (ADR-038)`);
|
|
3034
3234
|
return;
|
|
3035
3235
|
}
|
|
3036
|
-
const legacy_target =
|
|
3236
|
+
const legacy_target = path6.join(project_root, LEGACY_SETTINGS_FILE);
|
|
3037
3237
|
if (isFile(legacy_target) && pathExists(target)) {
|
|
3038
3238
|
warn(
|
|
3039
3239
|
`Both ${SETTINGS_FILE} and legacy ${LEGACY_SETTINGS_FILE} exist. Skipping migration to avoid overwriting ${SETTINGS_FILE}. Delete one of them manually and re-run.`
|
|
@@ -3050,7 +3250,7 @@ function ensure_agent_settings(project_root, package_root, profile, force, user_
|
|
|
3050
3250
|
skip(`${SETTINGS_FILE} already exists`);
|
|
3051
3251
|
return;
|
|
3052
3252
|
}
|
|
3053
|
-
mkdirp(
|
|
3253
|
+
mkdirp(path6.dirname(target));
|
|
3054
3254
|
write_file(target, template_body);
|
|
3055
3255
|
const user_type_value = profile_values["user_type"] ?? "";
|
|
3056
3256
|
const suffix = user_type_value ? `, user_type=${user_type_value}` : "";
|
|
@@ -3063,7 +3263,7 @@ function ensure_vscode_bridge(project_root, package_type, force) {
|
|
|
3063
3263
|
const plugin_path = plugin_paths[package_type] ?? "./plugin/agent-config";
|
|
3064
3264
|
const bridge = { "chat.pluginLocations": { [plugin_path]: true } };
|
|
3065
3265
|
return merge_json_file(
|
|
3066
|
-
|
|
3266
|
+
path6.join(project_root, ".vscode", "settings.json"),
|
|
3067
3267
|
bridge,
|
|
3068
3268
|
force,
|
|
3069
3269
|
".vscode/settings.json"
|
|
@@ -3072,14 +3272,14 @@ function ensure_vscode_bridge(project_root, package_type, force) {
|
|
|
3072
3272
|
function ensure_augment_bridge(project_root, force) {
|
|
3073
3273
|
const bridge = { enabledPlugins: { "agent-config@event4u": true } };
|
|
3074
3274
|
return merge_json_file(
|
|
3075
|
-
|
|
3275
|
+
path6.join(project_root, ".augment", "settings.json"),
|
|
3076
3276
|
bridge,
|
|
3077
3277
|
force,
|
|
3078
3278
|
".augment/settings.json"
|
|
3079
3279
|
);
|
|
3080
3280
|
}
|
|
3081
|
-
var AUGMENT_USER_DIR =
|
|
3082
|
-
var AUGMENT_USER_HOOKS_DIR =
|
|
3281
|
+
var AUGMENT_USER_DIR = path6.join(os2.homedir(), ".augment");
|
|
3282
|
+
var AUGMENT_USER_HOOKS_DIR = path6.join(AUGMENT_USER_DIR, "hooks");
|
|
3083
3283
|
var AUGMENT_DISPATCHER_TRAMPOLINE = "augment-dispatcher.sh";
|
|
3084
3284
|
var AUGMENT_LEGACY_TRAMPOLINES = [
|
|
3085
3285
|
"augment-chat-history.sh",
|
|
@@ -3095,29 +3295,29 @@ var AUGMENT_DISPATCHER_BINDINGS = [
|
|
|
3095
3295
|
["post_tool_use", "PostToolUse"]
|
|
3096
3296
|
];
|
|
3097
3297
|
function _deploy_augment_trampoline(package_root, name, force) {
|
|
3098
|
-
const src =
|
|
3298
|
+
const src = path6.join(package_root, "scripts", "hooks", name);
|
|
3099
3299
|
if (!pathExists(src)) {
|
|
3100
3300
|
skip(`augment trampoline missing in package: ${src}`);
|
|
3101
3301
|
return null;
|
|
3102
3302
|
}
|
|
3103
3303
|
mkdirp(AUGMENT_USER_HOOKS_DIR);
|
|
3104
|
-
const dst =
|
|
3304
|
+
const dst = path6.join(AUGMENT_USER_HOOKS_DIR, name);
|
|
3105
3305
|
const src_text = readText(src);
|
|
3106
3306
|
if (pathExists(dst) && readText(dst) === src_text && !force) {
|
|
3107
3307
|
skip(`~/.augment/hooks/${name} already up to date`);
|
|
3108
3308
|
} else {
|
|
3109
3309
|
writeText(dst, src_text);
|
|
3110
|
-
|
|
3310
|
+
fs7.chmodSync(dst, 493);
|
|
3111
3311
|
success(`~/.augment/hooks/${name} installed`);
|
|
3112
3312
|
}
|
|
3113
3313
|
return dst;
|
|
3114
3314
|
}
|
|
3115
3315
|
function _remove_legacy_augment_trampolines() {
|
|
3116
3316
|
for (const name of AUGMENT_LEGACY_TRAMPOLINES) {
|
|
3117
|
-
const legacy =
|
|
3317
|
+
const legacy = path6.join(AUGMENT_USER_HOOKS_DIR, name);
|
|
3118
3318
|
try {
|
|
3119
3319
|
if (isFile(legacy)) {
|
|
3120
|
-
|
|
3320
|
+
fs7.unlinkSync(legacy);
|
|
3121
3321
|
skip(`removed legacy ~/.augment/hooks/${name}`);
|
|
3122
3322
|
}
|
|
3123
3323
|
} catch (err) {
|
|
@@ -3137,7 +3337,7 @@ function ensure_augment_user_hooks(package_root, force) {
|
|
|
3137
3337
|
}
|
|
3138
3338
|
const settings_patch = { hooks: per_event };
|
|
3139
3339
|
return merge_json_file(
|
|
3140
|
-
|
|
3340
|
+
path6.join(AUGMENT_USER_DIR, "settings.json"),
|
|
3141
3341
|
settings_patch,
|
|
3142
3342
|
force,
|
|
3143
3343
|
"~/.augment/settings.json"
|
|
@@ -3162,7 +3362,7 @@ function _heal_legacy_claude_plugin_ids(p) {
|
|
|
3162
3362
|
return removed;
|
|
3163
3363
|
}
|
|
3164
3364
|
function ensure_claude_bridge(project_root, force) {
|
|
3165
|
-
const target =
|
|
3365
|
+
const target = path6.join(project_root, ".claude", "settings.json");
|
|
3166
3366
|
const healed = _heal_legacy_claude_plugin_ids(target);
|
|
3167
3367
|
for (const pid of healed) {
|
|
3168
3368
|
success(`.claude/settings.json: removed stale plugin id \`${pid}\``);
|
|
@@ -3187,29 +3387,29 @@ function ensure_cursor_bridge(project_root, force) {
|
|
|
3187
3387
|
}
|
|
3188
3388
|
const bridge = { version: 1, hooks };
|
|
3189
3389
|
return merge_json_file(
|
|
3190
|
-
|
|
3390
|
+
path6.join(project_root, ".cursor", "hooks.json"),
|
|
3191
3391
|
bridge,
|
|
3192
3392
|
force,
|
|
3193
3393
|
".cursor/hooks.json"
|
|
3194
3394
|
);
|
|
3195
3395
|
}
|
|
3196
|
-
var CURSOR_USER_DIR =
|
|
3197
|
-
var CURSOR_USER_HOOKS_DIR =
|
|
3396
|
+
var CURSOR_USER_DIR = path6.join(os2.homedir(), ".cursor");
|
|
3397
|
+
var CURSOR_USER_HOOKS_DIR = path6.join(CURSOR_USER_DIR, "hooks");
|
|
3198
3398
|
var CURSOR_DISPATCHER_TRAMPOLINE = "cursor-dispatcher.sh";
|
|
3199
3399
|
function ensure_cursor_user_hooks(package_root, force) {
|
|
3200
|
-
const src =
|
|
3400
|
+
const src = path6.join(package_root, "scripts", "hooks", CURSOR_DISPATCHER_TRAMPOLINE);
|
|
3201
3401
|
if (!pathExists(src)) {
|
|
3202
3402
|
skip(`cursor trampoline missing in package: ${src}`);
|
|
3203
3403
|
return [];
|
|
3204
3404
|
}
|
|
3205
3405
|
mkdirp(CURSOR_USER_HOOKS_DIR);
|
|
3206
|
-
const dst =
|
|
3406
|
+
const dst = path6.join(CURSOR_USER_HOOKS_DIR, CURSOR_DISPATCHER_TRAMPOLINE);
|
|
3207
3407
|
const src_text = readText(src);
|
|
3208
3408
|
if (pathExists(dst) && readText(dst) === src_text && !force) {
|
|
3209
3409
|
skip(`~/.cursor/hooks/${CURSOR_DISPATCHER_TRAMPOLINE} already up to date`);
|
|
3210
3410
|
} else {
|
|
3211
3411
|
writeText(dst, src_text);
|
|
3212
|
-
|
|
3412
|
+
fs7.chmodSync(dst, 493);
|
|
3213
3413
|
success(`~/.cursor/hooks/${CURSOR_DISPATCHER_TRAMPOLINE} installed`);
|
|
3214
3414
|
}
|
|
3215
3415
|
const hooks = {};
|
|
@@ -3218,7 +3418,7 @@ function ensure_cursor_user_hooks(package_root, force) {
|
|
|
3218
3418
|
}
|
|
3219
3419
|
const settings_patch = { version: 1, hooks };
|
|
3220
3420
|
return merge_json_file(
|
|
3221
|
-
|
|
3421
|
+
path6.join(CURSOR_USER_DIR, "hooks.json"),
|
|
3222
3422
|
settings_patch,
|
|
3223
3423
|
force,
|
|
3224
3424
|
"~/.cursor/hooks.json"
|
|
@@ -3261,12 +3461,12 @@ exit 0
|
|
|
3261
3461
|
`;
|
|
3262
3462
|
}
|
|
3263
3463
|
function ensure_cline_bridge(project_root, force) {
|
|
3264
|
-
const hooks_dir =
|
|
3464
|
+
const hooks_dir = path6.join(project_root, ".clinerules", "hooks");
|
|
3265
3465
|
mkdirp(hooks_dir);
|
|
3266
3466
|
const workspace_quoted = shlexQuote(resolvePath(project_root));
|
|
3267
3467
|
let written = 0;
|
|
3268
3468
|
for (const [ac_event, native_event] of CLINE_DISPATCHER_BINDINGS) {
|
|
3269
|
-
const target =
|
|
3469
|
+
const target = path6.join(hooks_dir, native_event);
|
|
3270
3470
|
const body = clineProjectHookBody(native_event, ac_event, workspace_quoted);
|
|
3271
3471
|
if (pathExists(target) && readText(target) === body && !force) {
|
|
3272
3472
|
continue;
|
|
@@ -3276,7 +3476,7 @@ function ensure_cline_bridge(project_root, force) {
|
|
|
3276
3476
|
continue;
|
|
3277
3477
|
}
|
|
3278
3478
|
writeText(target, body);
|
|
3279
|
-
|
|
3479
|
+
fs7.chmodSync(target, 493);
|
|
3280
3480
|
written += 1;
|
|
3281
3481
|
}
|
|
3282
3482
|
if (written) {
|
|
@@ -3285,27 +3485,27 @@ function ensure_cline_bridge(project_root, force) {
|
|
|
3285
3485
|
skip(".clinerules/hooks/ already up to date");
|
|
3286
3486
|
}
|
|
3287
3487
|
}
|
|
3288
|
-
var CLINE_USER_DIR =
|
|
3488
|
+
var CLINE_USER_DIR = path6.join(os2.homedir(), "Documents", "Cline", "Hooks");
|
|
3289
3489
|
var CLINE_DISPATCHER_TRAMPOLINE = "cline-dispatcher.sh";
|
|
3290
3490
|
function ensure_cline_user_hooks(package_root, force) {
|
|
3291
|
-
const src =
|
|
3491
|
+
const src = path6.join(package_root, "scripts", "hooks", CLINE_DISPATCHER_TRAMPOLINE);
|
|
3292
3492
|
if (!pathExists(src)) {
|
|
3293
3493
|
skip(`cline trampoline missing in package: ${src}`);
|
|
3294
3494
|
return;
|
|
3295
3495
|
}
|
|
3296
3496
|
mkdirp(CLINE_USER_DIR);
|
|
3297
|
-
const trampoline =
|
|
3497
|
+
const trampoline = path6.join(CLINE_USER_DIR, CLINE_DISPATCHER_TRAMPOLINE);
|
|
3298
3498
|
const src_text = readText(src);
|
|
3299
3499
|
if (pathExists(trampoline) && readText(trampoline) === src_text && !force) {
|
|
3300
3500
|
skip(`~/Documents/Cline/Hooks/${CLINE_DISPATCHER_TRAMPOLINE} already up to date`);
|
|
3301
3501
|
} else {
|
|
3302
3502
|
writeText(trampoline, src_text);
|
|
3303
|
-
|
|
3503
|
+
fs7.chmodSync(trampoline, 493);
|
|
3304
3504
|
success(`~/Documents/Cline/Hooks/${CLINE_DISPATCHER_TRAMPOLINE} installed`);
|
|
3305
3505
|
}
|
|
3306
3506
|
const trampoline_quoted = shlexQuote(trampoline);
|
|
3307
3507
|
for (const [ac_event, native_event] of CLINE_DISPATCHER_BINDINGS) {
|
|
3308
|
-
const wrapper =
|
|
3508
|
+
const wrapper = path6.join(CLINE_USER_DIR, native_event);
|
|
3309
3509
|
const body = `#!/usr/bin/env bash
|
|
3310
3510
|
# Generated by event4u/agent-config install.py \u2014 DO NOT EDIT.
|
|
3311
3511
|
# User-scope Cline hook for ${native_event} \u2192 agent-config ${ac_event}.
|
|
@@ -3315,7 +3515,7 @@ exec ${trampoline_quoted} ${ac_event} ${native_event}
|
|
|
3315
3515
|
continue;
|
|
3316
3516
|
}
|
|
3317
3517
|
writeText(wrapper, body);
|
|
3318
|
-
|
|
3518
|
+
fs7.chmodSync(wrapper, 493);
|
|
3319
3519
|
}
|
|
3320
3520
|
}
|
|
3321
3521
|
var WINDSURF_DISPATCHER_BINDINGS = [
|
|
@@ -3336,29 +3536,29 @@ function ensure_windsurf_bridge(project_root, force) {
|
|
|
3336
3536
|
}
|
|
3337
3537
|
const bridge = { hooks };
|
|
3338
3538
|
return merge_json_file(
|
|
3339
|
-
|
|
3539
|
+
path6.join(project_root, ".windsurf", "hooks.json"),
|
|
3340
3540
|
bridge,
|
|
3341
3541
|
force,
|
|
3342
3542
|
".windsurf/hooks.json"
|
|
3343
3543
|
);
|
|
3344
3544
|
}
|
|
3345
|
-
var WINDSURF_USER_DIR =
|
|
3346
|
-
var WINDSURF_USER_HOOKS_DIR =
|
|
3545
|
+
var WINDSURF_USER_DIR = path6.join(os2.homedir(), ".codeium", "windsurf");
|
|
3546
|
+
var WINDSURF_USER_HOOKS_DIR = path6.join(WINDSURF_USER_DIR, "hooks");
|
|
3347
3547
|
var WINDSURF_DISPATCHER_TRAMPOLINE = "windsurf-dispatcher.sh";
|
|
3348
3548
|
function ensure_windsurf_user_hooks(package_root, force) {
|
|
3349
|
-
const src =
|
|
3549
|
+
const src = path6.join(package_root, "scripts", "hooks", WINDSURF_DISPATCHER_TRAMPOLINE);
|
|
3350
3550
|
if (!pathExists(src)) {
|
|
3351
3551
|
skip(`windsurf trampoline missing in package: ${src}`);
|
|
3352
3552
|
return [];
|
|
3353
3553
|
}
|
|
3354
3554
|
mkdirp(WINDSURF_USER_HOOKS_DIR);
|
|
3355
|
-
const dst =
|
|
3555
|
+
const dst = path6.join(WINDSURF_USER_HOOKS_DIR, WINDSURF_DISPATCHER_TRAMPOLINE);
|
|
3356
3556
|
const src_text = readText(src);
|
|
3357
3557
|
if (pathExists(dst) && readText(dst) === src_text && !force) {
|
|
3358
3558
|
skip(`~/.codeium/windsurf/hooks/${WINDSURF_DISPATCHER_TRAMPOLINE} already up to date`);
|
|
3359
3559
|
} else {
|
|
3360
3560
|
writeText(dst, src_text);
|
|
3361
|
-
|
|
3561
|
+
fs7.chmodSync(dst, 493);
|
|
3362
3562
|
success(`~/.codeium/windsurf/hooks/${WINDSURF_DISPATCHER_TRAMPOLINE} installed`);
|
|
3363
3563
|
}
|
|
3364
3564
|
const hooks = {};
|
|
@@ -3370,7 +3570,7 @@ function ensure_windsurf_user_hooks(package_root, force) {
|
|
|
3370
3570
|
}
|
|
3371
3571
|
const settings_patch = { hooks };
|
|
3372
3572
|
return merge_json_file(
|
|
3373
|
-
|
|
3573
|
+
path6.join(WINDSURF_USER_DIR, "hooks.json"),
|
|
3374
3574
|
settings_patch,
|
|
3375
3575
|
force,
|
|
3376
3576
|
"~/.codeium/windsurf/hooks.json"
|
|
@@ -3399,43 +3599,43 @@ function _gemini_hooks_dict(command_factory) {
|
|
|
3399
3599
|
function ensure_gemini_bridge(project_root, force) {
|
|
3400
3600
|
const bridge = { hooks: _gemini_hooks_dict(_gemini_dispatch_command) };
|
|
3401
3601
|
return merge_json_file(
|
|
3402
|
-
|
|
3602
|
+
path6.join(project_root, ".gemini", "settings.json"),
|
|
3403
3603
|
bridge,
|
|
3404
3604
|
force,
|
|
3405
3605
|
".gemini/settings.json"
|
|
3406
3606
|
);
|
|
3407
3607
|
}
|
|
3408
|
-
var GEMINI_USER_DIR =
|
|
3409
|
-
var GEMINI_USER_HOOKS_DIR =
|
|
3608
|
+
var GEMINI_USER_DIR = path6.join(os2.homedir(), ".gemini");
|
|
3609
|
+
var GEMINI_USER_HOOKS_DIR = path6.join(GEMINI_USER_DIR, "hooks");
|
|
3410
3610
|
var GEMINI_DISPATCHER_TRAMPOLINE = "gemini-dispatcher.sh";
|
|
3411
3611
|
function ensure_gemini_user_hooks(package_root, force) {
|
|
3412
|
-
const src =
|
|
3612
|
+
const src = path6.join(package_root, "scripts", "hooks", GEMINI_DISPATCHER_TRAMPOLINE);
|
|
3413
3613
|
if (!pathExists(src)) {
|
|
3414
3614
|
skip(`gemini trampoline missing in package: ${src}`);
|
|
3415
3615
|
return [];
|
|
3416
3616
|
}
|
|
3417
3617
|
mkdirp(GEMINI_USER_HOOKS_DIR);
|
|
3418
|
-
const dst =
|
|
3618
|
+
const dst = path6.join(GEMINI_USER_HOOKS_DIR, GEMINI_DISPATCHER_TRAMPOLINE);
|
|
3419
3619
|
const src_text = readText(src);
|
|
3420
3620
|
if (pathExists(dst) && readText(dst) === src_text && !force) {
|
|
3421
3621
|
skip(`~/.gemini/hooks/${GEMINI_DISPATCHER_TRAMPOLINE} already up to date`);
|
|
3422
3622
|
} else {
|
|
3423
3623
|
writeText(dst, src_text);
|
|
3424
|
-
|
|
3624
|
+
fs7.chmodSync(dst, 493);
|
|
3425
3625
|
success(`~/.gemini/hooks/${GEMINI_DISPATCHER_TRAMPOLINE} installed`);
|
|
3426
3626
|
}
|
|
3427
3627
|
const settings_patch = {
|
|
3428
3628
|
hooks: _gemini_hooks_dict((ac_event, native) => `${dst} ${ac_event} ${native}`)
|
|
3429
3629
|
};
|
|
3430
3630
|
return merge_json_file(
|
|
3431
|
-
|
|
3631
|
+
path6.join(GEMINI_USER_DIR, "settings.json"),
|
|
3432
3632
|
settings_patch,
|
|
3433
3633
|
force,
|
|
3434
3634
|
"~/.gemini/settings.json"
|
|
3435
3635
|
);
|
|
3436
3636
|
}
|
|
3437
3637
|
function ensure_copilot_bridge(project_root, force) {
|
|
3438
|
-
const target =
|
|
3638
|
+
const target = path6.join(project_root, ".github", "plugin", "marketplace.json");
|
|
3439
3639
|
const bridge = {
|
|
3440
3640
|
marketplace: {
|
|
3441
3641
|
name: "event4u-agent-marketplace",
|
|
@@ -3478,7 +3678,7 @@ See \`docs/setup/per-ide/roocode.md\` for the full activation guide.
|
|
|
3478
3678
|
Run \`./agent-config --help\` for available commands.
|
|
3479
3679
|
`;
|
|
3480
3680
|
function ensure_roocode_bridge(project_root, force) {
|
|
3481
|
-
const target =
|
|
3681
|
+
const target = path6.join(project_root, ".roo", "rules", "agent-config.md");
|
|
3482
3682
|
if (pathExists(target) && !force) {
|
|
3483
3683
|
skip(".roo/rules/agent-config.md already exists");
|
|
3484
3684
|
return;
|
|
@@ -3500,7 +3700,7 @@ To wire Claude Desktop to this project's rules, run:
|
|
|
3500
3700
|
Canonical rule and skill source: \`.augment/\` (see \`AGENTS.md\`).
|
|
3501
3701
|
`;
|
|
3502
3702
|
function ensure_claude_desktop_bridge(project_root, force) {
|
|
3503
|
-
const target =
|
|
3703
|
+
const target = path6.join(project_root, ".claude-desktop", "agent-config.md");
|
|
3504
3704
|
if (pathExists(target) && !force) {
|
|
3505
3705
|
skip(".claude-desktop/agent-config.md already exists");
|
|
3506
3706
|
return;
|
|
@@ -3525,7 +3725,7 @@ Or pass \`--read .aider/agent-config.md\` on the command line.
|
|
|
3525
3725
|
Canonical rule and skill source: \`.augment/\` (see \`AGENTS.md\`).
|
|
3526
3726
|
`;
|
|
3527
3727
|
function ensure_aider_bridge(project_root, force) {
|
|
3528
|
-
const target =
|
|
3728
|
+
const target = path6.join(project_root, ".aider", "agent-config.md");
|
|
3529
3729
|
if (pathExists(target) && !force) {
|
|
3530
3730
|
skip(".aider/agent-config.md already exists");
|
|
3531
3731
|
return;
|
|
@@ -3544,7 +3744,7 @@ developers where the rules and skills live.
|
|
|
3544
3744
|
Canonical rule and skill source: \`.augment/\` (see project \`AGENTS.md\`).
|
|
3545
3745
|
`;
|
|
3546
3746
|
function ensure_codex_bridge(project_root, force) {
|
|
3547
|
-
const target =
|
|
3747
|
+
const target = path6.join(project_root, ".codex", "agent-config.md");
|
|
3548
3748
|
if (pathExists(target) && !force) {
|
|
3549
3749
|
skip(".codex/agent-config.md already exists");
|
|
3550
3750
|
return;
|
|
@@ -3562,7 +3762,7 @@ rules per session. The canonical rule and skill source lives under
|
|
|
3562
3762
|
orientation).
|
|
3563
3763
|
`;
|
|
3564
3764
|
function ensure_continue_bridge(project_root, force) {
|
|
3565
|
-
const target =
|
|
3765
|
+
const target = path6.join(project_root, ".continue", "rules", "agent-config.md");
|
|
3566
3766
|
if (pathExists(target) && !force) {
|
|
3567
3767
|
skip(".continue/rules/agent-config.md already exists");
|
|
3568
3768
|
return;
|
|
@@ -3593,7 +3793,7 @@ orientation).
|
|
|
3593
3793
|
See \`docs/setup/per-ide/kilocode.md\` for the full activation guide.
|
|
3594
3794
|
`;
|
|
3595
3795
|
function ensure_kilocode_bridge(project_root, force) {
|
|
3596
|
-
const target =
|
|
3796
|
+
const target = path6.join(project_root, ".kilocode", "rules", "agent-config.md");
|
|
3597
3797
|
if (pathExists(target) && !force) {
|
|
3598
3798
|
skip(".kilocode/rules/agent-config.md already exists");
|
|
3599
3799
|
return;
|
|
@@ -3620,7 +3820,7 @@ canonical source (or symlink it):
|
|
|
3620
3820
|
Canonical rule and skill source: \`.augment/\` (see \`AGENTS.md\`).
|
|
3621
3821
|
`;
|
|
3622
3822
|
function ensure_zed_bridge(project_root, force) {
|
|
3623
|
-
const target =
|
|
3823
|
+
const target = path6.join(project_root, ".zed", "agent-config.md");
|
|
3624
3824
|
if (pathExists(target) && !force) {
|
|
3625
3825
|
skip(".zed/agent-config.md already exists");
|
|
3626
3826
|
return;
|
|
@@ -3641,7 +3841,7 @@ rules into your JetBrains profile.
|
|
|
3641
3841
|
Canonical rule and skill source: \`.augment/\` (see \`AGENTS.md\`).
|
|
3642
3842
|
`;
|
|
3643
3843
|
function ensure_jetbrains_bridge(project_root, force) {
|
|
3644
|
-
const target =
|
|
3844
|
+
const target = path6.join(project_root, ".jetbrains", "agent-config.md");
|
|
3645
3845
|
if (pathExists(target) && !force) {
|
|
3646
3846
|
skip(".jetbrains/agent-config.md already exists");
|
|
3647
3847
|
return;
|
|
@@ -3672,7 +3872,7 @@ session. The canonical rule and skill source lives under \`.augment/\`
|
|
|
3672
3872
|
See \`docs/setup/per-ide/kiro.md\` for the full activation guide.
|
|
3673
3873
|
`;
|
|
3674
3874
|
function ensure_kiro_bridge(project_root, force) {
|
|
3675
|
-
const target =
|
|
3875
|
+
const target = path6.join(project_root, ".kiro", "steering", "agent-config.md");
|
|
3676
3876
|
if (pathExists(target) && !force) {
|
|
3677
3877
|
skip(".kiro/steering/agent-config.md already exists");
|
|
3678
3878
|
return;
|
|
@@ -3698,35 +3898,35 @@ var SMOKE_BRIDGE_PATHS = {
|
|
|
3698
3898
|
};
|
|
3699
3899
|
function dirHasEntries(p) {
|
|
3700
3900
|
try {
|
|
3701
|
-
return
|
|
3901
|
+
return fs7.readdirSync(p).length > 0;
|
|
3702
3902
|
} catch {
|
|
3703
3903
|
return false;
|
|
3704
3904
|
}
|
|
3705
3905
|
}
|
|
3706
3906
|
function _resolve_tsx_invocation(scriptPath, scriptArgs) {
|
|
3707
3907
|
const binName = process2.platform === "win32" ? "tsx.cmd" : "tsx";
|
|
3708
|
-
let dir =
|
|
3908
|
+
let dir = path6.dirname(scriptPath);
|
|
3709
3909
|
for (; ; ) {
|
|
3710
|
-
const candidate =
|
|
3910
|
+
const candidate = path6.join(dir, "node_modules", ".bin", binName);
|
|
3711
3911
|
if (isFile(candidate)) {
|
|
3712
3912
|
return { command: candidate, args: [scriptPath, ...scriptArgs] };
|
|
3713
3913
|
}
|
|
3714
|
-
const parent =
|
|
3914
|
+
const parent = path6.dirname(dir);
|
|
3715
3915
|
if (parent === dir) break;
|
|
3716
3916
|
dir = parent;
|
|
3717
3917
|
}
|
|
3718
3918
|
return { command: "npx", args: ["tsx", scriptPath, ...scriptArgs] };
|
|
3719
3919
|
}
|
|
3720
3920
|
function _smoke_test_hooks(project_root, package_root) {
|
|
3721
|
-
const dispatcher =
|
|
3722
|
-
const manifest =
|
|
3921
|
+
const dispatcher = path6.join(package_root, "scripts", "hooks", "dispatch_hook.ts");
|
|
3922
|
+
const manifest = path6.join(package_root, "scripts", "hook_manifest.yaml");
|
|
3723
3923
|
if (!isFile(dispatcher) || !isFile(manifest)) return 0;
|
|
3724
3924
|
const failed = [];
|
|
3725
3925
|
const skipped = [];
|
|
3726
3926
|
const passed = [];
|
|
3727
3927
|
for (const [platform, native] of SMOKE_PROBE_EVENTS) {
|
|
3728
3928
|
const rel_bridge = SMOKE_BRIDGE_PATHS[platform] ?? "";
|
|
3729
|
-
const bridge_path = rel_bridge ?
|
|
3929
|
+
const bridge_path = rel_bridge ? path6.join(project_root, rel_bridge) : null;
|
|
3730
3930
|
const bridge_present = Boolean(
|
|
3731
3931
|
bridge_path && (isFile(bridge_path) || isDir(bridge_path) && dirHasEntries(bridge_path))
|
|
3732
3932
|
);
|
|
@@ -3926,9 +4126,9 @@ To remove this marker, delete this file.
|
|
|
3926
4126
|
`;
|
|
3927
4127
|
}
|
|
3928
4128
|
var _CLAUDE_DESKTOP_BUNDLES_SUBPATH = "claude-desktop/bundles";
|
|
3929
|
-
var GLOBAL_ROOT =
|
|
3930
|
-
var GLOBAL_USER_SETTINGS_PATH =
|
|
3931
|
-
var GLOBAL_AGENT_SETTINGS_PATH =
|
|
4129
|
+
var GLOBAL_ROOT = path6.join(os2.homedir(), ".event4u", "agent-config");
|
|
4130
|
+
var GLOBAL_USER_SETTINGS_PATH = path6.join(GLOBAL_ROOT, ".agent-user.yml");
|
|
4131
|
+
var GLOBAL_AGENT_SETTINGS_PATH = path6.join(GLOBAL_ROOT, ".agent-settings.yml");
|
|
3932
4132
|
function _bridge_marker(tool_id, scope) {
|
|
3933
4133
|
if (scope === "global") return USER_SCOPE_PATHS[tool_id] ?? "";
|
|
3934
4134
|
return PROJECT_BRIDGE_MARKERS[tool_id] ?? "";
|
|
@@ -3977,7 +4177,7 @@ function _load_yaml_doc(p) {
|
|
|
3977
4177
|
return _isPlainObject(data) ? data : {};
|
|
3978
4178
|
}
|
|
3979
4179
|
function _load_default_settings(package_root) {
|
|
3980
|
-
const template_source =
|
|
4180
|
+
const template_source = path6.join(package_root, "src", "config", "agent-settings.template.yml");
|
|
3981
4181
|
if (!pathExists(template_source)) return {};
|
|
3982
4182
|
let text;
|
|
3983
4183
|
try {
|
|
@@ -3991,11 +4191,11 @@ function _load_default_settings(package_root) {
|
|
|
3991
4191
|
}
|
|
3992
4192
|
var RULE_LAYER_CHOICES = ["global", "project", "both-acknowledged"];
|
|
3993
4193
|
function _suppress_rule_layer(project_root, suppress_dir) {
|
|
3994
|
-
const target =
|
|
4194
|
+
const target = path6.join(project_root, ".claude", "settings.local.json");
|
|
3995
4195
|
const existing = pathExists(target) ? read_json_file(target) : {};
|
|
3996
4196
|
let real_dir = suppress_dir;
|
|
3997
4197
|
try {
|
|
3998
|
-
real_dir =
|
|
4198
|
+
real_dir = fs7.realpathSync(suppress_dir);
|
|
3999
4199
|
} catch {
|
|
4000
4200
|
real_dir = suppress_dir;
|
|
4001
4201
|
}
|
|
@@ -4006,8 +4206,8 @@ function _suppress_rule_layer(project_root, suppress_dir) {
|
|
|
4006
4206
|
success(`.claude/settings.local.json: claudeMdExcludes += ${entry}`);
|
|
4007
4207
|
}
|
|
4008
4208
|
function _gate_rule_layer_overlap(project_root, layer, dry_run) {
|
|
4009
|
-
const global_dir =
|
|
4010
|
-
const project_dir =
|
|
4209
|
+
const global_dir = path6.join(os2.homedir(), ".claude", "rules");
|
|
4210
|
+
const project_dir = path6.join(project_root, ".claude", "rules");
|
|
4011
4211
|
const g = readRuleLayer(global_dir);
|
|
4012
4212
|
const p = readRuleLayer(project_dir);
|
|
4013
4213
|
if (g === null || p === null) return true;
|
|
@@ -4117,9 +4317,9 @@ function detect_scope(cwd) {
|
|
|
4117
4317
|
if (pathExists(_resolve_settings_read(cwd))) {
|
|
4118
4318
|
return ["project", `existing ${SETTINGS_FILE}`];
|
|
4119
4319
|
}
|
|
4120
|
-
const has_manifest = SCOPE_DETECT_MANIFESTS.find((m) => pathExists(
|
|
4121
|
-
const has_ai_dir = SCOPE_DETECT_AI_DIRS.find((d) => isDir(
|
|
4122
|
-
const has_ai_file = SCOPE_DETECT_AI_FILES.find((f) => pathExists(
|
|
4320
|
+
const has_manifest = SCOPE_DETECT_MANIFESTS.find((m) => pathExists(path6.join(cwd, m))) ?? null;
|
|
4321
|
+
const has_ai_dir = SCOPE_DETECT_AI_DIRS.find((d) => isDir(path6.join(cwd, d))) ?? null;
|
|
4322
|
+
const has_ai_file = SCOPE_DETECT_AI_FILES.find((f) => pathExists(path6.join(cwd, f))) ?? null;
|
|
4123
4323
|
if (has_manifest && (has_ai_dir || has_ai_file)) {
|
|
4124
4324
|
const marker = has_ai_dir || has_ai_file;
|
|
4125
4325
|
return ["prompt", `manifest (${has_manifest}) + AI-tool config (${marker})`];
|
|
@@ -4140,7 +4340,7 @@ function readLineSyncRaw(promptText) {
|
|
|
4140
4340
|
for (; ; ) {
|
|
4141
4341
|
let n;
|
|
4142
4342
|
try {
|
|
4143
|
-
n =
|
|
4343
|
+
n = fs7.readSync(0, buf, 0, 1, null);
|
|
4144
4344
|
} catch (err) {
|
|
4145
4345
|
const code = err.code;
|
|
4146
4346
|
if (code === "EAGAIN") {
|
|
@@ -4215,8 +4415,8 @@ function _files_by_tool_from_bridges(tools, project_root, scope) {
|
|
|
4215
4415
|
const marker = _bridge_marker(tool_id, scope);
|
|
4216
4416
|
if (!marker) continue;
|
|
4217
4417
|
let marker_path = marker;
|
|
4218
|
-
if (!
|
|
4219
|
-
marker_path =
|
|
4418
|
+
if (!path6.isAbsolute(marker_path)) {
|
|
4419
|
+
marker_path = path6.join(project_root, marker_path);
|
|
4220
4420
|
}
|
|
4221
4421
|
out[tool_id] = [_file_entry(marker_path, "bridge", false)];
|
|
4222
4422
|
}
|
|
@@ -4255,26 +4455,26 @@ function _update_installed_tools_manifest(project_root, tools, scope, force, fil
|
|
|
4255
4455
|
}
|
|
4256
4456
|
write_manifest(target, version, entries);
|
|
4257
4457
|
if (!state.QUIET) {
|
|
4258
|
-
const rel = isRelativeTo(target, project_root) ?
|
|
4458
|
+
const rel = isRelativeTo(target, project_root) ? path6.relative(project_root, target) : target;
|
|
4259
4459
|
info(`Manifest updated: ${rel}`);
|
|
4260
4460
|
}
|
|
4261
4461
|
return 0;
|
|
4262
4462
|
}
|
|
4263
4463
|
function isRelativeTo(child, parent) {
|
|
4264
|
-
const rel =
|
|
4265
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
4464
|
+
const rel = path6.relative(parent, child);
|
|
4465
|
+
return rel === "" || !rel.startsWith("..") && !path6.isAbsolute(rel);
|
|
4266
4466
|
}
|
|
4267
4467
|
function _resolve_package_root_for_global() {
|
|
4268
4468
|
const here = resolvePath(_HERE);
|
|
4269
|
-
const candidate =
|
|
4270
|
-
if (!pathExists(
|
|
4469
|
+
const candidate = path6.dirname(path6.dirname(path6.dirname(here)));
|
|
4470
|
+
if (!pathExists(path6.join(candidate, "src", "config", "profiles", "minimal.ini"))) {
|
|
4271
4471
|
fail(
|
|
4272
4472
|
`Could not locate agent-config package root from ${here}. Expected src/config/profiles/minimal.ini at the parent directory.`
|
|
4273
4473
|
);
|
|
4274
4474
|
}
|
|
4275
4475
|
return candidate;
|
|
4276
4476
|
}
|
|
4277
|
-
var CONSUMER_BRIDGE_MARKER_RELPATH =
|
|
4477
|
+
var CONSUMER_BRIDGE_MARKER_RELPATH = path6.join("agents", ".event4u-bridge.yml");
|
|
4278
4478
|
var MIGRATE_LEGACY_YAML_FILES = [".agent-settings.yml", ".agent-user.yml"];
|
|
4279
4479
|
var MIGRATE_LEGACY_TOOL_DIRS = [".augment", ".claude", ".cursor"];
|
|
4280
4480
|
var AGENT_CONFIG_PACKAGE_NAME = "@event4u/agent-config";
|
|
@@ -4282,7 +4482,7 @@ function _is_agent_config_source_repo(project_root) {
|
|
|
4282
4482
|
if (process2.env["AGENT_CONFIG_CONSUMER_MODE"] === "1") {
|
|
4283
4483
|
return [false, "consumer-mode-override"];
|
|
4284
4484
|
}
|
|
4285
|
-
const pkg_json =
|
|
4485
|
+
const pkg_json = path6.join(project_root, "package.json");
|
|
4286
4486
|
if (isFile(pkg_json)) {
|
|
4287
4487
|
let data = {};
|
|
4288
4488
|
try {
|
|
@@ -4294,18 +4494,18 @@ function _is_agent_config_source_repo(project_root) {
|
|
|
4294
4494
|
return [true, "package.json:name"];
|
|
4295
4495
|
}
|
|
4296
4496
|
}
|
|
4297
|
-
if (isDir(
|
|
4497
|
+
if (isDir(path6.join(project_root, ".agent-src.uncondensed"))) {
|
|
4298
4498
|
return [true, ".agent-src.uncondensed/"];
|
|
4299
4499
|
}
|
|
4300
|
-
const packages_dir =
|
|
4500
|
+
const packages_dir = path6.join(project_root, "packages");
|
|
4301
4501
|
if (isDir(packages_dir)) {
|
|
4302
|
-
for (const child of
|
|
4303
|
-
if (isDir(
|
|
4502
|
+
for (const child of fs7.readdirSync(packages_dir)) {
|
|
4503
|
+
if (isDir(path6.join(packages_dir, child, ".agent-src.uncondensed"))) {
|
|
4304
4504
|
return [true, `packages/${child}/.agent-src.uncondensed/`];
|
|
4305
4505
|
}
|
|
4306
4506
|
}
|
|
4307
4507
|
}
|
|
4308
|
-
const installer_self =
|
|
4508
|
+
const installer_self = path6.join(project_root, "scripts", "install.py");
|
|
4309
4509
|
try {
|
|
4310
4510
|
if (isFile(installer_self) && resolvePath(installer_self) === resolvePath(_HERE)) {
|
|
4311
4511
|
return [true, "src/scripts/install.py (self)"];
|
|
@@ -4325,17 +4525,17 @@ function _detect_legacy_for_migration(project_root) {
|
|
|
4325
4525
|
}
|
|
4326
4526
|
return [];
|
|
4327
4527
|
}
|
|
4328
|
-
if (isFile(
|
|
4528
|
+
if (isFile(path6.join(project_root, INSTALL_MODE_MARKER_REL))) return [];
|
|
4329
4529
|
const found = [];
|
|
4330
4530
|
for (const name of MIGRATE_LEGACY_YAML_FILES) {
|
|
4331
|
-
if (isFile(
|
|
4531
|
+
if (isFile(path6.join(project_root, name))) {
|
|
4332
4532
|
found.push(name);
|
|
4333
|
-
} else if (isFile(
|
|
4533
|
+
} else if (isFile(path6.join(project_root, "settings", name))) {
|
|
4334
4534
|
found.push(`settings/${name}`);
|
|
4335
4535
|
}
|
|
4336
4536
|
}
|
|
4337
4537
|
for (const name of MIGRATE_LEGACY_TOOL_DIRS) {
|
|
4338
|
-
const p =
|
|
4538
|
+
const p = path6.join(project_root, name);
|
|
4339
4539
|
if (isDir(p) && !isSymlink(p)) {
|
|
4340
4540
|
found.push(`${name}/`);
|
|
4341
4541
|
}
|
|
@@ -4347,7 +4547,7 @@ function _prompt_migrate_to_global(project_root, artefacts) {
|
|
|
4347
4547
|
process2.stdout.write("\n");
|
|
4348
4548
|
warn("Legacy project-local artefacts detected \u2014 pre-ADR-020 layout:");
|
|
4349
4549
|
for (const rel of artefacts) {
|
|
4350
|
-
info(` ${
|
|
4550
|
+
info(` ${path6.join(project_root, rel)}`);
|
|
4351
4551
|
}
|
|
4352
4552
|
info("The unified `agent-config migrate` sweeps these in one pass.");
|
|
4353
4553
|
info("The wizard recreates fresh config afterwards.");
|
|
@@ -4378,20 +4578,20 @@ function _run_migrate_to_global(project_root) {
|
|
|
4378
4578
|
function _format_global_root_for_marker(global_root) {
|
|
4379
4579
|
const home = resolvePath(os2.homedir());
|
|
4380
4580
|
const resolved = resolvePath(global_root);
|
|
4381
|
-
const rel =
|
|
4382
|
-
if (rel === "" || rel.startsWith("..") ||
|
|
4581
|
+
const rel = path6.relative(home, resolved);
|
|
4582
|
+
if (rel === "" || rel.startsWith("..") || path6.isAbsolute(rel)) {
|
|
4383
4583
|
return global_root;
|
|
4384
4584
|
}
|
|
4385
|
-
return `~/${rel.split(
|
|
4585
|
+
return `~/${rel.split(path6.sep).join("/")}`;
|
|
4386
4586
|
}
|
|
4387
4587
|
function _remove_legacy_consumer_bridge_marker(project_root, env = null) {
|
|
4388
4588
|
const env_map = env ?? process2.env;
|
|
4389
4589
|
if (env_map["AGENT_CONFIG_DEV_MODE"] === "1") return null;
|
|
4390
|
-
if (isDir(
|
|
4391
|
-
const target =
|
|
4590
|
+
if (isDir(path6.join(project_root, ".agent-src.uncondensed"))) return null;
|
|
4591
|
+
const target = path6.join(project_root, CONSUMER_BRIDGE_MARKER_RELPATH);
|
|
4392
4592
|
if (!isFile(target)) return null;
|
|
4393
4593
|
try {
|
|
4394
|
-
|
|
4594
|
+
fs7.rmSync(target);
|
|
4395
4595
|
} catch {
|
|
4396
4596
|
return null;
|
|
4397
4597
|
}
|
|
@@ -4405,7 +4605,7 @@ var PROJECT_ANCHOR_TOOLS = {
|
|
|
4405
4605
|
function _write_per_tool_project_anchors(project_root, tools, env = null, now = null) {
|
|
4406
4606
|
const env_map = env ?? process2.env;
|
|
4407
4607
|
if (env_map["AGENT_CONFIG_DEV_MODE"] === "1") return [];
|
|
4408
|
-
if (isDir(
|
|
4608
|
+
if (isDir(path6.join(project_root, ".agent-src.uncondensed"))) return [];
|
|
4409
4609
|
const global_root_str = _format_global_root_for_marker(
|
|
4410
4610
|
event4u_root(env_map)
|
|
4411
4611
|
);
|
|
@@ -4414,8 +4614,8 @@ function _write_per_tool_project_anchors(project_root, tools, env = null, now =
|
|
|
4414
4614
|
for (const tool_id of Object.keys(PROJECT_ANCHOR_TOOLS).sort()) {
|
|
4415
4615
|
const rel_path = PROJECT_ANCHOR_TOOLS[tool_id];
|
|
4416
4616
|
if (!tools.has(tool_id)) continue;
|
|
4417
|
-
const target =
|
|
4418
|
-
mkdirp(
|
|
4617
|
+
const target = path6.join(project_root, rel_path);
|
|
4618
|
+
mkdirp(path6.dirname(target));
|
|
4419
4619
|
const body = `# event4u/agent-config \u2014 per-tool project anchor (auto-written).
|
|
4420
4620
|
# Spec: docs/contracts/consumer-bridge.md \xA7 Per-tool anchor strategy.
|
|
4421
4621
|
# Tool: ${tool_id}. Resolves the global install directly \u2014 no
|
|
@@ -4433,7 +4633,7 @@ installed_at: ${stamp}
|
|
|
4433
4633
|
}
|
|
4434
4634
|
var PACKAGE_TAG_ID = "event4u/agent-config";
|
|
4435
4635
|
function _inject_package_tag(target, source, package_root) {
|
|
4436
|
-
if (
|
|
4636
|
+
if (path6.extname(target) !== ".md") return;
|
|
4437
4637
|
let text;
|
|
4438
4638
|
try {
|
|
4439
4639
|
text = readText(target);
|
|
@@ -4461,8 +4661,8 @@ function _inject_package_tag(target, source, package_root) {
|
|
|
4461
4661
|
resolved_src = source;
|
|
4462
4662
|
}
|
|
4463
4663
|
if (package_root !== null) {
|
|
4464
|
-
const rel =
|
|
4465
|
-
if (rel !== "" && !rel.startsWith("..") && !
|
|
4664
|
+
const rel = path6.relative(resolvePath(package_root), resolved_src);
|
|
4665
|
+
if (rel !== "" && !rel.startsWith("..") && !path6.isAbsolute(rel)) {
|
|
4466
4666
|
source_value = rel;
|
|
4467
4667
|
} else {
|
|
4468
4668
|
source_value = resolved_src;
|
|
@@ -4497,7 +4697,7 @@ function _escapes_package_root(resolved, package_root) {
|
|
|
4497
4697
|
if (package_root === null) return false;
|
|
4498
4698
|
let root;
|
|
4499
4699
|
try {
|
|
4500
|
-
root =
|
|
4700
|
+
root = fs7.realpathSync(package_root);
|
|
4501
4701
|
} catch {
|
|
4502
4702
|
return false;
|
|
4503
4703
|
}
|
|
@@ -4512,7 +4712,7 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
|
|
|
4512
4712
|
if (file_filter !== null && !file_filter(src)) return [0, 0, written_paths];
|
|
4513
4713
|
let resolved_src = src;
|
|
4514
4714
|
try {
|
|
4515
|
-
resolved_src =
|
|
4715
|
+
resolved_src = fs7.realpathSync(src);
|
|
4516
4716
|
} catch {
|
|
4517
4717
|
resolved_src = src;
|
|
4518
4718
|
}
|
|
@@ -4520,10 +4720,10 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
|
|
|
4520
4720
|
warn(`refused: ${src} dereferences outside the package root \u2014 not copied`);
|
|
4521
4721
|
return [0, 0, written_paths];
|
|
4522
4722
|
}
|
|
4523
|
-
mkdirp(
|
|
4723
|
+
mkdirp(path6.dirname(dest));
|
|
4524
4724
|
const decision = _resolve_file_conflict(dest, force);
|
|
4525
4725
|
if (decision === "skip") return [0, 1, written_paths];
|
|
4526
|
-
|
|
4726
|
+
fs7.copyFileSync(src, dest);
|
|
4527
4727
|
_inject_package_tag(dest, src, package_root);
|
|
4528
4728
|
written_paths.push(dest);
|
|
4529
4729
|
return [1, 0, written_paths];
|
|
@@ -4531,11 +4731,11 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
|
|
|
4531
4731
|
mkdirp(dest);
|
|
4532
4732
|
const walk = (node) => {
|
|
4533
4733
|
const acc = [];
|
|
4534
|
-
const names =
|
|
4734
|
+
const names = fs7.readdirSync(node).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
|
|
4535
4735
|
for (const name of names) {
|
|
4536
|
-
const entry =
|
|
4736
|
+
const entry = path6.join(node, name);
|
|
4537
4737
|
acc.push(entry);
|
|
4538
|
-
const lst =
|
|
4738
|
+
const lst = fs7.lstatSync(entry);
|
|
4539
4739
|
if (lst.isDirectory() && !lst.isSymbolicLink()) {
|
|
4540
4740
|
acc.push(...walk(entry));
|
|
4541
4741
|
}
|
|
@@ -4543,9 +4743,9 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
|
|
|
4543
4743
|
return acc;
|
|
4544
4744
|
};
|
|
4545
4745
|
for (const entry of walk(src)) {
|
|
4546
|
-
const rel =
|
|
4547
|
-
const target =
|
|
4548
|
-
const lst =
|
|
4746
|
+
const rel = path6.relative(src, entry);
|
|
4747
|
+
const target = path6.join(dest, rel);
|
|
4748
|
+
const lst = fs7.lstatSync(entry);
|
|
4549
4749
|
if (lst.isDirectory() && !lst.isSymbolicLink()) {
|
|
4550
4750
|
mkdirp(target);
|
|
4551
4751
|
continue;
|
|
@@ -4553,8 +4753,8 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
|
|
|
4553
4753
|
let resolvedIsDir = false;
|
|
4554
4754
|
let resolved = entry;
|
|
4555
4755
|
try {
|
|
4556
|
-
resolved =
|
|
4557
|
-
resolvedIsDir =
|
|
4756
|
+
resolved = fs7.realpathSync(entry);
|
|
4757
|
+
resolvedIsDir = fs7.statSync(entry).isDirectory();
|
|
4558
4758
|
} catch {
|
|
4559
4759
|
resolvedIsDir = false;
|
|
4560
4760
|
}
|
|
@@ -4584,8 +4784,8 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
|
|
|
4584
4784
|
skipped += 1;
|
|
4585
4785
|
continue;
|
|
4586
4786
|
}
|
|
4587
|
-
mkdirp(
|
|
4588
|
-
|
|
4787
|
+
mkdirp(path6.dirname(target));
|
|
4788
|
+
fs7.copyFileSync(resolved, target);
|
|
4589
4789
|
_inject_package_tag(target, resolved, package_root);
|
|
4590
4790
|
written += 1;
|
|
4591
4791
|
written_paths.push(target);
|
|
@@ -4597,7 +4797,7 @@ function _claude_desktop_bundles_dir() {
|
|
|
4597
4797
|
}
|
|
4598
4798
|
function _write_claude_desktop_marker(_force, lockfile_path2, bundles_dir, bundle_count) {
|
|
4599
4799
|
const anchor = expanduser2(USER_SCOPE_PATHS["claude-desktop"]);
|
|
4600
|
-
const target =
|
|
4800
|
+
const target = path6.join(anchor, "agent-config.md");
|
|
4601
4801
|
mkdirp(anchor);
|
|
4602
4802
|
const body = claudeDesktopMarkerBody(lockfile_path2, anchor, bundles_dir, bundle_count);
|
|
4603
4803
|
writeText(target, body);
|
|
@@ -4621,23 +4821,23 @@ function _apply_claude_flat_command_wrappers(anchor, package_root, current_files
|
|
|
4621
4821
|
const wrapped = [];
|
|
4622
4822
|
const collisions = [];
|
|
4623
4823
|
const reserved = [];
|
|
4624
|
-
const commands_dir =
|
|
4824
|
+
const commands_dir = path6.join(anchor, "commands");
|
|
4625
4825
|
let flat_entries = [];
|
|
4626
4826
|
try {
|
|
4627
|
-
flat_entries =
|
|
4827
|
+
flat_entries = fs7.readdirSync(commands_dir).filter((f) => f.endsWith(".md"));
|
|
4628
4828
|
} catch {
|
|
4629
4829
|
}
|
|
4630
4830
|
for (const fname of flat_entries.sort()) {
|
|
4631
4831
|
const slug = fname.slice(0, -".md".length);
|
|
4632
4832
|
if (!is_claude_builtin_name(slug)) continue;
|
|
4633
|
-
|
|
4833
|
+
fs7.rmSync(path6.join(commands_dir, fname), { force: true });
|
|
4634
4834
|
current_files.delete(`commands/${fname}`);
|
|
4635
4835
|
reserved.push(slug);
|
|
4636
4836
|
}
|
|
4637
4837
|
const eligible = new Set(_CLAUDE_FLAT_WRAPPER_EXTRA);
|
|
4638
4838
|
try {
|
|
4639
4839
|
const manifest = JSON.parse(
|
|
4640
|
-
|
|
4840
|
+
fs7.readFileSync(path6.join(package_root, "dist", "discovery", "discovery-manifest.json"), "utf8")
|
|
4641
4841
|
);
|
|
4642
4842
|
for (const a of manifest.artefacts ?? []) {
|
|
4643
4843
|
if (a.category !== "command" || typeof a.slug !== "string") continue;
|
|
@@ -4648,22 +4848,22 @@ function _apply_claude_flat_command_wrappers(anchor, package_root, current_files
|
|
|
4648
4848
|
}
|
|
4649
4849
|
for (const slug of [...eligible].sort()) {
|
|
4650
4850
|
const flat_rel = `commands/${slug}.md`;
|
|
4651
|
-
const flat_abs =
|
|
4652
|
-
if (!
|
|
4653
|
-
const skill_dir =
|
|
4654
|
-
if (
|
|
4851
|
+
const flat_abs = path6.join(anchor, "commands", `${slug}.md`);
|
|
4852
|
+
if (!fs7.existsSync(flat_abs)) continue;
|
|
4853
|
+
const skill_dir = path6.join(anchor, "skills", slug);
|
|
4854
|
+
if (fs7.existsSync(skill_dir)) {
|
|
4655
4855
|
collisions.push(slug);
|
|
4656
4856
|
continue;
|
|
4657
4857
|
}
|
|
4658
|
-
let body =
|
|
4858
|
+
let body = fs7.readFileSync(flat_abs, "utf8");
|
|
4659
4859
|
if (body.startsWith("---\n") && !/^name:/m.test(body.split("\n---")[0] ?? "")) {
|
|
4660
4860
|
body = body.replace("---\n", `---
|
|
4661
4861
|
name: ${slug}
|
|
4662
4862
|
`);
|
|
4663
4863
|
}
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4864
|
+
fs7.mkdirSync(skill_dir, { recursive: true });
|
|
4865
|
+
fs7.writeFileSync(path6.join(skill_dir, "SKILL.md"), body, "utf8");
|
|
4866
|
+
fs7.rmSync(flat_abs, { force: true });
|
|
4667
4867
|
current_files.delete(flat_rel);
|
|
4668
4868
|
current_files.add(`skills/${slug}/SKILL.md`);
|
|
4669
4869
|
wrapped.push(slug);
|
|
@@ -4695,8 +4895,8 @@ function _deploy_global_content(tools, force, package_root, lockfile_path2) {
|
|
|
4695
4895
|
const written_paths = [];
|
|
4696
4896
|
let current_files = /* @__PURE__ */ new Set();
|
|
4697
4897
|
for (const [src_rel, dest_sub] of plan) {
|
|
4698
|
-
const src =
|
|
4699
|
-
const dest = dest_sub ?
|
|
4898
|
+
const src = path6.join(package_root, src_rel);
|
|
4899
|
+
const dest = dest_sub ? path6.join(anchor, dest_sub) : anchor;
|
|
4700
4900
|
const rule_filter = _rule_filter_for_source(src_rel, rule_scope);
|
|
4701
4901
|
const [w, s, paths] = _copy_dir_dereferencing_symlinks(
|
|
4702
4902
|
src,
|
|
@@ -4770,10 +4970,10 @@ function _deploy_global_content(tools, force, package_root, lockfile_path2) {
|
|
|
4770
4970
|
results[tool_id] = [written_total, skipped_total, "deployed", written_paths];
|
|
4771
4971
|
if (tool_id === "claude-code") {
|
|
4772
4972
|
try {
|
|
4773
|
-
const manifest =
|
|
4973
|
+
const manifest = path6.join(package_root, "src", "scripts", "hook_manifest.yaml");
|
|
4774
4974
|
const matrix = build_claude_hook_matrix(manifest);
|
|
4775
4975
|
const res = ensure_managed_hooks(
|
|
4776
|
-
|
|
4976
|
+
path6.join(anchor, "settings.json"),
|
|
4777
4977
|
matrix
|
|
4778
4978
|
);
|
|
4779
4979
|
if (!state.QUIET) {
|
|
@@ -4810,7 +5010,7 @@ function _preview_global_reap(tools, package_root) {
|
|
|
4810
5010
|
const anchor = expanduser2(anchor_raw);
|
|
4811
5011
|
let current_files = /* @__PURE__ */ new Set();
|
|
4812
5012
|
for (const [src_rel, dest_sub] of plan) {
|
|
4813
|
-
const src =
|
|
5013
|
+
const src = path6.join(package_root, src_rel);
|
|
4814
5014
|
current_files = setUnion(
|
|
4815
5015
|
current_files,
|
|
4816
5016
|
expected_deploy_files(
|
|
@@ -4844,14 +5044,14 @@ function _preview_global_reap(tools, package_root) {
|
|
|
4844
5044
|
function _verify_deploy_targets(anchor, plan) {
|
|
4845
5045
|
const missing = [];
|
|
4846
5046
|
for (const [, dest_sub] of plan) {
|
|
4847
|
-
const target = dest_sub ?
|
|
5047
|
+
const target = dest_sub ? path6.join(anchor, dest_sub) : anchor;
|
|
4848
5048
|
const label = dest_sub || ".";
|
|
4849
5049
|
if (!isDir(target)) {
|
|
4850
5050
|
missing.push(label);
|
|
4851
5051
|
continue;
|
|
4852
5052
|
}
|
|
4853
5053
|
try {
|
|
4854
|
-
const entries =
|
|
5054
|
+
const entries = fs7.readdirSync(target);
|
|
4855
5055
|
if (entries.length === 0) missing.push(label);
|
|
4856
5056
|
} catch {
|
|
4857
5057
|
missing.push(label);
|
|
@@ -4866,13 +5066,13 @@ function _prune_modules_by(deploy_results, is_pruned) {
|
|
|
4866
5066
|
const [written, skipped, status, paths] = deploy_results[tool_id];
|
|
4867
5067
|
const pruned_skill_dirs = /* @__PURE__ */ new Set();
|
|
4868
5068
|
for (const p of paths) {
|
|
4869
|
-
const parts = p.split(
|
|
5069
|
+
const parts = p.split(path6.sep);
|
|
4870
5070
|
if (parts.includes("skills")) {
|
|
4871
5071
|
const i = parts.indexOf("skills");
|
|
4872
5072
|
if (i + 1 < parts.length) {
|
|
4873
|
-
const skill_root = parts.slice(0, i + 2).join(
|
|
5073
|
+
const skill_root = parts.slice(0, i + 2).join(path6.sep);
|
|
4874
5074
|
if (!pruned_skill_dirs.has(skill_root)) {
|
|
4875
|
-
const skillmd =
|
|
5075
|
+
const skillmd = path6.join(skill_root, "SKILL.md");
|
|
4876
5076
|
if (pathExists(skillmd) && is_pruned(skillmd)) {
|
|
4877
5077
|
pruned_skill_dirs.add(skill_root);
|
|
4878
5078
|
}
|
|
@@ -4883,25 +5083,25 @@ function _prune_modules_by(deploy_results, is_pruned) {
|
|
|
4883
5083
|
const keep = [];
|
|
4884
5084
|
const delete_files = [];
|
|
4885
5085
|
for (const p of paths) {
|
|
4886
|
-
const parts = p.split(
|
|
5086
|
+
const parts = p.split(path6.sep);
|
|
4887
5087
|
let is_target = false;
|
|
4888
5088
|
if (parts.includes("skills")) {
|
|
4889
5089
|
const i = parts.indexOf("skills");
|
|
4890
|
-
if (i + 1 < parts.length && pruned_skill_dirs.has(parts.slice(0, i + 2).join(
|
|
5090
|
+
if (i + 1 < parts.length && pruned_skill_dirs.has(parts.slice(0, i + 2).join(path6.sep))) {
|
|
4891
5091
|
is_target = true;
|
|
4892
5092
|
}
|
|
4893
|
-
} else if (parts.includes("commands") &&
|
|
5093
|
+
} else if (parts.includes("commands") && path6.extname(p) === ".md" && is_pruned(p)) {
|
|
4894
5094
|
is_target = true;
|
|
4895
5095
|
}
|
|
4896
5096
|
(is_target ? delete_files : keep).push(p);
|
|
4897
5097
|
}
|
|
4898
5098
|
for (const d of pruned_skill_dirs) {
|
|
4899
|
-
|
|
5099
|
+
fs7.rmSync(d, { recursive: true, force: true });
|
|
4900
5100
|
}
|
|
4901
5101
|
for (const p of delete_files) {
|
|
4902
|
-
if (p.split(
|
|
5102
|
+
if (p.split(path6.sep).includes("commands") && pathExists(p)) {
|
|
4903
5103
|
try {
|
|
4904
|
-
|
|
5104
|
+
fs7.unlinkSync(p);
|
|
4905
5105
|
} catch {
|
|
4906
5106
|
}
|
|
4907
5107
|
}
|
|
@@ -4922,9 +5122,9 @@ function _resolve_global_settings_doc() {
|
|
|
4922
5122
|
}
|
|
4923
5123
|
function _resolve_global_settings_path() {
|
|
4924
5124
|
const root = event4u_root();
|
|
4925
|
-
const canonical =
|
|
5125
|
+
const canonical = path6.join(root, "settings", SETTINGS_FILE);
|
|
4926
5126
|
if (pathExists(canonical)) return canonical;
|
|
4927
|
-
const legacy =
|
|
5127
|
+
const legacy = path6.join(root, SETTINGS_FILE);
|
|
4928
5128
|
if (pathExists(legacy)) return legacy;
|
|
4929
5129
|
return null;
|
|
4930
5130
|
}
|
|
@@ -5035,7 +5235,7 @@ function install_global(tools, force, project_root = null, core_only = false) {
|
|
|
5035
5235
|
info(` schema_version=1, agent_config_version=${installed_version}`);
|
|
5036
5236
|
info(` tools=${merged_tools.join(",")}`);
|
|
5037
5237
|
}
|
|
5038
|
-
if (project_root !== null && pathExists(_resolve_settings_read(project_root)) && !isDir(
|
|
5238
|
+
if (project_root !== null && pathExists(_resolve_settings_read(project_root)) && !isDir(path6.join(project_root, ".agent-src.uncondensed"))) {
|
|
5039
5239
|
const drift = collect_drift(project_root);
|
|
5040
5240
|
if (!state.QUIET) {
|
|
5041
5241
|
process2.stdout.write("\n");
|
|
@@ -5135,19 +5335,19 @@ function install_global(tools, force, project_root = null, core_only = false) {
|
|
|
5135
5335
|
}
|
|
5136
5336
|
}
|
|
5137
5337
|
}
|
|
5138
|
-
if (project_root !== null && pathExists(_resolve_settings_read(project_root)) && !isDir(
|
|
5338
|
+
if (project_root !== null && pathExists(_resolve_settings_read(project_root)) && !isDir(path6.join(project_root, ".agent-src.uncondensed"))) {
|
|
5139
5339
|
const files_by_tool = _files_by_tool_from_deploy(deploy_results);
|
|
5140
5340
|
const rc = _update_installed_tools_manifest(project_root, tools, "global", force, files_by_tool);
|
|
5141
5341
|
if (rc !== 0) return rc;
|
|
5142
5342
|
const removed_marker = _remove_legacy_consumer_bridge_marker(project_root);
|
|
5143
5343
|
if (removed_marker !== null && !state.QUIET) {
|
|
5144
|
-
const rel = isRelativeTo(removed_marker, project_root) ?
|
|
5344
|
+
const rel = isRelativeTo(removed_marker, project_root) ? path6.relative(project_root, removed_marker) : removed_marker;
|
|
5145
5345
|
info(`Removed legacy bridge marker: ${rel}`);
|
|
5146
5346
|
}
|
|
5147
5347
|
const anchor_paths = _write_per_tool_project_anchors(project_root, tools);
|
|
5148
5348
|
if (anchor_paths.length > 0 && !state.QUIET) {
|
|
5149
5349
|
for (const p of anchor_paths) {
|
|
5150
|
-
const rel = isRelativeTo(p, project_root) ?
|
|
5350
|
+
const rel = isRelativeTo(p, project_root) ? path6.relative(project_root, p) : p;
|
|
5151
5351
|
info(`Project anchor written: ${rel}`);
|
|
5152
5352
|
}
|
|
5153
5353
|
}
|
|
@@ -5157,6 +5357,23 @@ function install_global(tools, force, project_root = null, core_only = false) {
|
|
|
5157
5357
|
} catch (e) {
|
|
5158
5358
|
if (!state.QUIET) warn(`settings-surface snapshot failed \u2014 ${String(e)}`);
|
|
5159
5359
|
}
|
|
5360
|
+
if (!state.QUIET) {
|
|
5361
|
+
try {
|
|
5362
|
+
for (const line of _catalogue_truncation_warnings(deploy_results, project_root)) {
|
|
5363
|
+
warn(line);
|
|
5364
|
+
}
|
|
5365
|
+
const notice = _scoped_migration_notice(deploy_results, project_root, package_root, {
|
|
5366
|
+
env: process2.env,
|
|
5367
|
+
stdinTty: process2.stdin.isTTY === true,
|
|
5368
|
+
stdoutTty: process2.stdout.isTTY === true
|
|
5369
|
+
});
|
|
5370
|
+
if (notice.length > 0) {
|
|
5371
|
+
process2.stdout.write("\n");
|
|
5372
|
+
for (const line of notice) info(line);
|
|
5373
|
+
}
|
|
5374
|
+
} catch {
|
|
5375
|
+
}
|
|
5376
|
+
}
|
|
5160
5377
|
if (!state.QUIET) {
|
|
5161
5378
|
process2.stdout.write("\n");
|
|
5162
5379
|
success(`Global install completed (v${installed_version}).`);
|
|
@@ -5164,8 +5381,59 @@ function install_global(tools, force, project_root = null, core_only = false) {
|
|
|
5164
5381
|
}
|
|
5165
5382
|
return 0;
|
|
5166
5383
|
}
|
|
5167
|
-
|
|
5168
|
-
|
|
5384
|
+
function _catalogue_truncation_warnings(deploy_results, project_root) {
|
|
5385
|
+
const log_candidates = [
|
|
5386
|
+
path6.join(event4u_root(), "state", "skill-catalogue.jsonl"),
|
|
5387
|
+
...project_root ? [path6.join(project_root, OBSERVATION_LOG)] : []
|
|
5388
|
+
];
|
|
5389
|
+
const records = log_candidates.flatMap((p) => readObservationLog(p));
|
|
5390
|
+
if (records.length === 0) return [];
|
|
5391
|
+
const limits = knownHostLimits(records);
|
|
5392
|
+
if (limits.size === 0) return [];
|
|
5393
|
+
const lines = [];
|
|
5394
|
+
for (const tool_id of Object.keys(deploy_results).sort()) {
|
|
5395
|
+
const [, , status] = deploy_results[tool_id];
|
|
5396
|
+
if (status !== "deployed") continue;
|
|
5397
|
+
const limit = limits.get(tool_id);
|
|
5398
|
+
if (limit === void 0) continue;
|
|
5399
|
+
const anchor_raw = USER_SCOPE_PATHS[tool_id];
|
|
5400
|
+
if (!anchor_raw) continue;
|
|
5401
|
+
const volume = measureCatalogueVolume(tool_id, expanduser2(anchor_raw));
|
|
5402
|
+
const warning = catalogueLimitWarning(volume, limit);
|
|
5403
|
+
if (warning !== null) lines.push(warning);
|
|
5404
|
+
}
|
|
5405
|
+
return lines;
|
|
5406
|
+
}
|
|
5407
|
+
function _scoped_migration_notice(deploy_results, project_root, package_root, probe) {
|
|
5408
|
+
if (!isInteractiveSession(probe)) return [];
|
|
5409
|
+
const log_candidates = [
|
|
5410
|
+
path6.join(event4u_root(), "state", "skill-catalogue.jsonl"),
|
|
5411
|
+
...project_root ? [path6.join(project_root, OBSERVATION_LOG)] : []
|
|
5412
|
+
];
|
|
5413
|
+
const limits = knownHostLimits(log_candidates.flatMap((p) => readObservationLog(p)));
|
|
5414
|
+
if (limits.size === 0) return [];
|
|
5415
|
+
const resolved = _resolve_scoped_projection(package_root);
|
|
5416
|
+
const settings_path = _resolve_global_settings_path() ?? path6.join(event4u_root(), "settings", SETTINGS_FILE);
|
|
5417
|
+
for (const tool_id of Object.keys(deploy_results).sort()) {
|
|
5418
|
+
const [, , status] = deploy_results[tool_id];
|
|
5419
|
+
if (status !== "deployed") continue;
|
|
5420
|
+
const anchor_raw = USER_SCOPE_PATHS[tool_id];
|
|
5421
|
+
if (!anchor_raw) continue;
|
|
5422
|
+
const volume = measureCatalogueVolume(tool_id, expanduser2(anchor_raw));
|
|
5423
|
+
const eligibility = migrationEligibility(
|
|
5424
|
+
tool_id,
|
|
5425
|
+
resolved.mode,
|
|
5426
|
+
volume.skillEntries,
|
|
5427
|
+
limits
|
|
5428
|
+
);
|
|
5429
|
+
if (eligibility.eligible) {
|
|
5430
|
+
return migrationPromptLines(tool_id, eligibility, settings_path);
|
|
5431
|
+
}
|
|
5432
|
+
}
|
|
5433
|
+
return [];
|
|
5434
|
+
}
|
|
5435
|
+
var SETTINGS_SURFACE_REL = path6.join("state", "settings-surface.json");
|
|
5436
|
+
var SETTINGS_DELTA_REL = path6.join("state", "settings-delta.json");
|
|
5169
5437
|
function _current_settings_surface(version) {
|
|
5170
5438
|
const jsonSchema = zodToJsonSchema(settingsSchema, {
|
|
5171
5439
|
name: "AgentSettings",
|
|
@@ -5176,20 +5444,20 @@ function _current_settings_surface(version) {
|
|
|
5176
5444
|
}
|
|
5177
5445
|
function _write_settings_surface_snapshot(installed_version) {
|
|
5178
5446
|
const root = event4u_root();
|
|
5179
|
-
const surface_path =
|
|
5180
|
-
const delta_path =
|
|
5447
|
+
const surface_path = path6.join(root, SETTINGS_SURFACE_REL);
|
|
5448
|
+
const delta_path = path6.join(root, SETTINGS_DELTA_REL);
|
|
5181
5449
|
const next = _current_settings_surface(installed_version);
|
|
5182
5450
|
let previous = null;
|
|
5183
5451
|
try {
|
|
5184
|
-
const parsed = JSON.parse(
|
|
5452
|
+
const parsed = JSON.parse(fs7.readFileSync(surface_path, "utf8"));
|
|
5185
5453
|
if (parsed !== null && typeof parsed === "object" && parsed.entries !== void 0) previous = parsed;
|
|
5186
5454
|
} catch {
|
|
5187
5455
|
}
|
|
5188
5456
|
if (previous !== null && previous.version !== next.version) {
|
|
5189
5457
|
const delta = computeSurfaceDelta(previous, next);
|
|
5190
5458
|
if (delta.changes.length > 0) {
|
|
5191
|
-
|
|
5192
|
-
|
|
5459
|
+
fs7.mkdirSync(path6.dirname(delta_path), { recursive: true, mode: 448 });
|
|
5460
|
+
fs7.writeFileSync(delta_path, `${JSON.stringify(delta, null, 2)}
|
|
5193
5461
|
`, { mode: 384 });
|
|
5194
5462
|
if (!state.QUIET) {
|
|
5195
5463
|
const counts = {};
|
|
@@ -5201,8 +5469,8 @@ function _write_settings_surface_snapshot(installed_version) {
|
|
|
5201
5469
|
}
|
|
5202
5470
|
}
|
|
5203
5471
|
}
|
|
5204
|
-
|
|
5205
|
-
|
|
5472
|
+
fs7.mkdirSync(path6.dirname(surface_path), { recursive: true, mode: 448 });
|
|
5473
|
+
fs7.writeFileSync(surface_path, `${JSON.stringify(next, null, 2)}
|
|
5206
5474
|
`, { mode: 384 });
|
|
5207
5475
|
}
|
|
5208
5476
|
function arrayStrEqual(a, b) {
|
|
@@ -5422,13 +5690,13 @@ function _minimal_templates_root() {
|
|
|
5422
5690
|
const chain = [start];
|
|
5423
5691
|
let cur = start;
|
|
5424
5692
|
for (; ; ) {
|
|
5425
|
-
const parent =
|
|
5693
|
+
const parent = path6.dirname(cur);
|
|
5426
5694
|
if (parent === cur) break;
|
|
5427
5695
|
chain.push(parent);
|
|
5428
5696
|
cur = parent;
|
|
5429
5697
|
}
|
|
5430
5698
|
for (const ancestor of chain) {
|
|
5431
|
-
const candidate =
|
|
5699
|
+
const candidate = path6.join(ancestor, "src", "templates", "minimal");
|
|
5432
5700
|
if (isDir(candidate)) return candidate;
|
|
5433
5701
|
}
|
|
5434
5702
|
fail("Could not locate src/templates/minimal/ \u2014 package install is corrupt.");
|
|
@@ -5436,9 +5704,9 @@ function _minimal_templates_root() {
|
|
|
5436
5704
|
var INSTALL_MODE_MARKER_REL = "agents/.agent-state/install-mode.txt";
|
|
5437
5705
|
function _write_install_mode_marker(project_root, mode) {
|
|
5438
5706
|
if (mode !== "minimal" && mode !== "full") return;
|
|
5439
|
-
const marker =
|
|
5707
|
+
const marker = path6.join(project_root, INSTALL_MODE_MARKER_REL);
|
|
5440
5708
|
try {
|
|
5441
|
-
mkdirp(
|
|
5709
|
+
mkdirp(path6.dirname(marker));
|
|
5442
5710
|
writeText(marker, `${mode}
|
|
5443
5711
|
`);
|
|
5444
5712
|
} catch {
|
|
@@ -5447,7 +5715,7 @@ function _write_install_mode_marker(project_root, mode) {
|
|
|
5447
5715
|
function install_minimal(target_root_in, force, user_type = "") {
|
|
5448
5716
|
let target_root = resolvePath(target_root_in);
|
|
5449
5717
|
mkdirp(target_root);
|
|
5450
|
-
const parent =
|
|
5718
|
+
const parent = path6.dirname(target_root);
|
|
5451
5719
|
if (parent !== target_root) {
|
|
5452
5720
|
const existing = find_project_root_with_anchor(parent);
|
|
5453
5721
|
if (existing !== null && existing[0] !== target_root) {
|
|
@@ -5458,21 +5726,21 @@ function install_minimal(target_root_in, force, user_type = "") {
|
|
|
5458
5726
|
}
|
|
5459
5727
|
}
|
|
5460
5728
|
const templates = _minimal_templates_root();
|
|
5461
|
-
const settings_src =
|
|
5462
|
-
const overrides_gitkeep_src =
|
|
5463
|
-
const overrides_readme_src =
|
|
5729
|
+
const settings_src = path6.join(templates, SETTINGS_FILE);
|
|
5730
|
+
const overrides_gitkeep_src = path6.join(templates, "overrides-gitkeep");
|
|
5731
|
+
const overrides_readme_src = path6.join(templates, "agents-overrides-readme.md");
|
|
5464
5732
|
if (!isFile(settings_src)) fail(`Bundled minimal settings template missing under ${templates}`);
|
|
5465
5733
|
if (!isFile(overrides_gitkeep_src) || !isFile(overrides_readme_src)) {
|
|
5466
5734
|
fail(`Bundled overrides scaffold templates missing under ${templates}`);
|
|
5467
5735
|
}
|
|
5468
5736
|
info(`Minimal init \u2192 ${target_root}`);
|
|
5469
|
-
const overrides_root =
|
|
5737
|
+
const overrides_root = path6.join(target_root, "agents", "overrides");
|
|
5470
5738
|
mkdirp(overrides_root);
|
|
5471
5739
|
const gitkeep_body = readText(overrides_gitkeep_src);
|
|
5472
5740
|
for (const sub of ["rules", "skills", "commands"]) {
|
|
5473
|
-
const sub_dir =
|
|
5741
|
+
const sub_dir = path6.join(overrides_root, sub);
|
|
5474
5742
|
mkdirp(sub_dir);
|
|
5475
|
-
const gitkeep_dst =
|
|
5743
|
+
const gitkeep_dst = path6.join(sub_dir, ".gitkeep");
|
|
5476
5744
|
if (pathExists(gitkeep_dst) && !force) {
|
|
5477
5745
|
skip(`agents/overrides/${sub}/.gitkeep already exists (use --force to overwrite)`);
|
|
5478
5746
|
} else {
|
|
@@ -5480,7 +5748,7 @@ function install_minimal(target_root_in, force, user_type = "") {
|
|
|
5480
5748
|
success(`Wrote agents/overrides/${sub}/.gitkeep`);
|
|
5481
5749
|
}
|
|
5482
5750
|
}
|
|
5483
|
-
const readme_dst =
|
|
5751
|
+
const readme_dst = path6.join(overrides_root, "README.md");
|
|
5484
5752
|
if (pathExists(readme_dst) && !force) {
|
|
5485
5753
|
skip("agents/overrides/README.md already exists (use --force to overwrite)");
|
|
5486
5754
|
} else {
|
|
@@ -5498,14 +5766,14 @@ function install_minimal(target_root_in, force, user_type = "") {
|
|
|
5498
5766
|
personal:
|
|
5499
5767
|
user_type: ${user_type}
|
|
5500
5768
|
`;
|
|
5501
|
-
mkdirp(
|
|
5769
|
+
mkdirp(path6.dirname(settings_dst));
|
|
5502
5770
|
writeText(settings_dst, body);
|
|
5503
5771
|
success(`Wrote ${SETTINGS_FILE} (user_type=${user_type})`);
|
|
5504
5772
|
}
|
|
5505
5773
|
}
|
|
5506
5774
|
const removed_marker = _remove_legacy_consumer_bridge_marker(target_root);
|
|
5507
5775
|
if (removed_marker !== null) {
|
|
5508
|
-
const rel = isRelativeTo(removed_marker, target_root) ?
|
|
5776
|
+
const rel = isRelativeTo(removed_marker, target_root) ? path6.relative(target_root, removed_marker) : removed_marker;
|
|
5509
5777
|
success(`Removed legacy bridge marker: ${rel}`);
|
|
5510
5778
|
}
|
|
5511
5779
|
_write_install_mode_marker(target_root, "minimal");
|
|
@@ -5579,7 +5847,7 @@ function run_interactive_init(project_root, force) {
|
|
|
5579
5847
|
);
|
|
5580
5848
|
return 0;
|
|
5581
5849
|
}
|
|
5582
|
-
const target =
|
|
5850
|
+
const target = path6.join(project_root, _LOCAL_CONFIG_FILE);
|
|
5583
5851
|
if (pathExists(target) && !force) {
|
|
5584
5852
|
warn(
|
|
5585
5853
|
`${_LOCAL_CONFIG_FILE} already exists; re-run with --force to overwrite. Skipping interactive init.`
|
|
@@ -5606,7 +5874,7 @@ function run_interactive_init(project_root, force) {
|
|
|
5606
5874
|
warn(`Could not write ${target}: ${String(exc)}`);
|
|
5607
5875
|
return 1;
|
|
5608
5876
|
}
|
|
5609
|
-
success(`Wrote ${
|
|
5877
|
+
success(`Wrote ${path6.relative(project_root, target)} (${user_type} / ${stack} / ${verbosity})`);
|
|
5610
5878
|
return 0;
|
|
5611
5879
|
}
|
|
5612
5880
|
var _WIZARD_READY_RE = /^WIZARD_READY (http:\/\/(?:127\.0\.0\.1|localhost):\d+\/\S*)\r?$/;
|
|
@@ -5624,12 +5892,12 @@ function _wizard_should_launch(opts) {
|
|
|
5624
5892
|
return [true, ""];
|
|
5625
5893
|
}
|
|
5626
5894
|
function _wizard_cli_dist(_project_root) {
|
|
5627
|
-
const package_root =
|
|
5628
|
-
const cli =
|
|
5895
|
+
const package_root = path6.dirname(path6.dirname(path6.dirname(resolvePath(_HERE))));
|
|
5896
|
+
const cli = path6.join(package_root, "dist", "cli", "agent-config.js");
|
|
5629
5897
|
return pathExists(cli) ? cli : null;
|
|
5630
5898
|
}
|
|
5631
5899
|
function _server_info_path() {
|
|
5632
|
-
return
|
|
5900
|
+
return path6.join(os2.homedir(), ".event4u", "agent-config", "local-server.json");
|
|
5633
5901
|
}
|
|
5634
5902
|
function _pid_is_agent_config(pid) {
|
|
5635
5903
|
let res;
|
|
@@ -5646,7 +5914,7 @@ function _pid_is_agent_config(pid) {
|
|
|
5646
5914
|
}
|
|
5647
5915
|
function unlinkMissingOk(p) {
|
|
5648
5916
|
try {
|
|
5649
|
-
|
|
5917
|
+
fs7.unlinkSync(p);
|
|
5650
5918
|
} catch {
|
|
5651
5919
|
}
|
|
5652
5920
|
}
|
|
@@ -5724,14 +5992,14 @@ function _wizard_spawn(project_root, pass_project_root = true) {
|
|
|
5724
5992
|
}
|
|
5725
5993
|
function _wizard_run_sync(cmd, env, cli) {
|
|
5726
5994
|
const total = _WIZARD_TIMEOUTS.reduce((a, b) => a + b, 0);
|
|
5727
|
-
const log_path =
|
|
5995
|
+
const log_path = path6.join(
|
|
5728
5996
|
os2.tmpdir(),
|
|
5729
5997
|
`agent-config-wizard-${process2.pid}-${Date.now()}.log`
|
|
5730
5998
|
);
|
|
5731
5999
|
let child;
|
|
5732
6000
|
let log_fd = null;
|
|
5733
6001
|
try {
|
|
5734
|
-
log_fd =
|
|
6002
|
+
log_fd = fs7.openSync(log_path, "w");
|
|
5735
6003
|
child = spawn(cmd[0], cmd.slice(1), {
|
|
5736
6004
|
env,
|
|
5737
6005
|
detached: true,
|
|
@@ -5749,7 +6017,7 @@ function _wizard_run_sync(cmd, env, cli) {
|
|
|
5749
6017
|
} finally {
|
|
5750
6018
|
if (log_fd !== null) {
|
|
5751
6019
|
try {
|
|
5752
|
-
|
|
6020
|
+
fs7.closeSync(log_fd);
|
|
5753
6021
|
} catch {
|
|
5754
6022
|
}
|
|
5755
6023
|
}
|
|
@@ -5999,8 +6267,8 @@ function main2(argv) {
|
|
|
5999
6267
|
const target_root = resolvePath(
|
|
6000
6268
|
opts.custom_path || opts.project || process2.env["PROJECT_ROOT"] || process2.cwd()
|
|
6001
6269
|
);
|
|
6002
|
-
const minimal_package_root =
|
|
6003
|
-
|
|
6270
|
+
const minimal_package_root = path6.dirname(
|
|
6271
|
+
path6.dirname(path6.dirname(_minimal_templates_root()))
|
|
6004
6272
|
);
|
|
6005
6273
|
const validated_user_type = _validate_user_type(minimal_package_root, opts.user_type);
|
|
6006
6274
|
return install_minimal(target_root, opts.force, validated_user_type);
|
|
@@ -6032,7 +6300,7 @@ function main2(argv) {
|
|
|
6032
6300
|
return rc2;
|
|
6033
6301
|
}
|
|
6034
6302
|
const project_root = custom_path || resolvePath(opts.project || process2.env["PROJECT_ROOT"] || process2.cwd());
|
|
6035
|
-
const is_first_run = !pathExists(
|
|
6303
|
+
const is_first_run = !pathExists(path6.join(project_root, SETTINGS_FILE));
|
|
6036
6304
|
const rc = _main_project_install(opts, project_root, parsed_tools, is_first_run);
|
|
6037
6305
|
if (rc === 0 && opts.interactive) {
|
|
6038
6306
|
run_interactive_init(project_root, opts.force);
|
|
@@ -6096,16 +6364,16 @@ function _team_setup_hint_line(project_root) {
|
|
|
6096
6364
|
return " \u2022 Claude Code team mode (optional cross-model review via the official codex plugin): run `agent-config doctor --check team` for setup status.";
|
|
6097
6365
|
}
|
|
6098
6366
|
function finalize_claude_model_tiers(project_root) {
|
|
6099
|
-
const claude_skills =
|
|
6100
|
-
const augment_skills =
|
|
6367
|
+
const claude_skills = path6.join(project_root, ".claude", "skills");
|
|
6368
|
+
const augment_skills = path6.join(project_root, ".augment", "skills");
|
|
6101
6369
|
if (!isDir(claude_skills) || !isDir(augment_skills)) return 0;
|
|
6102
6370
|
if (_read_consumer_auto_switch(project_root) !== "auto") return 0;
|
|
6103
6371
|
let rendered = 0;
|
|
6104
|
-
const entries =
|
|
6372
|
+
const entries = fs7.readdirSync(claude_skills).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
|
|
6105
6373
|
for (const name of entries) {
|
|
6106
|
-
const entry =
|
|
6107
|
-
const src_dir =
|
|
6108
|
-
const src_md =
|
|
6374
|
+
const entry = path6.join(claude_skills, name);
|
|
6375
|
+
const src_dir = path6.join(augment_skills, name);
|
|
6376
|
+
const src_md = path6.join(src_dir, "SKILL.md");
|
|
6109
6377
|
let tier;
|
|
6110
6378
|
try {
|
|
6111
6379
|
tier = read_model_tier(src_md);
|
|
@@ -6114,22 +6382,22 @@ function finalize_claude_model_tiers(project_root) {
|
|
|
6114
6382
|
}
|
|
6115
6383
|
if (tier === null || !(tier in TIER_TO_CLAUDE_MODEL) || !isDir(src_dir)) continue;
|
|
6116
6384
|
if (isSymlink(entry) || isFile(entry)) {
|
|
6117
|
-
|
|
6385
|
+
fs7.unlinkSync(entry);
|
|
6118
6386
|
} else if (isDir(entry)) {
|
|
6119
|
-
|
|
6387
|
+
fs7.rmSync(entry, { recursive: true, force: true });
|
|
6120
6388
|
}
|
|
6121
6389
|
mkdirp(entry);
|
|
6122
|
-
const srcFiles =
|
|
6390
|
+
const srcFiles = fs7.readdirSync(src_dir).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
|
|
6123
6391
|
for (const fname of srcFiles) {
|
|
6124
6392
|
if (fname === "SKILL.md") {
|
|
6125
6393
|
writeText(
|
|
6126
|
-
|
|
6394
|
+
path6.join(entry, "SKILL.md"),
|
|
6127
6395
|
render_native_model_md(readText(src_md), tier)
|
|
6128
6396
|
);
|
|
6129
6397
|
} else {
|
|
6130
|
-
|
|
6131
|
-
|
|
6132
|
-
|
|
6398
|
+
fs7.symlinkSync(
|
|
6399
|
+
path6.join("../../../.augment/skills", name, fname),
|
|
6400
|
+
path6.join(entry, fname)
|
|
6133
6401
|
);
|
|
6134
6402
|
}
|
|
6135
6403
|
}
|
|
@@ -6147,7 +6415,7 @@ function _main_project_install(opts, project_root, parsed_tools, is_first_run) {
|
|
|
6147
6415
|
let package_type;
|
|
6148
6416
|
if (opts.package) {
|
|
6149
6417
|
package_root = resolvePath(opts.package);
|
|
6150
|
-
if (!pathExists(
|
|
6418
|
+
if (!pathExists(path6.join(package_root, "src", "config", "profiles", "minimal.ini"))) {
|
|
6151
6419
|
fail(`Invalid --package path (missing src/config/profiles/minimal.ini): ${package_root}`);
|
|
6152
6420
|
}
|
|
6153
6421
|
package_type = detect_package_type_for_project(project_root, package_root);
|
|
@@ -6284,9 +6552,9 @@ function _main_project_install(opts, project_root, parsed_tools, is_first_run) {
|
|
|
6284
6552
|
function _resolvedArgv1() {
|
|
6285
6553
|
if (process2.argv[1] === void 0) return void 0;
|
|
6286
6554
|
try {
|
|
6287
|
-
return
|
|
6555
|
+
return fs7.realpathSync(path6.resolve(process2.argv[1]));
|
|
6288
6556
|
} catch {
|
|
6289
|
-
return
|
|
6557
|
+
return path6.resolve(process2.argv[1]);
|
|
6290
6558
|
}
|
|
6291
6559
|
}
|
|
6292
6560
|
var _argv1 = _resolvedArgv1();
|