@adia-ai/adia-ui-forge 0.1.3 → 0.8.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/plugin.json +3 -6
- package/CHANGELOG.md +27 -34
- package/README.md +35 -40
- package/agents/a2ui-engineer.md +22 -53
- package/agents/component-author.md +29 -0
- package/agents/framework-verifier.md +26 -0
- package/agents/release-engineer.md +21 -81
- package/agents/routing-corpus.json +293 -64
- package/bin/demo-postwrite-pattern-gate +94 -0
- package/bin/forge-lint +17 -2
- package/bin/sidecar-prewrite-guard +104 -0
- package/commands/deploy.md +9 -0
- package/commands/dogfood.md +10 -0
- package/commands/gen-review.md +9 -0
- package/commands/release.md +10 -0
- package/hooks/hooks.json +15 -0
- package/package.json +3 -6
- package/references/contracts/a2ui-mcp-surface.md +35 -0
- package/references/contracts/migration-guide-format.md +34 -0
- package/references/shared/content-trust.md +19 -74
- package/skills/adia-a2ui/SKILL.md +99 -0
- package/skills/{adia-ui-a2ui → adia-a2ui}/evals/routing-corpus.json +10 -10
- package/skills/adia-a2ui/references/anti-patterns.md +27 -0
- package/skills/adia-a2ui/references/chunk-authoring.md +71 -0
- package/skills/adia-a2ui/references/corpus-discipline.md +68 -0
- package/skills/adia-a2ui/references/eval-diagnostics.md +86 -0
- package/skills/adia-a2ui/references/format-extension-decisions.md +66 -0
- package/skills/adia-a2ui/references/leverage-rules.md +52 -0
- package/skills/adia-a2ui/references/mcp-pipeline-ops.md +83 -0
- package/skills/adia-a2ui/references/mcp-tool-reference.md +59 -0
- package/skills/adia-a2ui/references/pipeline-overview.md +115 -0
- package/skills/adia-a2ui/references/semantic-fail-lifting.md +74 -0
- package/skills/adia-a2ui/references/strategy-engines.md +109 -0
- package/skills/adia-a2ui/references/zettel-calibration.md +104 -0
- package/skills/adia-author/SKILL.md +112 -0
- package/skills/adia-author/evals/routing-corpus.json +222 -0
- package/skills/{adia-ui-authoring → adia-author}/references/anti-patterns.md +33 -4
- package/skills/{adia-ui-authoring → adia-author}/references/authoring-cycle.md +9 -11
- package/skills/adia-author/references/canonical-pattern-index.md +243 -0
- package/skills/{adia-ui-authoring → adia-author}/references/code-style.md +19 -21
- package/skills/adia-author/references/common-gotchas.md +129 -0
- package/skills/adia-author/references/composite-demo-protocol.md +271 -0
- package/skills/{adia-ui-authoring → adia-author}/references/css-patterns.md +19 -6
- package/skills/{adia-ui-authoring → adia-author}/references/lifecycle-patterns.md +1 -0
- package/skills/{adia-ui-authoring → adia-author}/references/llm-bridge.md +3 -5
- package/skills/{adia-ui-authoring → adia-author}/references/module-promotion.md +20 -38
- package/skills/{adia-ui-authoring → adia-author}/references/primitive-audit.md +2 -4
- package/skills/{adia-ui-authoring → adia-author}/references/shell-patterns.md +12 -18
- package/skills/{adia-ui-authoring → adia-author}/references/token-contract.md +5 -7
- package/skills/{adia-ui-authoring → adia-author}/references/worked-example.md +3 -3
- package/skills/{adia-ui-authoring → adia-author}/references/yaml-contract.md +3 -3
- package/skills/{adia-ui-authoring → adia-author}/scripts/build-canonical-pattern-index.mjs +3 -3
- package/skills/adia-deploy/SKILL.md +128 -0
- package/skills/{adia-ui-ops → adia-deploy}/references/deploy-playbooks.md +47 -30
- package/skills/adia-dogfood/SKILL.md +124 -0
- package/skills/adia-dogfood/references/admin-shell-anatomy.md +77 -0
- package/skills/adia-dogfood/references/app-shell-pitfalls.md +66 -0
- package/skills/adia-dogfood/references/card-anatomy-sweep.md +66 -0
- package/skills/adia-dogfood/references/html-attr-sweep.md +63 -0
- package/skills/adia-dogfood/references/native-leak-annotations.md +73 -0
- package/skills/adia-dogfood/references/visual-probe-triage.md +80 -0
- package/skills/{adia-ui-dogfood → adia-dogfood}/scripts/analyze.mjs +30 -14
- package/skills/adia-gen-review/SKILL.md +127 -0
- package/skills/adia-gen-review/references/corpus-html-patterns.md +279 -0
- package/skills/adia-gen-review/references/loop-protocol.md +216 -0
- package/skills/adia-gen-review/references/rubric-cosmetic.md +100 -0
- package/skills/adia-gen-review/references/rubric-decompose.md +101 -0
- package/skills/adia-gen-review/references/rubric-score.md +214 -0
- package/skills/{adia-ui-gen-review → adia-gen-review}/references/scores.schema.json +2 -2
- package/skills/{adia-ui-gen-review → adia-gen-review}/scripts/gen-review-coverage-audit.mjs +4 -4
- package/skills/{adia-ui-gen-review → adia-gen-review}/scripts/gen-review-decompose.mjs +10 -6
- package/skills/{adia-ui-gen-review → adia-gen-review}/scripts/gen-review-status.mjs +5 -5
- package/skills/{adia-ui-gen-review → adia-gen-review}/scripts/validate-cycle-scores.mjs +5 -5
- package/skills/adia-llm-internals/SKILL.md +77 -0
- package/skills/{adia-ui-llm → adia-llm-internals}/references/adapter-contract.md +4 -2
- package/skills/{adia-ui-llm → adia-llm-internals}/references/add-a-provider.md +4 -5
- package/skills/{adia-ui-llm → adia-llm-internals}/references/bridge-facade.md +10 -3
- package/skills/{adia-ui-llm → adia-llm-internals}/references/browser-proxy-boundary.md +1 -1
- package/skills/{adia-ui-llm → adia-llm-internals}/references/model-registry.md +5 -3
- package/skills/{adia-ui-llm → adia-llm-internals}/references/streaming-sse.md +2 -2
- package/skills/adia-release/SKILL.md +72 -0
- package/skills/adia-release/references/changelog-discipline.md +119 -0
- package/skills/adia-release/references/cut-procedure.md +247 -0
- package/skills/adia-release/references/gates-catalog.md +222 -0
- package/skills/adia-release/references/independent-package-release.md +52 -0
- package/skills/adia-release/references/migration-guide-authoring.md +86 -0
- package/skills/adia-release/references/notes-authoring.md +90 -0
- package/skills/adia-release/references/recovery-paths.md +106 -0
- package/skills/{adia-ui-release → adia-release}/scripts/bump.mjs +27 -2
- package/skills/{adia-ui-release → adia-release}/scripts/dispatch-publish.mjs +4 -1
- package/skills/{adia-ui-release → adia-release}/scripts/insert-stub.mjs +1 -1
- package/skills/{adia-ui-release → adia-release}/scripts/package-paths.mjs +6 -0
- package/skills/{adia-ui-release → adia-release}/scripts/promote-unreleased.mjs +1 -1
- package/skills/{adia-ui-release → adia-release}/scripts/release-pack.mjs +13 -21
- package/skills/{adia-ui-release → adia-release}/scripts/tag-lockstep.mjs +5 -1
- package/skills/adia-site-docs/SKILL.md +68 -0
- package/skills/adia-site-docs/evals/audit-report.md +30 -0
- package/skills/adia-site-docs/evals/routing-corpus.json +176 -0
- package/skills/adia-site-docs/intent.md +72 -0
- package/agents/README.md +0 -209
- package/agents/author.md +0 -56
- package/agents/repo-steward.md +0 -56
- package/agents/spec-architect.md +0 -53
- package/agents/tech-lead.md +0 -57
- package/agents/verifier.md +0 -55
- package/bin/lib/audit-axes.mjs +0 -555
- package/bin/lib/dry-run-irreversible.mjs +0 -236
- package/bin/lib/run-skill-evals.mjs +0 -487
- package/bin/lib/teach-router.mjs +0 -250
- package/commands/adia-forge-a2ui.md +0 -10
- package/commands/adia-forge-author.md +0 -10
- package/commands/adia-forge-dogfood.md +0 -8
- package/commands/adia-forge-llm.md +0 -8
- package/commands/adia-forge-orient.md +0 -10
- package/commands/adia-forge-release.md +0 -8
- package/commands/adia-forge-review.md +0 -10
- package/references/shared/pev-rationale.md +0 -64
- package/references/shared/skill-conventions.md +0 -133
- package/skills/adia-ui-a2ui/CHANGELOG.md +0 -32
- package/skills/adia-ui-a2ui/SKILL.md +0 -243
- package/skills/adia-ui-a2ui/evals/adversarial-corpus.json +0 -75
- package/skills/adia-ui-a2ui/evals/teach-routing-cases.json +0 -100
- package/skills/adia-ui-a2ui/references/anti-patterns.md +0 -24
- package/skills/adia-ui-a2ui/references/chunk-authoring.md +0 -88
- package/skills/adia-ui-a2ui/references/corpus-discipline.md +0 -56
- package/skills/adia-ui-a2ui/references/eval-diagnostics.md +0 -127
- package/skills/adia-ui-a2ui/references/fragment-graph.md +0 -91
- package/skills/adia-ui-a2ui/references/mcp-pipeline-ops.md +0 -106
- package/skills/adia-ui-a2ui/references/mcp-tool-reference.md +0 -398
- package/skills/adia-ui-a2ui/references/pipeline-overview.md +0 -175
- package/skills/adia-ui-a2ui/references/semantic-fail-lifting.md +0 -120
- package/skills/adia-ui-a2ui/references/strategy-engines.md +0 -111
- package/skills/adia-ui-a2ui/references/teach-protocol.md +0 -220
- package/skills/adia-ui-a2ui/references/zettel-calibration.md +0 -93
- package/skills/adia-ui-a2ui/scripts/audit-a2ui-roster.mjs +0 -96
- package/skills/adia-ui-a2ui/scripts/teach-route.mjs +0 -157
- package/skills/adia-ui-a2ui/skill.json +0 -38
- package/skills/adia-ui-authoring/CHANGELOG.md +0 -32
- package/skills/adia-ui-authoring/SKILL.md +0 -256
- package/skills/adia-ui-authoring/assets/case-studies/admin-shell-decomposition.md +0 -101
- package/skills/adia-ui-authoring/assets/case-studies/maxtokens-32768-discovery.md +0 -109
- package/skills/adia-ui-authoring/assets/case-studies/theme-panel-promotion.md +0 -113
- package/skills/adia-ui-authoring/evals/adversarial-design-plan-gates.json +0 -138
- package/skills/adia-ui-authoring/evals/routing-corpus.json +0 -245
- package/skills/adia-ui-authoring/references/canonical-pattern-index.md +0 -179
- package/skills/adia-ui-authoring/references/common-gotchas.md +0 -93
- package/skills/adia-ui-authoring/references/composite-demo-protocol.md +0 -1084
- package/skills/adia-ui-authoring/references/teach-protocol.md +0 -428
- package/skills/adia-ui-authoring/scripts/audit-authoring-roster.mjs +0 -148
- package/skills/adia-ui-authoring/skill.json +0 -45
- package/skills/adia-ui-dogfood/CHANGELOG.md +0 -17
- package/skills/adia-ui-dogfood/README.md +0 -62
- package/skills/adia-ui-dogfood/SKILL.md +0 -866
- package/skills/adia-ui-dogfood/skill.json +0 -40
- package/skills/adia-ui-forge/SKILL.md +0 -88
- package/skills/adia-ui-forge/evals/routing-corpus.json +0 -30
- package/skills/adia-ui-gen-review/CHANGELOG.md +0 -108
- package/skills/adia-ui-gen-review/SKILL.md +0 -266
- package/skills/adia-ui-gen-review/references/loop-protocol.md +0 -712
- package/skills/adia-ui-gen-review/references/rubric-cosmetic.md +0 -144
- package/skills/adia-ui-gen-review/references/rubric-decompose.md +0 -117
- package/skills/adia-ui-gen-review/references/rubric-score.md +0 -249
- package/skills/adia-ui-gen-review/references/teach-protocol.md +0 -214
- package/skills/adia-ui-gen-review/skill.json +0 -23
- package/skills/adia-ui-llm/CHANGELOG.md +0 -25
- package/skills/adia-ui-llm/SKILL.md +0 -165
- package/skills/adia-ui-llm/evals/adversarial-corpus.json +0 -75
- package/skills/adia-ui-llm/evals/routing-corpus.json +0 -30
- package/skills/adia-ui-llm/evals/teach-routing-cases.json +0 -73
- package/skills/adia-ui-llm/references/teach-protocol.md +0 -78
- package/skills/adia-ui-llm/scripts/audit-llm-roster.mjs +0 -93
- package/skills/adia-ui-llm/scripts/teach-route.mjs +0 -119
- package/skills/adia-ui-llm/skill.json +0 -33
- package/skills/adia-ui-ops/CHANGELOG.md +0 -291
- package/skills/adia-ui-ops/SKILL.md +0 -401
- package/skills/adia-ui-ops/references/INDEX.md +0 -158
- package/skills/adia-ui-ops/references/audit-cadence.md +0 -263
- package/skills/adia-ui-ops/references/audit-patterns/archive-link-sweep.md +0 -96
- package/skills/adia-ui-ops/references/audit-patterns/audit-history-ledger.md +0 -162
- package/skills/adia-ui-ops/references/audit-patterns/browser-bundle-node-imports.md +0 -154
- package/skills/adia-ui-ops/references/audit-patterns/changelog-unreleased-bloat.md +0 -75
- package/skills/adia-ui-ops/references/audit-patterns/coverage-gaps.md +0 -187
- package/skills/adia-ui-ops/references/audit-patterns/entry-file-coverage.md +0 -122
- package/skills/adia-ui-ops/references/audit-patterns/format-hygiene.md +0 -217
- package/skills/adia-ui-ops/references/audit-patterns/lockstep-versioning.md +0 -113
- package/skills/adia-ui-ops/references/audit-patterns/memory-fragmentation.md +0 -180
- package/skills/adia-ui-ops/references/audit-patterns/orphan-detection.md +0 -202
- package/skills/adia-ui-ops/references/audit-patterns/pointer-validation.md +0 -180
- package/skills/adia-ui-ops/references/audit-patterns/redundancy-detection.md +0 -210
- package/skills/adia-ui-ops/references/audit-patterns/spec-dating-sweep.md +0 -91
- package/skills/adia-ui-ops/references/audit-patterns/stale-content.md +0 -182
- package/skills/adia-ui-ops/references/audit-patterns/staleness-tooling.md +0 -156
- package/skills/adia-ui-ops/references/audit-patterns/token-waste-detection.md +0 -196
- package/skills/adia-ui-ops/references/doc-types/adr-pattern.md +0 -210
- package/skills/adia-ui-ops/references/doc-types/architecture-md.md +0 -190
- package/skills/adia-ui-ops/references/doc-types/changelog.md +0 -183
- package/skills/adia-ui-ops/references/doc-types/decisions-log.md +0 -146
- package/skills/adia-ui-ops/references/doc-types/plan-roadmap.md +0 -182
- package/skills/adia-ui-ops/references/doc-types/postmortem-pattern.md +0 -206
- package/skills/adia-ui-ops/references/genres/prose-and-writing.md +0 -149
- package/skills/adia-ui-ops/references/guidance/context-budget.md +0 -137
- package/skills/adia-ui-ops/references/guidance/llm-doc-writing.md +0 -116
- package/skills/adia-ui-ops/references/guidance/reliability-dial.md +0 -186
- package/skills/adia-ui-ops/references/recipes/adr-introduction.md +0 -211
- package/skills/adia-ui-ops/references/recipes/audit-existing-repo.md +0 -234
- package/skills/adia-ui-ops/references/recipes/cold-start-harvest.md +0 -263
- package/skills/adia-ui-ops/references/recipes/concurrent-learnings-merge.md +0 -158
- package/skills/adia-ui-ops/references/recipes/continuous-learning-loop.md +0 -169
- package/skills/adia-ui-ops/references/recipes/external-reference-verification.md +0 -158
- package/skills/adia-ui-ops/references/recipes/findings-index-readout.md +0 -126
- package/skills/adia-ui-ops/references/recipes/greenfield-setup.md +0 -252
- package/skills/adia-ui-ops/references/recipes/harvest-repo-brain.md +0 -169
- package/skills/adia-ui-ops/references/recipes/import-repo-brain-harvest.md +0 -153
- package/skills/adia-ui-ops/references/recipes/memory-organization.md +0 -182
- package/skills/adia-ui-ops/references/recipes/recommend-then-validate.md +0 -199
- package/skills/adia-ui-ops/references/recipes/self-healing-hooks.md +0 -366
- package/skills/adia-ui-ops/references/recipes/skill-stewardship-loop.md +0 -113
- package/skills/adia-ui-ops/references/standards/agents-md-spec.md +0 -138
- package/skills/adia-ui-ops/references/standards/claude-md-convention.md +0 -123
- package/skills/adia-ui-ops/references/standards/cross-tool-matrix.md +0 -85
- package/skills/adia-ui-ops/references/standards/readme-conventions.md +0 -232
- package/skills/adia-ui-ops/references/teach-protocol.md +0 -215
- package/skills/adia-ui-ops/scripts/audit-ops-roster.mjs +0 -104
- package/skills/adia-ui-ops/skill.json +0 -65
- package/skills/adia-ui-release/CHANGELOG.md +0 -66
- package/skills/adia-ui-release/SKILL.md +0 -323
- package/skills/adia-ui-release/assets/case-studies/2026-05-20-batch-push-v0.6.14-v0.6.15.md +0 -144
- package/skills/adia-ui-release/assets/case-studies/2026-05-20-corpus-drift-remediation-v0.6.15.md +0 -155
- package/skills/adia-ui-release/assets/case-studies/2026-05-20-version-skip-correction-v0.6.12.md +0 -114
- package/skills/adia-ui-release/assets/case-studies/2026-05-21-author-from-scratch-v0.6.18.md +0 -139
- package/skills/adia-ui-release/assets/case-studies/2026-05-21-feedback37-retraction-v0.6.21.md +0 -124
- package/skills/adia-ui-release/assets/case-studies/2026-05-21-fn1-enrichment-pass-v0.6.19.md +0 -125
- package/skills/adia-ui-release/assets/case-studies/2026-05-21-stale-test-detection-v0.6.20.md +0 -142
- package/skills/adia-ui-release/assets/case-studies/2026-05-23-freshness-gate-recovery-v0.6.32.md +0 -97
- package/skills/adia-ui-release/assets/case-studies/2026-05-26-catalog-drift-recurring-v0.6.40.md +0 -147
- package/skills/adia-ui-release/assets/templates/stub-changelog.template.md +0 -22
- package/skills/adia-ui-release/evals/evals.json +0 -164
- package/skills/adia-ui-release/references/changelog-discipline.md +0 -250
- package/skills/adia-ui-release/references/cycle-happy-path.md +0 -520
- package/skills/adia-ui-release/references/exe-deploy.md +0 -149
- package/skills/adia-ui-release/references/gates-catalog.md +0 -778
- package/skills/adia-ui-release/references/independent-package-release.md +0 -129
- package/skills/adia-ui-release/references/ledger-discipline.md +0 -232
- package/skills/adia-ui-release/references/migration-guide-authoring.md +0 -174
- package/skills/adia-ui-release/references/multi-agent-baseline.md +0 -207
- package/skills/adia-ui-release/references/notes-authoring.md +0 -212
- package/skills/adia-ui-release/references/recovery-paths.md +0 -262
- package/skills/adia-ui-release/references/rollup-notes.md +0 -208
- package/skills/adia-ui-release/references/teach-protocol.md +0 -468
- package/skills/adia-ui-release/scripts/audit-gate-roster.mjs +0 -196
- package/skills/adia-ui-release/scripts/make-ledger.mjs +0 -200
- package/skills/adia-ui-release/skill.json +0 -77
- package/skills/dogfood-sweep/CHANGELOG.md +0 -37
- package/skills/dogfood-sweep/README.md +0 -105
- package/skills/dogfood-sweep/SKILL.md +0 -1000
- package/skills/dogfood-sweep/analyze.mjs +0 -600
- package/skills/dogfood-sweep/skill.json +0 -31
- /package/skills/{adia-ui-authoring → adia-author}/references/api-contract.md +0 -0
- /package/skills/{adia-ui-release → adia-release}/scripts/assert-monorepo-root.mjs +0 -0
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* dry-run-irreversible.mjs — Dry-run preview + confirmation for irreversible ops
|
|
4
|
-
*
|
|
5
|
-
* Wraps operations like `git push`, `npm publish`, `systemctl restart`,
|
|
6
|
-
* `gh release create` with a preview step and blast-radius-appropriate
|
|
7
|
-
* confirmation gate.
|
|
8
|
-
*
|
|
9
|
-
* Usage (per-skill script):
|
|
10
|
-
* import { executeWithAuthorization, isDryRunMode } from
|
|
11
|
-
* '${CLAUDE_PLUGIN_ROOT}/bin/lib/dry-run-irreversible.mjs';
|
|
12
|
-
*
|
|
13
|
-
* const result = await executeWithAuthorization({
|
|
14
|
-
* action: 'Publish @acme/kit@1.4.0 to npm',
|
|
15
|
-
* blastRadius: 'high',
|
|
16
|
-
* dryRun: async () => `npm pack --dry-run output:\n kit-1.4.0.tgz (42 kB)`,
|
|
17
|
-
* apply: async () => { execSync('npm publish --access public', { stdio: 'inherit' }); },
|
|
18
|
-
* options: { dryRunOnly: isDryRunMode() },
|
|
19
|
-
* });
|
|
20
|
-
*
|
|
21
|
-
* @module dry-run-irreversible
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
import readline from 'node:readline';
|
|
25
|
-
|
|
26
|
-
// ─── constants ────────────────────────────────────────────────────────────────
|
|
27
|
-
|
|
28
|
-
const BLAST_CONFIG = {
|
|
29
|
-
low: {
|
|
30
|
-
symbol: '✓',
|
|
31
|
-
label: 'LOW BLAST RADIUS',
|
|
32
|
-
note: 'local/reversible',
|
|
33
|
-
color: '\x1b[32m', // green
|
|
34
|
-
requireYes: false,
|
|
35
|
-
autoApprove: true,
|
|
36
|
-
},
|
|
37
|
-
medium: {
|
|
38
|
-
symbol: '⚡',
|
|
39
|
-
label: 'MEDIUM BLAST RADIUS',
|
|
40
|
-
note: 'shared state, reversible with effort',
|
|
41
|
-
color: '\x1b[33m', // yellow
|
|
42
|
-
requireYes: false,
|
|
43
|
-
autoApprove: false,
|
|
44
|
-
},
|
|
45
|
-
high: {
|
|
46
|
-
symbol: '⚠',
|
|
47
|
-
label: 'HIGH BLAST RADIUS',
|
|
48
|
-
note: 'irreversible (publish/push/ssh-write)',
|
|
49
|
-
color: '\x1b[31m', // red
|
|
50
|
-
requireYes: true,
|
|
51
|
-
autoApprove: false,
|
|
52
|
-
},
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const RESET = '\x1b[0m';
|
|
56
|
-
const BOLD = '\x1b[1m';
|
|
57
|
-
|
|
58
|
-
// ─── helpers ──────────────────────────────────────────────────────────────────
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Return a formatted blast-radius label string for display.
|
|
62
|
-
* @param {'low'|'medium'|'high'} br
|
|
63
|
-
* @returns {string}
|
|
64
|
-
*/
|
|
65
|
-
export function blastRadiusLabel(br) {
|
|
66
|
-
const cfg = BLAST_CONFIG[br];
|
|
67
|
-
if (!cfg) throw new Error(`Unknown blastRadius: ${br}`);
|
|
68
|
-
return `${cfg.color}${BOLD}${cfg.symbol} ${cfg.label}${RESET} — ${cfg.note}`;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Check whether the current process was invoked with --dry-run or DRY_RUN=1.
|
|
73
|
-
* @returns {boolean}
|
|
74
|
-
*/
|
|
75
|
-
export function isDryRunMode() {
|
|
76
|
-
return process.argv.includes('--dry-run') || process.env.DRY_RUN === '1';
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Default stdin prompter. Reads one line from stdin.
|
|
81
|
-
* @param {string} question
|
|
82
|
-
* @returns {Promise<string>}
|
|
83
|
-
*/
|
|
84
|
-
function stdinPrompter(question) {
|
|
85
|
-
return new Promise(resolve => {
|
|
86
|
-
const rl = readline.createInterface({
|
|
87
|
-
input: process.stdin,
|
|
88
|
-
output: process.stdout,
|
|
89
|
-
terminal: true,
|
|
90
|
-
});
|
|
91
|
-
rl.question(question, answer => {
|
|
92
|
-
rl.close();
|
|
93
|
-
resolve(answer.trim());
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// ─── core export ──────────────────────────────────────────────────────────────
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Execute an irreversible operation with dry-run preview and confirmation.
|
|
102
|
-
*
|
|
103
|
-
* @param {{
|
|
104
|
-
* action: string,
|
|
105
|
-
* dryRun: () => Promise<string>,
|
|
106
|
-
* apply: () => Promise<any>,
|
|
107
|
-
* blastRadius: 'low'|'medium'|'high',
|
|
108
|
-
* options?: {
|
|
109
|
-
* autoApprove?: boolean,
|
|
110
|
-
* force?: boolean,
|
|
111
|
-
* dryRunOnly?: boolean,
|
|
112
|
-
* prompter?: (q: string) => Promise<string>
|
|
113
|
-
* }
|
|
114
|
-
* }} params
|
|
115
|
-
*
|
|
116
|
-
* @returns {Promise<{
|
|
117
|
-
* status: 'applied'|'declined'|'dry-run-only'|'applied-forced',
|
|
118
|
-
* result?: any,
|
|
119
|
-
* preview?: string,
|
|
120
|
-
* reason?: string
|
|
121
|
-
* }>}
|
|
122
|
-
*/
|
|
123
|
-
export async function executeWithAuthorization({ action, dryRun, apply, blastRadius, options = {} }) {
|
|
124
|
-
if (!action) throw new Error('action is required');
|
|
125
|
-
if (typeof dryRun !== 'function') throw new Error('dryRun must be an async function');
|
|
126
|
-
if (typeof apply !== 'function') throw new Error('apply must be an async function');
|
|
127
|
-
|
|
128
|
-
const cfg = BLAST_CONFIG[blastRadius];
|
|
129
|
-
if (!cfg) throw new Error(`blastRadius must be 'low', 'medium', or 'high'`);
|
|
130
|
-
|
|
131
|
-
const {
|
|
132
|
-
autoApprove: autoApproveOpt,
|
|
133
|
-
force = false,
|
|
134
|
-
dryRunOnly = false,
|
|
135
|
-
prompter = stdinPrompter,
|
|
136
|
-
} = options;
|
|
137
|
-
|
|
138
|
-
// force skips everything — dangerous but explicit
|
|
139
|
-
if (force) {
|
|
140
|
-
const result = await apply();
|
|
141
|
-
return { status: 'applied-forced', result, reason: '--force flag bypassed confirmation' };
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Always run the dry-run preview first
|
|
145
|
-
let preview;
|
|
146
|
-
try {
|
|
147
|
-
preview = await dryRun();
|
|
148
|
-
} catch (err) {
|
|
149
|
-
throw new Error(`dryRun() threw: ${err.message}`);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Print blast-radius warning (prominent for high)
|
|
153
|
-
if (blastRadius === 'high') {
|
|
154
|
-
console.log(`\n${cfg.color}${BOLD}${'─'.repeat(60)}${RESET}`);
|
|
155
|
-
console.log(blastRadiusLabel(blastRadius));
|
|
156
|
-
console.log(`${cfg.color}${BOLD}${'─'.repeat(60)}${RESET}\n`);
|
|
157
|
-
} else {
|
|
158
|
-
console.log(`\n${blastRadiusLabel(blastRadius)}\n`);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
console.log(`${BOLD}Action:${RESET} ${action}`);
|
|
162
|
-
console.log(`\n${BOLD}Dry-run preview:${RESET}`);
|
|
163
|
-
console.log(preview);
|
|
164
|
-
|
|
165
|
-
if (dryRunOnly) {
|
|
166
|
-
console.log('\n(dry-run-only mode — not applying)');
|
|
167
|
-
return { status: 'dry-run-only', preview };
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// Auto-approve low blast radius unless explicitly disabled
|
|
171
|
-
const canAutoApprove = (autoApproveOpt ?? cfg.autoApprove) && blastRadius === 'low';
|
|
172
|
-
if (canAutoApprove) {
|
|
173
|
-
console.log(`\n${BLAST_CONFIG.low.color}Auto-approved (low blast radius).${RESET}`);
|
|
174
|
-
const result = await apply();
|
|
175
|
-
return { status: 'applied', result, preview };
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
// Prompt for confirmation
|
|
179
|
-
let answer;
|
|
180
|
-
if (cfg.requireYes) {
|
|
181
|
-
answer = await prompter(`\nType ${BOLD}yes${RESET} to confirm, anything else to abort: `);
|
|
182
|
-
if (answer !== 'yes') {
|
|
183
|
-
console.log('Aborted.');
|
|
184
|
-
return { status: 'declined', preview, reason: `User typed '${answer}' instead of 'yes'` };
|
|
185
|
-
}
|
|
186
|
-
} else {
|
|
187
|
-
answer = await prompter('\nApply? [y/N] ');
|
|
188
|
-
if (!/^y(es)?$/i.test(answer)) {
|
|
189
|
-
console.log('Aborted.');
|
|
190
|
-
return { status: 'declined', preview, reason: 'User declined' };
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
const result = await apply();
|
|
195
|
-
console.log('\nApplied.');
|
|
196
|
-
return { status: 'applied', result, preview };
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// ─── convenience wrapper ──────────────────────────────────────────────────────
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Wrap a CLI script's main function with dry-run / blast-radius handling.
|
|
203
|
-
* The returned function accepts raw CLI args and calls back into the script.
|
|
204
|
-
*
|
|
205
|
-
* @param {(args: string[]) => Promise<any>} script
|
|
206
|
-
* @param {{ action: string, blastRadius: 'low'|'medium'|'high' }} meta
|
|
207
|
-
* @returns {(args: string[]) => Promise<{
|
|
208
|
-
* status: 'applied'|'declined'|'dry-run-only'|'applied-forced',
|
|
209
|
-
* result?: any,
|
|
210
|
-
* preview?: string
|
|
211
|
-
* }>}
|
|
212
|
-
*/
|
|
213
|
-
export function wrapScript(script, { action, blastRadius }) {
|
|
214
|
-
return async function wrappedScript(args = []) {
|
|
215
|
-
const isDry = args.includes('--dry-run') || isDryRunMode();
|
|
216
|
-
const isForce = args.includes('--force');
|
|
217
|
-
|
|
218
|
-
return executeWithAuthorization({
|
|
219
|
-
action,
|
|
220
|
-
blastRadius,
|
|
221
|
-
dryRun: async () => {
|
|
222
|
-
// Scripts that support --dry-run should honour the flag themselves
|
|
223
|
-
const dryArgs = isDry ? args : [...args, '--dry-run'];
|
|
224
|
-
const preview = await script(dryArgs);
|
|
225
|
-
return typeof preview === 'string'
|
|
226
|
-
? preview
|
|
227
|
-
: JSON.stringify(preview, null, 2);
|
|
228
|
-
},
|
|
229
|
-
apply: async () => script(args),
|
|
230
|
-
options: {
|
|
231
|
-
dryRunOnly: isDry && !isForce,
|
|
232
|
-
force: isForce,
|
|
233
|
-
},
|
|
234
|
-
});
|
|
235
|
-
};
|
|
236
|
-
}
|