@event4u/agent-config 14.5.0 → 14.7.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 +384 -3
- package/README.md +1 -1
- package/dist/agent-src/commands/analyze/decision.md +7 -0
- package/dist/agent-src/commands/analyze/inbox.md +264 -10
- package/dist/agent-src/commands/analyze.md +1 -1
- package/dist/agent-src/commands/optimize/project.md +10 -0
- package/dist/agent-src/commands/roadmap/process-full.md +132 -4
- package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +31 -0
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +161 -1
- package/dist/agent-src/rules/context-hygiene.md +2 -0
- package/dist/agent-src/rules/decision-revisit-gate.md +111 -7
- package/dist/agent-src/rules/fix-what-you-see.md +108 -0
- package/dist/agent-src/rules/no-roadmap-references.md +0 -5
- package/dist/agent-src/rules/recurring-criticism.md +110 -0
- package/dist/agent-src/rules/roadmap-progress-sync.md +1 -1
- package/dist/agent-src/rules/rule-type-governance.md +0 -2
- package/dist/agent-src/rules/self-repair-loop.md +17 -0
- package/dist/agent-src/rules/skill-quality.md +0 -2
- package/dist/agent-src/rules/source-confidentiality.md +37 -7
- package/dist/agent-src/scripts/archival_sweep.ts +117 -0
- package/dist/agent-src/scripts/archive_completed_roadmaps.ts +19 -3
- package/dist/agent-src/scripts/gate_budget.ts +282 -0
- package/dist/agent-src/scripts/gate_execute.ts +72 -31
- package/dist/agent-src/scripts/roadmap_gates.ts +74 -3
- package/dist/agent-src/scripts/update_roadmap_progress.ts +251 -7
- package/dist/agent-src/skills/adr-create/SKILL.md +25 -3
- package/dist/agent-src/skills/ai-council/SKILL.md +48 -807
- package/dist/agent-src/skills/ai-council/references/advanced-modes.md +320 -0
- package/dist/agent-src/skills/ai-council/references/cost-and-redaction.md +99 -0
- package/dist/agent-src/skills/ai-council/references/execution-modes.md +162 -0
- package/dist/agent-src/skills/ai-council/references/output-and-synthesis.md +125 -0
- package/dist/agent-src/skills/ai-council/references/procedure.md +143 -0
- package/dist/agent-src/skills/decision-review/SKILL.md +18 -0
- package/dist/agent-src/skills/quality-tools/SKILL.md +34 -326
- package/dist/agent-src/skills/quality-tools/references/js-ts-tools.md +113 -0
- package/dist/agent-src/skills/quality-tools/references/php-tools.md +222 -0
- package/dist/agent-src/skills/roadmap-management/SKILL.md +15 -409
- package/dist/agent-src/skills/roadmap-management/references/archival.md +226 -0
- package/dist/agent-src/skills/roadmap-management/references/authoring.md +107 -0
- package/dist/agent-src/skills/roadmap-management/references/dashboard.md +47 -0
- package/dist/agent-src/skills/roadmap-management/references/lifecycle.md +58 -0
- package/dist/agent-src/skills/skill-writing/SKILL.md +34 -570
- package/dist/agent-src/skills/skill-writing/references/procedure.md +275 -0
- package/dist/agent-src/skills/skill-writing/references/read-only-scripts.md +18 -0
- package/dist/agent-src/skills/skill-writing/references/section-patterns.md +298 -0
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +45 -2
- package/dist/agent-src/templates/scripts/telemetry/flush_sender.mjs +163 -0
- package/dist/agent-src/templates/scripts/telemetry/remote.ts +160 -7
- package/dist/agent-src/templates/scripts/telemetry/transport.ts +169 -0
- package/dist/cli/registry.js +1 -1
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli-delegate/chunk-2GNWGMAL.js +172 -0
- package/dist/cli-delegate/{chunk-RLN73PR5.js → chunk-4VR4ORQ6.js} +10 -7
- package/dist/cli-delegate/chunk-6EOCNQAM.js +402 -0
- package/dist/cli-delegate/{chunk-XURJ4AQC.js → chunk-74E3TKWV.js} +381 -280
- package/dist/cli-delegate/{chunk-3UCJWMMP.js → chunk-7F3VYSM2.js} +4 -4
- package/dist/cli-delegate/{chunk-BKO2AZ7Z.js → chunk-B2ERU2VA.js} +1 -1
- package/dist/cli-delegate/{chunk-NXFWFAYV.js → chunk-G23AT6GD.js} +1 -0
- package/dist/cli-delegate/{chunk-63WSP6YZ.js → chunk-GJ5BVHXM.js} +72 -165
- package/dist/cli-delegate/{chunk-ZPSXJTLI.js → chunk-JZ4NR2TW.js} +353 -1
- package/dist/cli-delegate/chunk-MWRD5YOH.js +100 -0
- package/dist/cli-delegate/{chunk-GRRPEPRN.js → chunk-T7L2QK3K.js} +24 -5
- package/dist/cli-delegate/{chunk-EVTY7ISR.js → chunk-YM4GZDJG.js} +9 -1
- package/dist/cli-delegate/cmd_conformance.js +459 -709
- package/dist/cli-delegate/cmd_doctor.js +6 -6
- package/dist/cli-delegate/cmd_explain.js +1 -1
- package/dist/cli-delegate/cmd_export.js +7 -6
- package/dist/cli-delegate/cmd_handoff.js +6 -6
- package/dist/cli-delegate/cmd_packs_active.js +1 -1
- package/dist/cli-delegate/cmd_preflight.js +2 -2
- package/dist/cli-delegate/cmd_prune.js +7 -6
- package/dist/cli-delegate/cmd_session_recycle.js +840 -30
- package/dist/cli-delegate/cmd_settings_migrate.js +7 -6
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +7 -6
- package/dist/cli-delegate/cmd_uninstall.js +9 -7
- package/dist/cli-delegate/cmd_update.js +1 -1
- package/dist/cli-delegate/cmd_upgrade.js +1 -1
- package/dist/cli-delegate/cmd_validate.js +7 -6
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +72 -29
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +4 -4
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +10 -8
- package/dist/discovery/trust-report.md +3 -3
- package/dist/discovery/workspaces.json +8 -6
- package/dist/hooks/dispatch.js +3127 -2022
- package/dist/install/claudePathsPlan.js +187 -0
- package/dist/install/claudePathsPlan.js.map +1 -0
- package/dist/install/hostLayerFingerprint.js +136 -0
- package/dist/install/hostLayerFingerprint.js.map +1 -0
- package/dist/install/install.mjs +553 -425
- package/dist/install/partitionEligibility.js +276 -0
- package/dist/install/partitionEligibility.js.map +1 -0
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +1744 -1191
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/agent_src.js +41 -0
- package/dist/scripts/_lib/agent_src.js.map +1 -1
- package/dist/scripts/_lib/install_layout.js +83 -0
- package/dist/scripts/_lib/install_layout.js.map +1 -0
- package/dist/scripts/_lib/installed_lock.js +444 -0
- package/dist/scripts/_lib/installed_lock.js.map +1 -0
- package/dist/scripts/condense.js +13 -164
- package/dist/scripts/condense.js.map +1 -1
- package/dist/server/schemas/settings.js +4 -0
- package/dist/server/schemas/settings.js.map +1 -1
- package/docs/contracts/settings-classes.md +12 -6
- package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +8 -3
- package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +26 -0
- package/docs/guidelines/agent-infra/engineering-memory-data-format.md +49 -0
- package/docs/guidelines/agent-infra/memory-access.md +17 -0
- package/docs/guidelines/agent-infra/recurring-criticism-mechanics.md +96 -0
- package/package.json +1 -1
- package/src/agent-src/scripts/archival_sweep.ts +117 -0
- package/src/agent-src/scripts/archive_completed_roadmaps.ts +19 -3
- package/src/agent-src/scripts/gate_budget.ts +282 -0
- package/src/agent-src/scripts/gate_execute.ts +72 -31
- package/src/agent-src/scripts/roadmap_gates.ts +74 -3
- package/src/agent-src/scripts/update_roadmap_progress.ts +251 -7
- package/src/agent-src/templates/scripts/telemetry/flush_sender.mjs +163 -0
- package/src/agent-src/templates/scripts/telemetry/remote.ts +160 -7
- package/src/agent-src/templates/scripts/telemetry/transport.ts +169 -0
- package/src/config/agent-settings.template.yml +27 -2
- package/src/config/ci-local-parity.yml +18 -0
- package/src/config/estate-count-budget.json +367 -3
- package/src/config/gate-violation-baselines.json +41 -41
- package/src/config/pack-size-budget.json +3 -2
- package/src/config/rule-activation-census.json +14 -6
- package/src/config/rule-stub-ceilings.json +19 -6
- package/src/install/claudePathsPlan.ts +196 -0
- package/src/install/hostLayerFingerprint.ts +145 -0
- package/src/install/partitionEligibility.ts +325 -0
- package/src/scripts/_cli/cmd_session_recycle.ts +9 -1
- package/src/scripts/_dispatch.bash +6 -1
- package/src/scripts/_lib/ac_heading.ts +30 -0
- package/src/scripts/_lib/agent_src.ts +42 -0
- package/src/scripts/_lib/bench_ab_pinned_repo.ts +162 -0
- package/src/scripts/_lib/bench_ab_workspace.ts +10 -1
- package/src/scripts/_lib/envelope_grounding.ts +38 -8
- package/src/scripts/_lib/installed_lock.ts +50 -5
- package/src/scripts/_lib/layer_overlap_notice.ts +85 -0
- package/src/scripts/_lib/md_section.ts +129 -0
- package/src/scripts/_lib/scope_guard.sh +86 -4
- package/src/scripts/_lib/self_repair.ts +19 -0
- package/src/scripts/_lib/self_repair_class_b.ts +171 -0
- package/src/scripts/_lib/subagent_capsule.ts +81 -1
- package/src/scripts/adr/regenerate_index.ts +13 -2
- package/src/scripts/adr_cite_check.ts +424 -0
- package/src/scripts/ai_council/cli_help.ts +55 -0
- package/src/scripts/before_complete_hook.ts +153 -28
- package/src/scripts/bench_ab_v2_complexity.ts +27 -7
- package/src/scripts/check_adr_frontmatter.ts +187 -1
- package/src/scripts/check_references.ts +60 -0
- package/src/scripts/check_release_published.ts +32 -11
- package/src/scripts/check_single_delivery.ts +517 -0
- package/src/scripts/ci_settle.ts +170 -0
- package/src/scripts/condense.ts +20 -170
- package/src/scripts/council_cli.ts +3 -3
- package/src/scripts/dispatch_r2_reviewer.ts +6 -14
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +77 -14
- package/src/scripts/hooks/block_no_verify.ts +61 -10
- package/src/scripts/hooks/block_unauthorized_git.ts +1 -1
- package/src/scripts/hooks/concern_registry.ts +4 -0
- package/src/scripts/hooks/rtk_wrap_hook.ts +8 -3
- package/src/scripts/hooks/run_continuation_hook.ts +887 -68
- package/src/scripts/hooks/ship_diff_volume_hook.ts +81 -15
- package/src/scripts/hooks/source_first_gate_hook.ts +464 -0
- package/src/scripts/hooks/state_io.ts +782 -20
- package/src/scripts/hooks/subagent_ledger_hook.ts +44 -15
- package/src/scripts/hooks/telemetry_flush_hook.ts +139 -0
- package/src/scripts/hooks/telemetry_self_repair.ts +128 -0
- package/src/scripts/hooks/telemetry_usage_hook.ts +22 -4
- package/src/scripts/hooks/turn_end_gate_hook.ts +81 -15
- package/src/scripts/install.sh +12 -2
- package/src/scripts/install.ts +16 -11
- package/src/scripts/language_mirror_hook.ts +561 -25
- package/src/scripts/lint_framework_leakage_allowlist.json +2 -2
- package/src/scripts/lint_plan_risk_register.ts +4 -3
- package/src/scripts/lint_skill_router_head.ts +4 -4
- package/src/scripts/mcp_server/tools.ts +2 -2
- package/src/scripts/memory_consolidation.ts +189 -0
- package/src/scripts/memory_eviction.ts +384 -0
- package/src/scripts/new_roadmap.ts +136 -0
- package/src/scripts/pack_mcp_content.ts +20 -5
- package/src/scripts/release.ts +37 -38
- package/src/scripts/report_layer_overlap.ts +78 -0
- package/src/scripts/report_memory_pointers.ts +622 -0
- package/src/scripts/self_repair_hook.ts +37 -5
- package/src/scripts/session_register_hook.ts +115 -15
- package/src/scripts/skill_usage_collect.ts +11 -1
- package/src/scripts/skill_usage_report.ts +278 -8
- package/src/scripts/sync_pr_branch.ts +7 -0
- package/src/server/schemas/settings.ts +8 -0
- package/dist/cli-delegate/chunk-EJITJBJX.js +0 -172
- package/dist/cli-delegate/chunk-PZWRPRWP.js +0 -38
- /package/dist/cli-delegate/{chunk-RYNADUFG.js → chunk-LWTYTX6F.js} +0 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Emit a roadmap skeleton that passes every roadmap gate unedited.
|
|
4
|
+
*
|
|
5
|
+
* WHY THIS EXISTS. Four authoring conventions are enforced by four different
|
|
6
|
+
* gates and documented in prose an author has to already know to look for:
|
|
7
|
+
*
|
|
8
|
+
* 1. `complexity:` is a two-value enum — `lightweight` | `structural`.
|
|
9
|
+
* Measured 2026-08-20 across 88 roadmaps: six DIFFERENT invented values
|
|
10
|
+
* were in the tree (`bounded`, `medium`, `moderate`, `small`, `standard`),
|
|
11
|
+
* one of them on the active side and reddening the trunk, seven more in
|
|
12
|
+
* `later/` where the gate does not scan and which would red on the day
|
|
13
|
+
* they are reactivated.
|
|
14
|
+
* 2. The acceptance heading is matched CASE-INSENSITIVELY and without an end
|
|
15
|
+
* anchor — one predicate, `_lib/ac_heading.ts`, shared by the R1 gate and
|
|
16
|
+
* the R2 dispatcher. It was not always: an end-anchored, case-sensitive
|
|
17
|
+
* copy made 10 of 22 roadmaps writing `Acceptance criteria` invisible to
|
|
18
|
+
* the extractor, and a third copy in `lint_plan_risk_register` kept both
|
|
19
|
+
* faults until 2026-08-20, hashing the empty string for 8 of the 32 ready
|
|
20
|
+
* roadmaps while the gate exited 0. The skeleton still emits the
|
|
21
|
+
* capitalised form: it is the shape every reader already recognises, and
|
|
22
|
+
* nothing now depends on the case.
|
|
23
|
+
* 3. The Risk Register needs its `<!-- risk-review: … -->` marker as the
|
|
24
|
+
* first non-blank line of the section.
|
|
25
|
+
* 4. `Risk type` is a two-value enum — `product` | `implementation`. The
|
|
26
|
+
* natural third word (`process`) hard-fails at pre-push.
|
|
27
|
+
*
|
|
28
|
+
* Every one of those is cheap to satisfy up front and costs a full gate round
|
|
29
|
+
* to discover. This command satisfies them by construction.
|
|
30
|
+
*
|
|
31
|
+
* The skeleton is deliberately MINIMAL: one phase, one step, one risk row. It
|
|
32
|
+
* is a starting point that is green, not a template to fill in blindly — the
|
|
33
|
+
* content is the author's, the shape is not worth rediscovering.
|
|
34
|
+
*
|
|
35
|
+
* Usage: ./scripts-run src/scripts/new_roadmap <slug> [--structural] [--stdout]
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
import * as fs from 'node:fs';
|
|
39
|
+
import * as path from 'node:path';
|
|
40
|
+
|
|
41
|
+
/** Today, as the risk-review marker wants it. */
|
|
42
|
+
function today(): string {
|
|
43
|
+
return new Date().toISOString().slice(0, 10);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** `road to X` from a kebab slug, for the H1. */
|
|
47
|
+
function titleOf(slug: string): string {
|
|
48
|
+
return slug.replace(/-/g, ' ');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function skeleton(slug: string, complexity: 'lightweight' | 'structural', date: string): string {
|
|
52
|
+
return `---
|
|
53
|
+
complexity: ${complexity}
|
|
54
|
+
status: draft
|
|
55
|
+
execution:
|
|
56
|
+
mode: phase-checkpoints
|
|
57
|
+
---
|
|
58
|
+
# Road to ${titleOf(slug)}
|
|
59
|
+
|
|
60
|
+
> **Source:** replace this with where the finding came from — a measurement, a
|
|
61
|
+
> review, an incident. A roadmap whose origin is not stated cannot be checked
|
|
62
|
+
> against it later.
|
|
63
|
+
|
|
64
|
+
## Goal
|
|
65
|
+
|
|
66
|
+
One paragraph: what is true when this is finished, phrased so someone else
|
|
67
|
+
could tell whether it happened.
|
|
68
|
+
|
|
69
|
+
## Phase 1 — <name the first coherent slice>
|
|
70
|
+
|
|
71
|
+
- [ ] **1.1 <the step, as an imperative>.** What changes, and why it is not
|
|
72
|
+
already the case.
|
|
73
|
+
verify: the check that proves it — a command, a test, an observable
|
|
74
|
+
state. Never "looks right".
|
|
75
|
+
|
|
76
|
+
## Risk Register
|
|
77
|
+
<!-- risk-review: v1 | reviewed: ${date} | reviewer: claude/host -->
|
|
78
|
+
|
|
79
|
+
| Rank | Item | Risk type | Description | Mitigation | Anchored under |
|
|
80
|
+
|------|------|-----------|-------------|------------|----------------|
|
|
81
|
+
| 1 | <the way this roadmap most plausibly fails> | implementation | What goes wrong, concretely | What makes it not happen, or what catches it | Phase 1 — <name the first coherent slice> |
|
|
82
|
+
|
|
83
|
+
## Acceptance Criteria
|
|
84
|
+
|
|
85
|
+
- [ ] AC-1 — <the residual state, not the activity>. Phrase it on what is true
|
|
86
|
+
afterwards, so a step that ran but achieved nothing cannot satisfy it.
|
|
87
|
+
`;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function main(argv: readonly string[]): number {
|
|
91
|
+
const args = argv.filter((a) => !a.startsWith('--'));
|
|
92
|
+
const structural = argv.includes('--structural');
|
|
93
|
+
const toStdout = argv.includes('--stdout');
|
|
94
|
+
const slug = args[0];
|
|
95
|
+
|
|
96
|
+
if (slug === undefined || slug.length === 0) {
|
|
97
|
+
process.stderr.write(
|
|
98
|
+
'usage: new_roadmap <slug> [--structural] [--stdout]\n' +
|
|
99
|
+
' <slug> kebab-case, without the road-to- prefix\n' +
|
|
100
|
+
' --structural tag structural instead of lightweight (no line/phase cap)\n' +
|
|
101
|
+
' --stdout print instead of writing the file\n',
|
|
102
|
+
);
|
|
103
|
+
return 2;
|
|
104
|
+
}
|
|
105
|
+
if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(slug)) {
|
|
106
|
+
process.stderr.write(`new_roadmap: slug must be kebab-case, got '${slug}'\n`);
|
|
107
|
+
return 2;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const body = skeleton(slug, structural ? 'structural' : 'lightweight', today());
|
|
111
|
+
if (toStdout) {
|
|
112
|
+
process.stdout.write(body);
|
|
113
|
+
return 0;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const rel = path.join('agents', 'roadmaps', `road-to-${slug}.md`);
|
|
117
|
+
if (fs.existsSync(rel)) {
|
|
118
|
+
process.stderr.write(`new_roadmap: ${rel} already exists — refusing to overwrite\n`);
|
|
119
|
+
return 1;
|
|
120
|
+
}
|
|
121
|
+
fs.mkdirSync(path.dirname(rel), { recursive: true });
|
|
122
|
+
fs.writeFileSync(rel, body, 'utf-8');
|
|
123
|
+
process.stdout.write(
|
|
124
|
+
`✅ wrote ${rel}\n` +
|
|
125
|
+
' It passes the roadmap gates as emitted. Adding a `### blocker:` entry or\n' +
|
|
126
|
+
' flipping status to `ready` grows the estate — check_estate_count wants the\n' +
|
|
127
|
+
' baseline raised with a reason in the same commit.\n',
|
|
128
|
+
);
|
|
129
|
+
return 0;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (process.argv[1] !== undefined && import.meta.url.endsWith(path.basename(process.argv[1]))) {
|
|
133
|
+
process.exitCode = main(process.argv.slice(2));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export { main, titleOf, today };
|
|
@@ -41,11 +41,26 @@ import { scan_contexts, scan_guidelines, scan_rules } from './mcp_server/resourc
|
|
|
41
41
|
|
|
42
42
|
const SCHEMA_VERSION = 1;
|
|
43
43
|
const PACKER_VERSION = '1.0.0';
|
|
44
|
-
// Worker bundle is the compact JSON; gzipped copy lives in R2.
|
|
45
|
-
// condensed-bundle limit
|
|
46
|
-
//
|
|
47
|
-
// the
|
|
48
|
-
|
|
44
|
+
// Worker bundle is the compact JSON; gzipped copy lives in R2. This constant is
|
|
45
|
+
// a PROXY for Cloudflare's condensed-bundle limit (3 MB free / 10 MB paid) — it
|
|
46
|
+
// hard-fails early so the build dies before the Worker upload does. Because it is
|
|
47
|
+
// a proxy, the number that matters is the gz one, and both are restated here as
|
|
48
|
+
// MEASURED values rather than remembered ones.
|
|
49
|
+
//
|
|
50
|
+
// Measured 2026-08-20 on origin/main (770 entries): uncondensed 5,230,537 B,
|
|
51
|
+
// gz 1,793,879 B. So the real constraint sits at 57 % of the free tier with
|
|
52
|
+
// ~1.2 MB of room, while the old 5 MiB proxy had 12,343 B of headroom — a 0.24 %
|
|
53
|
+
// margin on trunk, which made ANY addition above ~12 KB to rules, guidelines or
|
|
54
|
+
// contexts fail here regardless of merit. Raised to 6 MiB, deliberately well
|
|
55
|
+
// above the measurement: a cap pinned just over the current figure reds on the
|
|
56
|
+
// next commit and teaches people to raise it again.
|
|
57
|
+
//
|
|
58
|
+
// The prior comment claimed "778 KB gz today (438 entries)". That was stale by
|
|
59
|
+
// 2.3x on size and 332 entries — the reason the proxy drifted into a blocker
|
|
60
|
+
// without anyone noticing was that its own justification was never re-measured.
|
|
61
|
+
// If this needs raising again, re-measure BOTH numbers and replace them here;
|
|
62
|
+
// the gz figure against 3 MB is the one that decides whether there is a problem.
|
|
63
|
+
const MAX_UNCONDENSED_BYTES = 6 * 1024 * 1024;
|
|
49
64
|
|
|
50
65
|
/** Sentinel for the early-exit paths (`raise SystemExit(n)` in Python). */
|
|
51
66
|
class SystemExit extends Error {
|
package/src/scripts/release.ts
CHANGED
|
@@ -2475,55 +2475,54 @@ export function nothing_to_release_ci(
|
|
|
2475
2475
|
|
|
2476
2476
|
const _RELEASE_BRANCH_RE = /^release\/(\d+\.\d+\.\d+)$/;
|
|
2477
2477
|
|
|
2478
|
+
/** `package.json`'s `version`, or null when unreadable, not JSON, or key-less. */
|
|
2479
|
+
function _package_version_or_null(): string | null {
|
|
2480
|
+
try {
|
|
2481
|
+
const data = JSON.parse(fs.readFileSync(PACKAGE_JSON, 'utf-8')) as Record<string, unknown>;
|
|
2482
|
+
return 'version' in data ? (data['version'] as string) : null;
|
|
2483
|
+
} catch {
|
|
2484
|
+
return null;
|
|
2485
|
+
}
|
|
2486
|
+
}
|
|
2487
|
+
|
|
2488
|
+
/** Observations `_detect_in_flight_target` reads; injected by its tests. */
|
|
2489
|
+
export interface InFlightProbes {
|
|
2490
|
+
head_branch?: () => string;
|
|
2491
|
+
package_version?: () => string | null;
|
|
2492
|
+
/** True when the tag is ON THE REMOTE — never merely local. */
|
|
2493
|
+
tag_published?: (tag: string) => boolean;
|
|
2494
|
+
}
|
|
2495
|
+
|
|
2478
2496
|
/**
|
|
2479
|
-
*
|
|
2480
|
-
*
|
|
2481
|
-
*
|
|
2482
|
-
*
|
|
2483
|
-
*
|
|
2484
|
-
*
|
|
2485
|
-
* `release
|
|
2486
|
-
*
|
|
2487
|
-
* Why not the branch set: merged release branches are frequently left
|
|
2488
|
-
* undeleted on the remote, so "highest existing release/* branch" can resolve
|
|
2489
|
-
* to an OLD, already-published version (e.g. picking 5.4.0 while 5.8.0 is the
|
|
2490
|
-
* real in-flight target) and tag a downgrade. The package.json version cannot
|
|
2491
|
-
* lie that way — it is the version main currently claims to be, and an
|
|
2492
|
-
* untagged claim is exactly an incomplete release.
|
|
2493
|
-
*
|
|
2494
|
-
* Resolution order:
|
|
2495
|
-
* 1. If HEAD is on a `release/X.Y.Z` branch, that explicit checkout wins.
|
|
2496
|
-
* 2. Else: read `package.json` version `V`. If tag `V` does not exist
|
|
2497
|
-
* (local or remote), `V` is the in-flight target. If it is already
|
|
2498
|
-
* tagged, the release is complete → return null (regular bump path).
|
|
2499
|
-
*
|
|
2500
|
-
* Stale `release/*` branches are never used for version detection.
|
|
2497
|
+
* In-flight release target: `package.json` claims `V` while no PUBLISHED tag
|
|
2498
|
+
* `V` exists, so the publish step never completed. HEAD on `release/X.Y.Z`
|
|
2499
|
+
* wins first; stale `release/*` branches are never consulted (a merged one
|
|
2500
|
+
* left undeleted can tag a downgrade). PUBLISHED means on the REMOTE, because
|
|
2501
|
+
* publish-npm.yml triggers on `push: tags:`. Why not a local tag, and the
|
|
2502
|
+
* 14.6.0 release that stranded on the old form: see
|
|
2503
|
+
* `tests/scripts/release.test.ts` § _detect_in_flight_target.
|
|
2501
2504
|
*/
|
|
2502
|
-
function _detect_in_flight_target(): string | null {
|
|
2503
|
-
const
|
|
2504
|
-
|
|
2505
|
+
function _detect_in_flight_target(probes: InFlightProbes = {}): string | null {
|
|
2506
|
+
const head_branch =
|
|
2507
|
+
probes.head_branch ?? (() => git(['rev-parse', '--abbrev-ref', 'HEAD'], { capture: true }));
|
|
2508
|
+
const package_version = probes.package_version ?? _package_version_or_null;
|
|
2509
|
+
const tag_published = probes.tag_published ?? _tag_exists_remote;
|
|
2510
|
+
|
|
2511
|
+
const m = _RELEASE_BRANCH_RE.exec(head_branch());
|
|
2505
2512
|
if (m) {
|
|
2506
2513
|
return m[1] as string;
|
|
2507
2514
|
}
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
const data = JSON.parse(fs.readFileSync(PACKAGE_JSON, 'utf-8')) as Record<string, unknown>;
|
|
2512
|
-
if (!('version' in data)) {
|
|
2513
|
-
return null; // KeyError analogue.
|
|
2514
|
-
}
|
|
2515
|
-
version = data['version'] as string;
|
|
2516
|
-
} catch {
|
|
2517
|
-
return null; // OSError / JSONDecodeError analogue.
|
|
2515
|
+
const version = package_version();
|
|
2516
|
+
if (version === null) {
|
|
2517
|
+
return null;
|
|
2518
2518
|
}
|
|
2519
2519
|
try {
|
|
2520
2520
|
parse_version(version);
|
|
2521
2521
|
} catch {
|
|
2522
2522
|
return null;
|
|
2523
2523
|
}
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
if (_tag_exists_local(version) || _tag_exists_remote(version)) {
|
|
2524
|
+
// A PUBLISHED tag is a completed release; a local-only tag is not.
|
|
2525
|
+
if (tag_published(version)) {
|
|
2527
2526
|
return null;
|
|
2528
2527
|
}
|
|
2529
2528
|
return version;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* report_layer_overlap — print what writing the project layer costs, if anything.
|
|
3
|
+
*
|
|
4
|
+
* Runs as its own step of `task generate-tools` rather than as a call inside
|
|
5
|
+
* `condense.ts`, and the reason is a gate rather than taste: `condense.ts` is
|
|
6
|
+
* already over `check_source_size_budget`'s 1500-line ceiling, and that ratchet is
|
|
7
|
+
* shrink-only — an import plus a call there is +2 lines it refuses, and re-pinning
|
|
8
|
+
* the baseline is named a defect in the gate's own message. So the notice lives
|
|
9
|
+
* beside the task it belongs to.
|
|
10
|
+
*
|
|
11
|
+
* WHY THE NOTICE EXISTS. `generate-tools` writes ONE of the two layers Claude Code
|
|
12
|
+
* loads and was silent about the other existing, while the installer's overlap gate
|
|
13
|
+
* runs at install time and cannot see a layer written afterwards. The overlap is
|
|
14
|
+
* therefore created by whichever producer runs LAST, and neither said so.
|
|
15
|
+
*
|
|
16
|
+
* ADVISORY BY CONSTRUCTION: always exits 0. The build must not fail on a topology
|
|
17
|
+
* the operator may not be able to change today — that would make the build unusable
|
|
18
|
+
* rather than the duplication visible. The check that can refuse is
|
|
19
|
+
* `check_single_delivery --enforce`. Invariant: ADR-236.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import * as fs from 'node:fs';
|
|
23
|
+
import * as path from 'node:path';
|
|
24
|
+
import process from 'node:process';
|
|
25
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
26
|
+
|
|
27
|
+
import { warnLayerOverlap } from './_lib/layer_overlap_notice.js';
|
|
28
|
+
|
|
29
|
+
// ledger-exempt: this is a REPORTER, not a gate — it always exits 0 by construction
|
|
30
|
+
// (see the docstring above), so there is no verdict for a per-target ledger to
|
|
31
|
+
// account for. `_lib/gate_ledger` records why a gate passed over a target; a script
|
|
32
|
+
// that cannot fail passes over nothing. The advisory-only property is asserted by the
|
|
33
|
+
// task step that calls it, not by this marker.
|
|
34
|
+
|
|
35
|
+
const _HERE = fileURLToPath(import.meta.url);
|
|
36
|
+
const REPO_ROOT = path.resolve(path.dirname(_HERE), '..', '..');
|
|
37
|
+
|
|
38
|
+
export function main(argv?: readonly string[]): number {
|
|
39
|
+
const args = argv ?? process.argv.slice(2);
|
|
40
|
+
let projectRoot = REPO_ROOT;
|
|
41
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
42
|
+
const a = args[i];
|
|
43
|
+
if (a === '--project') {
|
|
44
|
+
const v = args[i + 1];
|
|
45
|
+
if (v === undefined || v.startsWith('-')) {
|
|
46
|
+
process.stderr.write('report_layer_overlap: --project needs a directory\n');
|
|
47
|
+
return 1;
|
|
48
|
+
}
|
|
49
|
+
projectRoot = path.resolve(v);
|
|
50
|
+
i += 1;
|
|
51
|
+
} else if (a === '--help' || a === '-h') {
|
|
52
|
+
process.stdout.write('usage: report_layer_overlap [--project DIR]\n');
|
|
53
|
+
return 0;
|
|
54
|
+
} else if (a !== undefined) {
|
|
55
|
+
// Unrecognised arguments are an error even here, where the exit code is
|
|
56
|
+
// otherwise always 0: a silently ignored typo in a build step is how a
|
|
57
|
+
// notice stops firing without anyone noticing.
|
|
58
|
+
process.stderr.write(`report_layer_overlap: unexpected argument ${a}\n`);
|
|
59
|
+
return 1;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
warnLayerOverlap(projectRoot, (m) => process.stdout.write(`${m}\n`));
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function _isCliEntry(): boolean {
|
|
67
|
+
if (process.argv[1] === undefined) return false;
|
|
68
|
+
if (import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href) return true;
|
|
69
|
+
try {
|
|
70
|
+
return fs.realpathSync(_HERE) === fs.realpathSync(path.resolve(process.argv[1]));
|
|
71
|
+
} catch {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (_isCliEntry()) {
|
|
77
|
+
process.exit(main());
|
|
78
|
+
}
|