@event4u/agent-config 14.21.0 → 14.22.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/.augment-plugin/marketplace.json +3 -3
- package/.augment-plugin/plugin.json +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +198 -0
- package/CREDITS.md +37 -0
- package/dist/agent-src/commands/analyze/inbox.md +380 -5
- package/dist/agent-src/commands/analyze/repo.md +4 -2
- package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +69 -0
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +5 -5
- package/dist/agent-src/rules/external-code-graph-interop.md +19 -14
- package/dist/agent-src/rules/token-efficiency.md +26 -3
- package/dist/agent-src/scripts/_cli_entry.ts +51 -0
- package/dist/agent-src/scripts/archive_completed_roadmaps.ts +14 -23
- package/dist/agent-src/scripts/roadmap_gates.ts +4 -20
- package/dist/agent-src/scripts/roadmap_set_step.ts +5 -2
- package/dist/agent-src/scripts/stubs_due.ts +4 -18
- package/dist/agent-src/scripts/update_roadmap_progress.ts +7 -24
- package/dist/agent-src/skills/code-intelligence/SKILL.md +25 -0
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +17 -0
- package/dist/agent-src/templates/agent-settings.md +0 -1
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/cli-delegate/_cli_entry.js +8 -0
- package/dist/cli-delegate/_lib/pin_resolver.js +170 -0
- package/dist/cli-delegate/archival_sweep.js +8 -0
- package/dist/cli-delegate/archive_completed_roadmaps.js +494 -0
- package/dist/cli-delegate/check_update_banner.js +923 -0
- package/dist/cli-delegate/chunk-5EK5WQN6.js +28 -0
- package/dist/cli-delegate/chunk-7XGD2OEU.js +96 -0
- package/dist/cli-delegate/{chunk-643Z7FIC.js → chunk-BIXEDQPZ.js} +6 -0
- package/dist/cli-delegate/chunk-DBH4AHDK.js +155 -0
- package/dist/cli-delegate/chunk-JO25G5H7.js +20 -0
- package/dist/cli-delegate/chunk-LTYVIY76.js +7961 -0
- package/dist/cli-delegate/chunk-QAJS5YWY.js +999 -0
- package/dist/cli-delegate/{chunk-ZVBOHSVF.js → chunk-TGIPZBCW.js} +1 -1
- package/dist/cli-delegate/{chunk-YS6XTLEK.js → chunk-TYSY33MD.js} +56 -6
- package/dist/cli-delegate/chunk-ULET4BYS.js +328 -0
- package/dist/cli-delegate/chunk-YDQSHTD7.js +187 -0
- package/dist/cli-delegate/chunk-YWVXLR44.js +48 -0
- package/dist/cli-delegate/chunk-ZZQBUHFK.js +273 -0
- package/dist/cli-delegate/cmd_conformance.js +2 -2
- package/dist/cli-delegate/cmd_export.js +1 -1
- package/dist/cli-delegate/cmd_handoff.js +26 -2
- package/dist/cli-delegate/cmd_prune.js +1 -1
- package/dist/cli-delegate/cmd_session_recycle.js +2 -2
- package/dist/cli-delegate/cmd_settings_migrate.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +1 -1
- package/dist/cli-delegate/cmd_uninstall.js +1 -1
- package/dist/cli-delegate/cmd_validate.js +1 -1
- package/dist/cli-delegate/dashboard_mode.js +16 -0
- package/dist/cli-delegate/gate_budget.js +24 -0
- package/dist/cli-delegate/gate_execute.js +25 -0
- package/dist/cli-delegate/guarded_baseline.js +18 -0
- package/dist/cli-delegate/resume_probe.js +22 -0
- package/dist/cli-delegate/roadmap_gates.js +638 -0
- package/dist/cli-delegate/roadmap_set_step.js +173 -0
- package/dist/cli-delegate/stub_queue.js +47 -0
- package/dist/cli-delegate/stubs_due.js +38 -0
- package/dist/cli-delegate/ticket_bundles.js +59 -0
- package/dist/cli-delegate/update_roadmap_progress.js +60 -0
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +8 -8
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +1 -1
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +2 -2
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +2 -2
- package/dist/hooks/dispatch.js +1193 -917
- package/dist/install/claudeLayerCarriage.js +237 -0
- package/dist/install/claudePathsPlan.js +79 -0
- package/dist/install/hostLayerFingerprint.js +1 -1
- package/dist/install/install.mjs +6 -0
- package/dist/install/partitionEligibility.js +231 -117
- package/dist/install/ruleLayerPartition.js +10 -7
- package/dist/mcp/registry-manifest.json +2 -2
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +39219 -38995
- package/dist/scripts/condense.js +32 -25
- package/docs/MIGRATION.md +49 -1
- package/docs/contracts/settings-classes.md +1 -1
- package/docs/guidelines/agent-infra/minimal-safe-diff-mechanics.md +73 -0
- package/package.json +7 -4
- package/src/agent-src/scripts/_cli_entry.ts +51 -0
- package/src/agent-src/scripts/archive_completed_roadmaps.ts +14 -23
- package/src/agent-src/scripts/roadmap_gates.ts +4 -20
- package/src/agent-src/scripts/roadmap_set_step.ts +5 -2
- package/src/agent-src/scripts/stubs_due.ts +4 -18
- package/src/agent-src/scripts/update_roadmap_progress.ts +7 -24
- package/src/config/continuity-surface.json +509 -0
- package/src/config/estate-count-budget.json +1 -1
- package/src/config/gate-coverage.yml +29 -8
- package/src/config/gate-violation-baselines.json +8 -8
- package/src/config/gitignore-block.txt +19 -0
- package/src/config/host-injection-effect.json +73 -0
- package/src/config/packed-binary-manifest.json +33 -0
- package/src/config/preamble-payload-budget.json +112 -105
- package/src/config/publish-surface.json +4 -2
- package/src/install/claudeLayerCarriage.ts +273 -0
- package/src/install/claudePathsPlan.ts +76 -0
- package/src/install/hostLayerFingerprint.ts +1 -1
- package/src/install/partitionEligibility.ts +261 -127
- package/src/install/ruleLayerPartition.ts +19 -23
- package/src/scripts/_dispatch.bash +77 -27
- package/src/scripts/_lib/auto_dispatch.ts +2 -2
- package/src/scripts/_lib/catalogue_layer_parity.ts +146 -0
- package/src/scripts/_lib/continuity_surface.ts +296 -0
- package/src/scripts/_lib/corpus_manifest.ts +26 -9
- package/src/scripts/_lib/hook_settings.ts +1 -1
- package/src/scripts/_lib/injection_effect.ts +151 -0
- package/src/scripts/_lib/layer_overlap_notice.ts +50 -6
- package/src/scripts/_lib/packed_binary_predicate.ts +225 -0
- package/src/scripts/_lib/pin_resolver.ts +13 -0
- package/src/scripts/_lib/regression_neighbourhood.ts +1 -1
- package/src/scripts/_lib/retired_status.ts +74 -0
- package/src/scripts/_lib/skill_catalogue.ts +156 -21
- package/src/scripts/_lib/subagent_capsule.ts +117 -8
- package/src/scripts/ai_council/api_transport.ts +5 -0
- package/src/scripts/ai_council/deliberation_metrics.ts +353 -0
- package/src/scripts/ai_council/prompts.ts +9 -0
- package/src/scripts/ai_council/synthesis_disagreement.ts +206 -0
- package/src/scripts/capture_skill_catalogue.ts +24 -11
- package/src/scripts/check_candidate_lines.ts +499 -0
- package/src/scripts/check_continuity_surface.ts +475 -0
- package/src/scripts/check_dependency_floors.ts +13 -6
- package/src/scripts/check_estate_count.ts +40 -79
- package/src/scripts/check_pack_size.ts +262 -23
- package/src/scripts/check_roadmap_trackable.ts +19 -16
- package/src/scripts/check_rule_layer_partition.ts +54 -34
- package/src/scripts/check_single_delivery.ts +97 -31
- package/src/scripts/check_update_banner.ts +13 -0
- package/src/scripts/code_graph/build.ts +138 -15
- package/src/scripts/code_graph/cli.ts +76 -8
- package/src/scripts/code_graph/extract.ts +11 -0
- package/src/scripts/code_graph/grammar_probe.ts +43 -0
- package/src/scripts/code_graph/loader.ts +88 -14
- package/src/scripts/code_graph/query.ts +121 -11
- package/src/scripts/code_graph/resolution_tiers.ts +238 -0
- package/src/scripts/code_graph/sqlite_store.ts +247 -6
- package/src/scripts/code_graph/types.ts +66 -1
- package/src/scripts/code_graph/validate.ts +23 -0
- package/src/scripts/condense.ts +34 -22
- package/src/scripts/corpus_manifest.ts +5 -5
- package/src/scripts/council_cli.ts +11 -12
- package/src/scripts/count_intent_disagreement.ts +426 -0
- package/src/scripts/handoff_context_hook.ts +79 -0
- package/src/scripts/hook_effect_doctor.ts +82 -1
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +64 -12
- package/src/scripts/hooks/chain_nudge_hook.ts +282 -0
- package/src/scripts/hooks/code_graph_context_hook.ts +212 -0
- package/src/scripts/hooks/concern_registry.ts +4 -2
- package/src/scripts/hooks/host_semantics.ts +1 -1
- package/src/scripts/hooks/orchestration_record_hook.ts +2 -2
- package/src/scripts/hooks/rule_inject_hook.ts +1 -1
- package/src/scripts/hooks/skill_route_hook.ts +11 -4
- package/src/scripts/inbox_source_census.ts +322 -0
- package/src/scripts/install-hooks.sh +82 -0
- package/src/scripts/{lint_carrier_integrity.ts → lint_deferral_integrity.ts} +60 -214
- package/src/scripts/lint_plan_risk_register.ts +13 -17
- package/src/scripts/mcp_server/suggest_skill.ts +72 -0
- package/src/scripts/mcp_server/tools.ts +2 -56
- package/src/scripts/media/lib/adapter-contract.md +7 -2
- package/src/scripts/media/lib/fixtures/flux/asset-0001.png +0 -0
- package/src/scripts/media/lib/fixtures/gemini-image/asset-0001.png +0 -0
- package/src/scripts/media/lib/fixtures/ideogram/asset-0001.png +0 -0
- package/src/scripts/rdp_candidates_delta.ts +276 -0
- package/src/scripts/rdp_quality_eval.ts +217 -19
- package/src/scripts/release_mix_taxonomy.json +3 -2
- package/src/scripts/report_host_injection_effect.ts +189 -0
- package/src/scripts/report_layer_overlap.ts +41 -0
- package/src/scripts/report_skill_menu_census.ts +341 -0
- package/src/scripts/skill_tools/score_skill_relevance.ts +70 -6
- package/src/scripts/skill_tools/suggest_skill_for_task.ts +37 -3
- package/src/vendor/grammars/README.md +61 -0
- package/src/vendor/grammars/tree-sitter-javascript.wasm +0 -0
- package/src/vendor/grammars/tree-sitter-php.wasm +0 -0
- package/src/vendor/grammars/tree-sitter-typescript.wasm +0 -0
- package/src/scripts/_lib/carrier_status.ts +0 -118
- package/src/scripts/_lib/estate_carrier_cases.ts +0 -72
- package/src/scripts/hooks/code_graph_nudge_hook.ts +0 -191
package/dist/scripts/condense.js
CHANGED
|
@@ -232,9 +232,9 @@ export { rule_in_scope } from '../install/ruleInScope.js';
|
|
|
232
232
|
export { CLAUDE_PATHS_PATTERN_BUDGET, _claude_paths_plan, _escape_claude_bracket, _expanded_pattern_count, _has_non_path_trigger, _is_unresolved_placeholder, derive_trigger_globs, } from '../install/claudePathsPlan.js';
|
|
233
233
|
import { rule_in_scope } from '../install/ruleInScope.js';
|
|
234
234
|
import { pruneEmptyDirs } from './_lib/prune_empty_dirs.js';
|
|
235
|
-
import {
|
|
235
|
+
import { claudeLayerHolds, commandWithheld, keepInProjectLayer, personaPartition } from '../install/partitionEligibility.js'; // ADR-236
|
|
236
236
|
import { dedupableRules, partitionRulesForDir } from '../install/ruleLayerPartition.js'; // ADR-236, per-host evidence
|
|
237
|
-
import { _claude_paths_plan, derive_trigger_globs } from '../install/claudePathsPlan.js';
|
|
237
|
+
import { _claude_paths_plan, applies_when, derive_trigger_globs } from '../install/claudePathsPlan.js';
|
|
238
238
|
const _HERE = path.dirname(fileURLToPath(import.meta.url)); // <repo>/src/scripts
|
|
239
239
|
const _DEFAULT_PROJECT_ROOT = path.resolve(_HERE, '..', '..');
|
|
240
240
|
function _deriveState(root) {
|
|
@@ -263,7 +263,6 @@ function _deriveState(root) {
|
|
|
263
263
|
};
|
|
264
264
|
}
|
|
265
265
|
export const MODULE_STATE = _deriveState(_DEFAULT_PROJECT_ROOT);
|
|
266
|
-
setPartitionAnnounce(success); // ADR-236: the mode line must be visible at the default level
|
|
267
266
|
/**
|
|
268
267
|
* Test seam — reassign one or more module-state fields, mirroring the pytest
|
|
269
268
|
* monkeypatch of `condense.<NAME> = ...`. When `PROJECT_ROOT` is overridden,
|
|
@@ -1149,7 +1148,7 @@ export function _emit_cursor_mdc(source, target) {
|
|
|
1149
1148
|
const globs = always_apply ? [] : derive_trigger_globs(meta);
|
|
1150
1149
|
const lines = [
|
|
1151
1150
|
'---',
|
|
1152
|
-
`description: ${_yaml_scalar(description)}`,
|
|
1151
|
+
`description: ${_yaml_scalar(always_apply ? description : applies_when(description, meta))}`,
|
|
1153
1152
|
`globs: ${globs.join(',')}`,
|
|
1154
1153
|
`alwaysApply: ${always_apply ? 'true' : 'false'}`,
|
|
1155
1154
|
'---',
|
|
@@ -1170,7 +1169,7 @@ export function _emit_windsurf_rule(source, target) {
|
|
|
1170
1169
|
const lines = [
|
|
1171
1170
|
'---',
|
|
1172
1171
|
`trigger: ${trigger}`,
|
|
1173
|
-
`description: ${_yaml_scalar(description)}`,
|
|
1172
|
+
`description: ${_yaml_scalar(always_apply ? description : applies_when(description, meta))}`,
|
|
1174
1173
|
`globs: ${globs.join(',')}`,
|
|
1175
1174
|
'---',
|
|
1176
1175
|
'',
|
|
@@ -1448,23 +1447,21 @@ function _render_native_model_md(src_md, tier) {
|
|
|
1448
1447
|
return text.replace(_MODEL_TIER_RE, `model: ${model}`);
|
|
1449
1448
|
}
|
|
1450
1449
|
export function generate_claude_skills(active_skill_names = null) {
|
|
1451
|
-
if (partitionActive(MODULE_STATE.PROJECT_ROOT))
|
|
1452
|
-
active_skill_names = new Set();
|
|
1453
1450
|
if (!_exists(MODULE_STATE.SKILLS_SOURCE)) {
|
|
1454
1451
|
process.stderr.write(' ⚠️ dist/agent-src/skills/ not found — skipping skills\n');
|
|
1455
1452
|
return 0;
|
|
1456
1453
|
}
|
|
1457
|
-
|
|
1454
|
+
const all_skills = _iterdirSorted(MODULE_STATE.SKILLS_SOURCE)
|
|
1458
1455
|
.filter((p) => _isDir(p))
|
|
1459
1456
|
.map((p) => path.basename(p))
|
|
1460
1457
|
.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
|
|
1458
|
+
// ADR-236: withhold every skill `~/.claude/skills` holds — see `keepInProjectLayer`.
|
|
1459
|
+
let skills = keepInProjectLayer('skills', all_skills);
|
|
1461
1460
|
if (active_skill_names !== null) {
|
|
1462
1461
|
skills = skills.filter((s) => active_skill_names.has(s));
|
|
1463
1462
|
}
|
|
1464
1463
|
const skill_set = new Set(skills);
|
|
1465
|
-
const command_slugs =
|
|
1466
|
-
? new Set()
|
|
1467
|
-
: new Set([...iterCommands()].map(([, slug]) => slug));
|
|
1464
|
+
const command_slugs = _emitted_wrapper_slugs(new Set(all_skills));
|
|
1468
1465
|
_mkdirp(MODULE_STATE.CLAUDE_SKILLS_DIR);
|
|
1469
1466
|
const auto = _read_model_auto_switch() === 'auto';
|
|
1470
1467
|
for (const item of _iterdirSorted(MODULE_STATE.CLAUDE_SKILLS_DIR)) {
|
|
@@ -1549,6 +1546,17 @@ function _nested_command_subpath(source_file) {
|
|
|
1549
1546
|
const sub = logical.slice('commands/'.length).replace(/\.md$/, '');
|
|
1550
1547
|
return sub.includes('/') ? sub : null;
|
|
1551
1548
|
}
|
|
1549
|
+
/** The emitter's four skips, in one place — see `emittedWrapperSlugs`. */
|
|
1550
|
+
const _wrapper_is_emitted = (f, s, skills) => !skills.has(s) &&
|
|
1551
|
+
_nested_command_subpath(f) === null &&
|
|
1552
|
+
!is_claude_builtin_name(s) &&
|
|
1553
|
+
!claudeLayerHolds('skills', s);
|
|
1554
|
+
/** Wrapper slugs the command emitter really writes — see `emittedWrapperSlugs`. */
|
|
1555
|
+
function _emitted_wrapper_slugs(skill_names) {
|
|
1556
|
+
return new Set([...iterCommands()]
|
|
1557
|
+
.filter(([f, s]) => _wrapper_is_emitted(f, s, skill_names))
|
|
1558
|
+
.map(([, slug]) => slug));
|
|
1559
|
+
}
|
|
1552
1560
|
/**
|
|
1553
1561
|
* Project-scope `.claude/commands/<cluster>/<sub>.md` — the colon form.
|
|
1554
1562
|
*
|
|
@@ -1561,15 +1569,12 @@ function _nested_command_subpath(source_file) {
|
|
|
1561
1569
|
*
|
|
1562
1570
|
* Emitting the nested form here lets `generate_claude_commands` stop wrapping
|
|
1563
1571
|
* the clustered commands: one listing, same reachability, and reachability no
|
|
1564
|
-
* longer depends on a global deploy. Dedup AND precedence: `
|
|
1572
|
+
* longer depends on a global deploy. Dedup AND precedence: `commandWithheld`.
|
|
1565
1573
|
*
|
|
1566
1574
|
* ADR-003 (colon canonical for clusters) and ADR-044 (flat commands stay
|
|
1567
1575
|
* hyphenated) both hold: flat commands are untouched and keep their wrapper.
|
|
1568
1576
|
*/
|
|
1569
1577
|
export function generate_claude_project_commands(active_command_slugs = null) {
|
|
1570
|
-
if (commandsWithheld(MODULE_STATE.PROJECT_ROOT))
|
|
1571
|
-
active_command_slugs = new Set();
|
|
1572
|
-
// Returns before the stale sweep — invariant, see `commandsWithheld`.
|
|
1573
1578
|
if (!_isDir(path.join(MODULE_STATE.PROJECT_ROOT, 'src', 'domains'))) {
|
|
1574
1579
|
return 0;
|
|
1575
1580
|
}
|
|
@@ -1579,7 +1584,7 @@ export function generate_claude_project_commands(active_command_slugs = null) {
|
|
|
1579
1584
|
continue;
|
|
1580
1585
|
}
|
|
1581
1586
|
const sub = _nested_command_subpath(source_file);
|
|
1582
|
-
if (sub !== null) {
|
|
1587
|
+
if (sub !== null && !commandWithheld(`${sub}.md`)) {
|
|
1583
1588
|
nested.push([source_file, sub]);
|
|
1584
1589
|
}
|
|
1585
1590
|
}
|
|
@@ -1613,8 +1618,6 @@ export function generate_claude_project_commands(active_command_slugs = null) {
|
|
|
1613
1618
|
return count;
|
|
1614
1619
|
}
|
|
1615
1620
|
export function generate_claude_commands(active_command_slugs = null) {
|
|
1616
|
-
if (partitionActive(MODULE_STATE.PROJECT_ROOT))
|
|
1617
|
-
active_command_slugs = new Set();
|
|
1618
1621
|
if (!_isDir(path.join(MODULE_STATE.PROJECT_ROOT, 'src', 'domains'))) {
|
|
1619
1622
|
process.stderr.write(' ⚠️ src/domains/ not found — skipping commands\n');
|
|
1620
1623
|
return 0;
|
|
@@ -1630,6 +1633,7 @@ export function generate_claude_commands(active_command_slugs = null) {
|
|
|
1630
1633
|
let count = 0;
|
|
1631
1634
|
let skipped = 0;
|
|
1632
1635
|
let reserved = 0;
|
|
1636
|
+
let withheld = 0;
|
|
1633
1637
|
let rendered = 0;
|
|
1634
1638
|
const auto = _read_model_auto_switch() === 'auto';
|
|
1635
1639
|
for (const [source_file, slug] of iterCommands()) {
|
|
@@ -1658,6 +1662,12 @@ export function generate_claude_commands(active_command_slugs = null) {
|
|
|
1658
1662
|
reserved += 1;
|
|
1659
1663
|
continue;
|
|
1660
1664
|
}
|
|
1665
|
+
// ADR-236 per-name: the INSTALLER re-projects visible flat commands as
|
|
1666
|
+
// `~/.claude/skills/<slug>/SKILL.md` (install.ts:_apply_claude_flat_command_wrappers).
|
|
1667
|
+
if (claudeLayerHolds('skills', slug)) {
|
|
1668
|
+
withheld += 1;
|
|
1669
|
+
continue;
|
|
1670
|
+
}
|
|
1661
1671
|
current_slugs.add(slug);
|
|
1662
1672
|
const skill_dir = path.join(MODULE_STATE.CLAUDE_SKILLS_DIR, slug);
|
|
1663
1673
|
_mkdirp(skill_dir);
|
|
@@ -1706,6 +1716,9 @@ export function generate_claude_commands(active_command_slugs = null) {
|
|
|
1706
1716
|
if (reserved) {
|
|
1707
1717
|
msg += ` (${reserved} withheld — Claude Code built-in name)`;
|
|
1708
1718
|
}
|
|
1719
|
+
if (withheld > 0) {
|
|
1720
|
+
msg += ` (${withheld} withheld — ~/.claude/skills carries the wrapper)`;
|
|
1721
|
+
}
|
|
1709
1722
|
if (removed_dirs) {
|
|
1710
1723
|
msg += ` (${removed_dirs} stale dirs removed)`;
|
|
1711
1724
|
}
|
|
@@ -2019,19 +2032,13 @@ export function generate_persona_symlinks() {
|
|
|
2019
2032
|
_print(' ⚠️ dist/agent-src/personas/ not found — skipping personas');
|
|
2020
2033
|
return 0;
|
|
2021
2034
|
}
|
|
2022
|
-
const personas = _rglobSorted(MODULE_STATE.PERSONAS_SOURCE, '*.md')
|
|
2023
|
-
.filter((p) => _isFile(p) && path.basename(p, '.md') !== 'README')
|
|
2024
|
-
.map((p) => path.basename(p))
|
|
2025
|
-
// glob('*.md') is non-recursive in Python; mirror that — only top level.
|
|
2026
|
-
.filter((name) => _isFile(path.join(MODULE_STATE.PERSONAS_SOURCE, name)));
|
|
2027
2035
|
// Python uses PERSONAS_SOURCE.glob("*.md") (non-recursive). Re-derive
|
|
2028
2036
|
// from a direct listing to match exactly.
|
|
2029
2037
|
const direct = _iterdirSorted(MODULE_STATE.PERSONAS_SOURCE)
|
|
2030
2038
|
.filter((p) => p.endsWith('.md') && _isFile(p) && path.basename(p, '.md') !== 'README')
|
|
2031
2039
|
.map((p) => path.basename(p))
|
|
2032
2040
|
.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
|
|
2033
|
-
|
|
2034
|
-
const partition = personaPartition(MODULE_STATE.PROJECT_ROOT, direct);
|
|
2041
|
+
const partition = personaPartition(direct);
|
|
2035
2042
|
const tool_dirs = _filter_tool_dirs(PERSONA_TOOL_DIRS);
|
|
2036
2043
|
let total = 0;
|
|
2037
2044
|
for (const [tool_dir, rel_prefix] of Object.entries(tool_dirs)) {
|
package/docs/MIGRATION.md
CHANGED
|
@@ -17,7 +17,7 @@ releaser here on every `release:major`.
|
|
|
17
17
|
| Surface | Committed | Deprecation notice due | Removal due | Reversal condition |
|
|
18
18
|
|---|---|---|---|---|
|
|
19
19
|
| Free-text `compatibility` skill-frontmatter field (`src/scripts/schemas/skill.schema.json`) | 2026-08-14 | shipped 2026-08-14 — `deprecated: true` + superseded-by note in the schema; `harness_compat` lands beside it, additively | next major after the notice — **not pinned here** (removal date is maintainer-owned, same stance as the manifest `tier` entry, whose `sunset` shipped `null`) | The public Agent-Skills spec makes `compatibility` load-bearing for cross-host portability, or an external consumer is found reading it. `harness_compat` is package-local; `compatibility` mirrors the public spec, so keeping the mirror stays cheaply reversible. Superseded by `harness_compat` (class) + `runtime_requires` (probeable detail); both users (`docx-authoring`, `pdf-tools`) already carry both fields, so nothing breaks on removal day. |
|
|
20
|
-
| `code_graph` native code-graph engine (`code_graph.enabled`, the `code-intelligence` skill's native arm, `code_graph_nudge_hook`) | 2026-07-28 | next major after 9.x | **REVISED 2026-08-15 — no removal date; see below** | A consumer case the graph answers and disciplined grep cannot. Measured null: recall 0.365 vs grep 0.797 (`docs/CLAIMS.md` `code-graph-retrieval-null`), measured 2026-07-28 against a build predating the 2026-08-22 extractor repair. `enabled: false` stays the DEFAULT — "permanent" is retracted here on 2026-08-26, because this row's own revision below withdraws the removal commitment and a withdrawn schedule cannot leave a permanence behind it. **Revision (ADR-232 track, maintainer decision 2026-08-15).** The original row committed removal to 11.0; the tree reached 12.0.0 with the runtime paths still registered, i.e. the commitment was missed. Rather than quietly re-dating it, the commitment is withdrawn with its reason recorded, because the measurement changed what removal is worth: **the payload this deprecation existed for has already shipped** — the parser pair (`web-tree-sitter@0.24.7` / `tree-sitter-wasms@0.1.13`, ~51 MB unpacked) moved from `dependencies` to `devDependencies` ahead of schedule, so no consumer
|
|
20
|
+
| `code_graph` native code-graph engine (`code_graph.enabled`, the `code-intelligence` skill's native arm, `code_graph_nudge_hook`) | 2026-07-28 | next major after 9.x | **REVISED 2026-08-15 — no removal date; see below** | A consumer case the graph answers and disciplined grep cannot. Measured null: recall 0.365 vs grep 0.797 (`docs/CLAIMS.md` `code-graph-retrieval-null`), measured 2026-07-28 against a build predating the 2026-08-22 extractor repair. `enabled: false` stays the DEFAULT — "permanent" is retracted here on 2026-08-26, because this row's own revision below withdraws the removal commitment and a withdrawn schedule cannot leave a permanence behind it. **Revision (ADR-232 track, maintainer decision 2026-08-15).** The original row committed removal to 11.0; the tree reached 12.0.0 with the runtime paths still registered, i.e. the commitment was missed. Rather than quietly re-dating it, the commitment is withdrawn with its reason recorded, because the measurement changed what removal is worth: **the payload this deprecation existed for has already shipped** — the parser pair (`web-tree-sitter@0.24.7` / `tree-sitter-wasms@0.1.13`, ~51 MB unpacked) moved from `dependencies` to `devDependencies` ahead of schedule, so no consumer installed it. **REVERSED 2026-09-07 by ADR-259 (as amended) — this clause no longer holds and is kept only so the reversal is legible.** Delivery and measurement are decoupled: `web-tree-sitter` is a runtime `dependency` again and the three loadable grammars are vendored at `src/vendor/grammars/`, so a consumer now DOES install the engine. The measured null above is untouched and `enabled: false` stays the default — what changed is that the reopen trigger ("a consumer case the graph answers") became reachable at all, which it was not while no consumer could receive the engine. The install delta is recorded below under "14.21.x — the code-graph engine ships to consumers". What source removal would still free is ~112 K against a 27 M tree (0.4 %). Against that it costs a breaking change across four consumer-visible surfaces (CLI verb, `code-intelligence` skill, `external-code-graph-interop` rule, `hooks.code_graph.enabled`) plus one surface that is re-plumbing rather than deletion: `_lib/auto_dispatch.ts` routes the `definition` / `references` lookup classes to `primitive: 'code-graph-query'`, and `_lib/judgment_ladder.ts` calls that live at Rung 0. There is also no cheap middle — `code_graph/detect.ts` handles the `consumer` / `scip` / `native` source kinds in one type union, so stripping only the native engine while keeping consumer-index interop is a redesign. **New commitment:** the surfaces stay registered and disabled; removal happens when a concrete reason appears (a maintenance cost that bites, a conflicting redesign, or a consumer asking), not on a date. This row stays in the table so the decision is visible rather than forgotten — a withdrawn commitment recorded is not the folklore this table exists to prevent; an unrecorded one would be. |
|
|
21
21
|
| `telegraph-speak` condenser (`telegraph.speak`, `src/rules/telegraph-speak.md`, `src/scripts/_lib/compile_time_toggles.ts`, `src/scripts/validate_telegraph_carveouts.ts`) | 2026-07-29 | shipped 2026-07-29 — dormant by default, `speak` defaults `false` | **not pinned here** — removal is authorized in principle and deliberately not executed (ADR `telegraph/0002` § Decision part 3), pending a `prose_only` bench (~$0.80). The date is maintainer-owned, same stance as the `compatibility` row above | An output-side bench clears the kill-criterion bar, at which point `telegraph.speak: true` restores the feature intact. Measured basis for dormancy: median vs_terse **−9.27 %** (API) / −5.47 % (exact `cl100k_base`) — the condenser emits MORE than a plain "be terse". Tracked as a row rather than left dormant-and-unlisted: dormancy without a row is untracked in *both* directions, neither scheduled nor recorded as a keep. Deliberately NOT a due version (that would invent a commitment ADR 0002 declined to make) and NOT a permanent keep (that would contradict its authorized removal). |
|
|
22
22
|
|
|
23
23
|
### Row status — what is currently late, and who owns it
|
|
@@ -42,6 +42,54 @@ reason, which no arithmetic can.
|
|
|
42
42
|
or that promises a future breaking removal, gets a row here in the same commit
|
|
43
43
|
that makes the promise. A promise with no row is not tracked and will be missed.
|
|
44
44
|
|
|
45
|
+
## 14.21.x — the code-graph engine ships to consumers
|
|
46
|
+
|
|
47
|
+
💡 advisory · 🔄 automatic — no action required.
|
|
48
|
+
|
|
49
|
+
`npm install @event4u/agent-config` now carries everything the native
|
|
50
|
+
code-graph engine needs, so `agent-config code-graph build` works on the next
|
|
51
|
+
command with no manual parser install (ADR-259, as amended 2026-09-07).
|
|
52
|
+
|
|
53
|
+
### What changed
|
|
54
|
+
|
|
55
|
+
- `web-tree-sitter@0.24.7` moved from `devDependencies` to `dependencies`.
|
|
56
|
+
- Three compiled tree-sitter grammars are **vendored** in the published tarball
|
|
57
|
+
at `src/vendor/grammars/` — php, typescript (which also serves `.tsx`), and
|
|
58
|
+
javascript. These are the three `GRAMMAR_WASM` entries the engine can load.
|
|
59
|
+
- `tree-sitter-wasms` stays a `devDependency`. It is the source the vendored
|
|
60
|
+
copies are refreshed from, not a runtime dependency, so consumers do **not**
|
|
61
|
+
receive the 36-grammar pack.
|
|
62
|
+
|
|
63
|
+
### Install delta, measured
|
|
64
|
+
|
|
65
|
+
Measured on 2026-09-07 with `npm pack --dry-run --json --ignore-scripts`,
|
|
66
|
+
against the same tree with the vendored directory excluded from `files[]`:
|
|
67
|
+
|
|
68
|
+
| Axis | Before | After | Delta |
|
|
69
|
+
|---|---|---|---|
|
|
70
|
+
| Compressed tarball | 9,821,600 B | 10,195,522 B | **+373,922 B** (+0.357 MiB) |
|
|
71
|
+
| Vendored grammars, on disk | 0 B | 3,802,618 B | **+3,802,618 B** (+3.63 MiB) |
|
|
72
|
+
| `web-tree-sitter` in `node_modules` | 0 B (dev-only) | ~389,120 B | **+~380 KiB** |
|
|
73
|
+
|
|
74
|
+
Per-grammar, uncompressed: `tree-sitter-php.wasm` 812,594 B ·
|
|
75
|
+
`tree-sitter-typescript.wasm` 2,342,690 B · `tree-sitter-javascript.wasm`
|
|
76
|
+
647,334 B.
|
|
77
|
+
|
|
78
|
+
For contrast, the two rejected shapes: depending on `tree-sitter-wasms`
|
|
79
|
+
directly would have delivered all 36 grammars (51,765,657 B apparent, 49 MiB on
|
|
80
|
+
disk), and the 13-grammar set ADR-259 originally named measures 9,085,798 B
|
|
81
|
+
apparent / 1,016,804 B compressed — the latter would have put the tarball at
|
|
82
|
+
~10.84 MB. Only three grammars are loadable today, so the other ten would have
|
|
83
|
+
been payload with no reader.
|
|
84
|
+
|
|
85
|
+
### Rolling back
|
|
86
|
+
|
|
87
|
+
Set `hooks.code_graph.enabled: false` — which is already the default; the
|
|
88
|
+
engine ships disabled. Nothing runs the parsers unless you build a graph. To
|
|
89
|
+
drop the payload entirely, remove `src/vendor/grammars/` from `files[]` and
|
|
90
|
+
move `web-tree-sitter` back to `devDependencies`; the loader falls back to the
|
|
91
|
+
`tree-sitter-wasms` pack, which is this repository's own dev path.
|
|
92
|
+
|
|
45
93
|
## 8.x → 9.0.0 — consumer rule projection scoped by default
|
|
46
94
|
|
|
47
95
|
9.0.0 flips the consumer rule-projection default to **scoped**: fresh
|
|
@@ -558,7 +558,7 @@ Rows follow template order, so a diff against the template reads straight down.
|
|
|
558
558
|
| `hooks.runtime_journal.enabled` | C | `false` | configures code that runs on every dispatched hook event | consent |
|
|
559
559
|
| `hooks.ui_route_nudge.enabled` | C | `false` | configures code that runs on every tool call | derivable — the UI-surface predicate plus the hook's own two-nudges-per-session cap |
|
|
560
560
|
| `hooks.design_pass.enabled` | C | `false` | C-test 1 — it configures code that runs on every tool call and at every turn end, and unlike its two `hooks.*` neighbours its stop pass can BLOCK rather than warn | policy — whether an operator accepts a gate that can refuse a turn is a risk preference, not a fact the tree can compute. The two neighbours are `derivable` because they only ever warn; the block is the discriminator. `road-to-frontend-power` transfers the default flip to the owner for the same reason |
|
|
561
|
-
| `hooks.code_graph.enabled` | C | `false` |
|
|
561
|
+
| `hooks.code_graph.enabled` | C | `false` | INERT since 2026-09-07 — the nudge it gated was replaced by `code-graph-context`, which reads no flag. The KEY stays registered because `docs/MIGRATION.md` commits to exactly that ("the surfaces stay registered and disabled"): removing it is a breaking change for any consumer who set it, and the row was briefly marked REMOVED, which left the template's own leaf unclassified. Classified, not deleted. | derivable — the index-detection probe the replacement hook already runs; no index means silence |
|
|
562
562
|
| `hooks.suggestion_capture.enabled` | C | `false` | configures code that runs at every turn end and every prompt | consent |
|
|
563
563
|
| `decision_engine.surface_traces` | C | `false` | the decision engine’s own black box; the agent must not be able to close it | derivable — the engine's own active-gate state; there is nothing to surface when no gate fired |
|
|
564
564
|
| `decision_engine.min_confidence` | C | `"off"` | the confidence gate | derivable — the confidence band the scoring engine already computes at the plan phase |
|
|
@@ -166,3 +166,76 @@ reviewer has to untangle.
|
|
|
166
166
|
|
|
167
167
|
- `minimal-safe-diff` (rule) — Iron Law, the rule, the pre-fix shared-path repair clause, own-orphan cleanup. The pre-diff checklist, the red-flag catalog and the when-in-doubt line live HERE since A1.
|
|
168
168
|
- [`active-remediation-mechanics`](active-remediation-mechanics.md) — the fix-now / note+ask / follow-up-PR ladder detail.
|
|
169
|
+
|
|
170
|
+
## Re-derive the requirement, don't inherit the shape
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
A REPAIR INHERITS THE SHAPE OF WHAT IT REPAIRS UNLESS YOU ASK OTHERWISE.
|
|
174
|
+
STATE THE REQUIREMENT IN ONE LINE, THEN ASK WHETHER THE CURRENT FORM
|
|
175
|
+
*CAN* EXPRESS IT. A FORM THAT CANNOT IS NOT A PARAMETER BUG.
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Applies to a downstream repair — clearing a red, or fixing what your own diff
|
|
179
|
+
broke — where the smallest change is a different VALUE and the form is
|
|
180
|
+
unexamined.
|
|
181
|
+
|
|
182
|
+
### Why this is a guideline section and not a rule clause
|
|
183
|
+
|
|
184
|
+
It was drafted as a clause in `minimal-safe-diff` on 2026-09-07 and moved here
|
|
185
|
+
the same day, on the gate's own evidence rather than on preference.
|
|
186
|
+
`check_preamble_payload_budget` measured the clause at +460 delivered tokens,
|
|
187
|
+
then +271, then +180 after two rounds of cutting — a floor set by the Iron-Law
|
|
188
|
+
block itself. That payload is re-written on EVERY subagent spawn, and the rule it
|
|
189
|
+
would have lived in is `type: auto`: it fires on prompt keywords, not on tool
|
|
190
|
+
output, so a red test nobody mentioned never loads it.
|
|
191
|
+
|
|
192
|
+
Certain per-spawn cost against an activation path that misses the case the clause
|
|
193
|
+
was written for is a bad trade, and the deterministic half does not depend on it
|
|
194
|
+
— see § Honest limit below. The rule already routes here
|
|
195
|
+
(`routes_to: guideline:agent-infra/minimal-safe-diff-mechanics`), which is the
|
|
196
|
+
same reachability every other migrated body in this repository has.
|
|
197
|
+
|
|
198
|
+
### Worked failure — 2026-09-07
|
|
199
|
+
|
|
200
|
+
A change emptied `<repo>/.claude/skills` of skills and left ~49 flat-command
|
|
201
|
+
wrappers behind. `resolveSkillsRoot` tried two workspace-relative roots and took
|
|
202
|
+
the first non-empty one, so it resolved the wrappers, and the skill ranker ranked
|
|
203
|
+
49 command wrappers instead of 299 skills.
|
|
204
|
+
|
|
205
|
+
The repair chosen was to swap the ORDER of the two roots. The requirement was
|
|
206
|
+
*"rank every catalogue the session can reach"*, which **no ordering of a
|
|
207
|
+
first-hit loop can satisfy** — and the host-global root the whole task was about
|
|
208
|
+
appeared in neither position. The evidence had been measured an hour earlier and
|
|
209
|
+
sat in the same session's own notes: `~/.claude/skills` 307, `.claude/skills` 49,
|
|
210
|
+
`src/skills` 299.
|
|
211
|
+
|
|
212
|
+
Two things made it easy to miss, and both are the shape of the trap rather than
|
|
213
|
+
this instance of it:
|
|
214
|
+
|
|
215
|
+
- **The docstring framed the question.** It read *"First existing catalogue root
|
|
216
|
+
… `.claude/skills` before `src/skills` because a CONSUMER install carries the
|
|
217
|
+
former"* — i.e. it asked *which root wins*, and that question was answered. A
|
|
218
|
+
docstring records what the code decided; it never records whether that was the
|
|
219
|
+
decision to make.
|
|
220
|
+
- **The same docstring contained the premise of the correct answer.** If
|
|
221
|
+
consumers carry their own skills *and* the package ships skills, both must be
|
|
222
|
+
read. The sentence was read, used to justify an ordering, and its consequence
|
|
223
|
+
was not drawn.
|
|
224
|
+
|
|
225
|
+
### Why the pre-work rules do not cover it
|
|
226
|
+
|
|
227
|
+
[`improve-before-implement`](../../../src/rules/improve-before-implement.md) does
|
|
228
|
+
not activate for bug fixes ("the problem is already defined") and
|
|
229
|
+
[`invite-challenge`](../../../src/rules/invite-challenge.md) excludes "evidenced
|
|
230
|
+
bug fixes". Both exclusions are right for the case they were written for and
|
|
231
|
+
wrong for a downstream repair, which presents as a defined problem while its
|
|
232
|
+
definition came from the broken code.
|
|
233
|
+
|
|
234
|
+
### Honest limit
|
|
235
|
+
|
|
236
|
+
The rule is `type: auto`, so it fires on prompt keywords and not on tool output:
|
|
237
|
+
a red test nobody prompted about does not load it. The clause is the
|
|
238
|
+
model-carried half. The deterministic half is a comparison of the two lists that
|
|
239
|
+
diverged — `tests/contracts/catalogue_layer_parity.test.ts`, which reds when a
|
|
240
|
+
directory the delivery side treats as an artifact source is not a root the reader
|
|
241
|
+
reads, and which was measured to catch this exact defect on the pre-change tree.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@event4u/agent-config",
|
|
3
3
|
"mcpName": "io.github.event4u-app/agent-config",
|
|
4
|
-
"version": "14.
|
|
4
|
+
"version": "14.22.0",
|
|
5
5
|
"description": "Governed skills, rules and commands for AI coding tools (Claude Code, Cursor, Windsurf, Copilot) — every claim machine-checked, including the counts in these badges.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"private": false,
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"src/agent-src/scripts/",
|
|
49
49
|
"src/agent-src/templates/scripts/",
|
|
50
50
|
"src/templates/",
|
|
51
|
+
"src/vendor/grammars/",
|
|
51
52
|
"tests/fixtures/hooks/",
|
|
52
53
|
"AGENTS.md",
|
|
53
54
|
"CHANGELOG.md",
|
|
@@ -80,13 +81,15 @@
|
|
|
80
81
|
"build:hooks": "esbuild src/scripts/hooks/dispatch_entry.ts --bundle --platform=node --format=esm --target=node20 --define:__AGENT_CONFIG_BUNDLE__=true --outfile=dist/hooks/dispatch.js --banner:js=\"import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url); const __acPath = require('node:path'); const __acFs = require('node:fs'); const __acUrl = require('node:url'); const __acReal = (p) => { try { return __acFs.realpathSync(p); } catch { return p; } }; const __acSelf = __acReal(__acUrl.fileURLToPath(import.meta.url)); if (process.argv[1] !== undefined && __acReal(__acPath.resolve(process.argv[1])) === __acSelf) { globalThis.__AC_HOOKS_BUNDLE_DIRECT = true; process.argv = [process.argv[0], __acSelf + '.__direct__', ...process.argv.slice(2)]; }\"",
|
|
81
82
|
"build:mcp-bundle": "esbuild src/scripts/mcp_server/__main__.ts --bundle --platform=node --format=esm --target=node20 --define:__AGENT_CONFIG_BUNDLE__=true --outfile=dist/mcp/server.mjs --banner:js=\"import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url); const __acPath = require('node:path'); const __acFs = require('node:fs'); const __acUrl = require('node:url'); const __acReal = (p) => { try { return __acFs.realpathSync(p); } catch { return p; } }; const __acSelf = __acReal(__acUrl.fileURLToPath(import.meta.url)); if (process.argv[1] !== undefined && __acReal(__acPath.resolve(process.argv[1])) === __acSelf) { globalThis.__AC_MCP_BUNDLE_DIRECT = true; process.argv = [process.argv[0], __acSelf + '.__direct__', ...process.argv.slice(2)]; }\"",
|
|
82
83
|
"build:cli-delegate": "esbuild src/scripts/_cli/cmd_*.ts --bundle --splitting --platform=node --format=esm --target=node20 --define:__AGENT_CONFIG_BUNDLE__=true --define:__AGENT_CONFIG_CLI_DELEGATE__=true --outdir=dist/cli-delegate --banner:js=\"import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url);\"",
|
|
84
|
+
"build:agent-src-delegate": "esbuild src/agent-src/scripts/*.ts --bundle --splitting --platform=node --format=esm --target=node20 --define:__AGENT_CONFIG_BUNDLE__=true --define:__AGENT_CONFIG_CLI_DELEGATE__=true --outdir=dist/cli-delegate --banner:js=\"import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url);\"",
|
|
85
|
+
"build:delegate-aux": "esbuild src/scripts/_lib/pin_resolver.ts src/scripts/check_update_banner.ts --bundle --splitting --platform=node --format=esm --target=node20 --define:__AGENT_CONFIG_BUNDLE__=true --define:__AGENT_CONFIG_CLI_DELEGATE__=true --outbase=src/scripts --outdir=dist/cli-delegate --banner:js=\"import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url);\"",
|
|
83
86
|
"build:ui": "vite build",
|
|
84
87
|
"tokens:build": "node tokens/build-ac.mjs && node tokens/build-as.mjs",
|
|
85
88
|
"tokens:check": "node tokens/build-ac.mjs --check && node tokens/build-as.mjs --check && node tokens/check-contrast.mjs",
|
|
86
89
|
"build:discovery": "./scripts-run src/scripts/build_discovery_manifest --write --strict",
|
|
87
90
|
"build:mcp-manifest": "./scripts-run src/scripts/build_mcp_registry_manifest --write --strict",
|
|
88
91
|
"build:mcp-catalog": "./scripts-run src/scripts/build_mcp_catalog --write --strict",
|
|
89
|
-
"build": "npm run build:cli && npm run build:install-bundle && npm run build:hooks && npm run build:mcp-bundle && npm run build:cli-delegate && npm run build:ui",
|
|
92
|
+
"build": "npm run build:cli && npm run build:install-bundle && npm run build:hooks && npm run build:mcp-bundle && npm run build:cli-delegate && npm run build:agent-src-delegate && npm run build:delegate-aux && npm run build:ui",
|
|
90
93
|
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.scripts.json",
|
|
91
94
|
"lint:ts": "eslint --cache --max-warnings 0 'src/**/*.ts'",
|
|
92
95
|
"test:ts": "vitest run",
|
|
@@ -116,8 +119,7 @@
|
|
|
116
119
|
"tsx": "^4.23.1",
|
|
117
120
|
"typescript": "^5.9.3",
|
|
118
121
|
"vite": "^5.4.21",
|
|
119
|
-
"vitest": "^2.1.9"
|
|
120
|
-
"web-tree-sitter": "0.24.7"
|
|
122
|
+
"vitest": "^2.1.9"
|
|
121
123
|
},
|
|
122
124
|
"dependencies": {
|
|
123
125
|
"@fastify/static": "^10.1.2",
|
|
@@ -129,6 +131,7 @@
|
|
|
129
131
|
"js-yaml": "^5.2.0",
|
|
130
132
|
"open": "^11.0.0",
|
|
131
133
|
"preact": "^10.29.0",
|
|
134
|
+
"web-tree-sitter": "0.24.7",
|
|
132
135
|
"yaml": "^2.9.0",
|
|
133
136
|
"zod": "^3.25.0",
|
|
134
137
|
"zod-to-json-schema": "^3.25.0"
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Was this module invoked as the command?" — one definition for the scripts
|
|
3
|
+
* under `agents/scripts` that both run directly and are imported by siblings.
|
|
4
|
+
*
|
|
5
|
+
* Five of them carried a byte-identical copy of this logic, and the copies were
|
|
6
|
+
* about to gain a sixth clause each. The interesting part is why the obvious
|
|
7
|
+
* one-liner is not enough:
|
|
8
|
+
*
|
|
9
|
+
* - `--splitting` in `build:agent-src-delegate` can move a module body into a
|
|
10
|
+
* shared chunk, where `import.meta.url` names the CHUNK. The URL comparison
|
|
11
|
+
* then never matches and the command exits 0 having done nothing — measured
|
|
12
|
+
* on `update_roadmap_progress` before this guard existed. Inside the bundle
|
|
13
|
+
* the invoked file name is the reliable signal, so the delegate branch runs
|
|
14
|
+
* first and a miss falls through rather than returning false.
|
|
15
|
+
* - A symlinked invocation (`.augment/scripts` → `dist/agent-src/scripts`, or
|
|
16
|
+
* macOS `/var` → `/private/var`) makes the raw URLs differ: `import.meta.url`
|
|
17
|
+
* is the resolved real path while `argv[1]` keeps the symlink. Hence the
|
|
18
|
+
* realpath comparison last.
|
|
19
|
+
*
|
|
20
|
+
* `moduleUrl` is the caller's own `import.meta.url` — it cannot be read from
|
|
21
|
+
* here, which is why it is a parameter rather than a lookup.
|
|
22
|
+
*/
|
|
23
|
+
import * as fs from 'node:fs';
|
|
24
|
+
import * as path from 'node:path';
|
|
25
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
26
|
+
|
|
27
|
+
/** Defined only by the esbuild delegate builds; `undefined` under tsx and node. */
|
|
28
|
+
declare const __AGENT_CONFIG_CLI_DELEGATE__: boolean | undefined;
|
|
29
|
+
|
|
30
|
+
export function isCliEntry(moduleUrl: string, name: string): boolean {
|
|
31
|
+
const argv1 = process.argv[1];
|
|
32
|
+
if (argv1 === undefined) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
if (
|
|
36
|
+
typeof __AGENT_CONFIG_CLI_DELEGATE__ !== 'undefined' &&
|
|
37
|
+
__AGENT_CONFIG_CLI_DELEGATE__ &&
|
|
38
|
+
path.basename(argv1, '.js') === name
|
|
39
|
+
) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
const argvPath = path.resolve(argv1);
|
|
43
|
+
if (moduleUrl === pathToFileURL(argvPath).href) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
return fs.realpathSync(fileURLToPath(moduleUrl)) === fs.realpathSync(argvPath);
|
|
48
|
+
} catch {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -56,11 +56,13 @@ import { spawnSync } from 'node:child_process';
|
|
|
56
56
|
import * as fs from 'node:fs';
|
|
57
57
|
import * as path from 'node:path';
|
|
58
58
|
import process from 'node:process';
|
|
59
|
-
import { fileURLToPath
|
|
59
|
+
import { fileURLToPath } from 'node:url';
|
|
60
60
|
|
|
61
61
|
import { collect } from './update_roadmap_progress.js';
|
|
62
62
|
import { guardedBaselineProblems, parseGuardedBaselines } from './guarded_baseline.js';
|
|
63
63
|
|
|
64
|
+
import { isCliEntry } from './_cli_entry.js';
|
|
65
|
+
|
|
64
66
|
const _HERE = fileURLToPath(import.meta.url);
|
|
65
67
|
|
|
66
68
|
interface CompletedProcess {
|
|
@@ -638,6 +640,16 @@ function _regen_dashboard(root: string, dry_run: boolean): void {
|
|
|
638
640
|
if (dry_run) {
|
|
639
641
|
return;
|
|
640
642
|
}
|
|
643
|
+
// Inside `dist/cli-delegate/` the twin sits next to us as a precompiled
|
|
644
|
+
// bundle, and plain `node` runs it — the tsx walk below would otherwise
|
|
645
|
+
// reach `npx tsx`, which resolves against the CONSUMER's npm config and
|
|
646
|
+
// hard-fails on a mismatched `engines`/`devEngines` pin (the very class
|
|
647
|
+
// ADR-204 removed from the dispatcher and left standing here).
|
|
648
|
+
const bundledTwin = path.join(path.dirname(_HERE), 'update_roadmap_progress.js');
|
|
649
|
+
if (_isFile(bundledTwin)) {
|
|
650
|
+
spawnSync(process.execPath, [bundledTwin], { cwd: root, encoding: 'utf-8' });
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
641
653
|
const script = path.join(path.dirname(_HERE), 'update_roadmap_progress.ts');
|
|
642
654
|
// Python: `_run([sys.executable, str(script)], root)`; the twin spawns the
|
|
643
655
|
// dashboard generator twin through the same `tsx` runtime, cwd=root.
|
|
@@ -800,28 +812,7 @@ function main(argv?: readonly string[]): number {
|
|
|
800
812
|
return 0;
|
|
801
813
|
}
|
|
802
814
|
|
|
803
|
-
|
|
804
|
-
if (process.argv[1] === undefined) {
|
|
805
|
-
return false;
|
|
806
|
-
}
|
|
807
|
-
const argvUrl = pathToFileURL(path.resolve(process.argv[1])).href;
|
|
808
|
-
if (import.meta.url === argvUrl) {
|
|
809
|
-
return true;
|
|
810
|
-
}
|
|
811
|
-
// A symlinked invocation (e.g. via `.augment/scripts` → `dist/agent-src/scripts`,
|
|
812
|
-
// or macOS /var → /private/var temp dirs) makes the raw URLs differ:
|
|
813
|
-
// import.meta.url is the resolved real path while argv[1] keeps the symlink
|
|
814
|
-
// path. Compare realpaths so the entry guard still fires (without this the
|
|
815
|
-
// archival sweep silently no-ops when run through the symlink).
|
|
816
|
-
try {
|
|
817
|
-
const here = fs.realpathSync(fileURLToPath(import.meta.url));
|
|
818
|
-
const argv = fs.realpathSync(path.resolve(process.argv[1]));
|
|
819
|
-
return here === argv;
|
|
820
|
-
} catch {
|
|
821
|
-
return false;
|
|
822
|
-
}
|
|
823
|
-
}
|
|
824
|
-
if (_isCliEntry() || process.argv[1] === _HERE) {
|
|
815
|
+
if (isCliEntry(import.meta.url, 'archive_completed_roadmaps')) {
|
|
825
816
|
try {
|
|
826
817
|
process.exitCode = main();
|
|
827
818
|
} catch (exc) {
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
*/
|
|
66
66
|
|
|
67
67
|
import * as path from 'node:path';
|
|
68
|
-
import { fileURLToPath
|
|
68
|
+
import { fileURLToPath } from 'node:url';
|
|
69
69
|
import * as fs from 'node:fs';
|
|
70
70
|
import { spawnSync } from 'node:child_process';
|
|
71
71
|
|
|
@@ -80,6 +80,8 @@ import { execute } from './gate_execute.js';
|
|
|
80
80
|
import { listPending } from '../templates/scripts/work_engine/hooks/builtin/staged_confirmation_store.js';
|
|
81
81
|
import type { StagedAction } from '../templates/scripts/work_engine/hooks/builtin/staged_confirmation.js';
|
|
82
82
|
|
|
83
|
+
import { isCliEntry } from './_cli_entry.js';
|
|
84
|
+
|
|
83
85
|
const _HERE = fileURLToPath(import.meta.url);
|
|
84
86
|
|
|
85
87
|
/** Hard wrap for the rendered body — keeps output readable in a narrow pane. */
|
|
@@ -928,26 +930,8 @@ function main(argv?: readonly string[]): number {
|
|
|
928
930
|
return 0;
|
|
929
931
|
}
|
|
930
932
|
|
|
931
|
-
function _isCliEntry(): boolean {
|
|
932
|
-
if (process.argv[1] === undefined) {
|
|
933
|
-
return false;
|
|
934
|
-
}
|
|
935
|
-
const argvPath = path.resolve(process.argv[1]);
|
|
936
|
-
if (import.meta.url === pathToFileURL(argvPath).href) {
|
|
937
|
-
return true;
|
|
938
|
-
}
|
|
939
|
-
// A symlinked invocation (`.augment/scripts` → `dist/agent-src/scripts`, or
|
|
940
|
-
// macOS /var → /private/var) makes the raw URLs differ: import.meta.url is
|
|
941
|
-
// the resolved real path while argv[1] keeps the symlink. Compare realpaths
|
|
942
|
-
// so the entry guard still fires through the projection.
|
|
943
|
-
try {
|
|
944
|
-
return fs.realpathSync(_HERE) === fs.realpathSync(argvPath);
|
|
945
|
-
} catch {
|
|
946
|
-
return false;
|
|
947
|
-
}
|
|
948
|
-
}
|
|
949
933
|
|
|
950
|
-
if (
|
|
934
|
+
if (isCliEntry(import.meta.url, 'roadmap_gates')) {
|
|
951
935
|
process.exitCode = main();
|
|
952
936
|
}
|
|
953
937
|
|
|
@@ -30,7 +30,9 @@
|
|
|
30
30
|
import * as fs from 'node:fs';
|
|
31
31
|
import * as path from 'node:path';
|
|
32
32
|
import process from 'node:process';
|
|
33
|
-
import { fileURLToPath
|
|
33
|
+
import { fileURLToPath } from 'node:url';
|
|
34
|
+
|
|
35
|
+
import { isCliEntry } from './_cli_entry.js';
|
|
34
36
|
|
|
35
37
|
const _HERE = fileURLToPath(import.meta.url);
|
|
36
38
|
|
|
@@ -246,8 +248,9 @@ export function main(argv: string[] = process.argv.slice(2)): number {
|
|
|
246
248
|
}
|
|
247
249
|
}
|
|
248
250
|
|
|
251
|
+
|
|
249
252
|
/* c8 ignore start */
|
|
250
|
-
if (
|
|
253
|
+
if (isCliEntry(import.meta.url, 'roadmap_set_step')) {
|
|
251
254
|
process.exit(main());
|
|
252
255
|
}
|
|
253
256
|
/* c8 ignore stop */
|
|
@@ -42,7 +42,9 @@
|
|
|
42
42
|
*/
|
|
43
43
|
import * as fs from 'node:fs';
|
|
44
44
|
import * as path from 'node:path';
|
|
45
|
-
import { fileURLToPath
|
|
45
|
+
import { fileURLToPath } from 'node:url';
|
|
46
|
+
|
|
47
|
+
import { isCliEntry } from './_cli_entry.js';
|
|
46
48
|
|
|
47
49
|
const STUB_DIR = path.join('agents', 'roadmaps', 'stubs');
|
|
48
50
|
|
|
@@ -459,24 +461,8 @@ export function main(argv: readonly string[] = process.argv.slice(2)): number {
|
|
|
459
461
|
return 0;
|
|
460
462
|
}
|
|
461
463
|
|
|
462
|
-
function _isCliEntry(): boolean {
|
|
463
|
-
if (process.argv[1] === undefined) {
|
|
464
|
-
return false;
|
|
465
|
-
}
|
|
466
|
-
const argvUrl = pathToFileURL(path.resolve(process.argv[1])).href;
|
|
467
|
-
if (import.meta.url === argvUrl) {
|
|
468
|
-
return true;
|
|
469
|
-
}
|
|
470
|
-
try {
|
|
471
|
-
const here = fs.realpathSync(fileURLToPath(import.meta.url));
|
|
472
|
-
const argv = fs.realpathSync(path.resolve(process.argv[1]));
|
|
473
|
-
return here === argv;
|
|
474
|
-
} catch {
|
|
475
|
-
return false;
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
464
|
|
|
479
|
-
if (
|
|
465
|
+
if (isCliEntry(import.meta.url, 'stubs_due')) {
|
|
480
466
|
process.exitCode = main();
|
|
481
467
|
}
|
|
482
468
|
|