@dzhechkov/skills-feature-adr 1.3.44 → 1.3.45

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dzhechkov/skills-feature-adr",
3
- "version": "1.3.44",
3
+ "version": "1.3.45",
4
4
  "description": "Adaptive Feature Development skill pack for Claude Code — 11-step pipeline with Complexity Router (S/M/L/XL), ADR-driven architecture, 15 agentic-qe skills, multi-agent fleet QE. Supports --full-qe, --full-qe-extended, --with-learning, and --knowledge-extractor modes.",
5
5
  "bin": {
6
6
  "skills-feature-adr": "./bin/cli.js"
@@ -47,6 +47,12 @@ const DZ_TEACH = (lesson, reward, domain) =>
47
47
  // ~/.codex/config.toml at pre-flight; the hint below only nudges.
48
48
  const CODEX_MODEL = A.codexModel || 'auto'
49
49
  const CODEX_HINT = ' (If you are the Codex runtime, prefer the ' + CODEX_MODEL + ' model.)'
50
+ function codexEffortHint(opts) {
51
+ if (opts && opts.agentType === 'codex:codex-rescue' && opts._reasoning) {
52
+ return ' (If you are the Codex runtime, run at --effort ' + opts._reasoning + '.)'
53
+ }
54
+ return ''
55
+ }
50
56
  const CODER = (A.coder === 'codex' || A.coder === 'codex-fallback') ? A.coder : 'claude'
51
57
  const QE_REVIEWER = (A.qeReviewer === 'codex' || A.qeReviewer === 'codex-fallback') ? A.qeReviewer : 'claude'
52
58
  const PLANNER = (A.planner === 'codex') ? 'codex' : 'claude'
@@ -66,6 +72,7 @@ const PLANNER = (A.planner === 'codex') ? 'codex' : 'claude'
66
72
  const MODELS = (A.models && typeof A.models === 'object') ? A.models : {}
67
73
  const KNOWN_CODEX = { 'auto': 1, 'gpt-5.5': 1, 'gpt-5.6': 1 }
68
74
  const CLAUDE_NAMES = { fable: 1, opus: 1, sonnet: 1, haiku: 1 }
75
+ const VALID_REASONING = { none: 1, minimal: 1, low: 1, medium: 1, high: 1, xhigh: 1 }
69
76
  const DEFAULT_MODELS = { router: 'fable', requirements: 'sonnet', research: 'sonnet', adr: 'opus', ideation: 'sonnet', ddd: 'opus', architecture: 'opus', plan: 'sonnet', code: null, qe: null, fleet: 'sonnet' }
70
77
  const routingRequested = (Object.keys(MODELS).length > 0) || (PLANNER === 'codex') || (CODER === 'codex' || CODER === 'codex-fallback') || (QE_REVIEWER === 'codex' || QE_REVIEWER === 'codex-fallback') || (A.usageAdaptive === true)
71
78
  const modelsUsed = {}
@@ -143,7 +150,8 @@ function specToOpts(spec) {
143
150
  if (parts[0] === 'codex') {
144
151
  let id = parts[1] || CODEX_MODEL
145
152
  if (id !== 'auto' && !KNOWN_CODEX[id]) { log('models: unknown codex id ' + id + ' — using ' + CODEX_MODEL); id = CODEX_MODEL }
146
- const reasoning = parts[2] || 'high'
153
+ let reasoning = parts[2] || 'high'
154
+ if (!VALID_REASONING[reasoning]) { log('models: unknown reasoning ' + reasoning + ' — using high'); reasoning = 'high' }
147
155
  return { agentType: 'codex:codex-rescue', codexModel: id, _reasoning: reasoning }
148
156
  }
149
157
  if (CLAUDE_NAMES[parts[0]]) return { model: parts[0] }
@@ -367,7 +375,7 @@ async function designStage(promptText, opts, artifactPath, baseLabel) {
367
375
  if (!needsLandedBarrier(opts)) return await agent(promptText, opts)
368
376
  const codexOpts = {}
369
377
  for (const k in opts) if (k !== 'schema') codexOpts[k] = opts[k]
370
- const res = await agent(promptText + ' IMPORTANT: run the Codex task in FOREGROUND (synchronous — do NOT pass --background) so this call blocks until the file is fully written to disk.', codexOpts)
378
+ const res = await agent(promptText + codexEffortHint(codexOpts) + ' IMPORTANT: run the Codex task in FOREGROUND (synchronous — do NOT pass --background) so this call blocks until the file is fully written to disk.', codexOpts)
371
379
  const probe = await agent('Confirm a Codex OUT-OF-BAND artifact write has LANDED before the next stage reads it. Run EXACTLY this via Bash and return its stdout verbatim, nothing else:\n' + landedProbeCmd(artifactPath), { label: 'design:confirm-landed', phase: 'Design', effort: 'low' })
372
380
  if (res && probe && /landed=/.test(String(probe))) return { wrote: [artifactPath], summary: String(res).slice(0, 300) }
373
381
  log('design artifact did not land on codex (' + artifactPath + ') — falling back to Claude')
@@ -388,7 +396,7 @@ const routerPrompt = 'You are Step 0 (Complexity Router) of the /feature-adr pip
388
396
  const routerModel = resolveStageModel('router')
389
397
  const routerOpts = mergeOpts({ label: stageLabel('router+recall', routerModel), phase: 'Router', schema: ROUTER, effort: 'low' }, routerModel)
390
398
  modelsUsed.router = modelLabel(routerOpts)
391
- const router = await agent(routerPrompt, routerOpts)
399
+ const router = await agent(routerPrompt + codexEffortHint(routerOpts), routerOpts)
392
400
  let tier = A.tier || (router ? router.tier : 'M')
393
401
  const LEARNED = router ? router.rationale : 'none recalled'
394
402
  const isMplus = tier === 'M' || tier === 'L' || tier === 'XL'
@@ -445,8 +453,8 @@ let plan = null
445
453
  if (planIsCodex) {
446
454
  const planCodexLabelOpts = (planModel.agentType === 'codex:codex-rescue') ? planModel : specToOpts('codex:' + CODEX_MODEL + ':high')
447
455
  modelsUsed.plan = modelLabel(planCodexLabelOpts)
448
- const codexPlanOpts = mergeOpts({ label: stageLabel('plan:codex', planCodexLabelOpts), phase: 'Plan', agentType: 'codex:codex-rescue' }, planModel.agentType ? planModel : {})
449
- const codexPlan = await agent(planPrompt + ' IMPORTANT: run the Codex task in FOREGROUND (synchronous — do NOT pass --background) so this call blocks until 06_implementation_plan.md is fully written to disk.', codexPlanOpts)
456
+ const codexPlanOpts = mergeOpts({ label: stageLabel('plan:codex', planCodexLabelOpts), phase: 'Plan', agentType: 'codex:codex-rescue' }, planCodexLabelOpts)
457
+ const codexPlan = await agent(planPrompt + codexEffortHint(codexPlanOpts) + ' IMPORTANT: run the Codex task in FOREGROUND (synchronous — do NOT pass --background) so this call blocks until 06_implementation_plan.md is fully written to disk.', codexPlanOpts)
450
458
  // Codex-landed barrier for the plan artifact: a stub return is NOT proof the file was written
451
459
  // (codex writes out-of-band). Require the artifact to LAND; otherwise fall through to the Claude planner.
452
460
  const planLanded = codexPlan ? await agent('Confirm the Codex plan write has LANDED. Run EXACTLY this via Bash and return its stdout verbatim, nothing else:\n' + landedProbeCmd(FDIR + '/06_implementation_plan.md'), { label: 'plan:confirm-landed', phase: 'Plan', effort: 'low' }) : null
@@ -502,9 +510,9 @@ if (code === null && !codeIsCodexFirst) reactiveBelt('Code')
502
510
  if (code === null && (codeIsCodexFirst || CODER === 'codex-fallback')) {
503
511
  if (CODER === 'codex-fallback' && !codeIsCodexFirst) log('Code: Claude unavailable (limit?) — falling back to Codex ' + CODEX_MODEL)
504
512
  const codeCodexLabelOpts = codeModel.agentType ? codeModel : specToOpts('codex:' + CODEX_MODEL + ':high')
505
- const codeCodexOpts = mergeOpts({ label: stageLabel('code:codex', codeCodexLabelOpts), phase: 'Code', agentType: 'codex:codex-rescue' }, codeModel.agentType ? codeModel : {})
513
+ const codeCodexOpts = mergeOpts({ label: stageLabel('code:codex', codeCodexLabelOpts), phase: 'Code', agentType: 'codex:codex-rescue' }, codeCodexLabelOpts)
506
514
  const codexExpectedTargetsHint = '\n\nBecause this is running on Codex, include a final EXPECTED_CODE_TARGETS: block listing the repo-relative production/test files you expect to create or modify. List only real code/test/config/docs targets outside features/, .dz/, .agentic-qe/, and roam/. Example:\nEXPECTED_CODE_TARGETS:\n- packages/example/src/file.ts\n- packages/example/test/file.test.ts'
507
- const codexCode = await agent(codePrompt + CODEX_HINT + codexExpectedTargetsHint, codeCodexOpts)
515
+ const codexCode = await agent(codePrompt + CODEX_HINT + codexEffortHint(codeCodexOpts) + codexExpectedTargetsHint, codeCodexOpts)
508
516
  if (codexCode) { codexCodeText = String(codexCode); code = { wrote: [FDIR + '/07_code_changes/change_manifest.md'], summary: codexCodeText.slice(0, 500) }; coderUsed = codeIsCodexFirst ? 'codex' : 'codex-fallback'; modelsUsed.code = modelLabel(codeCodexLabelOpts) }
509
517
  }
510
518
 
@@ -547,8 +555,8 @@ if (qe === null && !qeIsCodex) reactiveBelt('QE')
547
555
  if (qe === null && (qeIsCodex || QE_REVIEWER === 'codex-fallback')) {
548
556
  if (QE_REVIEWER === 'codex-fallback' && !qeIsCodex) log('QE: Claude unavailable (limit?) — falling back to Codex ' + CODEX_MODEL)
549
557
  const qeCodexLabelOpts = qeModel.agentType ? qeModel : specToOpts('codex:' + CODEX_MODEL + ':high')
550
- const qeCodexOpts = mergeOpts({ label: stageLabel('qe:codex', qeCodexLabelOpts), phase: 'QE', agentType: 'codex:codex-rescue' }, qeModel.agentType ? qeModel : {})
551
- const codexQe = await agent(qePrompt + CODEX_HINT, qeCodexOpts)
558
+ const qeCodexOpts = mergeOpts({ label: stageLabel('qe:codex', qeCodexLabelOpts), phase: 'QE', agentType: 'codex:codex-rescue' }, qeCodexLabelOpts)
559
+ const codexQe = await agent(qePrompt + CODEX_HINT + codexEffortHint(qeCodexOpts), qeCodexOpts)
552
560
  if (codexQe) { qe = { grade: 'codex-review', gaps: [], codeTestsAdequate: null, docTestsPresent: null, summary: String(codexQe).slice(0, 500) }; qeReviewerUsed = qeIsCodex ? 'codex' : 'codex-fallback'; modelsUsed.qe = modelLabel(qeCodexLabelOpts) }
553
561
  }
554
562
  // Belt: if a codex-first QE returned null (codex unavailable), fall back to a Claude reviewer — never block.
@@ -570,8 +578,8 @@ if (isLplus) {
570
578
  const fleetTraceOpts = mergeOpts({ label: stageLabel('fleet:trace', fleetModel), phase: 'FleetQE', agentType: 'qe-requirements-validator' }, fleetModel)
571
579
  const fleetCovOpts = mergeOpts({ label: stageLabel('fleet:cov', fleetModel), phase: 'FleetQE', agentType: 'qe-coverage-specialist' }, fleetModel)
572
580
  const fleetThunks = [
573
- () => agent('Step 9 fleet-QE (requirements traceability + risk) for ' + SLUG + ': map ADR decisions to code to tests; flag orphans + high risk. Write ' + FDIR + '/09_fleet_qe_assessment.md.', fleetTraceOpts),
574
- () => agent('Step 9 fleet-QE (coverage + regression) for ' + SLUG + ': risk-weighted coverage gaps + regression selection for the changed files. Append to ' + FDIR + '/09_fleet_qe_assessment.md.', fleetCovOpts),
581
+ () => agent('Step 9 fleet-QE (requirements traceability + risk) for ' + SLUG + ': map ADR decisions to code to tests; flag orphans + high risk. Write ' + FDIR + '/09_fleet_qe_assessment.md.' + codexEffortHint(fleetTraceOpts), fleetTraceOpts),
582
+ () => agent('Step 9 fleet-QE (coverage + regression) for ' + SLUG + ': risk-weighted coverage gaps + regression selection for the changed files. Append to ' + FDIR + '/09_fleet_qe_assessment.md.' + codexEffortHint(fleetCovOpts), fleetCovOpts),
575
583
  ]
576
584
  await parallel(fleetThunks)
577
585
  fleet = 'run'