create-byan-agent 2.23.0 → 2.26.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/CHANGELOG.md +230 -0
- package/README.md +9 -12
- package/install/bin/create-byan-agent-v2.js +29 -169
- package/install/lib/agent-generator.js +5 -5
- package/install/lib/byan-web-integration.js +1 -1
- package/install/lib/claude-native-setup.js +1 -1
- package/install/lib/phase2-chat.js +3 -10
- package/install/lib/platforms/claude-code.js +2 -2
- package/install/lib/platforms/index.js +0 -2
- package/install/lib/project-agents-generator.js +3 -3
- package/install/lib/staging-consent.js +3 -3
- package/install/lib/subagent-generator.js +3 -3
- package/install/lib/yanstaller/agent-launcher.js +1 -27
- package/install/lib/yanstaller/detector.js +4 -4
- package/install/lib/yanstaller/installer.js +0 -2
- package/install/lib/yanstaller/interviewer.js +1 -1
- package/install/lib/yanstaller/platform-selector.js +1 -13
- package/install/package.json +1 -1
- package/install/src/byan-v2/context/session-state.js +2 -2
- package/install/src/byan-v2/index.js +2 -6
- package/install/src/byan-v2/orchestrator/generation-state.js +4 -4
- package/install/src/webui/api.js +0 -2
- package/install/src/webui/chat/bridge.js +1 -13
- package/install/src/webui/chat/cli-detector.js +0 -23
- package/install/src/webui/public/app.js +1 -3
- package/install/src/webui/public/chat.html +0 -2
- package/install/src/webui/public/chat.js +0 -1
- package/install/src/webui/public/index.html +2 -2
- package/install/templates/.claude/CLAUDE.md +13 -2
- package/install/templates/.claude/agents/bmad-byan.md +1 -1
- package/install/templates/.claude/hooks/autobench-stop-guard.js +286 -0
- package/install/templates/.claude/hooks/drain-advisory.js +85 -0
- package/install/templates/.claude/hooks/fact-check-absolutes.js +1 -61
- package/install/templates/.claude/hooks/fact-check-claims.js +69 -0
- package/install/templates/.claude/hooks/fd-response-check.js +37 -46
- package/install/templates/.claude/hooks/inject-soul.js +64 -25
- package/install/templates/.claude/hooks/leantime-fd-sync.js +216 -0
- package/install/templates/.claude/hooks/lib/autobench-config.json +81 -0
- package/install/templates/.claude/hooks/lib/autobench-fc-enrich.js +251 -0
- package/install/templates/.claude/hooks/lib/autobench-ledger-report.js +253 -0
- package/install/templates/.claude/hooks/lib/autobench-runtime.js +199 -0
- package/install/templates/.claude/hooks/lib/fact-check-core.js +69 -0
- package/install/templates/.claude/hooks/lib/failure-detector.js +18 -4
- package/install/templates/.claude/hooks/lib/transcript-read.js +137 -0
- package/install/templates/.claude/hooks/soul-memory-check.js +49 -25
- package/install/templates/.claude/hooks/soul-memory-triggers.js +27 -8
- package/install/templates/.claude/hooks/stage-to-byan.js +25 -7
- package/install/templates/.claude/hooks/strict-stop-guard.js +4 -16
- package/install/templates/.claude/rules/benchmark.md +251 -0
- package/install/templates/.claude/rules/byan-agents.md +0 -1
- package/install/templates/.claude/rules/byan-api.md +64 -0
- package/install/templates/.claude/rules/fact-check.md +1 -1
- package/install/templates/.claude/rules/strict-mode.md +10 -9
- package/install/templates/.claude/settings.json +16 -0
- package/install/templates/.claude/skills/byan-benchmark/SKILL.md +159 -0
- package/install/templates/.claude/skills/byan-byan/SKILL.md +73 -12
- package/install/templates/.claude/skills/byan-fact-check/SKILL.md +1 -1
- package/install/templates/.claude/skills/byan-hermes-dispatch/SKILL.md +5 -6
- package/install/templates/.claude/skills/byan-insight/SKILL.md +56 -0
- package/install/templates/.claude/skills/byan-orchestrate/SKILL.md +11 -3
- package/install/templates/.claude/skills/byan-strict/SKILL.md +4 -1
- package/install/templates/.claude/workflows/INDEX.md +2 -1
- package/install/templates/.claude/workflows/byan-benchmark.js +328 -0
- package/install/templates/.claude/workflows/check-implementation-readiness.js +1 -1
- package/install/templates/_byan/_config/agent-manifest.csv +1 -1
- package/install/templates/_byan/_config/autobench.yaml +510 -0
- package/install/templates/_byan/_config/strict-mode.yaml +9 -3
- package/install/templates/_byan/_config/workflow-manifest.csv +1 -0
- package/install/templates/_byan/agent/byan/byan.md +1 -3
- package/install/templates/_byan/agent/byan-flat/byan.md +1 -3
- package/install/templates/_byan/agent/byan-test/byan-test.md +2 -2
- package/install/templates/_byan/agent/byan-test-flat/byan-test.md +2 -2
- package/install/templates/_byan/agent/byan.optimized/byan.optimized.md +2 -2
- package/install/templates/_byan/agent/byan.optimized-v2/byan.optimized-v2.md +2 -2
- package/install/templates/_byan/agent/claude/claude.md +0 -2
- package/install/templates/_byan/agent/codex/codex.md +0 -2
- package/install/templates/_byan/agent/rachid/rachid.md +2 -10
- package/install/templates/_byan/agent/rachid-flat/rachid.md +2 -11
- package/install/templates/_byan/agent/turbo-whisper/turbo-whisper.md +2 -5
- package/install/templates/_byan/agent/turbo-whisper-integration/turbo-whisper-integration.md +5 -13
- package/install/templates/_byan/agent/yanstaller/yanstaller.md +2 -24
- package/install/templates/_byan/config.yaml +0 -1
- package/install/templates/_byan/core/activation/soul-activation.md +3 -3
- package/install/templates/_byan/mcp/byan-mcp-server/bin/byan-insight-digest.js +31 -0
- package/install/templates/_byan/mcp/byan-mcp-server/bin/byan-sync-rules.js +20 -4
- package/install/templates/_byan/mcp/byan-mcp-server/lib/advisory-autofeed.js +96 -0
- package/install/templates/_byan/mcp/byan-mcp-server/lib/index-generator.js +1 -1
- package/install/templates/_byan/mcp/byan-mcp-server/lib/insight-harvest.js +220 -0
- package/install/templates/_byan/mcp/byan-mcp-server/lib/kanban.js +6 -3
- package/install/templates/_byan/mcp/byan-mcp-server/lib/leantime-fd-core.js +205 -0
- package/install/templates/_byan/mcp/byan-mcp-server/lib/leantime-sync.js +415 -0
- package/install/templates/_byan/mcp/byan-mcp-server/lib/outcome-buffer.js +64 -0
- package/install/templates/_byan/mcp/byan-mcp-server/lib/precommit-gate.js +1 -1
- package/install/templates/_byan/mcp/byan-mcp-server/lib/strict-activation.js +1 -1
- package/install/templates/_byan/mcp/byan-mcp-server/lib/strict-mode.js +8 -0
- package/install/templates/_byan/mcp/byan-mcp-server/lib/sync-rules.js +172 -23
- package/install/templates/_byan/mcp/byan-mcp-server/lib/workflows-generator.js +1 -0
- package/install/templates/_byan/mcp/byan-mcp-server/server.js +262 -81
- package/install/templates/_byan/worker/launchers/README.md +4 -24
- package/install/templates/_byan/worker/workers.md +8 -9
- package/install/templates/_byan/workflow/simple/bmb/byan-benchmark/workflow.md +86 -0
- package/install/templates/_byan/workflow/simple/byan/feature-workflow.md +2 -2
- package/install/templates/docs/leantime-integration.md +160 -0
- package/package.json +3 -7
- package/src/byan-v2/context/session-state.js +2 -2
- package/src/byan-v2/generation/mantra-validator.js +3 -3
- package/src/byan-v2/index.js +1 -5
- package/src/byan-v2/integration/voice-integration.js +1 -1
- package/src/byan-v2/orchestrator/generation-state.js +4 -4
- package/src/loadbalancer/loadbalancer.js +1 -1
- package/src/staging/staging.js +20 -6
- package/install/bin/build-copilot-stubs.js +0 -138
- package/install/lib/platforms/copilot-cli.js +0 -123
- package/install/lib/platforms/vscode.js +0 -51
- package/install/src/byan-v2/context/copilot-context.js +0 -79
- package/install/src/webui/chat/copilot-adapter.js +0 -68
- package/install/templates/.claude/agents/bmad-marc.md +0 -25
- package/install/templates/.claude/skills/byan-marc/SKILL.md +0 -20
- package/install/templates/.github/agents/bmad-agent-bmad-master.md +0 -16
- package/install/templates/.github/agents/bmad-agent-bmb-agent-builder.md +0 -16
- package/install/templates/.github/agents/bmad-agent-bmb-module-builder.md +0 -16
- package/install/templates/.github/agents/bmad-agent-bmb-workflow-builder.md +0 -16
- package/install/templates/.github/agents/bmad-agent-bmm-analyst.md +0 -16
- package/install/templates/.github/agents/bmad-agent-bmm-architect.md +0 -16
- package/install/templates/.github/agents/bmad-agent-bmm-dev.md +0 -16
- package/install/templates/.github/agents/bmad-agent-bmm-pm.md +0 -16
- package/install/templates/.github/agents/bmad-agent-bmm-quick-flow-solo-dev.md +0 -16
- package/install/templates/.github/agents/bmad-agent-bmm-quinn.md +0 -16
- package/install/templates/.github/agents/bmad-agent-bmm-sm.md +0 -16
- package/install/templates/.github/agents/bmad-agent-bmm-tech-writer.md +0 -16
- package/install/templates/.github/agents/bmad-agent-bmm-ux-designer.md +0 -16
- package/install/templates/.github/agents/bmad-agent-byan-test.md +0 -33
- package/install/templates/.github/agents/bmad-agent-byan-v2.md +0 -44
- package/install/templates/.github/agents/bmad-agent-byan.md +0 -1062
- package/install/templates/.github/agents/bmad-agent-carmack.md +0 -14
- package/install/templates/.github/agents/bmad-agent-cis-brainstorming-coach.md +0 -16
- package/install/templates/.github/agents/bmad-agent-cis-creative-problem-solver.md +0 -16
- package/install/templates/.github/agents/bmad-agent-cis-design-thinking-coach.md +0 -16
- package/install/templates/.github/agents/bmad-agent-cis-innovation-strategist.md +0 -16
- package/install/templates/.github/agents/bmad-agent-cis-presentation-master.md +0 -16
- package/install/templates/.github/agents/bmad-agent-cis-storyteller.md +0 -16
- package/install/templates/.github/agents/bmad-agent-claude.md +0 -49
- package/install/templates/.github/agents/bmad-agent-codex.md +0 -49
- package/install/templates/.github/agents/bmad-agent-drawio.md +0 -45
- package/install/templates/.github/agents/bmad-agent-fact-checker.md +0 -16
- package/install/templates/.github/agents/bmad-agent-forgeron.md +0 -15
- package/install/templates/.github/agents/bmad-agent-jimmy.md +0 -15
- package/install/templates/.github/agents/bmad-agent-marc.md +0 -49
- package/install/templates/.github/agents/bmad-agent-mike.md +0 -15
- package/install/templates/.github/agents/bmad-agent-patnote.md +0 -49
- package/install/templates/.github/agents/bmad-agent-rachid.md +0 -48
- package/install/templates/.github/agents/bmad-agent-skeptic.md +0 -16
- package/install/templates/.github/agents/bmad-agent-tao.md +0 -14
- package/install/templates/.github/agents/bmad-agent-tea-tea.md +0 -16
- package/install/templates/.github/agents/bmad-agent-test-dynamic.md +0 -22
- package/install/templates/.github/agents/bmad-agent-yanstaller-interview.md +0 -50
- package/install/templates/.github/agents/bmad-agent-yanstaller-phase2.md +0 -189
- package/install/templates/.github/agents/bmad-agent-yanstaller.md +0 -350
- package/install/templates/.github/agents/expert-merise-agile.md +0 -178
- package/install/templates/.github/agents/franck.md +0 -379
- package/install/templates/.github/agents/hermes.md +0 -575
- package/install/templates/.github/extensions/byan-staging/extension.mjs +0 -169
- package/install/templates/.github/extensions/byan-staging/package.json +0 -8
- package/install/templates/_byan/agent/marc/marc-soul.md +0 -47
- package/install/templates/_byan/agent/marc/marc-tao.md +0 -77
- package/install/templates/_byan/agent/marc/marc.md +0 -324
- package/install/templates/_byan/agent/marc-flat/marc.md +0 -387
- package/install/templates/_byan/mcp/byan-mcp-server/lib/copilot.js +0 -148
- package/install/templates/_byan/worker/launchers/launch-yanstaller-copilot.md +0 -173
- package/install/templates/workers/cost-optimizer.js +0 -169
- package/src/byan-v2/context/copilot-context.js +0 -79
- package/src/core/dispatcher/execution-router.js +0 -66
|
@@ -9,7 +9,6 @@ import yaml from 'js-yaml';
|
|
|
9
9
|
// - .claude/skills/byan-strict/SKILL.md (owned, full-file)
|
|
10
10
|
// - .claude/hooks/lib/strict-config.json (owned, full-file)
|
|
11
11
|
// - AGENTS.md (upsert block, Codex)
|
|
12
|
-
// - .github/copilot-instructions.md (upsert block, Copilot)
|
|
13
12
|
//
|
|
14
13
|
// Owned files are rewritten wholesale (they carry a generated-by header).
|
|
15
14
|
// Shared files get a block upserted between BYAN-STRICT markers, leaving the
|
|
@@ -19,6 +18,10 @@ const BEGIN = 'BYAN-STRICT:BEGIN';
|
|
|
19
18
|
const END = 'BYAN-STRICT:END';
|
|
20
19
|
const DEFAULT_CONFIG_REL = path.join('_byan', '_config', 'strict-mode.yaml');
|
|
21
20
|
|
|
21
|
+
const AUTOBENCH_BEGIN = 'BYAN-AUTOBENCH:BEGIN';
|
|
22
|
+
const AUTOBENCH_END = 'BYAN-AUTOBENCH:END';
|
|
23
|
+
const AUTOBENCH_CONFIG_REL = path.join('_byan', '_config', 'autobench.yaml');
|
|
24
|
+
|
|
22
25
|
export function resolveRoot(projectRoot) {
|
|
23
26
|
return projectRoot || process.env.CLAUDE_PROJECT_DIR || process.cwd();
|
|
24
27
|
}
|
|
@@ -39,6 +42,31 @@ export function loadConfig({ projectRoot, configPath } = {}) {
|
|
|
39
42
|
return cfg;
|
|
40
43
|
}
|
|
41
44
|
|
|
45
|
+
// Loads and validates the auto-benchmark source of truth. Mirrors loadConfig:
|
|
46
|
+
// throws on a missing file, a non-object parse, an empty mantras list, or a
|
|
47
|
+
// missing doctrine brick — so a malformed YAML fails the generator loudly
|
|
48
|
+
// rather than emitting a half-rendered pointer block.
|
|
49
|
+
export function loadAutobenchConfig({ projectRoot, configPath } = {}) {
|
|
50
|
+
const root = resolveRoot(projectRoot);
|
|
51
|
+
const file = configPath || path.join(root, AUTOBENCH_CONFIG_REL);
|
|
52
|
+
if (!fs.existsSync(file)) {
|
|
53
|
+
throw new Error(`autobench config not found at ${file}`);
|
|
54
|
+
}
|
|
55
|
+
const cfg = yaml.load(fs.readFileSync(file, 'utf8'));
|
|
56
|
+
if (!cfg || typeof cfg !== 'object') {
|
|
57
|
+
throw new Error(`autobench config at ${file} did not parse to an object`);
|
|
58
|
+
}
|
|
59
|
+
if (!Array.isArray(cfg.mantras) || cfg.mantras.length === 0) {
|
|
60
|
+
throw new Error('autobench config must define a non-empty mantras list');
|
|
61
|
+
}
|
|
62
|
+
for (const brick of ['trigger', 'scaler', 'format']) {
|
|
63
|
+
if (!cfg[brick] || typeof cfg[brick] !== 'object') {
|
|
64
|
+
throw new Error(`autobench config must define the '${brick}' brick`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return cfg;
|
|
68
|
+
}
|
|
69
|
+
|
|
42
70
|
// ---------------------------------------------------------------------------
|
|
43
71
|
// Renderers — pure functions config -> string.
|
|
44
72
|
// ---------------------------------------------------------------------------
|
|
@@ -46,6 +74,9 @@ export function loadConfig({ projectRoot, configPath } = {}) {
|
|
|
46
74
|
const GENERATED_NOTE =
|
|
47
75
|
'Generated by byan-sync-rules from _byan/_config/strict-mode.yaml. Do not hand-edit.';
|
|
48
76
|
|
|
77
|
+
const AUTOBENCH_GENERATED_NOTE =
|
|
78
|
+
'Generated by byan-sync-rules from _byan/_config/autobench.yaml. Do not hand-edit.';
|
|
79
|
+
|
|
49
80
|
export function renderStrictConfig(cfg) {
|
|
50
81
|
return {
|
|
51
82
|
_generated_by: 'byan-sync-rules',
|
|
@@ -125,7 +156,10 @@ complete. Downgrading the scope is the failure this mode exists to prevent.
|
|
|
125
156
|
|
|
126
157
|
1. **Lock the scope** with \`byan_strict_lock_scope\` before building. Provide a
|
|
127
158
|
verbatim restatement of the request and testable \`acceptanceCriteria\`. The
|
|
128
|
-
locked scope is the contract.
|
|
159
|
+
locked scope is the contract. When one technical domain clearly dominates the
|
|
160
|
+
task, also pass \`domain\` (e.g. security, performance, javascript) — a
|
|
161
|
+
successful completion then feeds one VALIDATED tick to the ELO loop. Explicit
|
|
162
|
+
only; omit when no single domain is clear.
|
|
129
163
|
2. **Build the full scope.** Do not substitute an MVP, a stub, or a simplified
|
|
130
164
|
version. If a part cannot be done, surface it as a gap — do not cut silently.
|
|
131
165
|
3. **Self-verify at least ${cfg.self_verify.min_passes} times** with
|
|
@@ -160,19 +194,84 @@ Hard mantras:
|
|
|
160
194
|
${mantraLines(cfg)}`;
|
|
161
195
|
}
|
|
162
196
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
197
|
+
// Maps the enriched cfg.hooks section to the EXACT runtime shape read by
|
|
198
|
+
// autobench-stop-guard.js. Every key and every {source, flags} pair structure
|
|
199
|
+
// must stay in sync with what compileRegex / hasChoiceLanguage / hasMarker /
|
|
200
|
+
// hasNeverListed / readMarkerFields / escapeHatchActive / ledgerPath consume.
|
|
201
|
+
//
|
|
202
|
+
// This is the function that closes the single-source-of-truth gap: before it
|
|
203
|
+
// existed, autobench-config.json was hand-authored and the YAML toggle
|
|
204
|
+
// (escape_hatch.disabled) was never propagated to the runtime file.
|
|
205
|
+
export function renderAutobenchConfig(cfg) {
|
|
206
|
+
const h = cfg.hooks;
|
|
207
|
+
const mp = h.marker_patterns;
|
|
208
|
+
const mf = h.marker_fields;
|
|
209
|
+
const eh = h.escape_hatch;
|
|
172
210
|
|
|
173
|
-
|
|
211
|
+
return {
|
|
212
|
+
_generated_by: 'byan-sync-rules',
|
|
213
|
+
_note:
|
|
214
|
+
'Runtime subset read by autobench-stop-guard.js. Edit _byan/_config/autobench.yaml and regenerate; do not hand-edit. Regexes are {source, flags} pairs reconstructed into RegExp at load time.',
|
|
215
|
+
version: cfg.version,
|
|
216
|
+
marker_patterns: {
|
|
217
|
+
any: { source: mp.any.source, flags: mp.any.flags },
|
|
218
|
+
done: { source: mp.done.source, flags: mp.done.flags },
|
|
219
|
+
skip: { source: mp.skip.source, flags: mp.skip.flags },
|
|
220
|
+
},
|
|
221
|
+
marker_fields: {
|
|
222
|
+
g1: { source: mf.g1.source, flags: mf.g1.flags },
|
|
223
|
+
g2: { source: mf.g2.source, flags: mf.g2.flags },
|
|
224
|
+
scope: { source: mf.scope.source, flags: mf.scope.flags },
|
|
225
|
+
},
|
|
226
|
+
never_list: h.never_list.map((entry) => ({ source: entry.source, flags: entry.flags })),
|
|
227
|
+
choice_language: h.choice_language.map((entry) => {
|
|
228
|
+
const out = { source: entry.source, flags: entry.flags };
|
|
229
|
+
// Preserve optional threshold fields only when present; omitting them
|
|
230
|
+
// keeps the config lean and matches the runtime's typeof checks.
|
|
231
|
+
if (typeof entry.min_matches === 'number') out.min_matches = entry.min_matches;
|
|
232
|
+
if (typeof entry.requires_candidates === 'number') out.requires_candidates = entry.requires_candidates;
|
|
233
|
+
return out;
|
|
234
|
+
}),
|
|
235
|
+
candidate_token: { source: h.candidate_token.source, flags: h.candidate_token.flags },
|
|
236
|
+
escape_hatch: {
|
|
237
|
+
// session_flag is read by autobench-runtime.js but not stored in
|
|
238
|
+
// config.json (the runtime hardcodes the path). Carry only the two
|
|
239
|
+
// fields the runtime actually reads from config.json.
|
|
240
|
+
session_flag: eh.session_flag,
|
|
241
|
+
disabled: eh.disabled,
|
|
242
|
+
},
|
|
243
|
+
enforcement: {
|
|
244
|
+
// Disarmed-by-default (approach C): the Stop hook observes and ledgers but
|
|
245
|
+
// does not block until armed. Arming is config-only (armed: true in the
|
|
246
|
+
// YAML); there is no loose flag file, so a stray file cannot silently arm a
|
|
247
|
+
// machine. Defaulting armed to false keeps an older source inert by default.
|
|
248
|
+
armed: Boolean(h.enforcement && h.enforcement.armed === true),
|
|
249
|
+
},
|
|
250
|
+
ledger: {
|
|
251
|
+
path: h.ledger_path,
|
|
252
|
+
},
|
|
253
|
+
banners: {
|
|
254
|
+
stop_block: h.stop_block,
|
|
255
|
+
},
|
|
256
|
+
};
|
|
257
|
+
}
|
|
174
258
|
|
|
175
|
-
|
|
259
|
+
// The lean auto-benchmark pointer block. One shared block for both
|
|
260
|
+
// platform files (CLAUDE.md / AGENTS.md): names the
|
|
261
|
+
// feature, states the marker one-liner the agent must emit, and points to the
|
|
262
|
+
// full doctrine. Kept short on purpose — CLAUDE.md stays lean via pointers, and
|
|
263
|
+
// the full rule lives in .claude/rules/benchmark.md (owned, authored elsewhere).
|
|
264
|
+
export function renderAutobenchPointerBlock(cfg) {
|
|
265
|
+
const name = (cfg.name || 'BYAN Auto-Benchmark').trim();
|
|
266
|
+
return `## ${name}
|
|
267
|
+
|
|
268
|
+
Before asking the user to choose between options, benchmark the fork: render
|
|
269
|
+
ONE compact table (Option | <= 4 criteria | Niv + a best-first reco line) when
|
|
270
|
+
both gates hold (>= 2 non-substitutable options diverging on >= 1 weighted
|
|
271
|
+
criterion). Emit the marker verbatim before the table:
|
|
272
|
+
\`<!-- BYAN-BENCH:done g1=<#options> g2=<#divergent-criteria> scope=<internal|external> conf=<assertive|lean> -->\`.
|
|
273
|
+
A confirm, a destructive prompt, or an obvious default is not a fork — emit
|
|
274
|
+
\`<!-- BYAN-BENCH:skip reason=.. -->\` instead. Full doctrine: see @.claude/rules/benchmark.md`;
|
|
176
275
|
}
|
|
177
276
|
|
|
178
277
|
// ---------------------------------------------------------------------------
|
|
@@ -191,11 +290,29 @@ function writeIfChanged(filePath, content) {
|
|
|
191
290
|
return existing === null ? 'created' : 'updated';
|
|
192
291
|
}
|
|
193
292
|
|
|
293
|
+
// Escapes a marker string for safe embedding in a RegExp source. Markers are
|
|
294
|
+
// authored as plain identifiers today, but a literal-safe regex keeps the
|
|
295
|
+
// generalized signature robust if a future marker carries a regex metacharacter.
|
|
296
|
+
function escapeRegex(s) {
|
|
297
|
+
return String(s).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
298
|
+
}
|
|
299
|
+
|
|
194
300
|
// Insert or replace a block delimited by HTML-comment markers. Preserves
|
|
195
301
|
// everything outside the markers. If the file does not exist, creates it with
|
|
196
302
|
// just the block.
|
|
197
|
-
|
|
198
|
-
|
|
303
|
+
//
|
|
304
|
+
// markers defaults to the module-level STRICT pair so every existing strict
|
|
305
|
+
// callsite keeps working unchanged. Passing a distinct pair (e.g. the
|
|
306
|
+
// AUTOBENCH markers) scopes the replace-regex to that pair only, so a STRICT
|
|
307
|
+
// block and an AUTOBENCH block coexist in one file without clobbering each
|
|
308
|
+
// other.
|
|
309
|
+
export function upsertBlock({
|
|
310
|
+
filePath,
|
|
311
|
+
block,
|
|
312
|
+
markers = { begin: BEGIN, end: END },
|
|
313
|
+
note = GENERATED_NOTE,
|
|
314
|
+
}) {
|
|
315
|
+
const wrapped = `<!-- ${markers.begin} (${note}) -->\n${block}\n<!-- ${markers.end} -->`;
|
|
199
316
|
const existing = fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf8') : null;
|
|
200
317
|
|
|
201
318
|
if (existing === null) {
|
|
@@ -205,7 +322,7 @@ export function upsertBlock({ filePath, block }) {
|
|
|
205
322
|
}
|
|
206
323
|
|
|
207
324
|
const re = new RegExp(
|
|
208
|
-
`<!-- ${
|
|
325
|
+
`<!-- ${escapeRegex(markers.begin)}[\\s\\S]*?${escapeRegex(markers.end)} -->`,
|
|
209
326
|
'm'
|
|
210
327
|
);
|
|
211
328
|
let next;
|
|
@@ -216,7 +333,7 @@ export function upsertBlock({ filePath, block }) {
|
|
|
216
333
|
}
|
|
217
334
|
if (next === existing) return 'unchanged';
|
|
218
335
|
fs.writeFileSync(filePath, next);
|
|
219
|
-
return existing.includes(
|
|
336
|
+
return existing.includes(markers.begin) ? 'updated' : 'appended';
|
|
220
337
|
}
|
|
221
338
|
|
|
222
339
|
// ---------------------------------------------------------------------------
|
|
@@ -241,12 +358,6 @@ export function syncRules({ projectRoot, configPath } = {}) {
|
|
|
241
358
|
const agentsPath = path.join(root, 'AGENTS.md');
|
|
242
359
|
report['AGENTS.md'] = upsertBlock({ filePath: agentsPath, block: renderAgentsBlock(cfg) });
|
|
243
360
|
|
|
244
|
-
const copilotPath = path.join(root, '.github', 'copilot-instructions.md');
|
|
245
|
-
report['.github/copilot-instructions.md'] = upsertBlock({
|
|
246
|
-
filePath: copilotPath,
|
|
247
|
-
block: renderCopilotBlock(cfg),
|
|
248
|
-
});
|
|
249
|
-
|
|
250
361
|
const mantrasPath = path.join(root, 'src', 'byan-v2', 'data', 'strict-mantras.json');
|
|
251
362
|
if (fs.existsSync(path.dirname(mantrasPath))) {
|
|
252
363
|
report['src/byan-v2/data/strict-mantras.json'] = writeIfChanged(
|
|
@@ -258,4 +369,42 @@ export function syncRules({ projectRoot, configPath } = {}) {
|
|
|
258
369
|
return report;
|
|
259
370
|
}
|
|
260
371
|
|
|
372
|
+
// Auto-benchmark orchestrator. Kept SEPARATE from syncRules so the strict
|
|
373
|
+
// generator stays untouched and independently testable. Upserts the lean
|
|
374
|
+
// pointer block into the three platform files and writes the runtime config
|
|
375
|
+
// that the Stop hook reads. The config write closes the single-source-of-truth
|
|
376
|
+
// gap: escape_hatch.disabled toggled in the YAML now reaches the runtime file.
|
|
377
|
+
// Returns a {file: action} report like syncRules.
|
|
378
|
+
export function syncAutobench({ projectRoot, configPath } = {}) {
|
|
379
|
+
const root = resolveRoot(projectRoot);
|
|
380
|
+
const cfg = loadAutobenchConfig({ projectRoot: root, configPath });
|
|
381
|
+
|
|
382
|
+
const report = {};
|
|
383
|
+
const block = renderAutobenchPointerBlock(cfg);
|
|
384
|
+
const markers = { begin: AUTOBENCH_BEGIN, end: AUTOBENCH_END };
|
|
385
|
+
|
|
386
|
+
// CLAUDE.md uses the lean pointer convention (.claude/CLAUDE.md holds the
|
|
387
|
+
// other rule pointers: strict, fact-check, ELO). AGENTS.md (Codex) is the
|
|
388
|
+
// other cross-platform mechanism target.
|
|
389
|
+
const targets = {
|
|
390
|
+
'.claude/CLAUDE.md': path.join(root, '.claude', 'CLAUDE.md'),
|
|
391
|
+
'AGENTS.md': path.join(root, 'AGENTS.md'),
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
for (const [rel, filePath] of Object.entries(targets)) {
|
|
395
|
+
report[rel] = upsertBlock({ filePath, block, markers, note: AUTOBENCH_GENERATED_NOTE });
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// Write the runtime config that autobench-stop-guard.js reads. Mirrors the
|
|
399
|
+
// strict pattern (syncRules writes strict-config.json from strict-mode.yaml).
|
|
400
|
+
const autobenchCfgPath = path.join(root, '.claude', 'hooks', 'lib', 'autobench-config.json');
|
|
401
|
+
report['.claude/hooks/lib/autobench-config.json'] = writeIfChanged(
|
|
402
|
+
autobenchCfgPath,
|
|
403
|
+
JSON.stringify(renderAutobenchConfig(cfg), null, 2) + '\n'
|
|
404
|
+
);
|
|
405
|
+
|
|
406
|
+
return report;
|
|
407
|
+
}
|
|
408
|
+
|
|
261
409
|
export const MARKERS = { BEGIN, END };
|
|
410
|
+
export const AUTOBENCH_MARKERS = { BEGIN: AUTOBENCH_BEGIN, END: AUTOBENCH_END };
|