@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
package/dist/mcp/server.mjs
CHANGED
|
@@ -1841,17 +1841,17 @@ var require_visit = __commonJS({
|
|
|
1841
1841
|
visit.BREAK = BREAK;
|
|
1842
1842
|
visit.SKIP = SKIP;
|
|
1843
1843
|
visit.REMOVE = REMOVE;
|
|
1844
|
-
function visit_(key, node, visitor,
|
|
1845
|
-
const ctrl = callVisitor(key, node, visitor,
|
|
1844
|
+
function visit_(key, node, visitor, path77) {
|
|
1845
|
+
const ctrl = callVisitor(key, node, visitor, path77);
|
|
1846
1846
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
1847
|
-
replaceNode(key,
|
|
1848
|
-
return visit_(key, ctrl, visitor,
|
|
1847
|
+
replaceNode(key, path77, ctrl);
|
|
1848
|
+
return visit_(key, ctrl, visitor, path77);
|
|
1849
1849
|
}
|
|
1850
1850
|
if (typeof ctrl !== "symbol") {
|
|
1851
1851
|
if (identity.isCollection(node)) {
|
|
1852
|
-
|
|
1852
|
+
path77 = Object.freeze(path77.concat(node));
|
|
1853
1853
|
for (let i = 0; i < node.items.length; ++i) {
|
|
1854
|
-
const ci = visit_(i, node.items[i], visitor,
|
|
1854
|
+
const ci = visit_(i, node.items[i], visitor, path77);
|
|
1855
1855
|
if (typeof ci === "number")
|
|
1856
1856
|
i = ci - 1;
|
|
1857
1857
|
else if (ci === BREAK)
|
|
@@ -1862,13 +1862,13 @@ var require_visit = __commonJS({
|
|
|
1862
1862
|
}
|
|
1863
1863
|
}
|
|
1864
1864
|
} else if (identity.isPair(node)) {
|
|
1865
|
-
|
|
1866
|
-
const ck = visit_("key", node.key, visitor,
|
|
1865
|
+
path77 = Object.freeze(path77.concat(node));
|
|
1866
|
+
const ck = visit_("key", node.key, visitor, path77);
|
|
1867
1867
|
if (ck === BREAK)
|
|
1868
1868
|
return BREAK;
|
|
1869
1869
|
else if (ck === REMOVE)
|
|
1870
1870
|
node.key = null;
|
|
1871
|
-
const cv = visit_("value", node.value, visitor,
|
|
1871
|
+
const cv = visit_("value", node.value, visitor, path77);
|
|
1872
1872
|
if (cv === BREAK)
|
|
1873
1873
|
return BREAK;
|
|
1874
1874
|
else if (cv === REMOVE)
|
|
@@ -1889,17 +1889,17 @@ var require_visit = __commonJS({
|
|
|
1889
1889
|
visitAsync.BREAK = BREAK;
|
|
1890
1890
|
visitAsync.SKIP = SKIP;
|
|
1891
1891
|
visitAsync.REMOVE = REMOVE;
|
|
1892
|
-
async function visitAsync_(key, node, visitor,
|
|
1893
|
-
const ctrl = await callVisitor(key, node, visitor,
|
|
1892
|
+
async function visitAsync_(key, node, visitor, path77) {
|
|
1893
|
+
const ctrl = await callVisitor(key, node, visitor, path77);
|
|
1894
1894
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
1895
|
-
replaceNode(key,
|
|
1896
|
-
return visitAsync_(key, ctrl, visitor,
|
|
1895
|
+
replaceNode(key, path77, ctrl);
|
|
1896
|
+
return visitAsync_(key, ctrl, visitor, path77);
|
|
1897
1897
|
}
|
|
1898
1898
|
if (typeof ctrl !== "symbol") {
|
|
1899
1899
|
if (identity.isCollection(node)) {
|
|
1900
|
-
|
|
1900
|
+
path77 = Object.freeze(path77.concat(node));
|
|
1901
1901
|
for (let i = 0; i < node.items.length; ++i) {
|
|
1902
|
-
const ci = await visitAsync_(i, node.items[i], visitor,
|
|
1902
|
+
const ci = await visitAsync_(i, node.items[i], visitor, path77);
|
|
1903
1903
|
if (typeof ci === "number")
|
|
1904
1904
|
i = ci - 1;
|
|
1905
1905
|
else if (ci === BREAK)
|
|
@@ -1910,13 +1910,13 @@ var require_visit = __commonJS({
|
|
|
1910
1910
|
}
|
|
1911
1911
|
}
|
|
1912
1912
|
} else if (identity.isPair(node)) {
|
|
1913
|
-
|
|
1914
|
-
const ck = await visitAsync_("key", node.key, visitor,
|
|
1913
|
+
path77 = Object.freeze(path77.concat(node));
|
|
1914
|
+
const ck = await visitAsync_("key", node.key, visitor, path77);
|
|
1915
1915
|
if (ck === BREAK)
|
|
1916
1916
|
return BREAK;
|
|
1917
1917
|
else if (ck === REMOVE)
|
|
1918
1918
|
node.key = null;
|
|
1919
|
-
const cv = await visitAsync_("value", node.value, visitor,
|
|
1919
|
+
const cv = await visitAsync_("value", node.value, visitor, path77);
|
|
1920
1920
|
if (cv === BREAK)
|
|
1921
1921
|
return BREAK;
|
|
1922
1922
|
else if (cv === REMOVE)
|
|
@@ -1943,23 +1943,23 @@ var require_visit = __commonJS({
|
|
|
1943
1943
|
}
|
|
1944
1944
|
return visitor;
|
|
1945
1945
|
}
|
|
1946
|
-
function callVisitor(key, node, visitor,
|
|
1946
|
+
function callVisitor(key, node, visitor, path77) {
|
|
1947
1947
|
if (typeof visitor === "function")
|
|
1948
|
-
return visitor(key, node,
|
|
1948
|
+
return visitor(key, node, path77);
|
|
1949
1949
|
if (identity.isMap(node))
|
|
1950
|
-
return visitor.Map?.(key, node,
|
|
1950
|
+
return visitor.Map?.(key, node, path77);
|
|
1951
1951
|
if (identity.isSeq(node))
|
|
1952
|
-
return visitor.Seq?.(key, node,
|
|
1952
|
+
return visitor.Seq?.(key, node, path77);
|
|
1953
1953
|
if (identity.isPair(node))
|
|
1954
|
-
return visitor.Pair?.(key, node,
|
|
1954
|
+
return visitor.Pair?.(key, node, path77);
|
|
1955
1955
|
if (identity.isScalar(node))
|
|
1956
|
-
return visitor.Scalar?.(key, node,
|
|
1956
|
+
return visitor.Scalar?.(key, node, path77);
|
|
1957
1957
|
if (identity.isAlias(node))
|
|
1958
|
-
return visitor.Alias?.(key, node,
|
|
1958
|
+
return visitor.Alias?.(key, node, path77);
|
|
1959
1959
|
return void 0;
|
|
1960
1960
|
}
|
|
1961
|
-
function replaceNode(key,
|
|
1962
|
-
const parent =
|
|
1961
|
+
function replaceNode(key, path77, node) {
|
|
1962
|
+
const parent = path77[path77.length - 1];
|
|
1963
1963
|
if (identity.isCollection(parent)) {
|
|
1964
1964
|
parent.items[key] = node;
|
|
1965
1965
|
} else if (identity.isPair(parent)) {
|
|
@@ -2569,10 +2569,10 @@ var require_Collection = __commonJS({
|
|
|
2569
2569
|
var createNode = require_createNode();
|
|
2570
2570
|
var identity = require_identity();
|
|
2571
2571
|
var Node = require_Node();
|
|
2572
|
-
function collectionFromPath(schema,
|
|
2572
|
+
function collectionFromPath(schema, path77, value) {
|
|
2573
2573
|
let v = value;
|
|
2574
|
-
for (let i =
|
|
2575
|
-
const k =
|
|
2574
|
+
for (let i = path77.length - 1; i >= 0; --i) {
|
|
2575
|
+
const k = path77[i];
|
|
2576
2576
|
if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
|
|
2577
2577
|
const a = [];
|
|
2578
2578
|
a[k] = v;
|
|
@@ -2591,7 +2591,7 @@ var require_Collection = __commonJS({
|
|
|
2591
2591
|
sourceObjects: /* @__PURE__ */ new Map()
|
|
2592
2592
|
});
|
|
2593
2593
|
}
|
|
2594
|
-
var isEmptyPath = (
|
|
2594
|
+
var isEmptyPath = (path77) => path77 == null || typeof path77 === "object" && !!path77[Symbol.iterator]().next().done;
|
|
2595
2595
|
var Collection = class extends Node.NodeBase {
|
|
2596
2596
|
constructor(type, schema) {
|
|
2597
2597
|
super(type);
|
|
@@ -2621,11 +2621,11 @@ var require_Collection = __commonJS({
|
|
|
2621
2621
|
* be a Pair instance or a `{ key, value }` object, which may not have a key
|
|
2622
2622
|
* that already exists in the map.
|
|
2623
2623
|
*/
|
|
2624
|
-
addIn(
|
|
2625
|
-
if (isEmptyPath(
|
|
2624
|
+
addIn(path77, value) {
|
|
2625
|
+
if (isEmptyPath(path77))
|
|
2626
2626
|
this.add(value);
|
|
2627
2627
|
else {
|
|
2628
|
-
const [key, ...rest] =
|
|
2628
|
+
const [key, ...rest] = path77;
|
|
2629
2629
|
const node = this.get(key, true);
|
|
2630
2630
|
if (identity.isCollection(node))
|
|
2631
2631
|
node.addIn(rest, value);
|
|
@@ -2639,8 +2639,8 @@ var require_Collection = __commonJS({
|
|
|
2639
2639
|
* Removes a value from the collection.
|
|
2640
2640
|
* @returns `true` if the item was found and removed.
|
|
2641
2641
|
*/
|
|
2642
|
-
deleteIn(
|
|
2643
|
-
const [key, ...rest] =
|
|
2642
|
+
deleteIn(path77) {
|
|
2643
|
+
const [key, ...rest] = path77;
|
|
2644
2644
|
if (rest.length === 0)
|
|
2645
2645
|
return this.delete(key);
|
|
2646
2646
|
const node = this.get(key, true);
|
|
@@ -2654,8 +2654,8 @@ var require_Collection = __commonJS({
|
|
|
2654
2654
|
* scalar values from their surrounding node; to disable set `keepScalar` to
|
|
2655
2655
|
* `true` (collections are always returned intact).
|
|
2656
2656
|
*/
|
|
2657
|
-
getIn(
|
|
2658
|
-
const [key, ...rest] =
|
|
2657
|
+
getIn(path77, keepScalar) {
|
|
2658
|
+
const [key, ...rest] = path77;
|
|
2659
2659
|
const node = this.get(key, true);
|
|
2660
2660
|
if (rest.length === 0)
|
|
2661
2661
|
return !keepScalar && identity.isScalar(node) ? node.value : node;
|
|
@@ -2673,8 +2673,8 @@ var require_Collection = __commonJS({
|
|
|
2673
2673
|
/**
|
|
2674
2674
|
* Checks if the collection includes a value with the key `key`.
|
|
2675
2675
|
*/
|
|
2676
|
-
hasIn(
|
|
2677
|
-
const [key, ...rest] =
|
|
2676
|
+
hasIn(path77) {
|
|
2677
|
+
const [key, ...rest] = path77;
|
|
2678
2678
|
if (rest.length === 0)
|
|
2679
2679
|
return this.has(key);
|
|
2680
2680
|
const node = this.get(key, true);
|
|
@@ -2684,8 +2684,8 @@ var require_Collection = __commonJS({
|
|
|
2684
2684
|
* Sets a value in this collection. For `!!set`, `value` needs to be a
|
|
2685
2685
|
* boolean to add/remove the item from the set.
|
|
2686
2686
|
*/
|
|
2687
|
-
setIn(
|
|
2688
|
-
const [key, ...rest] =
|
|
2687
|
+
setIn(path77, value) {
|
|
2688
|
+
const [key, ...rest] = path77;
|
|
2689
2689
|
if (rest.length === 0) {
|
|
2690
2690
|
this.set(key, value);
|
|
2691
2691
|
} else {
|
|
@@ -5200,9 +5200,9 @@ var require_Document = __commonJS({
|
|
|
5200
5200
|
this.contents.add(value);
|
|
5201
5201
|
}
|
|
5202
5202
|
/** Adds a value to the document. */
|
|
5203
|
-
addIn(
|
|
5203
|
+
addIn(path77, value) {
|
|
5204
5204
|
if (assertCollection(this.contents))
|
|
5205
|
-
this.contents.addIn(
|
|
5205
|
+
this.contents.addIn(path77, value);
|
|
5206
5206
|
}
|
|
5207
5207
|
/**
|
|
5208
5208
|
* Create a new `Alias` node, ensuring that the target `node` has the required anchor.
|
|
@@ -5277,14 +5277,14 @@ var require_Document = __commonJS({
|
|
|
5277
5277
|
* Removes a value from the document.
|
|
5278
5278
|
* @returns `true` if the item was found and removed.
|
|
5279
5279
|
*/
|
|
5280
|
-
deleteIn(
|
|
5281
|
-
if (Collection.isEmptyPath(
|
|
5280
|
+
deleteIn(path77) {
|
|
5281
|
+
if (Collection.isEmptyPath(path77)) {
|
|
5282
5282
|
if (this.contents == null)
|
|
5283
5283
|
return false;
|
|
5284
5284
|
this.contents = null;
|
|
5285
5285
|
return true;
|
|
5286
5286
|
}
|
|
5287
|
-
return assertCollection(this.contents) ? this.contents.deleteIn(
|
|
5287
|
+
return assertCollection(this.contents) ? this.contents.deleteIn(path77) : false;
|
|
5288
5288
|
}
|
|
5289
5289
|
/**
|
|
5290
5290
|
* Returns item at `key`, or `undefined` if not found. By default unwraps
|
|
@@ -5299,10 +5299,10 @@ var require_Document = __commonJS({
|
|
|
5299
5299
|
* scalar values from their surrounding node; to disable set `keepScalar` to
|
|
5300
5300
|
* `true` (collections are always returned intact).
|
|
5301
5301
|
*/
|
|
5302
|
-
getIn(
|
|
5303
|
-
if (Collection.isEmptyPath(
|
|
5302
|
+
getIn(path77, keepScalar) {
|
|
5303
|
+
if (Collection.isEmptyPath(path77))
|
|
5304
5304
|
return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
|
|
5305
|
-
return identity.isCollection(this.contents) ? this.contents.getIn(
|
|
5305
|
+
return identity.isCollection(this.contents) ? this.contents.getIn(path77, keepScalar) : void 0;
|
|
5306
5306
|
}
|
|
5307
5307
|
/**
|
|
5308
5308
|
* Checks if the document includes a value with the key `key`.
|
|
@@ -5313,10 +5313,10 @@ var require_Document = __commonJS({
|
|
|
5313
5313
|
/**
|
|
5314
5314
|
* Checks if the document includes a value at `path`.
|
|
5315
5315
|
*/
|
|
5316
|
-
hasIn(
|
|
5317
|
-
if (Collection.isEmptyPath(
|
|
5316
|
+
hasIn(path77) {
|
|
5317
|
+
if (Collection.isEmptyPath(path77))
|
|
5318
5318
|
return this.contents !== void 0;
|
|
5319
|
-
return identity.isCollection(this.contents) ? this.contents.hasIn(
|
|
5319
|
+
return identity.isCollection(this.contents) ? this.contents.hasIn(path77) : false;
|
|
5320
5320
|
}
|
|
5321
5321
|
/**
|
|
5322
5322
|
* Sets a value in this document. For `!!set`, `value` needs to be a
|
|
@@ -5333,13 +5333,13 @@ var require_Document = __commonJS({
|
|
|
5333
5333
|
* Sets a value in this document. For `!!set`, `value` needs to be a
|
|
5334
5334
|
* boolean to add/remove the item from the set.
|
|
5335
5335
|
*/
|
|
5336
|
-
setIn(
|
|
5337
|
-
if (Collection.isEmptyPath(
|
|
5336
|
+
setIn(path77, value) {
|
|
5337
|
+
if (Collection.isEmptyPath(path77)) {
|
|
5338
5338
|
this.contents = value;
|
|
5339
5339
|
} else if (this.contents == null) {
|
|
5340
|
-
this.contents = Collection.collectionFromPath(this.schema, Array.from(
|
|
5340
|
+
this.contents = Collection.collectionFromPath(this.schema, Array.from(path77), value);
|
|
5341
5341
|
} else if (assertCollection(this.contents)) {
|
|
5342
|
-
this.contents.setIn(
|
|
5342
|
+
this.contents.setIn(path77, value);
|
|
5343
5343
|
}
|
|
5344
5344
|
}
|
|
5345
5345
|
/**
|
|
@@ -7299,9 +7299,9 @@ var require_cst_visit = __commonJS({
|
|
|
7299
7299
|
visit.BREAK = BREAK;
|
|
7300
7300
|
visit.SKIP = SKIP;
|
|
7301
7301
|
visit.REMOVE = REMOVE;
|
|
7302
|
-
visit.itemAtPath = (cst,
|
|
7302
|
+
visit.itemAtPath = (cst, path77) => {
|
|
7303
7303
|
let item = cst;
|
|
7304
|
-
for (const [field, index] of
|
|
7304
|
+
for (const [field, index] of path77) {
|
|
7305
7305
|
const tok = item?.[field];
|
|
7306
7306
|
if (tok && "items" in tok) {
|
|
7307
7307
|
item = tok.items[index];
|
|
@@ -7310,23 +7310,23 @@ var require_cst_visit = __commonJS({
|
|
|
7310
7310
|
}
|
|
7311
7311
|
return item;
|
|
7312
7312
|
};
|
|
7313
|
-
visit.parentCollection = (cst,
|
|
7314
|
-
const parent = visit.itemAtPath(cst,
|
|
7315
|
-
const field =
|
|
7313
|
+
visit.parentCollection = (cst, path77) => {
|
|
7314
|
+
const parent = visit.itemAtPath(cst, path77.slice(0, -1));
|
|
7315
|
+
const field = path77[path77.length - 1][0];
|
|
7316
7316
|
const coll = parent?.[field];
|
|
7317
7317
|
if (coll && "items" in coll)
|
|
7318
7318
|
return coll;
|
|
7319
7319
|
throw new Error("Parent collection not found");
|
|
7320
7320
|
};
|
|
7321
|
-
function _visit(
|
|
7322
|
-
let ctrl = visitor(item,
|
|
7321
|
+
function _visit(path77, item, visitor) {
|
|
7322
|
+
let ctrl = visitor(item, path77);
|
|
7323
7323
|
if (typeof ctrl === "symbol")
|
|
7324
7324
|
return ctrl;
|
|
7325
7325
|
for (const field of ["key", "value"]) {
|
|
7326
7326
|
const token = item[field];
|
|
7327
7327
|
if (token && "items" in token) {
|
|
7328
7328
|
for (let i = 0; i < token.items.length; ++i) {
|
|
7329
|
-
const ci = _visit(Object.freeze(
|
|
7329
|
+
const ci = _visit(Object.freeze(path77.concat([[field, i]])), token.items[i], visitor);
|
|
7330
7330
|
if (typeof ci === "number")
|
|
7331
7331
|
i = ci - 1;
|
|
7332
7332
|
else if (ci === BREAK)
|
|
@@ -7337,10 +7337,10 @@ var require_cst_visit = __commonJS({
|
|
|
7337
7337
|
}
|
|
7338
7338
|
}
|
|
7339
7339
|
if (typeof ctrl === "function" && field === "key")
|
|
7340
|
-
ctrl = ctrl(item,
|
|
7340
|
+
ctrl = ctrl(item, path77);
|
|
7341
7341
|
}
|
|
7342
7342
|
}
|
|
7343
|
-
return typeof ctrl === "function" ? ctrl(item,
|
|
7343
|
+
return typeof ctrl === "function" ? ctrl(item, path77) : ctrl;
|
|
7344
7344
|
}
|
|
7345
7345
|
exports.visit = visit;
|
|
7346
7346
|
}
|
|
@@ -8642,14 +8642,14 @@ var require_parser = __commonJS({
|
|
|
8642
8642
|
case "scalar":
|
|
8643
8643
|
case "single-quoted-scalar":
|
|
8644
8644
|
case "double-quoted-scalar": {
|
|
8645
|
-
const
|
|
8645
|
+
const fs80 = this.flowScalar(this.type);
|
|
8646
8646
|
if (atNextItem || it.value) {
|
|
8647
|
-
map.items.push({ start, key:
|
|
8647
|
+
map.items.push({ start, key: fs80, sep: [] });
|
|
8648
8648
|
this.onKeyLine = true;
|
|
8649
8649
|
} else if (it.sep) {
|
|
8650
|
-
this.stack.push(
|
|
8650
|
+
this.stack.push(fs80);
|
|
8651
8651
|
} else {
|
|
8652
|
-
Object.assign(it, { key:
|
|
8652
|
+
Object.assign(it, { key: fs80, sep: [] });
|
|
8653
8653
|
this.onKeyLine = true;
|
|
8654
8654
|
}
|
|
8655
8655
|
return;
|
|
@@ -8777,13 +8777,13 @@ var require_parser = __commonJS({
|
|
|
8777
8777
|
case "scalar":
|
|
8778
8778
|
case "single-quoted-scalar":
|
|
8779
8779
|
case "double-quoted-scalar": {
|
|
8780
|
-
const
|
|
8780
|
+
const fs80 = this.flowScalar(this.type);
|
|
8781
8781
|
if (!it || it.value)
|
|
8782
|
-
fc.items.push({ start: [], key:
|
|
8782
|
+
fc.items.push({ start: [], key: fs80, sep: [] });
|
|
8783
8783
|
else if (it.sep)
|
|
8784
|
-
this.stack.push(
|
|
8784
|
+
this.stack.push(fs80);
|
|
8785
8785
|
else
|
|
8786
|
-
Object.assign(it, { key:
|
|
8786
|
+
Object.assign(it, { key: fs80, sep: [] });
|
|
8787
8787
|
return;
|
|
8788
8788
|
}
|
|
8789
8789
|
case "flow-map-end":
|
|
@@ -18909,7 +18909,10 @@ function parse_blockers(raw_text) {
|
|
|
18909
18909
|
owner: _blockerField(body, "Owner") ?? "user",
|
|
18910
18910
|
blocks: _blockerField(body, "Blocks") ?? "(unspecified)",
|
|
18911
18911
|
todo: _blockerTodo(body),
|
|
18912
|
-
resolvedWhen: _blockerField(body, "Resolved when") ?? "(unspecified)"
|
|
18912
|
+
resolvedWhen: _blockerField(body, "Resolved when") ?? "(unspecified)",
|
|
18913
|
+
recommendation: _blockerField(body, "Recommendation") ?? "",
|
|
18914
|
+
ifNothing: _blockerField(body, "If you do nothing") ?? "",
|
|
18915
|
+
question: _blockerField(body, "Question") ?? ""
|
|
18913
18916
|
});
|
|
18914
18917
|
}
|
|
18915
18918
|
}
|
|
@@ -18935,7 +18938,10 @@ function parse_blockers(raw_text) {
|
|
|
18935
18938
|
owner: "user",
|
|
18936
18939
|
blocks: "entire roadmap",
|
|
18937
18940
|
todo: [parts.join(" ")],
|
|
18938
|
-
resolvedWhen: "condition described above clears"
|
|
18941
|
+
resolvedWhen: "condition described above clears",
|
|
18942
|
+
recommendation: "",
|
|
18943
|
+
ifNothing: "",
|
|
18944
|
+
question: ""
|
|
18939
18945
|
});
|
|
18940
18946
|
}
|
|
18941
18947
|
return blockers;
|
|
@@ -19207,6 +19213,12 @@ function render(roadmaps, bundles = null) {
|
|
|
19207
19213
|
lines.push("**Blockers**\n");
|
|
19208
19214
|
for (const b of openBlockers) {
|
|
19209
19215
|
lines.push(`- **${b.id}** (owner: ${b.owner}) \u2014 blocks ${b.blocks}`);
|
|
19216
|
+
if (b.recommendation) {
|
|
19217
|
+
lines.push(` - **Recommendation:** ${b.recommendation}`);
|
|
19218
|
+
}
|
|
19219
|
+
if (b.ifNothing) {
|
|
19220
|
+
lines.push(` - **If you do nothing:** ${b.ifNothing}`);
|
|
19221
|
+
}
|
|
19210
19222
|
lines.push(" - **What to do:**");
|
|
19211
19223
|
for (const step of b.todo) {
|
|
19212
19224
|
lines.push(` ${step}`);
|
|
@@ -19535,7 +19547,7 @@ var init_update_roadmap_progress = __esm({
|
|
|
19535
19547
|
BLOCKER_HEADING_RE = /^###[ \t]+blocker:[ \t]*(.+?)[ \t]*$/gim;
|
|
19536
19548
|
NEXT_H2_RE = /^##[ \t]+\S/m;
|
|
19537
19549
|
LEGACY_BLOCKED_UNTIL_RE = /^>[ \t]*Blocked until:?[ \t]*(.+)$/im;
|
|
19538
|
-
BLOCKER_FIELD_RE = /^-[ \t]*\*\*
|
|
19550
|
+
BLOCKER_FIELD_RE = /^-[ \t]*\*\*[^*]+:\*\*/;
|
|
19539
19551
|
ArgparseExit = class extends Error {
|
|
19540
19552
|
code;
|
|
19541
19553
|
constructor(code) {
|
|
@@ -19781,6 +19793,21 @@ function _regen_dashboard(root, dry_run) {
|
|
|
19781
19793
|
_run(["git", "add", "--", "agents/roadmaps-progress.md"], root);
|
|
19782
19794
|
}
|
|
19783
19795
|
}
|
|
19796
|
+
function _regen_archive_index(root, dry_run) {
|
|
19797
|
+
if (dry_run) {
|
|
19798
|
+
return;
|
|
19799
|
+
}
|
|
19800
|
+
const script = path22.join(root, "src", "scripts", "build_archive_index.ts");
|
|
19801
|
+
if (!_isFile8(script)) {
|
|
19802
|
+
return;
|
|
19803
|
+
}
|
|
19804
|
+
_runTwin(root, script);
|
|
19805
|
+
for (const rel of ["agents/roadmaps/archive/INDEX.md", "agents/roadmaps/archive/index.json"]) {
|
|
19806
|
+
if (_isFile8(path22.join(root, rel))) {
|
|
19807
|
+
_run(["git", "add", "--", rel], root);
|
|
19808
|
+
}
|
|
19809
|
+
}
|
|
19810
|
+
}
|
|
19784
19811
|
function _runTwin(root, script) {
|
|
19785
19812
|
const binName = process9.platform === "win32" ? "tsx.cmd" : "tsx";
|
|
19786
19813
|
let dir = path22.dirname(_HERE6);
|
|
@@ -19853,6 +19880,7 @@ function main10(argv) {
|
|
|
19853
19880
|
return 0;
|
|
19854
19881
|
}
|
|
19855
19882
|
_regen_dashboard(root, ns.dry_run);
|
|
19883
|
+
_regen_archive_index(root, ns.dry_run);
|
|
19856
19884
|
const verb = ns.dry_run ? "Would archive" : "Archived";
|
|
19857
19885
|
for (const rec of archived) {
|
|
19858
19886
|
process9.stdout.write(
|
|
@@ -21700,8 +21728,8 @@ function lockfile_path(env) {
|
|
|
21700
21728
|
}
|
|
21701
21729
|
return write_target("installed.lock", { env: env ?? null });
|
|
21702
21730
|
}
|
|
21703
|
-
function read_lockfile(
|
|
21704
|
-
const target =
|
|
21731
|
+
function read_lockfile(path77) {
|
|
21732
|
+
const target = path77 ?? lockfile_path();
|
|
21705
21733
|
let text;
|
|
21706
21734
|
try {
|
|
21707
21735
|
text = fs31.readFileSync(target, { encoding: "utf-8" });
|
|
@@ -21911,18 +21939,18 @@ function manifest_path(project_root, env) {
|
|
|
21911
21939
|
}
|
|
21912
21940
|
return fsPath.join(project_root, DEFAULT_MANIFEST_RELATIVE);
|
|
21913
21941
|
}
|
|
21914
|
-
function read_manifest(
|
|
21942
|
+
function read_manifest(path77) {
|
|
21915
21943
|
let text;
|
|
21916
21944
|
try {
|
|
21917
|
-
text = require_read_text(
|
|
21945
|
+
text = require_read_text(path77);
|
|
21918
21946
|
} catch {
|
|
21919
21947
|
return null;
|
|
21920
21948
|
}
|
|
21921
21949
|
const data = _parse_manual(text);
|
|
21922
21950
|
return _normalise_v2_shape(data);
|
|
21923
21951
|
}
|
|
21924
|
-
function require_read_text(
|
|
21925
|
-
return fs33.readFileSync(
|
|
21952
|
+
function require_read_text(path77) {
|
|
21953
|
+
return fs33.readFileSync(path77, { encoding: "utf-8" });
|
|
21926
21954
|
}
|
|
21927
21955
|
function _normalise_v2_shape(data) {
|
|
21928
21956
|
if (data["tools"] === void 0 || data["tools"] === null) {
|
|
@@ -22103,9 +22131,9 @@ function stable_sort(items, key) {
|
|
|
22103
22131
|
return a.index - b.index;
|
|
22104
22132
|
}).map((entry) => entry.item);
|
|
22105
22133
|
}
|
|
22106
|
-
function write_manifest(
|
|
22134
|
+
function write_manifest(path77, version, tools, options = {}) {
|
|
22107
22135
|
const rendered = _render(version, tools, { deploy_roots: options.deploy_roots ?? null });
|
|
22108
|
-
return write_atomic(
|
|
22136
|
+
return write_atomic(path77, rendered);
|
|
22109
22137
|
}
|
|
22110
22138
|
function upsert_tool(existing, options) {
|
|
22111
22139
|
const {
|
|
@@ -25792,6 +25820,7 @@ __export(clients_exports, {
|
|
|
25792
25820
|
AnthropicCliClient: () => AnthropicCliClient,
|
|
25793
25821
|
AnthropicClient: () => AnthropicClient,
|
|
25794
25822
|
CLI_CALLS_FILENAME: () => CLI_CALLS_FILENAME,
|
|
25823
|
+
CODEX_MEASURED_UNSERVABLE: () => CODEX_MEASURED_UNSERVABLE,
|
|
25795
25824
|
CliClient: () => CliClient,
|
|
25796
25825
|
CliClientError: () => CliClientError,
|
|
25797
25826
|
CouncilResponse: () => CouncilResponse,
|
|
@@ -25813,6 +25842,7 @@ __export(clients_exports, {
|
|
|
25813
25842
|
KeyGateError: () => KeyGateError,
|
|
25814
25843
|
MANUAL_END_MARKER: () => MANUAL_END_MARKER,
|
|
25815
25844
|
ManualClient: () => ManualClient,
|
|
25845
|
+
OPENAI_CLI_VENDOR_DEFAULT: () => OPENAI_CLI_VENDOR_DEFAULT,
|
|
25816
25846
|
OPENAI_KEY_FILENAME: () => OPENAI_KEY_FILENAME,
|
|
25817
25847
|
OPENAI_KEY_PATH: () => OPENAI_KEY_PATH,
|
|
25818
25848
|
OpenAICliClient: () => OpenAICliClient,
|
|
@@ -26435,7 +26465,7 @@ function _defaultStdin() {
|
|
|
26435
26465
|
}
|
|
26436
26466
|
};
|
|
26437
26467
|
}
|
|
26438
|
-
var _modelCeilingMemo, ANTHROPIC_KEY_FILENAME, OPENAI_KEY_FILENAME, ANTHROPIC_KEY_PATH, OPENAI_KEY_PATH, DEFAULT_ANTHROPIC_MODEL, DEFAULT_OPENAI_MODEL, DEFAULT_GEMINI_MODEL, DEFAULT_XAI_MODEL, DEFAULT_PERPLEXITY_MODEL, DEFAULT_OPENAI_CLI_MODEL, DEFAULT_ANTHROPIC_CLI_MODEL, DEFAULT_GEMINI_CLI_MODEL, XAI_BASE_URL, PERPLEXITY_BASE_URL, DEFAULT_MAX_TOKENS, UNLIMITED_TOKENS_FALLBACK, _REASONING_PREFIXES, KeyGateError, CliClientError, DEFAULT_PROMPT_CACHE_TTL, CouncilResponse, _monotonicSource, ExternalAIClient, AnthropicClient, OpenAIClient, GeminiClient, _OpenAICompatibleClient, XAIClient, PerplexityClient, CLI_CALLS_FILENAME, DEFAULT_CLI_TIMEOUT_SECONDS, SubprocessError, CliClient, AnthropicCliClient, OpenAICliClient, GeminiCliClient, XAICliClient, PerplexityCliClient, MANUAL_END_MARKER, ManualClient, ValueError3, JSONDecodeError;
|
|
26468
|
+
var _modelCeilingMemo, ANTHROPIC_KEY_FILENAME, OPENAI_KEY_FILENAME, ANTHROPIC_KEY_PATH, OPENAI_KEY_PATH, DEFAULT_ANTHROPIC_MODEL, DEFAULT_OPENAI_MODEL, DEFAULT_GEMINI_MODEL, DEFAULT_XAI_MODEL, DEFAULT_PERPLEXITY_MODEL, OPENAI_CLI_VENDOR_DEFAULT, CODEX_MEASURED_UNSERVABLE, DEFAULT_OPENAI_CLI_MODEL, DEFAULT_ANTHROPIC_CLI_MODEL, DEFAULT_GEMINI_CLI_MODEL, XAI_BASE_URL, PERPLEXITY_BASE_URL, DEFAULT_MAX_TOKENS, UNLIMITED_TOKENS_FALLBACK, _REASONING_PREFIXES, KeyGateError, CliClientError, DEFAULT_PROMPT_CACHE_TTL, CouncilResponse, _monotonicSource, ExternalAIClient, AnthropicClient, OpenAIClient, GeminiClient, _OpenAICompatibleClient, XAIClient, PerplexityClient, CLI_CALLS_FILENAME, DEFAULT_CLI_TIMEOUT_SECONDS, SubprocessError, CliClient, AnthropicCliClient, OpenAICliClient, GeminiCliClient, XAICliClient, PerplexityCliClient, MANUAL_END_MARKER, ManualClient, ValueError3, JSONDecodeError;
|
|
26439
26469
|
var init_clients = __esm({
|
|
26440
26470
|
"src/scripts/ai_council/clients.ts"() {
|
|
26441
26471
|
"use strict";
|
|
@@ -26454,7 +26484,13 @@ var init_clients = __esm({
|
|
|
26454
26484
|
DEFAULT_GEMINI_MODEL = "gemini-2.5-pro";
|
|
26455
26485
|
DEFAULT_XAI_MODEL = "grok-4";
|
|
26456
26486
|
DEFAULT_PERPLEXITY_MODEL = "sonar-pro";
|
|
26457
|
-
|
|
26487
|
+
OPENAI_CLI_VENDOR_DEFAULT = "codex-default";
|
|
26488
|
+
CODEX_MEASURED_UNSERVABLE = /* @__PURE__ */ new Map([
|
|
26489
|
+
["gpt-4o", "2026-08-15"],
|
|
26490
|
+
["gpt-5", "2026-08-15"],
|
|
26491
|
+
["gpt-5.1-codex", "2026-08-15"]
|
|
26492
|
+
]);
|
|
26493
|
+
DEFAULT_OPENAI_CLI_MODEL = OPENAI_CLI_VENDOR_DEFAULT;
|
|
26458
26494
|
DEFAULT_ANTHROPIC_CLI_MODEL = "claude-sonnet-4-5";
|
|
26459
26495
|
DEFAULT_GEMINI_CLI_MODEL = "gemini-2.5-pro";
|
|
26460
26496
|
XAI_BASE_URL = "https://api.x.ai/v1";
|
|
@@ -26677,7 +26713,7 @@ var init_clients = __esm({
|
|
|
26677
26713
|
_client;
|
|
26678
26714
|
constructor(opts = {}) {
|
|
26679
26715
|
super();
|
|
26680
|
-
this.model = opts.model
|
|
26716
|
+
this.model = opts.model === void 0 || opts.model === OPENAI_CLI_VENDOR_DEFAULT ? DEFAULT_OPENAI_MODEL : opts.model;
|
|
26681
26717
|
if (opts.client !== void 0 && opts.client !== null) {
|
|
26682
26718
|
this._client = opts.client;
|
|
26683
26719
|
return;
|
|
@@ -26997,6 +27033,19 @@ ${user_prompt}`;
|
|
|
26997
27033
|
} catch {
|
|
26998
27034
|
}
|
|
26999
27035
|
}
|
|
27036
|
+
/**
|
|
27037
|
+
* Refuse a call this transport cannot serve, BEFORE spawning.
|
|
27038
|
+
*
|
|
27039
|
+
* `null` means "nothing known to be wrong" — deliberately not "verified
|
|
27040
|
+
* servable". No vendor CLI here publishes the set of models its
|
|
27041
|
+
* subscription tier accepts, so an allow-list would be invented and would
|
|
27042
|
+
* reject valid pins the day the vendor adds one. What CAN be stated is the
|
|
27043
|
+
* complement: models this estate has MEASURED being rejected. Subclasses
|
|
27044
|
+
* override; the base transport knows of none.
|
|
27045
|
+
*/
|
|
27046
|
+
_preflight_transport() {
|
|
27047
|
+
return null;
|
|
27048
|
+
}
|
|
27000
27049
|
/** Return text to send on stdin, or `null` to inherit caller's stdin. */
|
|
27001
27050
|
_stdin_payload(system_prompt, user_prompt) {
|
|
27002
27051
|
void system_prompt;
|
|
@@ -27123,6 +27172,17 @@ ${user_prompt}`;
|
|
|
27123
27172
|
});
|
|
27124
27173
|
}
|
|
27125
27174
|
}
|
|
27175
|
+
const preflight = this._preflight_transport();
|
|
27176
|
+
if (preflight !== null) {
|
|
27177
|
+
return new CouncilResponse({
|
|
27178
|
+
provider: this.name,
|
|
27179
|
+
model: this.model,
|
|
27180
|
+
text: "",
|
|
27181
|
+
latency_ms: _elapsedMs(t0),
|
|
27182
|
+
error: preflight.code,
|
|
27183
|
+
metadata: { cli: true, transport: this.transport, detail: preflight.detail }
|
|
27184
|
+
});
|
|
27185
|
+
}
|
|
27126
27186
|
const cmd = this._build_command(system_prompt, user_prompt, max_tokens);
|
|
27127
27187
|
const stdinPayload = this._stdin_payload(system_prompt, user_prompt);
|
|
27128
27188
|
let proc;
|
|
@@ -27263,23 +27323,23 @@ ${user_prompt}`;
|
|
|
27263
27323
|
// documented "disable all tools" value.
|
|
27264
27324
|
//
|
|
27265
27325
|
// It also repairs a live failure, which is how the grant was found
|
|
27266
|
-
// rather than reasoned about.
|
|
27267
|
-
//
|
|
27268
|
-
//
|
|
27269
|
-
//
|
|
27270
|
-
//
|
|
27271
|
-
// In this package that overflowed the model's context window
|
|
27272
|
-
// outright: `is_error: true`, `"the request is ~214331 tokens
|
|
27326
|
+
// rather than reasoned about. AT THE TIME (2026-08-12) the spawn
|
|
27327
|
+
// inherited the caller's cwd, so invoking the council from inside a
|
|
27328
|
+
// repository made the child load that project's own instructions AND
|
|
27329
|
+
// every tool definition. In this package that overflowed the context
|
|
27330
|
+
// window outright: `is_error: true`, `"the request is ~214331 tokens
|
|
27273
27331
|
// (limit 200000) … the rest is system prompt, tool definitions"`,
|
|
27274
|
-
// exit 1, empty stderr —
|
|
27275
|
-
//
|
|
27276
|
-
//
|
|
27277
|
-
// returns the worktree call to exit 0.
|
|
27332
|
+
// exit 1, empty stderr — the member reported unavailable with no
|
|
27333
|
+
// diagnosable cause. Identical call from `/tmp` exit 0, from the
|
|
27334
|
+
// worktree exit 1, and this one flag returns the worktree to exit 0.
|
|
27278
27335
|
//
|
|
27279
|
-
//
|
|
27280
|
-
//
|
|
27281
|
-
//
|
|
27282
|
-
//
|
|
27336
|
+
// TENSE CORRECTED 2026-08-16. This block read "`_runSubprocess` sets
|
|
27337
|
+
// none, deliberately" and "dropping the tools RATHER THAN
|
|
27338
|
+
// neutralising the cwd" — both false since `_runSubprocess` set
|
|
27339
|
+
// `cwd: os.tmpdir()` for a DIFFERENT contamination (a member
|
|
27340
|
+
// answering this repo's `end-review-nudge`). Two repairs, one
|
|
27341
|
+
// cause, neither aware of the other, so a reader here concluded
|
|
27342
|
+
// the cwd is inherited. Both are live; this flag bounds what a member may DO.
|
|
27283
27343
|
"--tools",
|
|
27284
27344
|
"",
|
|
27285
27345
|
"--append-system-prompt",
|
|
@@ -27354,7 +27414,23 @@ ${user_prompt}`;
|
|
|
27354
27414
|
void system_prompt;
|
|
27355
27415
|
void user_prompt;
|
|
27356
27416
|
void max_tokens;
|
|
27357
|
-
|
|
27417
|
+
const modelArgs = this.model === OPENAI_CLI_VENDOR_DEFAULT ? [] : ["--model", this.model];
|
|
27418
|
+
return [this.binary, "exec", "--json", "--skip-git-repo-check", ...modelArgs, "-"];
|
|
27419
|
+
}
|
|
27420
|
+
/**
|
|
27421
|
+
* Refuse a pin this estate has measured the transport rejecting.
|
|
27422
|
+
*
|
|
27423
|
+
* The remedy is named because it is not guessable: removing the `model:`
|
|
27424
|
+
* line is the fix, and "remove a setting" is the last thing an operator
|
|
27425
|
+
* tries when a member is silent.
|
|
27426
|
+
*/
|
|
27427
|
+
_preflight_transport() {
|
|
27428
|
+
const measuredOn = CODEX_MEASURED_UNSERVABLE.get(this.model);
|
|
27429
|
+
if (measuredOn === void 0) return null;
|
|
27430
|
+
return {
|
|
27431
|
+
code: "model_unsupported_on_transport",
|
|
27432
|
+
detail: `openai member pins model \`${this.model}\`, which the codex CLI (subscription transport) refused when measured on ${measuredOn}: "The '${this.model}' model is not supported when using Codex with a ChatGPT account." The CLI publishes no list of models it DOES accept, so there is no supported set to offer here \u2014 the one configuration measured to work is no pin at all. Fix: set \`model: codex-default\` on the openai member. Do NOT delete the \`model:\` line \u2014 an enabled member with no model fails config load, so that takes EVERY provider to NOT CONFIGURED. A pin is reachable only on the API transport.`
|
|
27433
|
+
};
|
|
27358
27434
|
}
|
|
27359
27435
|
/**
|
|
27360
27436
|
* System and user prompt travel as ONE stdin payload, because `codex exec`
|
|
@@ -27376,6 +27452,7 @@ ${user_prompt}`;
|
|
|
27376
27452
|
let text = "";
|
|
27377
27453
|
let input_tokens = 0;
|
|
27378
27454
|
let output_tokens = 0;
|
|
27455
|
+
let failure = null;
|
|
27379
27456
|
const meta = {};
|
|
27380
27457
|
for (let line of _splitlines6(stdout)) {
|
|
27381
27458
|
line = line.trim();
|
|
@@ -27418,6 +27495,12 @@ ${user_prompt}`;
|
|
|
27418
27495
|
text = chunks.join("\n").trim();
|
|
27419
27496
|
}
|
|
27420
27497
|
}
|
|
27498
|
+
if (_dictGet(itemObj, "type", void 0) === "agent_message") {
|
|
27499
|
+
const flat = _pyStr3(_dictGet(itemObj, "text", "")).trim();
|
|
27500
|
+
if (flat) {
|
|
27501
|
+
text = flat;
|
|
27502
|
+
}
|
|
27503
|
+
}
|
|
27421
27504
|
if (_pyTruthy2(_dictGet(itemObj, "id", void 0))) {
|
|
27422
27505
|
meta["item_id"] = _pyStr3(itemObj["id"]);
|
|
27423
27506
|
}
|
|
@@ -27436,8 +27519,36 @@ ${user_prompt}`;
|
|
|
27436
27519
|
if (_pyTruthy2(_dictGet(ev, "session_id", void 0))) {
|
|
27437
27520
|
meta["session_id"] = _pyStr3(ev["session_id"]);
|
|
27438
27521
|
}
|
|
27522
|
+
} else if (event_type === "turn.failed") {
|
|
27523
|
+
let err = _dictGet(ev, "error", null);
|
|
27524
|
+
if (!_pyTruthy2(err)) err = {};
|
|
27525
|
+
if (_isPlainObject7(err)) {
|
|
27526
|
+
const raw = _pyStr3(_dictGet(err, "message", ""));
|
|
27527
|
+
if (raw) failure = raw;
|
|
27528
|
+
}
|
|
27439
27529
|
}
|
|
27440
27530
|
}
|
|
27531
|
+
if (failure !== null && !text) {
|
|
27532
|
+
const unsupported = /not supported when using Codex/i.test(failure);
|
|
27533
|
+
return new CouncilResponse({
|
|
27534
|
+
provider: this.name,
|
|
27535
|
+
model: this.model,
|
|
27536
|
+
text: "",
|
|
27537
|
+
input_tokens,
|
|
27538
|
+
output_tokens,
|
|
27539
|
+
error: unsupported ? "model_unsupported_on_transport" : "turn_failed",
|
|
27540
|
+
metadata: {
|
|
27541
|
+
...meta,
|
|
27542
|
+
// The vendor's own sentence, kept because it names the
|
|
27543
|
+
// model and the account type — the two facts an operator
|
|
27544
|
+
// needs and neither of which the error code carries.
|
|
27545
|
+
detail: failure.slice(0, 400),
|
|
27546
|
+
...unsupported ? {
|
|
27547
|
+
hint: "the codex subscription transport serves no explicitly pinned model measured so far \u2014 set `model: codex-default` on the openai member; deleting the line fails config load"
|
|
27548
|
+
} : {}
|
|
27549
|
+
}
|
|
27550
|
+
});
|
|
27551
|
+
}
|
|
27441
27552
|
return new CouncilResponse({
|
|
27442
27553
|
provider: this.name,
|
|
27443
27554
|
model: this.model,
|
|
@@ -28828,7 +28939,7 @@ function _build_member(name, cfg, default_mode = "auto", ignored = []) {
|
|
|
28828
28939
|
}
|
|
28829
28940
|
entries.push(entry);
|
|
28830
28941
|
}
|
|
28831
|
-
if (member_enabled && model && !entries.includes(model)) {
|
|
28942
|
+
if (member_enabled && model && model !== OPENAI_CLI_VENDOR_DEFAULT && !entries.includes(model)) {
|
|
28832
28943
|
throw new CouncilConfigError(
|
|
28833
28944
|
`members.${name}.model_ladder must include the active \`model\` (${_pyReprStr(model)}); got ${_pyRepr6(entries)}.`
|
|
28834
28945
|
);
|
|
@@ -29066,6 +29177,7 @@ var init_config = __esm({
|
|
|
29066
29177
|
"use strict";
|
|
29067
29178
|
import_yaml5 = __toESM(require_dist(), 1);
|
|
29068
29179
|
init_user_global_paths();
|
|
29180
|
+
init_clients();
|
|
29069
29181
|
init_quorum();
|
|
29070
29182
|
_VALID_PROVIDERS = /* @__PURE__ */ new Set([
|
|
29071
29183
|
"anthropic",
|
|
@@ -29716,6 +29828,9 @@ function classifyCliFailure(raw) {
|
|
|
29716
29828
|
if (s === "cli_unsupported" || s === "unsupported" || s === "parse_failed") {
|
|
29717
29829
|
return "cli_unsupported";
|
|
29718
29830
|
}
|
|
29831
|
+
if (s.startsWith("model_unservable") || s.includes("is not supported when using codex")) {
|
|
29832
|
+
return "model_unservable";
|
|
29833
|
+
}
|
|
29719
29834
|
if (s === "timeout") return "timeout";
|
|
29720
29835
|
if (s === "cli_quota_exhausted" || s === "quota_exhausted") return "quota_exhausted";
|
|
29721
29836
|
if (/^exit_5\d\d$/.test(s) || s === "server_error" || s === "os") return "server_error";
|
|
@@ -30484,8 +30599,8 @@ function ruleFileArrives(sourcePath, scope) {
|
|
|
30484
30599
|
if (!sourcePath.endsWith(".md")) {
|
|
30485
30600
|
return true;
|
|
30486
30601
|
}
|
|
30487
|
-
const
|
|
30488
|
-
if (COMPAT_ALWAYS_EXCLUDED.includes(
|
|
30602
|
+
const basename22 = path52.basename(sourcePath);
|
|
30603
|
+
if (COMPAT_ALWAYS_EXCLUDED.includes(basename22)) {
|
|
30489
30604
|
return false;
|
|
30490
30605
|
}
|
|
30491
30606
|
return rule_in_scope(sourcePath, scope.workspaces, scope.packs, scope.roles ?? null);
|
|
@@ -33345,9 +33460,9 @@ function detectToolPresence(root) {
|
|
|
33345
33460
|
agentsMd: existsSync25(join49(root, "AGENTS.md"))
|
|
33346
33461
|
};
|
|
33347
33462
|
}
|
|
33348
|
-
function isDir3(
|
|
33463
|
+
function isDir3(path77) {
|
|
33349
33464
|
try {
|
|
33350
|
-
return statSync32(
|
|
33465
|
+
return statSync32(path77).isDirectory();
|
|
33351
33466
|
} catch {
|
|
33352
33467
|
return false;
|
|
33353
33468
|
}
|
|
@@ -42706,8 +42821,8 @@ function aggregate_scores(findings, scores) {
|
|
|
42706
42821
|
by_id.get(s.finding_id).push(s);
|
|
42707
42822
|
}
|
|
42708
42823
|
const out = /* @__PURE__ */ new Map();
|
|
42709
|
-
for (const [fid,
|
|
42710
|
-
if (
|
|
42824
|
+
for (const [fid, fs80] of by_id) {
|
|
42825
|
+
if (fs80.length === 0) {
|
|
42711
42826
|
out.set(
|
|
42712
42827
|
fid,
|
|
42713
42828
|
new ConsensusMetadata({
|
|
@@ -42723,13 +42838,13 @@ function aggregate_scores(findings, scores) {
|
|
|
42723
42838
|
);
|
|
42724
42839
|
continue;
|
|
42725
42840
|
}
|
|
42726
|
-
const mean2 =
|
|
42727
|
-
const agree_rate =
|
|
42841
|
+
const mean2 = fs80.reduce((acc, s) => acc + s.score, 0) / fs80.length;
|
|
42842
|
+
const agree_rate = fs80.filter((s) => s.agree).length / fs80.length;
|
|
42728
42843
|
const strength = mean2 / 10 * agree_rate;
|
|
42729
|
-
const dissent =
|
|
42730
|
-
const concur =
|
|
42731
|
-
const scorers =
|
|
42732
|
-
const dissent_reasons =
|
|
42844
|
+
const dissent = fs80.filter((s) => !s.agree).length;
|
|
42845
|
+
const concur = fs80.filter((s) => s.agree).length;
|
|
42846
|
+
const scorers = fs80.map((s) => s.scorer);
|
|
42847
|
+
const dissent_reasons = fs80.filter((s) => !s.agree).map((s) => [s.scorer, s.reason]);
|
|
42733
42848
|
const mean_rounded = pyRound(mean2, 2);
|
|
42734
42849
|
out.set(
|
|
42735
42850
|
fid,
|
|
@@ -44353,7 +44468,8 @@ ${body}`);
|
|
|
44353
44468
|
function _render_quorum_line(q) {
|
|
44354
44469
|
const verdict = q.status === "concluded" ? "concluded" : "INCONCLUSIVE \u2014 release gate holds";
|
|
44355
44470
|
const solo = isSoloConcluded(q) ? " \xB7 **solo** \u2014 one voice concluded this pass" : "";
|
|
44356
|
-
|
|
44471
|
+
const degraded = q.present < q.total ? ` \u26A0\uFE0F DEGRADED \u2014 ${String(q.total - q.present)} member(s) did not answer; this is not convergence.` : "";
|
|
44472
|
+
return `**Quorum:** ${q.present}/${q.total} present, needed ${q.threshold} \u2014 ${verdict}.${solo}${degraded}`;
|
|
44357
44473
|
}
|
|
44358
44474
|
function _render_absent_members(absent) {
|
|
44359
44475
|
const lines = ["### Absent Members", ""];
|
|
@@ -45714,7 +45830,9 @@ function resolve_low_impact(question_text, plan, clients, price_table = null, no
|
|
|
45714
45830
|
const pinned = model_downgrade.model_tier_override?.[member.name];
|
|
45715
45831
|
const cheapest = member.model_ladder.length > 0 ? member.model_ladder[0] : null;
|
|
45716
45832
|
const target = pinned && pinned.length > 0 ? pinned : cheapest;
|
|
45717
|
-
|
|
45833
|
+
const unpinned = client.model === OPENAI_CLI_VENDOR_DEFAULT;
|
|
45834
|
+
const overrideWins = pinned !== void 0 && pinned.length > 0;
|
|
45835
|
+
if (target && target !== client.model && (!unpinned || overrideWins)) {
|
|
45718
45836
|
client.model = target;
|
|
45719
45837
|
}
|
|
45720
45838
|
}
|
|
@@ -46020,6 +46138,7 @@ var init_low_impact = __esm({
|
|
|
46020
46138
|
"src/scripts/ai_council/low_impact.ts"() {
|
|
46021
46139
|
"use strict";
|
|
46022
46140
|
init_value_ladder();
|
|
46141
|
+
init_clients();
|
|
46023
46142
|
init_orchestrator();
|
|
46024
46143
|
_INPUT_RATIO = 0.6;
|
|
46025
46144
|
FastPathPlan = class {
|
|
@@ -49089,7 +49208,7 @@ function run_enveloped(spec) {
|
|
|
49089
49208
|
if (cmd === void 0) {
|
|
49090
49209
|
throw new Error("envelope argv must not be empty");
|
|
49091
49210
|
}
|
|
49092
|
-
return new Promise((
|
|
49211
|
+
return new Promise((resolve44) => {
|
|
49093
49212
|
execFile(
|
|
49094
49213
|
cmd,
|
|
49095
49214
|
args,
|
|
@@ -49112,7 +49231,7 @@ function run_enveloped(spec) {
|
|
|
49112
49231
|
}
|
|
49113
49232
|
const [out, outTrunc] = _truncate(String(stdout ?? ""), spec.max_output_bytes);
|
|
49114
49233
|
const [err, errTrunc] = _truncate(String(stderr ?? ""), spec.max_output_bytes);
|
|
49115
|
-
|
|
49234
|
+
resolve44({
|
|
49116
49235
|
exit_code: timedOut ? null : exitCode,
|
|
49117
49236
|
timed_out: timedOut,
|
|
49118
49237
|
stdout: out,
|
|
@@ -49132,9 +49251,977 @@ var init_safety_envelope = __esm({
|
|
|
49132
49251
|
}
|
|
49133
49252
|
});
|
|
49134
49253
|
|
|
49135
|
-
// src/scripts/
|
|
49254
|
+
// src/scripts/_lib/skill_catalogue.ts
|
|
49255
|
+
var skill_catalogue_exports = {};
|
|
49256
|
+
__export(skill_catalogue_exports, {
|
|
49257
|
+
DEFAULT_CATALOGUE_ROOTS: () => DEFAULT_CATALOGUE_ROOTS,
|
|
49258
|
+
OBSERVATION_LOG: () => OBSERVATION_LOG,
|
|
49259
|
+
analyzeSelector: () => analyzeSelector,
|
|
49260
|
+
buildHostEventRecord: () => buildHostEventRecord,
|
|
49261
|
+
buildNoTruncationRecord: () => buildNoTruncationRecord,
|
|
49262
|
+
buildObservationRecord: () => buildObservationRecord,
|
|
49263
|
+
catalogueLimitWarning: () => catalogueLimitWarning,
|
|
49264
|
+
classifyHostProjection: () => classifyHostProjection,
|
|
49265
|
+
formatPerHostVerdicts: () => formatPerHostVerdicts,
|
|
49266
|
+
formatProjectionModes: () => formatProjectionModes,
|
|
49267
|
+
formatReport: () => formatReport,
|
|
49268
|
+
headlineRecordPerHost: () => headlineRecordPerHost,
|
|
49269
|
+
knownHostLimits: () => knownHostLimits,
|
|
49270
|
+
measureCatalogueVolume: () => measureCatalogueVolume,
|
|
49271
|
+
migrationEligibility: () => migrationEligibility,
|
|
49272
|
+
migrationPromptLines: () => migrationPromptLines,
|
|
49273
|
+
observationSourceOf: () => observationSourceOf,
|
|
49274
|
+
parseHostBudgetEvent: () => parseHostBudgetEvent,
|
|
49275
|
+
readObservationLog: () => readObservationLog,
|
|
49276
|
+
readProjectedCatalogue: () => readProjectedCatalogue,
|
|
49277
|
+
resolveSkillsRoot: () => resolveSkillsRoot,
|
|
49278
|
+
truncationModeOf: () => truncationModeOf
|
|
49279
|
+
});
|
|
49280
|
+
import * as fs77 from "node:fs";
|
|
49281
|
+
import * as path73 from "node:path";
|
|
49282
|
+
function resolveSkillsRoot(workspaceRoot) {
|
|
49283
|
+
for (const candidate of DEFAULT_CATALOGUE_ROOTS) {
|
|
49284
|
+
const abs = path73.join(workspaceRoot, candidate);
|
|
49285
|
+
try {
|
|
49286
|
+
if (fs77.existsSync(abs) && fs77.statSync(abs).isDirectory()) return abs;
|
|
49287
|
+
} catch {
|
|
49288
|
+
}
|
|
49289
|
+
}
|
|
49290
|
+
return null;
|
|
49291
|
+
}
|
|
49292
|
+
function frontmatterOf(content) {
|
|
49293
|
+
if (!content.startsWith("---")) return "";
|
|
49294
|
+
const end = content.indexOf("\n---", 3);
|
|
49295
|
+
if (end === -1) return "";
|
|
49296
|
+
return content.slice(3, end);
|
|
49297
|
+
}
|
|
49298
|
+
function topLevelKeys(frontmatter) {
|
|
49299
|
+
const keys = [];
|
|
49300
|
+
for (const line of frontmatter.split("\n")) {
|
|
49301
|
+
const match = /^([A-Za-z_][A-Za-z0-9_-]*):/.exec(line);
|
|
49302
|
+
if (match) keys.push(match[1]);
|
|
49303
|
+
}
|
|
49304
|
+
return keys;
|
|
49305
|
+
}
|
|
49306
|
+
function descriptionOf(frontmatter) {
|
|
49307
|
+
const lines = frontmatter.split("\n");
|
|
49308
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
49309
|
+
const match = /^description:\s*(.*)$/.exec(lines[i]);
|
|
49310
|
+
if (!match) continue;
|
|
49311
|
+
const rest = match[1].trim();
|
|
49312
|
+
if (/^[|>][-+]?\d*$/.test(rest)) {
|
|
49313
|
+
const body = [];
|
|
49314
|
+
for (let j = i + 1; j < lines.length; j += 1) {
|
|
49315
|
+
const line = lines[j];
|
|
49316
|
+
if (line.trim() === "") {
|
|
49317
|
+
body.push("");
|
|
49318
|
+
continue;
|
|
49319
|
+
}
|
|
49320
|
+
if (!/^\s/.test(line)) break;
|
|
49321
|
+
body.push(line.trim());
|
|
49322
|
+
}
|
|
49323
|
+
return body.join(" ").trim();
|
|
49324
|
+
}
|
|
49325
|
+
return rest.replace(/^["']|["']$/g, "");
|
|
49326
|
+
}
|
|
49327
|
+
return "";
|
|
49328
|
+
}
|
|
49329
|
+
function readProjectedCatalogue(root) {
|
|
49330
|
+
const names = fs77.readdirSync(root).filter((n) => fs77.existsSync(path73.join(root, n, "SKILL.md"))).sort();
|
|
49331
|
+
return names.map((name, index) => {
|
|
49332
|
+
const content = fs77.readFileSync(path73.join(root, name, "SKILL.md"), "utf-8");
|
|
49333
|
+
const frontmatter = frontmatterOf(content);
|
|
49334
|
+
const description = descriptionOf(frontmatter);
|
|
49335
|
+
return {
|
|
49336
|
+
name,
|
|
49337
|
+
position: index + 1,
|
|
49338
|
+
hasDescription: description.length > 0,
|
|
49339
|
+
descriptionLength: description.length,
|
|
49340
|
+
description,
|
|
49341
|
+
frontmatterKeys: topLevelKeys(frontmatter)
|
|
49342
|
+
};
|
|
49343
|
+
});
|
|
49344
|
+
}
|
|
49345
|
+
function rangesAreDisjoint(a, b) {
|
|
49346
|
+
if (a.length === 0 || b.length === 0) return false;
|
|
49347
|
+
const maxA = Math.max(...a);
|
|
49348
|
+
const minA = Math.min(...a);
|
|
49349
|
+
const maxB = Math.max(...b);
|
|
49350
|
+
const minB = Math.min(...b);
|
|
49351
|
+
return maxA < minB || maxB < minA;
|
|
49352
|
+
}
|
|
49353
|
+
function analyzeSelector(projected, observedBare, observedDescribed) {
|
|
49354
|
+
const known = new Map(projected.map((e) => [e.name, e]));
|
|
49355
|
+
const bare = observedBare.filter((n) => known.has(n));
|
|
49356
|
+
const describedInput = observedDescribed ?? projected.map((e) => e.name).filter((n) => !bare.includes(n));
|
|
49357
|
+
const described = describedInput.filter((n) => known.has(n));
|
|
49358
|
+
const unknownObserved = [
|
|
49359
|
+
.../* @__PURE__ */ new Set([
|
|
49360
|
+
...observedBare.filter((n) => !known.has(n)),
|
|
49361
|
+
...(observedDescribed ?? []).filter((n) => !known.has(n))
|
|
49362
|
+
])
|
|
49363
|
+
].sort();
|
|
49364
|
+
const base = {
|
|
49365
|
+
entriesTotal: projected.length,
|
|
49366
|
+
observedBare: [...bare].sort(),
|
|
49367
|
+
observedDescribed: [...described].sort(),
|
|
49368
|
+
unknownObserved
|
|
49369
|
+
};
|
|
49370
|
+
if (bare.length === 0 || described.length === 0) {
|
|
49371
|
+
return {
|
|
49372
|
+
...base,
|
|
49373
|
+
candidates: [],
|
|
49374
|
+
verdict: "insufficient-observation"
|
|
49375
|
+
};
|
|
49376
|
+
}
|
|
49377
|
+
const bareEntries = bare.map((n) => known.get(n));
|
|
49378
|
+
const describedEntries = described.map((n) => known.get(n));
|
|
49379
|
+
const candidates = [];
|
|
49380
|
+
const bareWithDesc = bareEntries.filter((e) => e.hasDescription).length;
|
|
49381
|
+
const describedWithoutDesc = describedEntries.filter((e) => !e.hasDescription).length;
|
|
49382
|
+
candidates.push({
|
|
49383
|
+
id: "declares-description",
|
|
49384
|
+
describes: "the projected SKILL.md declares a `description:`",
|
|
49385
|
+
separates: bareWithDesc === 0 && describedWithoutDesc === 0,
|
|
49386
|
+
detail: `${bareWithDesc}/${bareEntries.length} bare entries declare one; ${describedWithoutDesc}/${describedEntries.length} described entries do not`
|
|
49387
|
+
});
|
|
49388
|
+
const barePositions = bareEntries.map((e) => e.position);
|
|
49389
|
+
const describedPositions = describedEntries.map((e) => e.position);
|
|
49390
|
+
const positional = Math.max(...describedPositions) < Math.min(...barePositions);
|
|
49391
|
+
candidates.push({
|
|
49392
|
+
id: "positional-head",
|
|
49393
|
+
describes: "every described entry sorts before every bare entry (a head-N budget)",
|
|
49394
|
+
separates: positional,
|
|
49395
|
+
detail: positional ? `described top out at #${Math.max(...describedPositions)}, bare start at #${Math.min(...barePositions)}` : `described reach #${Math.max(...describedPositions)} while bare start at #${Math.min(...barePositions)} \u2014 the ranges overlap, so no head-N cut explains this`
|
|
49396
|
+
});
|
|
49397
|
+
const lengthSeparates = rangesAreDisjoint(
|
|
49398
|
+
bareEntries.map((e) => e.descriptionLength),
|
|
49399
|
+
describedEntries.map((e) => e.descriptionLength)
|
|
49400
|
+
);
|
|
49401
|
+
candidates.push({
|
|
49402
|
+
id: "description-length",
|
|
49403
|
+
describes: "description length ranges do not overlap between the groups",
|
|
49404
|
+
separates: lengthSeparates,
|
|
49405
|
+
detail: lengthSeparates ? "a length threshold separates the two groups" : "length ranges overlap"
|
|
49406
|
+
});
|
|
49407
|
+
const allKeys = /* @__PURE__ */ new Set();
|
|
49408
|
+
for (const entry of projected) for (const key of entry.frontmatterKeys) allKeys.add(key);
|
|
49409
|
+
for (const key of [...allKeys].sort()) {
|
|
49410
|
+
const bareHas = bareEntries.filter((e) => e.frontmatterKeys.includes(key)).length;
|
|
49411
|
+
const describedHas = describedEntries.filter(
|
|
49412
|
+
(e) => e.frontmatterKeys.includes(key)
|
|
49413
|
+
).length;
|
|
49414
|
+
const separates = bareHas === 0 && describedHas === describedEntries.length || describedHas === 0 && bareHas === bareEntries.length;
|
|
49415
|
+
if (!separates) continue;
|
|
49416
|
+
candidates.push({
|
|
49417
|
+
id: `frontmatter:${key}`,
|
|
49418
|
+
describes: `presence of the \`${key}:\` frontmatter key`,
|
|
49419
|
+
separates: true,
|
|
49420
|
+
detail: `bare ${bareHas}/${bareEntries.length}, described ${describedHas}/${describedEntries.length}`
|
|
49421
|
+
});
|
|
49422
|
+
}
|
|
49423
|
+
return {
|
|
49424
|
+
...base,
|
|
49425
|
+
candidates,
|
|
49426
|
+
verdict: candidates.some((c) => c.separates) ? "selector-found" : "no-selector"
|
|
49427
|
+
};
|
|
49428
|
+
}
|
|
49429
|
+
function truncationModeOf(record) {
|
|
49430
|
+
return record.truncation_mode ?? "per-entry";
|
|
49431
|
+
}
|
|
49432
|
+
function observationSourceOf(record) {
|
|
49433
|
+
return record.observation_source ?? "self-report";
|
|
49434
|
+
}
|
|
49435
|
+
function buildObservationRecord(report2, host, observedAt) {
|
|
49436
|
+
return {
|
|
49437
|
+
schema: 1,
|
|
49438
|
+
observed_at: observedAt,
|
|
49439
|
+
host,
|
|
49440
|
+
entries_total: report2.entriesTotal,
|
|
49441
|
+
bare_count: report2.observedBare.length,
|
|
49442
|
+
described_count: report2.observedDescribed.length,
|
|
49443
|
+
bare_names: report2.observedBare,
|
|
49444
|
+
verdict: report2.verdict,
|
|
49445
|
+
separating_candidates: report2.candidates.filter((c) => c.separates).map((c) => c.id),
|
|
49446
|
+
truncation_mode: "per-entry",
|
|
49447
|
+
observation_source: "self-report"
|
|
49448
|
+
};
|
|
49449
|
+
}
|
|
49450
|
+
function parseHostBudgetEvent(stream) {
|
|
49451
|
+
for (const line of stream.split("\n")) {
|
|
49452
|
+
const trimmed = line.trim();
|
|
49453
|
+
if (!trimmed.startsWith("{")) continue;
|
|
49454
|
+
let parsed;
|
|
49455
|
+
try {
|
|
49456
|
+
parsed = JSON.parse(trimmed);
|
|
49457
|
+
} catch {
|
|
49458
|
+
continue;
|
|
49459
|
+
}
|
|
49460
|
+
const item = parsed.item;
|
|
49461
|
+
if (item === void 0 || item === null || item.type !== "error") continue;
|
|
49462
|
+
const message = typeof item.message === "string" ? item.message : "";
|
|
49463
|
+
if (!/skills context budget/i.test(message)) continue;
|
|
49464
|
+
const dropped = /(\d+)\s+additional skills were not included/i.exec(message);
|
|
49465
|
+
if (!dropped) {
|
|
49466
|
+
return null;
|
|
49467
|
+
}
|
|
49468
|
+
return {
|
|
49469
|
+
droppedCount: Number.parseInt(dropped[1], 10),
|
|
49470
|
+
descriptionsStripped: /descriptions were removed/i.test(message)
|
|
49471
|
+
};
|
|
49472
|
+
}
|
|
49473
|
+
return null;
|
|
49474
|
+
}
|
|
49475
|
+
function buildHostEventRecord(host, observedAt, entriesOffered, event, projectedSkillCount, projectionMode) {
|
|
49476
|
+
return {
|
|
49477
|
+
schema: 1,
|
|
49478
|
+
observed_at: observedAt,
|
|
49479
|
+
host,
|
|
49480
|
+
// OUR projection, not the host's denominator. Measured 2026-08-15 they
|
|
49481
|
+
// are not the same number and there is no way to read the host's:
|
|
49482
|
+
// `~/.codex` projects 297 skills + 200 commands = 497 by this tool's
|
|
49483
|
+
// count, while the host reported dropping 393 — and a controlled +60
|
|
49484
|
+
// commands moved that by ZERO. Whatever codex counts, it is not this.
|
|
49485
|
+
// So `entries_total - dropped_count` is NOT a delivered count, and
|
|
49486
|
+
// nothing here computes one: a subtraction across two different
|
|
49487
|
+
// denominators produces a confident number describing neither.
|
|
49488
|
+
entries_total: entriesOffered,
|
|
49489
|
+
bare_count: 0,
|
|
49490
|
+
described_count: 0,
|
|
49491
|
+
bare_names: [],
|
|
49492
|
+
// There is nothing to separate: the host did not choose per entry, it
|
|
49493
|
+
// stripped all of them. `no-selector` would read as "we looked and
|
|
49494
|
+
// found none", which is not what happened.
|
|
49495
|
+
verdict: "insufficient-observation",
|
|
49496
|
+
separating_candidates: [],
|
|
49497
|
+
truncation_mode: "budget-strip-and-drop",
|
|
49498
|
+
observation_source: "host-event",
|
|
49499
|
+
dropped_count: event.droppedCount,
|
|
49500
|
+
...projectedSkillCount === void 0 ? {} : { projected_skill_count: projectedSkillCount },
|
|
49501
|
+
...projectionMode === void 0 ? {} : { projection_mode: projectionMode }
|
|
49502
|
+
};
|
|
49503
|
+
}
|
|
49504
|
+
function buildNoTruncationRecord(host, observedAt, entriesOffered, projectedSkillCount, projectionMode) {
|
|
49505
|
+
return {
|
|
49506
|
+
schema: 1,
|
|
49507
|
+
observed_at: observedAt,
|
|
49508
|
+
host,
|
|
49509
|
+
entries_total: entriesOffered,
|
|
49510
|
+
// BOTH counts stay 0, and neither is a claim that nothing arrived
|
|
49511
|
+
// described. The host published no per-entry breakdown at all — it
|
|
49512
|
+
// published nothing, which is what `truncation_mode: 'none'` records.
|
|
49513
|
+
// Writing `described_count: entriesOffered` would look like a
|
|
49514
|
+
// measurement and be an inference; 0 here means "not counted", exactly
|
|
49515
|
+
// as it does on the strip-and-drop record beside it.
|
|
49516
|
+
bare_count: 0,
|
|
49517
|
+
described_count: 0,
|
|
49518
|
+
bare_names: [],
|
|
49519
|
+
// Nothing arrived bare, so no property separated bare from described —
|
|
49520
|
+
// which is what `no-selector` states. Unlike the strip-and-drop case,
|
|
49521
|
+
// here the label is literally true rather than merely available.
|
|
49522
|
+
verdict: "no-selector",
|
|
49523
|
+
separating_candidates: [],
|
|
49524
|
+
truncation_mode: "none",
|
|
49525
|
+
observation_source: "host-event",
|
|
49526
|
+
dropped_count: 0,
|
|
49527
|
+
...projectedSkillCount === void 0 ? {} : { projected_skill_count: projectedSkillCount },
|
|
49528
|
+
...projectionMode === void 0 ? {} : { projection_mode: projectionMode }
|
|
49529
|
+
};
|
|
49530
|
+
}
|
|
49531
|
+
function markdownFilesUnder(root) {
|
|
49532
|
+
if (!fs77.existsSync(root)) return [];
|
|
49533
|
+
const out = [];
|
|
49534
|
+
const walk = (dir) => {
|
|
49535
|
+
for (const entry of fs77.readdirSync(dir, { withFileTypes: true })) {
|
|
49536
|
+
const full = path73.join(dir, entry.name);
|
|
49537
|
+
if (fs77.statSync(full).isDirectory()) walk(full);
|
|
49538
|
+
else if (entry.name.endsWith(".md")) out.push(full);
|
|
49539
|
+
}
|
|
49540
|
+
};
|
|
49541
|
+
walk(root);
|
|
49542
|
+
return out;
|
|
49543
|
+
}
|
|
49544
|
+
function measureCatalogueVolume(host, root) {
|
|
49545
|
+
const skillsRoot = path73.join(root, "skills");
|
|
49546
|
+
const skills = fs77.existsSync(skillsRoot) ? readProjectedCatalogue(skillsRoot) : [];
|
|
49547
|
+
const commandEntries = markdownFilesUnder(path73.join(root, "commands")).length;
|
|
49548
|
+
return {
|
|
49549
|
+
host,
|
|
49550
|
+
root,
|
|
49551
|
+
skillEntries: skills.length,
|
|
49552
|
+
commandEntries,
|
|
49553
|
+
artefacts: skills.length + commandEntries,
|
|
49554
|
+
descriptionBytes: skills.reduce((sum, e) => sum + Buffer.byteLength(e.description), 0)
|
|
49555
|
+
};
|
|
49556
|
+
}
|
|
49557
|
+
function classifyHostProjection(volume, counts) {
|
|
49558
|
+
const ambiguous = counts.scoped === counts.legacyAll;
|
|
49559
|
+
let matches = "indeterminate";
|
|
49560
|
+
if (!ambiguous) {
|
|
49561
|
+
if (volume.skillEntries === counts.scoped) matches = "scoped";
|
|
49562
|
+
else if (volume.skillEntries === counts.legacyAll) matches = "legacy-all";
|
|
49563
|
+
}
|
|
49564
|
+
return {
|
|
49565
|
+
host: volume.host,
|
|
49566
|
+
root: volume.root,
|
|
49567
|
+
installedSkills: volume.skillEntries,
|
|
49568
|
+
matches
|
|
49569
|
+
};
|
|
49570
|
+
}
|
|
49571
|
+
function formatProjectionModes(counts, rows) {
|
|
49572
|
+
const lines = [
|
|
49573
|
+
"projected SKILL counts by projection mode (package side, one walk):",
|
|
49574
|
+
` scoped: ${counts.scoped}`,
|
|
49575
|
+
` legacy-all: ${counts.legacyAll}`,
|
|
49576
|
+
` pruned under scoped: ${counts.prunedUnderScoped}`,
|
|
49577
|
+
` active packs under scoped: ${counts.activePacks.length}`,
|
|
49578
|
+
""
|
|
49579
|
+
];
|
|
49580
|
+
if (rows.length === 0) {
|
|
49581
|
+
lines.push(
|
|
49582
|
+
"No host root measured. Pass --host-root <dir> (repeatable) to read what",
|
|
49583
|
+
"each host currently holds against the two numbers above."
|
|
49584
|
+
);
|
|
49585
|
+
return lines.join("\n");
|
|
49586
|
+
}
|
|
49587
|
+
lines.push("installed host roots:");
|
|
49588
|
+
for (const row of [...rows].sort((a, b) => a.host.localeCompare(b.host))) {
|
|
49589
|
+
lines.push(` ${row.host}: ${row.installedSkills} skills \u2014 consistent with ${row.matches}`);
|
|
49590
|
+
}
|
|
49591
|
+
lines.push(
|
|
49592
|
+
"",
|
|
49593
|
+
"This is the PROJECTION half only, and it is a measurement: no default was",
|
|
49594
|
+
"read, changed, or recommended here. `indeterminate` means the root carries",
|
|
49595
|
+
"neither count \u2014 another suite, a plugin, or a stale install all produce it.",
|
|
49596
|
+
"No host limit is extrapolated from another host, and no delivered or",
|
|
49597
|
+
"survivor count is computed anywhere."
|
|
49598
|
+
);
|
|
49599
|
+
return lines.join("\n");
|
|
49600
|
+
}
|
|
49601
|
+
function _supersedes(candidate, incumbent) {
|
|
49602
|
+
if (candidate.observed_at !== incumbent.observed_at) {
|
|
49603
|
+
return candidate.observed_at > incumbent.observed_at;
|
|
49604
|
+
}
|
|
49605
|
+
return (candidate.dropped_count ?? 0) > (incumbent.dropped_count ?? 0);
|
|
49606
|
+
}
|
|
49607
|
+
function headlineRecordPerHost(records) {
|
|
49608
|
+
const out = /* @__PURE__ */ new Map();
|
|
49609
|
+
for (const record of records) {
|
|
49610
|
+
const previous = out.get(record.host);
|
|
49611
|
+
if (previous === void 0 || _supersedes(record, previous)) {
|
|
49612
|
+
out.set(record.host, record);
|
|
49613
|
+
}
|
|
49614
|
+
}
|
|
49615
|
+
return out;
|
|
49616
|
+
}
|
|
49617
|
+
function knownHostLimits(records) {
|
|
49618
|
+
const out = /* @__PURE__ */ new Map();
|
|
49619
|
+
const chosen = /* @__PURE__ */ new Map();
|
|
49620
|
+
for (const record of records) {
|
|
49621
|
+
if (truncationModeOf(record) !== "budget-strip-and-drop") continue;
|
|
49622
|
+
if (typeof record.dropped_count !== "number") continue;
|
|
49623
|
+
if (record.dropped_count <= 0) continue;
|
|
49624
|
+
const previous = chosen.get(record.host);
|
|
49625
|
+
if (previous !== void 0 && !_supersedes(record, previous)) continue;
|
|
49626
|
+
chosen.set(record.host, record);
|
|
49627
|
+
out.set(record.host, {
|
|
49628
|
+
host: record.host,
|
|
49629
|
+
droppedEntries: record.dropped_count,
|
|
49630
|
+
projectedVolume: record.entries_total,
|
|
49631
|
+
projectedSkills: record.projected_skill_count ?? null,
|
|
49632
|
+
observedAt: record.observed_at
|
|
49633
|
+
});
|
|
49634
|
+
}
|
|
49635
|
+
return out;
|
|
49636
|
+
}
|
|
49637
|
+
function catalogueLimitWarning(volume, limit) {
|
|
49638
|
+
if (limit === void 0) return null;
|
|
49639
|
+
if (limit.projectedSkills === null) return null;
|
|
49640
|
+
if (volume.skillEntries < limit.projectedSkills) return null;
|
|
49641
|
+
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\``;
|
|
49642
|
+
}
|
|
49643
|
+
function migrationEligibility(host, resolvedMode, currentSkillCount, limits) {
|
|
49644
|
+
if (resolvedMode === "scoped") return { eligible: false, reason: "already-scoped" };
|
|
49645
|
+
const limit = limits.get(host);
|
|
49646
|
+
if (limit === void 0) return { eligible: false, reason: "no-observation-for-host" };
|
|
49647
|
+
if (limit.projectedSkills === null) return { eligible: false, reason: "observation-not-comparable" };
|
|
49648
|
+
if (limit.droppedEntries <= 0) return { eligible: false, reason: "no-truncation-observed" };
|
|
49649
|
+
if (currentSkillCount < limit.projectedSkills) {
|
|
49650
|
+
return { eligible: false, reason: "below-observed-skill-volume" };
|
|
49651
|
+
}
|
|
49652
|
+
return {
|
|
49653
|
+
eligible: true,
|
|
49654
|
+
reason: "eligible",
|
|
49655
|
+
droppedEntries: limit.droppedEntries,
|
|
49656
|
+
observedAt: limit.observedAt
|
|
49657
|
+
};
|
|
49658
|
+
}
|
|
49659
|
+
function migrationPromptLines(host, eligibility, settingsPath) {
|
|
49660
|
+
return [
|
|
49661
|
+
`${host}: ${eligibility.droppedEntries} catalogue entries never reach the model.`,
|
|
49662
|
+
`Measured on this machine (${eligibility.observedAt}). This install is on \`legacy-all\`,`,
|
|
49663
|
+
"which ships everything and lets the host drop what does not fit \u2014 silently.",
|
|
49664
|
+
"",
|
|
49665
|
+
"Scoping the projection to your active packs is the alternative. Nothing here",
|
|
49666
|
+
"changes it for you: `projection.mode` is yours to set, by hand or in the GUI.",
|
|
49667
|
+
"",
|
|
49668
|
+
` edit ${settingsPath}`,
|
|
49669
|
+
" projection:",
|
|
49670
|
+
" mode: scoped",
|
|
49671
|
+
"",
|
|
49672
|
+
" or agent-config config (Settings \u2192 projection)",
|
|
49673
|
+
"",
|
|
49674
|
+
"Keeping `legacy-all` is a legitimate choice \u2014 this is a notification, not a gate."
|
|
49675
|
+
];
|
|
49676
|
+
}
|
|
49677
|
+
function readObservationLog(logPath) {
|
|
49678
|
+
if (!fs77.existsSync(logPath)) return [];
|
|
49679
|
+
const out = [];
|
|
49680
|
+
for (const line of fs77.readFileSync(logPath, "utf-8").split("\n")) {
|
|
49681
|
+
const trimmed = line.trim();
|
|
49682
|
+
if (trimmed.length === 0) continue;
|
|
49683
|
+
try {
|
|
49684
|
+
out.push(JSON.parse(trimmed));
|
|
49685
|
+
} catch {
|
|
49686
|
+
continue;
|
|
49687
|
+
}
|
|
49688
|
+
}
|
|
49689
|
+
return out;
|
|
49690
|
+
}
|
|
49691
|
+
function formatPerHostVerdicts(records) {
|
|
49692
|
+
if (records.length === 0) return "no observations recorded yet.";
|
|
49693
|
+
const byHost = /* @__PURE__ */ new Map();
|
|
49694
|
+
for (const record of records) {
|
|
49695
|
+
const bucket = byHost.get(record.host) ?? [];
|
|
49696
|
+
bucket.push(record);
|
|
49697
|
+
byHost.set(record.host, bucket);
|
|
49698
|
+
}
|
|
49699
|
+
const headline = headlineRecordPerHost(records);
|
|
49700
|
+
const lines = [];
|
|
49701
|
+
for (const host of [...byHost.keys()].sort()) {
|
|
49702
|
+
const bucket = byHost.get(host);
|
|
49703
|
+
const latest = headline.get(host);
|
|
49704
|
+
const mode = truncationModeOf(latest);
|
|
49705
|
+
lines.push(
|
|
49706
|
+
`${host}: ${bucket.length} observation(s) \xB7 mode ${mode} \xB7 source ${observationSourceOf(latest)} \xB7 latest ${latest.observed_at}`
|
|
49707
|
+
);
|
|
49708
|
+
lines.push(
|
|
49709
|
+
mode === "budget-strip-and-drop" ? ` offered ${latest.entries_total}, dropped ${latest.dropped_count ?? "unknown"} \u2014 no per-entry selector exists on this host; the quantity is the budget.` : ` verdict ${latest.verdict} \xB7 ${latest.bare_count} bare of ${latest.entries_total}`
|
|
49710
|
+
);
|
|
49711
|
+
}
|
|
49712
|
+
const modes = new Set([...headline.values()].map((r) => truncationModeOf(r)));
|
|
49713
|
+
lines.push("");
|
|
49714
|
+
lines.push(
|
|
49715
|
+
modes.size > 1 ? `hosts: ${byHost.size} \xB7 truncation modes DIFFER (${[...modes].sort().join(", ")}) \u2014 a pooled verdict across them would describe neither host.` : `hosts: ${byHost.size} \xB7 all observed hosts truncate the same way (${[...modes][0] ?? "none"}).`
|
|
49716
|
+
);
|
|
49717
|
+
return lines.join("\n");
|
|
49718
|
+
}
|
|
49719
|
+
function formatReport(report2) {
|
|
49720
|
+
const lines = [];
|
|
49721
|
+
lines.push(`catalogue root: ${report2.catalogueRoot}`);
|
|
49722
|
+
lines.push(`entries: ${report2.entriesTotal}`);
|
|
49723
|
+
lines.push(
|
|
49724
|
+
`observed: ${report2.observedBare.length} bare \xB7 ${report2.observedDescribed.length} described (self-reported)`
|
|
49725
|
+
);
|
|
49726
|
+
if (report2.unknownObserved.length > 0) {
|
|
49727
|
+
lines.push(
|
|
49728
|
+
`\u26A0\uFE0F ${report2.unknownObserved.length} observed name(s) absent from the projection: ${report2.unknownObserved.join(", ")}`
|
|
49729
|
+
);
|
|
49730
|
+
}
|
|
49731
|
+
if (report2.verdict === "insufficient-observation") {
|
|
49732
|
+
lines.push("");
|
|
49733
|
+
lines.push(
|
|
49734
|
+
"verdict: insufficient-observation \u2014 an observation needs at least one bare AND one described entry to separate anything."
|
|
49735
|
+
);
|
|
49736
|
+
return lines.join("\n");
|
|
49737
|
+
}
|
|
49738
|
+
lines.push("");
|
|
49739
|
+
lines.push("selector candidates:");
|
|
49740
|
+
for (const candidate of report2.candidates) {
|
|
49741
|
+
lines.push(` ${candidate.separates ? "\u2705" : "\u274C"} ${candidate.id} \u2014 ${candidate.describes}`);
|
|
49742
|
+
lines.push(` ${candidate.detail}`);
|
|
49743
|
+
}
|
|
49744
|
+
lines.push("");
|
|
49745
|
+
lines.push(
|
|
49746
|
+
report2.verdict === "selector-found" ? "verdict: selector-found \u2014 a delivery fix can act on the separating property above." : "verdict: no-selector \u2014 no measured property separates the groups; the selector is host-internal on this evidence. Publish the null rather than guessing a fix."
|
|
49747
|
+
);
|
|
49748
|
+
return lines.join("\n");
|
|
49749
|
+
}
|
|
49750
|
+
var DEFAULT_CATALOGUE_ROOTS, OBSERVATION_LOG;
|
|
49751
|
+
var init_skill_catalogue = __esm({
|
|
49752
|
+
"src/scripts/_lib/skill_catalogue.ts"() {
|
|
49753
|
+
"use strict";
|
|
49754
|
+
DEFAULT_CATALOGUE_ROOTS = [".claude/skills", "src/skills"];
|
|
49755
|
+
OBSERVATION_LOG = path73.join(
|
|
49756
|
+
"agents",
|
|
49757
|
+
"evidence",
|
|
49758
|
+
"metrics",
|
|
49759
|
+
"skill-catalogue.jsonl"
|
|
49760
|
+
);
|
|
49761
|
+
}
|
|
49762
|
+
});
|
|
49763
|
+
|
|
49764
|
+
// src/scripts/skill_tools/score_skill_relevance.ts
|
|
49765
|
+
var score_skill_relevance_exports = {};
|
|
49766
|
+
__export(score_skill_relevance_exports, {
|
|
49767
|
+
DEFAULT_SKILLS_DIR: () => DEFAULT_SKILLS_DIR,
|
|
49768
|
+
ROOT: () => ROOT3,
|
|
49769
|
+
_SAMPLE: () => _SAMPLE,
|
|
49770
|
+
_parse_frontmatter: () => _parse_frontmatter2,
|
|
49771
|
+
_tokenize: () => _tokenize,
|
|
49772
|
+
main: () => main35,
|
|
49773
|
+
parse_args: () => parse_args7,
|
|
49774
|
+
rank: () => rank
|
|
49775
|
+
});
|
|
49776
|
+
import * as fs78 from "node:fs";
|
|
49136
49777
|
import * as path74 from "node:path";
|
|
49137
|
-
import { fileURLToPath as
|
|
49778
|
+
import { fileURLToPath as fileURLToPath46, pathToFileURL as pathToFileURL35 } from "node:url";
|
|
49779
|
+
function pyLen(s) {
|
|
49780
|
+
let n = 0;
|
|
49781
|
+
for (const _ of s) {
|
|
49782
|
+
n++;
|
|
49783
|
+
}
|
|
49784
|
+
return n;
|
|
49785
|
+
}
|
|
49786
|
+
function _tokenize(text) {
|
|
49787
|
+
const out = /* @__PURE__ */ new Set();
|
|
49788
|
+
const matches = text.toLowerCase().match(TOKEN_RE3) ?? [];
|
|
49789
|
+
for (const t of matches) {
|
|
49790
|
+
if (!STOPWORDS.has(t) && pyLen(t) > 2) {
|
|
49791
|
+
out.add(t);
|
|
49792
|
+
}
|
|
49793
|
+
}
|
|
49794
|
+
return out;
|
|
49795
|
+
}
|
|
49796
|
+
function _parse_frontmatter2(filePath) {
|
|
49797
|
+
const text = fs78.readFileSync(filePath, "utf-8");
|
|
49798
|
+
if (!text.startsWith("---")) {
|
|
49799
|
+
return {};
|
|
49800
|
+
}
|
|
49801
|
+
const end = text.indexOf("\n---", 3);
|
|
49802
|
+
if (end === -1) {
|
|
49803
|
+
return {};
|
|
49804
|
+
}
|
|
49805
|
+
const block = text.slice(3, end);
|
|
49806
|
+
const out = {};
|
|
49807
|
+
let currentListKey = null;
|
|
49808
|
+
for (const raw of _splitlines13(block)) {
|
|
49809
|
+
const line = _rstrip3(raw);
|
|
49810
|
+
if (!line || line.startsWith("#")) {
|
|
49811
|
+
continue;
|
|
49812
|
+
}
|
|
49813
|
+
if (currentListKey !== null && line.startsWith(" - ")) {
|
|
49814
|
+
const existing = out[currentListKey];
|
|
49815
|
+
const list = Array.isArray(existing) ? existing : [];
|
|
49816
|
+
if (!Array.isArray(existing)) {
|
|
49817
|
+
out[currentListKey] = list;
|
|
49818
|
+
}
|
|
49819
|
+
list.push(line.slice(4).trim());
|
|
49820
|
+
continue;
|
|
49821
|
+
}
|
|
49822
|
+
currentListKey = null;
|
|
49823
|
+
const m = /^([a-zA-Z_][\w-]*)[ \t\r\f\v]*:[ \t\r\f\v]*(.*)$/u.exec(line);
|
|
49824
|
+
if (!m) {
|
|
49825
|
+
continue;
|
|
49826
|
+
}
|
|
49827
|
+
const key = m[1];
|
|
49828
|
+
let val = m[2].trim();
|
|
49829
|
+
if (val === "") {
|
|
49830
|
+
currentListKey = key;
|
|
49831
|
+
continue;
|
|
49832
|
+
}
|
|
49833
|
+
if (val.startsWith('"') && val.endsWith('"')) {
|
|
49834
|
+
val = val.slice(1, -1);
|
|
49835
|
+
}
|
|
49836
|
+
out[key] = val;
|
|
49837
|
+
}
|
|
49838
|
+
return out;
|
|
49839
|
+
}
|
|
49840
|
+
function _splitlines13(s) {
|
|
49841
|
+
if (s === "") {
|
|
49842
|
+
return [];
|
|
49843
|
+
}
|
|
49844
|
+
return s.split(/\r\n|\r|\n/u);
|
|
49845
|
+
}
|
|
49846
|
+
function _rstrip3(s) {
|
|
49847
|
+
return s.replace(/\s+$/u, "");
|
|
49848
|
+
}
|
|
49849
|
+
function _load_skills(skillsDir) {
|
|
49850
|
+
const skills = [];
|
|
49851
|
+
for (const skillMd of _globSkillMd(skillsDir)) {
|
|
49852
|
+
const fm = _parse_frontmatter2(skillMd);
|
|
49853
|
+
const rawName = fm["name"];
|
|
49854
|
+
const name = _truthyStr(rawName) ? String(rawName) : path74.basename(path74.dirname(skillMd));
|
|
49855
|
+
const rawDesc = fm["description"];
|
|
49856
|
+
const desc = _truthyStr(rawDesc) ? String(rawDesc) : "";
|
|
49857
|
+
let personas = fm["personas"] ?? [];
|
|
49858
|
+
if (typeof personas === "string") {
|
|
49859
|
+
personas = [personas];
|
|
49860
|
+
}
|
|
49861
|
+
const personaList = [...personas];
|
|
49862
|
+
skills.push({
|
|
49863
|
+
name,
|
|
49864
|
+
description: desc,
|
|
49865
|
+
personas: personaList,
|
|
49866
|
+
terms: _tokenize(name + " " + desc)
|
|
49867
|
+
});
|
|
49868
|
+
}
|
|
49869
|
+
return skills;
|
|
49870
|
+
}
|
|
49871
|
+
function _truthyStr(v) {
|
|
49872
|
+
if (typeof v === "string") {
|
|
49873
|
+
return v !== "";
|
|
49874
|
+
}
|
|
49875
|
+
return false;
|
|
49876
|
+
}
|
|
49877
|
+
function _globSkillMd(root) {
|
|
49878
|
+
let names;
|
|
49879
|
+
try {
|
|
49880
|
+
names = fs78.readdirSync(root);
|
|
49881
|
+
} catch {
|
|
49882
|
+
return [];
|
|
49883
|
+
}
|
|
49884
|
+
const dirs = [];
|
|
49885
|
+
for (const name of names) {
|
|
49886
|
+
const dir = path74.join(root, name);
|
|
49887
|
+
const skillMd = path74.join(dir, "SKILL.md");
|
|
49888
|
+
try {
|
|
49889
|
+
if (fs78.statSync(dir).isDirectory() && fs78.statSync(skillMd).isFile()) {
|
|
49890
|
+
dirs.push(name);
|
|
49891
|
+
}
|
|
49892
|
+
} catch {
|
|
49893
|
+
}
|
|
49894
|
+
}
|
|
49895
|
+
dirs.sort();
|
|
49896
|
+
return dirs.map((name) => path74.join(root, name, "SKILL.md"));
|
|
49897
|
+
}
|
|
49898
|
+
function _score3(taskTerms, skill) {
|
|
49899
|
+
if (taskTerms.size === 0) {
|
|
49900
|
+
return 0;
|
|
49901
|
+
}
|
|
49902
|
+
const skillTerms = skill.terms;
|
|
49903
|
+
let inter = 0;
|
|
49904
|
+
for (const t of taskTerms) {
|
|
49905
|
+
if (skillTerms.has(t)) {
|
|
49906
|
+
inter++;
|
|
49907
|
+
}
|
|
49908
|
+
}
|
|
49909
|
+
const overlap = inter / Math.max(taskTerms.size, 1);
|
|
49910
|
+
let personaHit = 0;
|
|
49911
|
+
const taskLower = [...taskTerms].join(" ");
|
|
49912
|
+
for (const persona of skill.personas) {
|
|
49913
|
+
const slug = String(persona).toLowerCase();
|
|
49914
|
+
const parts = slug.split("-");
|
|
49915
|
+
if (taskLower.includes(slug) || parts.some((part) => taskTerms.has(part))) {
|
|
49916
|
+
personaHit = 1;
|
|
49917
|
+
break;
|
|
49918
|
+
}
|
|
49919
|
+
}
|
|
49920
|
+
return pyRound(overlap * 70 + personaHit * 30, 0);
|
|
49921
|
+
}
|
|
49922
|
+
function rank(task, skillsDir) {
|
|
49923
|
+
const taskTerms = _tokenize(task);
|
|
49924
|
+
const skills = _load_skills(skillsDir);
|
|
49925
|
+
const rows = [];
|
|
49926
|
+
for (const s of skills) {
|
|
49927
|
+
const score = _score3(taskTerms, s);
|
|
49928
|
+
if (score > 0) {
|
|
49929
|
+
rows.push([s.name, score, [...s.personas]]);
|
|
49930
|
+
}
|
|
49931
|
+
}
|
|
49932
|
+
rows.sort((a, b) => {
|
|
49933
|
+
if (b[1] !== a[1]) {
|
|
49934
|
+
return b[1] - a[1];
|
|
49935
|
+
}
|
|
49936
|
+
if (a[0] < b[0]) {
|
|
49937
|
+
return -1;
|
|
49938
|
+
}
|
|
49939
|
+
if (a[0] > b[0]) {
|
|
49940
|
+
return 1;
|
|
49941
|
+
}
|
|
49942
|
+
return 0;
|
|
49943
|
+
});
|
|
49944
|
+
return rows;
|
|
49945
|
+
}
|
|
49946
|
+
function _ljust4(s, w) {
|
|
49947
|
+
const len = pyLen(s);
|
|
49948
|
+
return len >= w ? s : s + " ".repeat(w - len);
|
|
49949
|
+
}
|
|
49950
|
+
function _rjust3(n) {
|
|
49951
|
+
const s = String(n);
|
|
49952
|
+
return s.length >= 3 ? s : " ".repeat(3 - s.length) + s;
|
|
49953
|
+
}
|
|
49954
|
+
function _print_human(rowsIn, top) {
|
|
49955
|
+
let rows = rowsIn;
|
|
49956
|
+
if (top) {
|
|
49957
|
+
rows = rows.slice(0, top);
|
|
49958
|
+
}
|
|
49959
|
+
if (rows.length === 0) {
|
|
49960
|
+
return ["(no relevant skills found)"];
|
|
49961
|
+
}
|
|
49962
|
+
const width = Math.max(...rows.map((r) => pyLen(r[0])));
|
|
49963
|
+
const lines = [];
|
|
49964
|
+
for (const [name, score, personas] of rows) {
|
|
49965
|
+
const personaStr = personas.length > 0 ? personas.join(", ") : "\u2014";
|
|
49966
|
+
lines.push(` ${_rjust3(score)} ${_ljust4(name, width)} ${personaStr}`);
|
|
49967
|
+
}
|
|
49968
|
+
return lines;
|
|
49969
|
+
}
|
|
49970
|
+
function _pyJsonStr3(s) {
|
|
49971
|
+
let out = '"';
|
|
49972
|
+
for (const ch of s) {
|
|
49973
|
+
const code = ch.codePointAt(0);
|
|
49974
|
+
if (ch === '"') {
|
|
49975
|
+
out += '\\"';
|
|
49976
|
+
} else if (ch === "\\") {
|
|
49977
|
+
out += "\\\\";
|
|
49978
|
+
} else if (ch === "\n") {
|
|
49979
|
+
out += "\\n";
|
|
49980
|
+
} else if (ch === "\r") {
|
|
49981
|
+
out += "\\r";
|
|
49982
|
+
} else if (ch === " ") {
|
|
49983
|
+
out += "\\t";
|
|
49984
|
+
} else if (ch === "\b") {
|
|
49985
|
+
out += "\\b";
|
|
49986
|
+
} else if (ch === "\f") {
|
|
49987
|
+
out += "\\f";
|
|
49988
|
+
} else if (code < 32) {
|
|
49989
|
+
out += `\\u${code.toString(16).padStart(4, "0")}`;
|
|
49990
|
+
} else if (code < 127) {
|
|
49991
|
+
out += ch;
|
|
49992
|
+
} else if (code <= 65535) {
|
|
49993
|
+
out += `\\u${code.toString(16).padStart(4, "0")}`;
|
|
49994
|
+
} else {
|
|
49995
|
+
const c = code - 65536;
|
|
49996
|
+
const hi = 55296 + (c >> 10);
|
|
49997
|
+
const lo = 56320 + (c & 1023);
|
|
49998
|
+
out += `\\u${hi.toString(16).padStart(4, "0")}\\u${lo.toString(16).padStart(4, "0")}`;
|
|
49999
|
+
}
|
|
50000
|
+
}
|
|
50001
|
+
return out + '"';
|
|
50002
|
+
}
|
|
50003
|
+
function pyJsonDumpsIndent2(obj, level = 0) {
|
|
50004
|
+
if (obj === null) {
|
|
50005
|
+
return "null";
|
|
50006
|
+
}
|
|
50007
|
+
if (typeof obj === "number") {
|
|
50008
|
+
return String(obj);
|
|
50009
|
+
}
|
|
50010
|
+
if (typeof obj === "string") {
|
|
50011
|
+
return _pyJsonStr3(obj);
|
|
50012
|
+
}
|
|
50013
|
+
if (obj === true) {
|
|
50014
|
+
return "true";
|
|
50015
|
+
}
|
|
50016
|
+
if (obj === false) {
|
|
50017
|
+
return "false";
|
|
50018
|
+
}
|
|
50019
|
+
if (Array.isArray(obj)) {
|
|
50020
|
+
if (obj.length === 0) {
|
|
50021
|
+
return "[]";
|
|
50022
|
+
}
|
|
50023
|
+
const pad2 = " ".repeat(2 * (level + 1));
|
|
50024
|
+
const closePad2 = " ".repeat(2 * level);
|
|
50025
|
+
return `[
|
|
50026
|
+
${obj.map((v) => pad2 + pyJsonDumpsIndent2(v, level + 1)).join(",\n")}
|
|
50027
|
+
${closePad2}]`;
|
|
50028
|
+
}
|
|
50029
|
+
const keys = Object.keys(obj);
|
|
50030
|
+
if (keys.length === 0) {
|
|
50031
|
+
return "{}";
|
|
50032
|
+
}
|
|
50033
|
+
const pad = " ".repeat(2 * (level + 1));
|
|
50034
|
+
const closePad = " ".repeat(2 * level);
|
|
50035
|
+
const parts = keys.map(
|
|
50036
|
+
(k) => `${pad}${_pyJsonStr3(k)}: ${pyJsonDumpsIndent2(obj[k], level + 1)}`
|
|
50037
|
+
);
|
|
50038
|
+
return `{
|
|
50039
|
+
${parts.join(",\n")}
|
|
50040
|
+
${closePad}}`;
|
|
50041
|
+
}
|
|
50042
|
+
function _argError10(message) {
|
|
50043
|
+
process.stderr.write(`${PROG5}: error: ${message}
|
|
50044
|
+
`);
|
|
50045
|
+
process.exit(2);
|
|
50046
|
+
}
|
|
50047
|
+
function _parseInt2(raw) {
|
|
50048
|
+
if (!/^[+-]?\d+$/u.test(raw.trim())) {
|
|
50049
|
+
_argError10(`argument --top: invalid int value: '${raw}'`);
|
|
50050
|
+
}
|
|
50051
|
+
return parseInt(raw, 10);
|
|
50052
|
+
}
|
|
50053
|
+
function parse_args7(argv) {
|
|
50054
|
+
const args = {
|
|
50055
|
+
task: "",
|
|
50056
|
+
skills_dir: DEFAULT_SKILLS_DIR,
|
|
50057
|
+
top: 0,
|
|
50058
|
+
json: false,
|
|
50059
|
+
sample: false
|
|
50060
|
+
};
|
|
50061
|
+
for (let i = 0; i < argv.length; i++) {
|
|
50062
|
+
const a = argv[i];
|
|
50063
|
+
if (a === "--json") {
|
|
50064
|
+
args.json = true;
|
|
50065
|
+
} else if (a === "--sample") {
|
|
50066
|
+
args.sample = true;
|
|
50067
|
+
} else if (a === "--task") {
|
|
50068
|
+
const v = argv[++i];
|
|
50069
|
+
if (v === void 0) {
|
|
50070
|
+
_argError10("argument --task: expected one argument");
|
|
50071
|
+
}
|
|
50072
|
+
args.task = v;
|
|
50073
|
+
} else if (a.startsWith("--task=")) {
|
|
50074
|
+
args.task = a.slice("--task=".length);
|
|
50075
|
+
} else if (a === "--skills-dir") {
|
|
50076
|
+
const v = argv[++i];
|
|
50077
|
+
if (v === void 0) {
|
|
50078
|
+
_argError10("argument --skills-dir: expected one argument");
|
|
50079
|
+
}
|
|
50080
|
+
args.skills_dir = v;
|
|
50081
|
+
} else if (a.startsWith("--skills-dir=")) {
|
|
50082
|
+
args.skills_dir = a.slice("--skills-dir=".length);
|
|
50083
|
+
} else if (a === "--top") {
|
|
50084
|
+
const v = argv[++i];
|
|
50085
|
+
if (v === void 0) {
|
|
50086
|
+
_argError10("argument --top: expected one argument");
|
|
50087
|
+
}
|
|
50088
|
+
args.top = _parseInt2(v);
|
|
50089
|
+
} else if (a.startsWith("--top=")) {
|
|
50090
|
+
args.top = _parseInt2(a.slice("--top=".length));
|
|
50091
|
+
} else {
|
|
50092
|
+
_argError10(`unrecognized arguments: ${a}`);
|
|
50093
|
+
}
|
|
50094
|
+
}
|
|
50095
|
+
return args;
|
|
50096
|
+
}
|
|
50097
|
+
function main35(argv = null) {
|
|
50098
|
+
const args = parse_args7(argv ?? process.argv.slice(2));
|
|
50099
|
+
const task = args.sample ? _SAMPLE.task : args.task;
|
|
50100
|
+
if (!task) {
|
|
50101
|
+
_argError10("--task is required (or pass --sample)");
|
|
50102
|
+
}
|
|
50103
|
+
const rows = rank(task, args.skills_dir);
|
|
50104
|
+
if (args.json) {
|
|
50105
|
+
const sliced = args.top ? rows.slice(0, args.top) : rows;
|
|
50106
|
+
const payload = sliced.map(([n, s, p]) => ({ name: n, score: s, personas: p }));
|
|
50107
|
+
process.stdout.write(pyJsonDumpsIndent2({ task, ranked: payload }));
|
|
50108
|
+
process.stdout.write("\n");
|
|
50109
|
+
} else {
|
|
50110
|
+
const lines = _print_human(rows, args.top || null);
|
|
50111
|
+
process.stdout.write(lines.join("\n") + "\n");
|
|
50112
|
+
}
|
|
50113
|
+
return 0;
|
|
50114
|
+
}
|
|
50115
|
+
function _isCliEntry32() {
|
|
50116
|
+
if (process.argv[1] === void 0) {
|
|
50117
|
+
return false;
|
|
50118
|
+
}
|
|
50119
|
+
const argvUrl = pathToFileURL35(path74.resolve(process.argv[1])).href;
|
|
50120
|
+
if (import.meta.url === argvUrl) {
|
|
50121
|
+
return true;
|
|
50122
|
+
}
|
|
50123
|
+
try {
|
|
50124
|
+
const here = fs78.realpathSync(fileURLToPath46(import.meta.url));
|
|
50125
|
+
const argv = fs78.realpathSync(path74.resolve(process.argv[1]));
|
|
50126
|
+
return here === argv;
|
|
50127
|
+
} catch {
|
|
50128
|
+
return false;
|
|
50129
|
+
}
|
|
50130
|
+
}
|
|
50131
|
+
var _HERE23, ROOT3, DEFAULT_SKILLS_DIR, TOKEN_RE3, STOPWORDS, PROG5, _SAMPLE, _isMain5;
|
|
50132
|
+
var init_score_skill_relevance = __esm({
|
|
50133
|
+
"src/scripts/skill_tools/score_skill_relevance.ts"() {
|
|
50134
|
+
"use strict";
|
|
50135
|
+
init_value_ladder();
|
|
50136
|
+
_HERE23 = fileURLToPath46(import.meta.url);
|
|
50137
|
+
ROOT3 = path74.resolve(path74.dirname(_HERE23), "..", "..", "..");
|
|
50138
|
+
DEFAULT_SKILLS_DIR = path74.join(ROOT3, ".agent-src.uncondensed", "skills");
|
|
50139
|
+
TOKEN_RE3 = /[a-z][a-z0-9]+/g;
|
|
50140
|
+
STOPWORDS = /* @__PURE__ */ new Set([
|
|
50141
|
+
"the",
|
|
50142
|
+
"a",
|
|
50143
|
+
"an",
|
|
50144
|
+
"and",
|
|
50145
|
+
"or",
|
|
50146
|
+
"but",
|
|
50147
|
+
"of",
|
|
50148
|
+
"for",
|
|
50149
|
+
"with",
|
|
50150
|
+
"to",
|
|
50151
|
+
"in",
|
|
50152
|
+
"on",
|
|
50153
|
+
"at",
|
|
50154
|
+
"by",
|
|
50155
|
+
"from",
|
|
50156
|
+
"as",
|
|
50157
|
+
"is",
|
|
50158
|
+
"are",
|
|
50159
|
+
"was",
|
|
50160
|
+
"were",
|
|
50161
|
+
"be",
|
|
50162
|
+
"been",
|
|
50163
|
+
"this",
|
|
50164
|
+
"that",
|
|
50165
|
+
"these",
|
|
50166
|
+
"those",
|
|
50167
|
+
"it",
|
|
50168
|
+
"its",
|
|
50169
|
+
"use",
|
|
50170
|
+
"when",
|
|
50171
|
+
"even",
|
|
50172
|
+
"via",
|
|
50173
|
+
"via:",
|
|
50174
|
+
"into",
|
|
50175
|
+
"onto",
|
|
50176
|
+
"use:",
|
|
50177
|
+
"skill",
|
|
50178
|
+
"skills",
|
|
50179
|
+
"task",
|
|
50180
|
+
"tasks",
|
|
50181
|
+
"code",
|
|
50182
|
+
"file",
|
|
50183
|
+
"files",
|
|
50184
|
+
"doing",
|
|
50185
|
+
"make",
|
|
50186
|
+
"do",
|
|
50187
|
+
"go",
|
|
50188
|
+
"get",
|
|
50189
|
+
"set",
|
|
50190
|
+
"not",
|
|
50191
|
+
"no",
|
|
50192
|
+
"yes",
|
|
50193
|
+
"any",
|
|
50194
|
+
"some",
|
|
50195
|
+
"all",
|
|
50196
|
+
"one",
|
|
50197
|
+
"two",
|
|
50198
|
+
"new",
|
|
50199
|
+
"old",
|
|
50200
|
+
"user",
|
|
50201
|
+
"users",
|
|
50202
|
+
"our",
|
|
50203
|
+
"your",
|
|
50204
|
+
"their",
|
|
50205
|
+
"they",
|
|
50206
|
+
"we",
|
|
50207
|
+
"you",
|
|
50208
|
+
"i",
|
|
50209
|
+
"me"
|
|
50210
|
+
]);
|
|
50211
|
+
PROG5 = "score_skill_relevance.py";
|
|
50212
|
+
_SAMPLE = {
|
|
50213
|
+
task: "build a livewire component for the user dashboard with reactive state"
|
|
50214
|
+
};
|
|
50215
|
+
_isMain5 = _isCliEntry32();
|
|
50216
|
+
if (_isMain5) {
|
|
50217
|
+
process.exitCode = main35();
|
|
50218
|
+
}
|
|
50219
|
+
}
|
|
50220
|
+
});
|
|
50221
|
+
|
|
50222
|
+
// src/scripts/mcp_server/__main__.ts
|
|
50223
|
+
import * as path76 from "node:path";
|
|
50224
|
+
import { fileURLToPath as fileURLToPath48 } from "node:url";
|
|
49138
50225
|
|
|
49139
50226
|
// src/scripts/mcp_server/index.ts
|
|
49140
50227
|
var __version__ = "0.1.0";
|
|
@@ -49181,9 +50268,9 @@ init_prompts();
|
|
|
49181
50268
|
init_resources();
|
|
49182
50269
|
|
|
49183
50270
|
// src/scripts/mcp_server/tools.ts
|
|
49184
|
-
import * as
|
|
49185
|
-
import * as
|
|
49186
|
-
import { fileURLToPath as
|
|
50271
|
+
import * as fs79 from "node:fs";
|
|
50272
|
+
import * as path75 from "node:path";
|
|
50273
|
+
import { fileURLToPath as fileURLToPath47 } from "node:url";
|
|
49187
50274
|
|
|
49188
50275
|
// src/scripts/chat_history.ts
|
|
49189
50276
|
init_memory_lookup();
|
|
@@ -51416,9 +52503,9 @@ function _strip8(s) {
|
|
|
51416
52503
|
}
|
|
51417
52504
|
function _resolvePath2(p) {
|
|
51418
52505
|
try {
|
|
51419
|
-
return
|
|
52506
|
+
return fs79.realpathSync(p);
|
|
51420
52507
|
} catch {
|
|
51421
|
-
return
|
|
52508
|
+
return path75.resolve(p);
|
|
51422
52509
|
}
|
|
51423
52510
|
}
|
|
51424
52511
|
function _resolveConsumerRoot(override) {
|
|
@@ -51428,14 +52515,14 @@ function _resolveConsumerRoot(override) {
|
|
|
51428
52515
|
return _resolvePath2(process.cwd());
|
|
51429
52516
|
}
|
|
51430
52517
|
function _relativeUnder(target, root) {
|
|
51431
|
-
const rel =
|
|
52518
|
+
const rel = path75.relative(root, target);
|
|
51432
52519
|
if (rel === "") {
|
|
51433
52520
|
return "";
|
|
51434
52521
|
}
|
|
51435
|
-
if (rel.startsWith("..") ||
|
|
52522
|
+
if (rel.startsWith("..") || path75.isAbsolute(rel)) {
|
|
51436
52523
|
return null;
|
|
51437
52524
|
}
|
|
51438
|
-
return rel.split(
|
|
52525
|
+
return rel.split(path75.sep).join("/");
|
|
51439
52526
|
}
|
|
51440
52527
|
function _reprStrList(values) {
|
|
51441
52528
|
return `[${values.map((v) => `'${v}'`).join(", ")}]`;
|
|
@@ -51444,11 +52531,11 @@ function _validateInTreePath(raw, consumerRoot) {
|
|
|
51444
52531
|
const root = _resolvePath2(consumerRoot);
|
|
51445
52532
|
let target;
|
|
51446
52533
|
if (raw === null || raw === void 0 || raw === "") {
|
|
51447
|
-
target =
|
|
51448
|
-
} else if (
|
|
52534
|
+
target = path75.join(root, "agents", "runtime", ".agent-chat-history");
|
|
52535
|
+
} else if (path75.isAbsolute(raw)) {
|
|
51449
52536
|
target = _resolvePath2(raw);
|
|
51450
52537
|
} else {
|
|
51451
|
-
target = _resolvePath2(
|
|
52538
|
+
target = _resolvePath2(path75.join(root, raw));
|
|
51452
52539
|
}
|
|
51453
52540
|
const rel = _relativeUnder(target, root);
|
|
51454
52541
|
if (rel === null) {
|
|
@@ -51486,11 +52573,11 @@ async function _lintSkillsHandler(args, consumerRoot) {
|
|
|
51486
52573
|
if (typeof raw !== "string") {
|
|
51487
52574
|
throw new Error("'paths' entries must be strings");
|
|
51488
52575
|
}
|
|
51489
|
-
const resolved =
|
|
52576
|
+
const resolved = path75.isAbsolute(raw) ? _resolvePath2(raw) : _resolvePath2(path75.join(root, raw));
|
|
51490
52577
|
if (_relativeUnder(resolved, root) === null) {
|
|
51491
52578
|
throw new Error(`path escapes consumer_root: ${resolved}`);
|
|
51492
52579
|
}
|
|
51493
|
-
if (
|
|
52580
|
+
if (fs79.existsSync(resolved)) {
|
|
51494
52581
|
paths.push(resolved);
|
|
51495
52582
|
}
|
|
51496
52583
|
}
|
|
@@ -51527,7 +52614,7 @@ async function _chatHistoryAppendHandler(args, consumerRoot) {
|
|
|
51527
52614
|
if (typeof minSchema !== "number" || !Number.isInteger(minSchema) || typeof minSchema === "boolean") {
|
|
51528
52615
|
throw new Error("'min_schema_version' must be an integer");
|
|
51529
52616
|
}
|
|
51530
|
-
const existingHeader =
|
|
52617
|
+
const existingHeader = fs79.existsSync(target) ? _chReadHeader(target) : null;
|
|
51531
52618
|
const observed = existingHeader !== null && typeof existingHeader === "object" ? _pyInt7(existingHeader.v ?? 0) : SCHEMA_VERSION3;
|
|
51532
52619
|
if (observed < minSchema) {
|
|
51533
52620
|
throw new Error(`chat-history schema ${observed} below required ${minSchema}`);
|
|
@@ -51542,8 +52629,8 @@ async function _chatHistoryAppendHandler(args, consumerRoot) {
|
|
|
51542
52629
|
session: session === void 0 ? null : session
|
|
51543
52630
|
};
|
|
51544
52631
|
}
|
|
51545
|
-
if (!
|
|
51546
|
-
|
|
52632
|
+
if (!fs79.existsSync(target) || _chReadHeader(target) === null) {
|
|
52633
|
+
fs79.mkdirSync(path75.dirname(target), { recursive: true });
|
|
51547
52634
|
_chInit(target);
|
|
51548
52635
|
}
|
|
51549
52636
|
_chAppend(entry, target, session ?? null);
|
|
@@ -51587,7 +52674,7 @@ async function _chatHistoryReadHandler(args, consumerRoot) {
|
|
|
51587
52674
|
if (detail !== "full" && detail !== "index") {
|
|
51588
52675
|
throw new Error("'detail' must be 'index' or 'full'");
|
|
51589
52676
|
}
|
|
51590
|
-
if (!
|
|
52677
|
+
if (!fs79.existsSync(target)) {
|
|
51591
52678
|
return { path: target, entries: [], count: 0 };
|
|
51592
52679
|
}
|
|
51593
52680
|
if (around !== void 0 && around !== null) {
|
|
@@ -51689,8 +52776,8 @@ async function _memoryStatusHandler(_args, consumerRoot) {
|
|
|
51689
52776
|
}
|
|
51690
52777
|
return result;
|
|
51691
52778
|
}
|
|
51692
|
-
var _PACKAGE_ROOT3 =
|
|
51693
|
-
|
|
52779
|
+
var _PACKAGE_ROOT3 = path75.resolve(
|
|
52780
|
+
path75.dirname(fileURLToPath47(import.meta.url)),
|
|
51694
52781
|
"..",
|
|
51695
52782
|
"..",
|
|
51696
52783
|
".."
|
|
@@ -51734,10 +52821,10 @@ async function _memorySignalHandler(args, consumerRoot) {
|
|
|
51734
52821
|
async function _roadmapProgressHandler(args, consumerRoot) {
|
|
51735
52822
|
const dryRun = _pyTruthy6(args.dry_run ?? false);
|
|
51736
52823
|
const root = _resolvePath2(consumerRoot);
|
|
51737
|
-
const roadmapRoot =
|
|
51738
|
-
const target =
|
|
52824
|
+
const roadmapRoot = path75.join(root, "agents", "roadmaps");
|
|
52825
|
+
const target = path75.join(root, "agents", "roadmaps-progress.md");
|
|
51739
52826
|
const urp = await Promise.resolve().then(() => (init_update_roadmap_progress(), update_roadmap_progress_exports));
|
|
51740
|
-
if (!
|
|
52827
|
+
if (!fs79.existsSync(roadmapRoot)) {
|
|
51741
52828
|
return {
|
|
51742
52829
|
written: false,
|
|
51743
52830
|
path: target,
|
|
@@ -51752,7 +52839,7 @@ async function _roadmapProgressHandler(args, consumerRoot) {
|
|
|
51752
52839
|
const stepsDone = roadmaps.reduce((s, r) => s + r.done, 0);
|
|
51753
52840
|
const stepsTotal = roadmaps.reduce((s, r) => s + r.total_active, 0);
|
|
51754
52841
|
if (!dryRun) {
|
|
51755
|
-
|
|
52842
|
+
fs79.writeFileSync(target, content, "utf-8");
|
|
51756
52843
|
}
|
|
51757
52844
|
return {
|
|
51758
52845
|
written: !dryRun,
|
|
@@ -51773,11 +52860,11 @@ async function _roadmapArchiveHandler(_args, consumerRoot) {
|
|
|
51773
52860
|
let dashboardRegenerated = false;
|
|
51774
52861
|
if (archived.length > 0) {
|
|
51775
52862
|
const urp = await Promise.resolve().then(() => (init_update_roadmap_progress(), update_roadmap_progress_exports));
|
|
51776
|
-
const roadmapRoot =
|
|
51777
|
-
if (
|
|
52863
|
+
const roadmapRoot = path75.join(root, "agents", "roadmaps");
|
|
52864
|
+
if (fs79.existsSync(roadmapRoot)) {
|
|
51778
52865
|
const roadmaps = urp.collect(roadmapRoot);
|
|
51779
|
-
|
|
51780
|
-
|
|
52866
|
+
fs79.writeFileSync(
|
|
52867
|
+
path75.join(root, "agents", "roadmaps-progress.md"),
|
|
51781
52868
|
urp.render(roadmaps, urp.collect_bundles(root)),
|
|
51782
52869
|
"utf-8"
|
|
51783
52870
|
);
|
|
@@ -51793,9 +52880,9 @@ async function _roadmapArchiveHandler(_args, consumerRoot) {
|
|
|
51793
52880
|
async function _capabilitiesIndexHandler(args, consumerRoot) {
|
|
51794
52881
|
const check = _pyTruthy6(args.check ?? false);
|
|
51795
52882
|
const cap = await Promise.resolve().then(() => (init_generate_capabilities_index(), generate_capabilities_index_exports));
|
|
51796
|
-
const out =
|
|
52883
|
+
const out = path75.join(_PACKAGE_ROOT3, "CAPABILITIES.yaml");
|
|
51797
52884
|
const content = cap.build();
|
|
51798
|
-
const onDisk =
|
|
52885
|
+
const onDisk = fs79.existsSync(out) ? fs79.readFileSync(out, "utf-8") : "";
|
|
51799
52886
|
const drift = onDisk !== content;
|
|
51800
52887
|
if (check) {
|
|
51801
52888
|
return { check: true, written: false, drift, path: out };
|
|
@@ -51806,7 +52893,7 @@ async function _capabilitiesIndexHandler(args, consumerRoot) {
|
|
|
51806
52893
|
`CAPABILITIES.yaml path escapes consumer_root: ${out} not under ${root}`
|
|
51807
52894
|
);
|
|
51808
52895
|
}
|
|
51809
|
-
|
|
52896
|
+
fs79.writeFileSync(out, content, "utf-8");
|
|
51810
52897
|
return { check: false, written: true, drift, path: out };
|
|
51811
52898
|
}
|
|
51812
52899
|
async function _runDoctorLeg(consumerRoot) {
|
|
@@ -51906,11 +52993,11 @@ async function _councilEstimateHandler(args, consumerRoot) {
|
|
|
51906
52993
|
throw new Error("'depth' must be 'shallow' or 'deep' when provided");
|
|
51907
52994
|
}
|
|
51908
52995
|
const root = _resolvePath2(consumerRoot);
|
|
51909
|
-
const target =
|
|
52996
|
+
const target = path75.isAbsolute(inputRaw) ? _resolvePath2(inputRaw) : _resolvePath2(path75.join(root, inputRaw));
|
|
51910
52997
|
if (_relativeUnder(target, root) === null) {
|
|
51911
52998
|
throw new Error(`path escapes consumer_root: ${target}`);
|
|
51912
52999
|
}
|
|
51913
|
-
if (!
|
|
53000
|
+
if (!fs79.existsSync(target)) {
|
|
51914
53001
|
throw new Error(`input_path not found: ${target}`);
|
|
51915
53002
|
}
|
|
51916
53003
|
const cli = await Promise.resolve().then(() => (init_council_cli(), council_cli_exports));
|
|
@@ -51972,18 +53059,18 @@ async function _runTestsHandler(args, consumerRoot) {
|
|
|
51972
53059
|
if (typeof relPathRaw !== "string" || !_strip8(relPathRaw)) {
|
|
51973
53060
|
throw new Error("'path' must be a non-empty string when provided");
|
|
51974
53061
|
}
|
|
51975
|
-
const resolved =
|
|
53062
|
+
const resolved = path75.isAbsolute(relPathRaw) ? _resolvePath2(relPathRaw) : _resolvePath2(path75.join(root, relPathRaw));
|
|
51976
53063
|
const rel = _relativeUnder(resolved, root);
|
|
51977
53064
|
if (rel === null) {
|
|
51978
53065
|
throw new Error(`path escapes consumer_root: ${resolved}`);
|
|
51979
53066
|
}
|
|
51980
|
-
if (!
|
|
53067
|
+
if (!fs79.existsSync(resolved)) {
|
|
51981
53068
|
throw new Error(`path not found: ${resolved}`);
|
|
51982
53069
|
}
|
|
51983
53070
|
relArg = rel;
|
|
51984
53071
|
}
|
|
51985
|
-
const vitestEntry =
|
|
51986
|
-
if (!
|
|
53072
|
+
const vitestEntry = path75.join(root, "node_modules", "vitest", "vitest.mjs");
|
|
53073
|
+
if (!fs79.existsSync(vitestEntry)) {
|
|
51987
53074
|
throw new Error(
|
|
51988
53075
|
"run_tests pilot supports vitest projects only \u2014 node_modules/vitest/vitest.mjs not found under consumer_root"
|
|
51989
53076
|
);
|
|
@@ -52088,7 +53175,55 @@ async function _readResourceBodyHandler(args, consumerRoot) {
|
|
|
52088
53175
|
body: resource.body
|
|
52089
53176
|
};
|
|
52090
53177
|
}
|
|
53178
|
+
async function _suggestSkillForTaskHandler(args, consumerRoot) {
|
|
53179
|
+
const task = typeof args["task"] === "string" ? args["task"] : "";
|
|
53180
|
+
if (task.trim() === "") {
|
|
53181
|
+
return { status: "error", error: "task must be a non-empty string", suggestions: [] };
|
|
53182
|
+
}
|
|
53183
|
+
const limitRaw = args["limit"];
|
|
53184
|
+
const limit = typeof limitRaw === "number" && Number.isFinite(limitRaw) ? Math.floor(limitRaw) : 5;
|
|
53185
|
+
const catalogue = await Promise.resolve().then(() => (init_skill_catalogue(), skill_catalogue_exports));
|
|
53186
|
+
const skillsDir = catalogue.resolveSkillsRoot(consumerRoot);
|
|
53187
|
+
if (skillsDir === null) {
|
|
53188
|
+
return {
|
|
53189
|
+
status: "no_catalogue",
|
|
53190
|
+
searched: [...catalogue.DEFAULT_CATALOGUE_ROOTS],
|
|
53191
|
+
consumer_root: consumerRoot,
|
|
53192
|
+
suggestions: []
|
|
53193
|
+
};
|
|
53194
|
+
}
|
|
53195
|
+
const { rank: rank2 } = await Promise.resolve().then(() => (init_score_skill_relevance(), score_skill_relevance_exports));
|
|
53196
|
+
const rows = rank2(task, skillsDir).slice(0, Math.max(1, limit));
|
|
53197
|
+
return {
|
|
53198
|
+
status: "ok",
|
|
53199
|
+
skills_root: skillsDir,
|
|
53200
|
+
suggestions: rows.map(([name, score, personas]) => ({ skill: name, score, personas }))
|
|
53201
|
+
};
|
|
53202
|
+
}
|
|
52091
53203
|
var ALLOWLIST = {
|
|
53204
|
+
suggest_skill_for_task: {
|
|
53205
|
+
name: "suggest_skill_for_task",
|
|
53206
|
+
side_effect: "ro",
|
|
53207
|
+
description: "Match a free-form task description to the most relevant skills, ranked by a deterministic keyword scorer over SKILL.md frontmatter. Use when a skill you need is not in the catalogue the host delivered \u2014 a measured host dropped 402 entries from its model-visible list \u2014 so asking by name is impossible while asking by task is not. Read-only: no shell, no writes, and no skill bodies are returned, only names, scores and declared personas.",
|
|
53208
|
+
input_schema: {
|
|
53209
|
+
type: "object",
|
|
53210
|
+
required: ["task"],
|
|
53211
|
+
properties: {
|
|
53212
|
+
task: {
|
|
53213
|
+
type: "string",
|
|
53214
|
+
description: "Free-form description of the task to match skills against."
|
|
53215
|
+
},
|
|
53216
|
+
limit: {
|
|
53217
|
+
type: "integer",
|
|
53218
|
+
minimum: 1,
|
|
53219
|
+
default: 5,
|
|
53220
|
+
description: "Maximum number of skills to return. Defaults to 5."
|
|
53221
|
+
}
|
|
53222
|
+
},
|
|
53223
|
+
additionalProperties: false
|
|
53224
|
+
},
|
|
53225
|
+
handler: _suggestSkillForTaskHandler
|
|
53226
|
+
},
|
|
52092
53227
|
lint_skills: {
|
|
52093
53228
|
name: "lint_skills",
|
|
52094
53229
|
side_effect: "ro",
|
|
@@ -52589,8 +53724,8 @@ function _strCmp3(a, b) {
|
|
|
52589
53724
|
return a < b ? -1 : a > b ? 1 : 0;
|
|
52590
53725
|
}
|
|
52591
53726
|
function _pathlibCompare3(a, b) {
|
|
52592
|
-
const pa = a.split(
|
|
52593
|
-
const pb = b.split(
|
|
53727
|
+
const pa = a.split(path75.sep);
|
|
53728
|
+
const pb = b.split(path75.sep);
|
|
52594
53729
|
const n = Math.min(pa.length, pb.length);
|
|
52595
53730
|
for (let i = 0; i < n; i++) {
|
|
52596
53731
|
const c = _strCmp3(pa[i], pb[i]);
|
|
@@ -52809,18 +53944,18 @@ async function _serveOverSdk(server) {
|
|
|
52809
53944
|
const transport = new StdioServerTransport();
|
|
52810
53945
|
await sdkServer.connect(transport);
|
|
52811
53946
|
}
|
|
52812
|
-
function
|
|
53947
|
+
function main36() {
|
|
52813
53948
|
void run_stdio();
|
|
52814
53949
|
}
|
|
52815
53950
|
|
|
52816
53951
|
// src/scripts/mcp_server/__main__.ts
|
|
52817
|
-
var _selfPath =
|
|
52818
|
-
var _invokedDirectly2 = globalThis.__AC_MCP_BUNDLE_DIRECT === true || process.argv[1] !== void 0 &&
|
|
53952
|
+
var _selfPath = fileURLToPath48(import.meta.url);
|
|
53953
|
+
var _invokedDirectly2 = globalThis.__AC_MCP_BUNDLE_DIRECT === true || process.argv[1] !== void 0 && path76.resolve(process.argv[1]) === path76.resolve(_selfPath);
|
|
52819
53954
|
if (_invokedDirectly2) {
|
|
52820
|
-
|
|
53955
|
+
main36();
|
|
52821
53956
|
}
|
|
52822
53957
|
export {
|
|
52823
|
-
|
|
53958
|
+
main36 as main
|
|
52824
53959
|
};
|
|
52825
53960
|
/*! Bundled license information:
|
|
52826
53961
|
|