devflow-kit 1.8.2 → 2.0.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 +191 -6
- package/LICENSE +1 -1
- package/README.md +139 -219
- package/dist/cli/agents-view/index.js +9 -0
- package/dist/cli/agents-view/render.js +310 -0
- package/dist/cli/agents-view/state.js +423 -0
- package/dist/cli/agents-view/terminal.js +179 -0
- package/dist/cli/commands/agents.js +585 -0
- package/dist/cli/commands/ambient.js +231 -0
- package/dist/cli/commands/capture.js +133 -0
- package/dist/cli/commands/compliance-prompts.js +174 -0
- package/dist/cli/commands/compliance.js +337 -0
- package/dist/cli/commands/context.js +66 -0
- package/dist/cli/commands/debug.js +122 -0
- package/dist/cli/commands/flags.js +119 -0
- package/dist/cli/commands/hud.js +229 -0
- package/dist/cli/commands/init-seed.js +226 -0
- package/dist/cli/commands/init.js +1786 -0
- package/dist/cli/commands/knowledge/index.js +25 -0
- package/dist/cli/commands/knowledge/list.js +115 -0
- package/dist/cli/commands/knowledge/toggle.js +84 -0
- package/dist/cli/commands/learning.js +311 -0
- package/dist/cli/commands/legacy-hooks.js +40 -0
- package/dist/cli/commands/memory.js +349 -0
- package/dist/cli/commands/proxy.js +1435 -0
- package/dist/cli/commands/rules.js +334 -0
- package/dist/cli/commands/safe-delete.js +140 -0
- package/dist/cli/commands/security.js +179 -0
- package/dist/cli/commands/skills.js +140 -0
- package/dist/cli/commands/uninstall.js +1214 -0
- package/dist/cli.js +35 -10
- package/dist/commands/bug-analysis.md +400 -0
- package/dist/commands/code-review.md +403 -0
- package/dist/commands/debug.md +282 -0
- package/dist/commands/dynamic-build.md +972 -0
- package/dist/commands/dynamic-plan.md +383 -0
- package/dist/commands/dynamic-profile.md +206 -0
- package/dist/commands/dynamic-tickets.md +583 -0
- package/dist/commands/explore.md +208 -0
- package/dist/commands/implement.md +590 -0
- package/dist/commands/plan.md +570 -0
- package/dist/commands/release.md +206 -0
- package/dist/commands/research.md +212 -0
- package/dist/commands/resolve.md +731 -0
- package/dist/commands/self-review.md +251 -0
- package/dist/core/agent-frontmatter.js +209 -0
- package/dist/core/agent-models.js +556 -0
- package/dist/core/agent-state.js +44 -0
- package/dist/core/assets.js +39 -0
- package/dist/core/cache.js +205 -0
- package/dist/core/codex-auth-inspect.js +128 -0
- package/dist/core/compliance-compose.js +458 -0
- package/dist/core/compliance.js +165 -0
- package/dist/core/external-models.js +76 -0
- package/dist/core/feature-config.js +125 -0
- package/dist/core/flags.js +309 -0
- package/dist/core/fs-atomic.js +74 -0
- package/dist/core/git.js +61 -0
- package/dist/core/learning-queue-cleanup.js +92 -0
- package/dist/core/learning-tuning-config.js +78 -0
- package/dist/core/manifest.js +171 -0
- package/dist/core/migrations.js +330 -0
- package/dist/core/model-discovery.js +655 -0
- package/dist/core/observation-io.js +50 -0
- package/dist/core/observations.js +109 -0
- package/dist/core/orphan-sweep.js +92 -0
- package/dist/core/paths.js +48 -0
- package/dist/core/plugins.js +525 -0
- package/dist/core/project-paths.js +159 -0
- package/dist/core/proxy-log.js +165 -0
- package/dist/core/proxy-state.js +305 -0
- package/dist/core/safe-delete-install.js +191 -0
- package/dist/core/teammate-mode-cleanup.js +33 -0
- package/dist/hud/colors.js +13 -2
- package/dist/hud/components/config-counts.js +2 -2
- package/dist/hud/components/context-usage.js +2 -2
- package/dist/hud/components/learning-counts.js +92 -0
- package/dist/hud/components/session-cost.js +10 -2
- package/dist/hud/components/usage-quota.js +43 -8
- package/dist/hud/components/version-badge.js +17 -7
- package/dist/hud/config.js +4 -2
- package/dist/hud/cost-history.js +281 -0
- package/dist/hud/git.js +112 -71
- package/dist/hud/index.js +47 -4
- package/dist/hud/render.js +8 -20
- package/dist/hud/transcript.js +5 -6
- package/dist/targets/claude-code/claude-paths.js +106 -0
- package/dist/targets/claude-code/compliance-install.js +305 -0
- package/dist/targets/claude-code/hooks.js +9 -0
- package/dist/targets/claude-code/installer.js +458 -0
- package/dist/targets/claude-code/legacy.js +239 -0
- package/dist/targets/claude-code/post-install.js +971 -0
- package/package.json +23 -17
- package/src/assets/agents/code.md +244 -0
- package/src/assets/agents/design.md +113 -0
- package/src/assets/agents/diagnose.md +210 -0
- package/src/assets/agents/evaluate.md +117 -0
- package/src/assets/agents/git.md +938 -0
- package/src/assets/agents/knowledge.md +89 -0
- package/src/assets/agents/learning.md +203 -0
- package/src/assets/agents/research.md +134 -0
- package/src/assets/agents/review.md +220 -0
- package/src/assets/agents/scrutinize.md +95 -0
- package/src/assets/agents/simplify.md +108 -0
- package/src/assets/agents/skim.md +136 -0
- package/src/assets/agents/synthesize.md +402 -0
- package/src/assets/agents/test.md +155 -0
- package/src/assets/agents/triage.md +141 -0
- package/src/assets/agents/validate.md +103 -0
- package/src/assets/commands/_partials/_compliance.mds +5 -0
- package/src/assets/commands/_partials/_decisions.mds +20 -0
- package/src/assets/commands/_partials/_engine.mds +244 -0
- package/src/assets/commands/_partials/_factory.mds +216 -0
- package/src/assets/commands/_partials/_knowledge.mds +95 -0
- package/src/assets/commands/_partials/_plan_contract.mds +51 -0
- package/src/assets/commands/_partials/_preamble.mds +82 -0
- package/src/assets/commands/_partials/_publication.mds +7 -0
- package/src/assets/commands/_partials/_roster.mds +31 -0
- package/src/assets/commands/_partials/_ticket_template.mds +59 -0
- package/src/assets/commands/_partials/_wave.mds +123 -0
- package/src/assets/commands/bug-analysis.mds +353 -0
- package/src/assets/commands/code-review.mds +355 -0
- package/src/assets/commands/debug.mds +224 -0
- package/src/assets/commands/dynamic-build.mds +534 -0
- package/src/assets/commands/dynamic-plan.mds +244 -0
- package/src/assets/commands/dynamic-profile.mds +132 -0
- package/src/assets/commands/dynamic-tickets.mds +226 -0
- package/src/assets/commands/explore.mds +150 -0
- package/src/assets/commands/implement.mds +496 -0
- package/src/assets/commands/plan.mds +523 -0
- package/src/assets/commands/release.md +206 -0
- package/src/assets/commands/research.mds +164 -0
- package/src/assets/commands/resolve.mds +636 -0
- package/src/assets/commands/self-review.mds +156 -0
- package/src/assets/rules/accessibility.md +11 -0
- package/src/assets/rules/compliance.md +15 -0
- package/src/assets/rules/engineering.md +13 -0
- package/src/assets/rules/go.md +12 -0
- package/src/assets/rules/java.md +12 -0
- package/src/assets/rules/python.md +12 -0
- package/src/assets/rules/quality.md +14 -0
- package/src/assets/rules/react.md +11 -0
- package/src/assets/rules/reliability.md +12 -0
- package/src/assets/rules/rust.md +12 -0
- package/src/assets/rules/security.md +12 -0
- package/src/assets/rules/typescript.md +12 -0
- package/src/assets/rules/ui-design.md +11 -0
- package/src/assets/scripts/hooks/assets/orchestrator-charter.md +21 -0
- package/src/assets/scripts/hooks/background-memory-update +460 -0
- package/src/assets/scripts/hooks/capture-prompt +87 -0
- package/src/assets/scripts/hooks/capture-question +153 -0
- package/src/assets/scripts/hooks/capture-turn +105 -0
- package/src/assets/scripts/hooks/debug-trace +75 -0
- package/src/assets/scripts/hooks/decisions-usage-scan.cjs +131 -0
- package/src/assets/scripts/hooks/ensure-devflow-init +39 -0
- package/src/assets/scripts/hooks/ensure-proxy +294 -0
- package/src/assets/scripts/hooks/ensure-root-gitignore +116 -0
- package/src/assets/scripts/hooks/get-mtime +23 -0
- package/src/assets/scripts/hooks/git-marker +16 -0
- package/src/assets/scripts/hooks/hook-bootstrap +25 -0
- package/src/assets/scripts/hooks/hook-log-init +41 -0
- package/src/assets/scripts/hooks/json-helper.cjs +725 -0
- package/src/assets/scripts/hooks/json-parse +243 -0
- package/src/assets/scripts/hooks/learning-lock +44 -0
- package/src/assets/scripts/hooks/lib/decisions-format.cjs +301 -0
- package/src/assets/scripts/hooks/lib/mkdir-lock.cjs +106 -0
- package/src/assets/scripts/hooks/lib/project-paths.cjs +230 -0
- package/src/assets/scripts/hooks/lib/render-decisions.cjs +398 -0
- package/src/assets/scripts/hooks/lib/safe-path.cjs +29 -0
- package/src/assets/scripts/hooks/log-paths +24 -0
- package/src/assets/scripts/hooks/memory-worker +101 -0
- package/src/assets/scripts/hooks/pre-compact-memory +126 -0
- package/src/assets/scripts/hooks/preamble +77 -0
- package/src/assets/scripts/hooks/queue-append +120 -0
- package/src/assets/scripts/hooks/resolve-project-root +37 -0
- package/src/assets/scripts/hooks/run-hook +31 -0
- package/src/assets/scripts/hooks/session-start-context +180 -0
- package/src/assets/scripts/hooks/session-start-memory +318 -0
- package/src/assets/scripts/hooks/session-start-orchestrator +54 -0
- package/src/assets/scripts/hud.sh +5 -0
- package/src/assets/scripts/redact-secrets.cjs +410 -0
- package/src/assets/skills/accessibility/SKILL.md +145 -0
- package/src/assets/skills/accessibility/references/patterns.md +398 -0
- package/src/assets/skills/accessibility/references/sources.md +26 -0
- package/src/assets/skills/accessibility/references/violations.md +358 -0
- package/src/assets/skills/apply-decisions/SKILL.md +100 -0
- package/src/assets/skills/apply-feature-knowledge/SKILL.md +69 -0
- package/src/assets/skills/architecture/SKILL.md +138 -0
- package/src/assets/skills/architecture/references/patterns.md +378 -0
- package/src/assets/skills/architecture/references/sources.md +41 -0
- package/src/assets/skills/architecture/references/violations.md +314 -0
- package/src/assets/skills/boundary-validation/SKILL.md +119 -0
- package/src/assets/skills/boundary-validation/references/detection.md +283 -0
- package/src/assets/skills/boundary-validation/references/patterns.md +283 -0
- package/src/assets/skills/boundary-validation/references/sources.md +41 -0
- package/src/assets/skills/boundary-validation/references/violations.md +211 -0
- package/src/assets/skills/complexity/SKILL.md +150 -0
- package/src/assets/skills/compliance/SKILL.md +121 -0
- package/src/assets/skills/compliance/frameworks/gdpr/fragment.md +11 -0
- package/src/assets/skills/compliance/frameworks/gdpr/reference.md +50 -0
- package/src/assets/skills/compliance/frameworks/hipaa/fragment.md +11 -0
- package/src/assets/skills/compliance/frameworks/hipaa/reference.md +44 -0
- package/src/assets/skills/compliance/frameworks/iso-27001/fragment.md +10 -0
- package/src/assets/skills/compliance/frameworks/iso-27001/reference.md +45 -0
- package/src/assets/skills/compliance/frameworks/pci-dss/fragment.md +11 -0
- package/src/assets/skills/compliance/frameworks/pci-dss/reference.md +55 -0
- package/src/assets/skills/compliance/frameworks/soc2/fragment.md +10 -0
- package/src/assets/skills/compliance/frameworks/soc2/reference.md +53 -0
- package/src/assets/skills/compliance/frameworks/sox/fragment.md +10 -0
- package/src/assets/skills/compliance/frameworks/sox/reference.md +67 -0
- package/src/assets/skills/compliance/references/detection.md +108 -0
- package/src/assets/skills/compliance/references/sources.md +28 -0
- package/src/assets/skills/consistency/SKILL.md +140 -0
- package/src/assets/skills/database/SKILL.md +134 -0
- package/src/assets/skills/dependencies/SKILL.md +141 -0
- package/src/assets/skills/dependency-research/SKILL.md +133 -0
- package/src/assets/skills/dependency-research/references/evaluation-criteria.md +101 -0
- package/src/assets/skills/design-review/SKILL.md +155 -0
- package/src/assets/skills/design-review/references/anti-patterns.md +207 -0
- package/src/assets/skills/docs-framework/SKILL.md +190 -0
- package/src/assets/skills/docs-framework/references/patterns.md +381 -0
- package/src/assets/skills/docs-framework/references/violations.md +221 -0
- package/src/assets/skills/documentation/SKILL.md +126 -0
- package/src/assets/skills/feature-knowledge/SKILL.md +341 -0
- package/src/assets/skills/gap-analysis/SKILL.md +151 -0
- package/src/assets/skills/gap-analysis/references/check-layers.md +125 -0
- package/src/assets/skills/git/SKILL.md +287 -0
- package/src/assets/skills/git/references/github-api.md +666 -0
- package/src/assets/skills/git/references/patterns.md +324 -0
- package/src/assets/skills/git/references/sources.md +16 -0
- package/src/assets/skills/git/references/violations.md +128 -0
- package/src/assets/skills/go/SKILL.md +147 -0
- package/src/assets/skills/go/references/concurrency.md +335 -0
- package/src/assets/skills/go/references/patterns.md +278 -0
- package/src/assets/skills/go/references/sources.md +41 -0
- package/src/assets/skills/go/references/violations.md +262 -0
- package/src/assets/skills/java/SKILL.md +148 -0
- package/src/assets/skills/java/references/modern-java.md +335 -0
- package/src/assets/skills/java/references/patterns.md +311 -0
- package/src/assets/skills/java/references/sources.md +44 -0
- package/src/assets/skills/java/references/violations.md +257 -0
- package/src/assets/skills/patterns/SKILL.md +162 -0
- package/src/assets/skills/performance/SKILL.md +135 -0
- package/src/assets/skills/performance/references/patterns.md +516 -0
- package/src/assets/skills/performance/references/sources.md +41 -0
- package/src/assets/skills/performance/references/violations.md +417 -0
- package/src/assets/skills/python/SKILL.md +156 -0
- package/src/assets/skills/python/references/async.md +255 -0
- package/src/assets/skills/python/references/patterns.md +280 -0
- package/src/assets/skills/python/references/sources.md +41 -0
- package/src/assets/skills/python/references/violations.md +272 -0
- package/src/assets/skills/qa/SKILL.md +136 -0
- package/src/assets/skills/qa/references/browser-testing.md +97 -0
- package/src/assets/skills/qa/references/patterns.md +118 -0
- package/src/assets/skills/qa/references/scenario-templates.md +102 -0
- package/src/assets/skills/qa/references/sources.md +30 -0
- package/src/assets/skills/qa/references/violations.md +98 -0
- package/src/assets/skills/quality-gates/SKILL.md +152 -0
- package/src/assets/skills/quality-gates/references/stub-detection.md +135 -0
- package/src/assets/skills/react/SKILL.md +143 -0
- package/src/assets/skills/react/references/error-handling.md +179 -0
- package/src/assets/skills/react/references/forms.md +214 -0
- package/src/assets/skills/react/references/hooks.md +193 -0
- package/src/assets/skills/react/references/patterns.md +1336 -0
- package/src/assets/skills/react/references/sources.md +35 -0
- package/src/assets/skills/react/references/violations.md +570 -0
- package/src/assets/skills/regression/SKILL.md +146 -0
- package/src/assets/skills/reliability/SKILL.md +153 -0
- package/src/assets/skills/reliability/references/detection.md +66 -0
- package/src/assets/skills/reliability/references/patterns.md +151 -0
- package/src/assets/skills/reliability/references/sources.md +27 -0
- package/src/assets/skills/reliability/references/violations.md +125 -0
- package/src/assets/skills/research-codebase/SKILL.md +135 -0
- package/src/assets/skills/research-competitor/SKILL.md +145 -0
- package/src/assets/skills/research-external/SKILL.md +141 -0
- package/src/assets/skills/research-market/SKILL.md +145 -0
- package/src/assets/skills/research-technology/SKILL.md +180 -0
- package/src/assets/skills/review-methodology/SKILL.md +121 -0
- package/src/assets/skills/review-methodology/references/patterns.md +186 -0
- package/src/assets/skills/review-methodology/references/report-template.md +142 -0
- package/src/assets/skills/review-methodology/references/violations.md +125 -0
- package/src/assets/skills/rust/SKILL.md +148 -0
- package/src/assets/skills/rust/references/ownership.md +278 -0
- package/src/assets/skills/rust/references/patterns.md +247 -0
- package/src/assets/skills/rust/references/sources.md +46 -0
- package/src/assets/skills/rust/references/violations.md +252 -0
- package/src/assets/skills/security/SKILL.md +121 -0
- package/src/assets/skills/security/references/patterns.md +271 -0
- package/src/assets/skills/security/references/sources.md +41 -0
- package/src/assets/skills/security/references/violations.md +241 -0
- package/src/assets/skills/software-design/SKILL.md +143 -0
- package/src/assets/skills/software-design/references/checklist.md +259 -0
- package/src/assets/skills/software-design/references/code-smell-violations.md +189 -0
- package/src/assets/skills/software-design/references/patterns.md +359 -0
- package/src/assets/skills/software-design/references/sources.md +41 -0
- package/src/assets/skills/software-design/references/violations.md +341 -0
- package/src/assets/skills/test-driven-development/SKILL.md +197 -0
- package/src/assets/skills/testing/SKILL.md +139 -0
- package/src/assets/skills/testing/references/patterns.md +346 -0
- package/src/assets/skills/testing/references/sources.md +53 -0
- package/src/assets/skills/testing/references/violations.md +322 -0
- package/src/assets/skills/typescript/SKILL.md +150 -0
- package/src/assets/skills/typescript/references/async.md +333 -0
- package/src/assets/skills/typescript/references/patterns.md +440 -0
- package/src/assets/skills/typescript/references/sources.md +41 -0
- package/src/assets/skills/typescript/references/type-guards.md +333 -0
- package/src/assets/skills/typescript/references/utility-types.md +255 -0
- package/src/assets/skills/typescript/references/violations.md +285 -0
- package/src/assets/skills/ui-design/SKILL.md +144 -0
- package/src/assets/skills/ui-design/references/patterns.md +341 -0
- package/src/assets/skills/ui-design/references/sources.md +41 -0
- package/src/assets/skills/ui-design/references/violations.md +312 -0
- package/src/assets/skills/worktree-support/SKILL.md +92 -0
- package/src/targets/claude-code/templates/claudeignore.template +188 -0
- package/src/targets/claude-code/templates/settings.json +86 -0
- package/dist/cli.d.ts +0 -3
- package/dist/commands/ambient.d.ts +0 -18
- package/dist/commands/ambient.js +0 -137
- package/dist/commands/hud.d.ts +0 -22
- package/dist/commands/hud.js +0 -180
- package/dist/commands/init.d.ts +0 -16
- package/dist/commands/init.js +0 -738
- package/dist/commands/list.d.ts +0 -24
- package/dist/commands/list.js +0 -89
- package/dist/commands/memory.d.ts +0 -22
- package/dist/commands/memory.js +0 -175
- package/dist/commands/skills.d.ts +0 -11
- package/dist/commands/skills.js +0 -116
- package/dist/commands/uninstall.d.ts +0 -22
- package/dist/commands/uninstall.js +0 -558
- package/dist/hud/cache.d.ts +0 -14
- package/dist/hud/cache.js +0 -54
- package/dist/hud/colors.d.ts +0 -23
- package/dist/hud/components/config-counts.d.ts +0 -8
- package/dist/hud/components/context-usage.d.ts +0 -8
- package/dist/hud/components/diff-stats.d.ts +0 -3
- package/dist/hud/components/directory.d.ts +0 -3
- package/dist/hud/components/git-ahead-behind.d.ts +0 -3
- package/dist/hud/components/git-branch.d.ts +0 -3
- package/dist/hud/components/model.d.ts +0 -3
- package/dist/hud/components/release-info.d.ts +0 -3
- package/dist/hud/components/session-cost.d.ts +0 -3
- package/dist/hud/components/session-duration.d.ts +0 -3
- package/dist/hud/components/todo-progress.d.ts +0 -3
- package/dist/hud/components/usage-quota.d.ts +0 -3
- package/dist/hud/components/version-badge.d.ts +0 -3
- package/dist/hud/components/worktree-count.d.ts +0 -3
- package/dist/hud/config.d.ts +0 -10
- package/dist/hud/credentials.d.ts +0 -17
- package/dist/hud/credentials.js +0 -99
- package/dist/hud/git.d.ts +0 -7
- package/dist/hud/index.d.ts +0 -2
- package/dist/hud/render.d.ts +0 -7
- package/dist/hud/stdin.d.ts +0 -6
- package/dist/hud/transcript.d.ts +0 -7
- package/dist/hud/types.d.ts +0 -116
- package/dist/hud/usage-api.d.ts +0 -7
- package/dist/hud/usage-api.js +0 -84
- package/dist/plugins.d.ts +0 -46
- package/dist/plugins.js +0 -233
- package/dist/utils/cli.d.ts +0 -5
- package/dist/utils/cli.js +0 -14
- package/dist/utils/git.d.ts +0 -11
- package/dist/utils/git.js +0 -36
- package/dist/utils/installer.d.ts +0 -41
- package/dist/utils/installer.js +0 -195
- package/dist/utils/manifest.d.ts +0 -46
- package/dist/utils/manifest.js +0 -100
- package/dist/utils/paths.d.ts +0 -42
- package/dist/utils/paths.js +0 -106
- package/dist/utils/post-install.d.ts +0 -87
- package/dist/utils/post-install.js +0 -546
- package/dist/utils/safe-delete-install.d.ts +0 -29
- package/dist/utils/safe-delete-install.js +0 -191
- package/dist/utils/safe-delete.d.ts +0 -12
- package/plugins/devflow-accessibility/.claude-plugin/plugin.json +0 -21
- package/plugins/devflow-accessibility/skills/accessibility/SKILL.md +0 -229
- package/plugins/devflow-accessibility/skills/accessibility/references/patterns.md +0 -670
- package/plugins/devflow-accessibility/skills/accessibility/references/violations.md +0 -419
- package/plugins/devflow-ambient/.claude-plugin/plugin.json +0 -33
- package/plugins/devflow-ambient/README.md +0 -68
- package/plugins/devflow-ambient/agents/coder.md +0 -135
- package/plugins/devflow-ambient/agents/reviewer.md +0 -165
- package/plugins/devflow-ambient/agents/scrutinizer.md +0 -82
- package/plugins/devflow-ambient/agents/shepherd.md +0 -108
- package/plugins/devflow-ambient/agents/simplifier.md +0 -102
- package/plugins/devflow-ambient/agents/skimmer.md +0 -143
- package/plugins/devflow-ambient/agents/validator.md +0 -86
- package/plugins/devflow-ambient/skills/ambient-router/SKILL.md +0 -145
- package/plugins/devflow-ambient/skills/ambient-router/references/skill-catalog.md +0 -74
- package/plugins/devflow-ambient/skills/debug-orchestration/SKILL.md +0 -69
- package/plugins/devflow-ambient/skills/implementation-orchestration/SKILL.md +0 -92
- package/plugins/devflow-ambient/skills/plan-orchestration/SKILL.md +0 -71
- package/plugins/devflow-audit-claude/.claude-plugin/plugin.json +0 -19
- package/plugins/devflow-audit-claude/README.md +0 -46
- package/plugins/devflow-audit-claude/agents/claude-md-auditor.md +0 -134
- package/plugins/devflow-audit-claude/commands/audit-claude.md +0 -89
- package/plugins/devflow-code-review/.claude-plugin/plugin.json +0 -38
- package/plugins/devflow-code-review/README.md +0 -73
- package/plugins/devflow-code-review/agents/git.md +0 -277
- package/plugins/devflow-code-review/agents/reviewer.md +0 -165
- package/plugins/devflow-code-review/agents/synthesizer.md +0 -211
- package/plugins/devflow-code-review/commands/code-review-teams.md +0 -285
- package/plugins/devflow-code-review/commands/code-review.md +0 -163
- package/plugins/devflow-code-review/skills/agent-teams/SKILL.md +0 -124
- package/plugins/devflow-code-review/skills/agent-teams/references/cleanup.md +0 -104
- package/plugins/devflow-code-review/skills/agent-teams/references/communication.md +0 -122
- package/plugins/devflow-code-review/skills/agent-teams/references/team-patterns.md +0 -217
- package/plugins/devflow-code-review/skills/architecture-patterns/SKILL.md +0 -153
- package/plugins/devflow-code-review/skills/architecture-patterns/references/patterns.md +0 -873
- package/plugins/devflow-code-review/skills/architecture-patterns/references/violations.md +0 -575
- package/plugins/devflow-code-review/skills/complexity-patterns/SKILL.md +0 -143
- package/plugins/devflow-code-review/skills/consistency-patterns/SKILL.md +0 -140
- package/plugins/devflow-code-review/skills/database-patterns/SKILL.md +0 -134
- package/plugins/devflow-code-review/skills/dependencies-patterns/SKILL.md +0 -141
- package/plugins/devflow-code-review/skills/documentation-patterns/SKILL.md +0 -125
- package/plugins/devflow-code-review/skills/knowledge-persistence/SKILL.md +0 -128
- package/plugins/devflow-code-review/skills/knowledge-persistence/references/examples.md +0 -44
- package/plugins/devflow-code-review/skills/performance-patterns/SKILL.md +0 -154
- package/plugins/devflow-code-review/skills/performance-patterns/references/patterns.md +0 -503
- package/plugins/devflow-code-review/skills/performance-patterns/references/violations.md +0 -354
- package/plugins/devflow-code-review/skills/regression-patterns/SKILL.md +0 -146
- package/plugins/devflow-code-review/skills/review-methodology/SKILL.md +0 -119
- package/plugins/devflow-code-review/skills/review-methodology/references/patterns.md +0 -186
- package/plugins/devflow-code-review/skills/review-methodology/references/report-template.md +0 -142
- package/plugins/devflow-code-review/skills/review-methodology/references/violations.md +0 -125
- package/plugins/devflow-code-review/skills/security-patterns/SKILL.md +0 -156
- package/plugins/devflow-code-review/skills/security-patterns/references/patterns.md +0 -507
- package/plugins/devflow-code-review/skills/security-patterns/references/violations.md +0 -237
- package/plugins/devflow-code-review/skills/test-patterns/SKILL.md +0 -183
- package/plugins/devflow-code-review/skills/test-patterns/references/patterns.md +0 -220
- package/plugins/devflow-code-review/skills/test-patterns/references/violations.md +0 -221
- package/plugins/devflow-core-skills/.claude-plugin/plugin.json +0 -31
- package/plugins/devflow-core-skills/README.md +0 -50
- package/plugins/devflow-core-skills/skills/core-patterns/SKILL.md +0 -162
- package/plugins/devflow-core-skills/skills/core-patterns/references/checklist.md +0 -276
- package/plugins/devflow-core-skills/skills/core-patterns/references/code-smell-violations.md +0 -144
- package/plugins/devflow-core-skills/skills/core-patterns/references/patterns.md +0 -576
- package/plugins/devflow-core-skills/skills/core-patterns/references/violations.md +0 -369
- package/plugins/devflow-core-skills/skills/docs-framework/SKILL.md +0 -143
- package/plugins/devflow-core-skills/skills/docs-framework/references/patterns.md +0 -346
- package/plugins/devflow-core-skills/skills/docs-framework/references/violations.md +0 -221
- package/plugins/devflow-core-skills/skills/git-safety/SKILL.md +0 -122
- package/plugins/devflow-core-skills/skills/git-safety/references/patterns.md +0 -289
- package/plugins/devflow-core-skills/skills/git-safety/references/violations.md +0 -18
- package/plugins/devflow-core-skills/skills/git-workflow/SKILL.md +0 -158
- package/plugins/devflow-core-skills/skills/git-workflow/references/commit-patterns.md +0 -115
- package/plugins/devflow-core-skills/skills/git-workflow/references/commit-violations.md +0 -77
- package/plugins/devflow-core-skills/skills/git-workflow/references/pr-patterns.md +0 -127
- package/plugins/devflow-core-skills/skills/git-workflow/references/pr-violations.md +0 -96
- package/plugins/devflow-core-skills/skills/github-patterns/SKILL.md +0 -153
- package/plugins/devflow-core-skills/skills/github-patterns/references/patterns.md +0 -572
- package/plugins/devflow-core-skills/skills/github-patterns/references/violations.md +0 -298
- package/plugins/devflow-core-skills/skills/input-validation/SKILL.md +0 -148
- package/plugins/devflow-core-skills/skills/input-validation/references/detection.md +0 -283
- package/plugins/devflow-core-skills/skills/input-validation/references/patterns.md +0 -361
- package/plugins/devflow-core-skills/skills/input-validation/references/violations.md +0 -224
- package/plugins/devflow-core-skills/skills/search-first/SKILL.md +0 -133
- package/plugins/devflow-core-skills/skills/search-first/references/evaluation-criteria.md +0 -101
- package/plugins/devflow-core-skills/skills/test-driven-development/SKILL.md +0 -137
- package/plugins/devflow-core-skills/skills/test-patterns/SKILL.md +0 -183
- package/plugins/devflow-core-skills/skills/test-patterns/references/detection.md +0 -149
- package/plugins/devflow-core-skills/skills/test-patterns/references/patterns.md +0 -220
- package/plugins/devflow-core-skills/skills/test-patterns/references/report-template.md +0 -108
- package/plugins/devflow-core-skills/skills/test-patterns/references/violations.md +0 -221
- package/plugins/devflow-debug/.claude-plugin/plugin.json +0 -26
- package/plugins/devflow-debug/README.md +0 -65
- package/plugins/devflow-debug/agents/git.md +0 -277
- package/plugins/devflow-debug/agents/synthesizer.md +0 -211
- package/plugins/devflow-debug/commands/debug-teams.md +0 -245
- package/plugins/devflow-debug/commands/debug.md +0 -174
- package/plugins/devflow-debug/skills/agent-teams/SKILL.md +0 -124
- package/plugins/devflow-debug/skills/agent-teams/references/cleanup.md +0 -104
- package/plugins/devflow-debug/skills/agent-teams/references/communication.md +0 -122
- package/plugins/devflow-debug/skills/agent-teams/references/team-patterns.md +0 -217
- package/plugins/devflow-debug/skills/git-safety/SKILL.md +0 -122
- package/plugins/devflow-debug/skills/git-safety/references/detection.md +0 -290
- package/plugins/devflow-debug/skills/git-safety/references/patterns.md +0 -289
- package/plugins/devflow-debug/skills/git-safety/references/violations.md +0 -18
- package/plugins/devflow-debug/skills/knowledge-persistence/SKILL.md +0 -128
- package/plugins/devflow-debug/skills/knowledge-persistence/references/examples.md +0 -44
- package/plugins/devflow-frontend-design/.claude-plugin/plugin.json +0 -21
- package/plugins/devflow-frontend-design/skills/frontend-design/SKILL.md +0 -254
- package/plugins/devflow-frontend-design/skills/frontend-design/references/patterns.md +0 -511
- package/plugins/devflow-frontend-design/skills/frontend-design/references/violations.md +0 -453
- package/plugins/devflow-go/.claude-plugin/plugin.json +0 -21
- package/plugins/devflow-go/skills/go/SKILL.md +0 -187
- package/plugins/devflow-go/skills/go/references/concurrency.md +0 -312
- package/plugins/devflow-go/skills/go/references/patterns.md +0 -232
- package/plugins/devflow-go/skills/go/references/violations.md +0 -205
- package/plugins/devflow-implement/.claude-plugin/plugin.json +0 -35
- package/plugins/devflow-implement/README.md +0 -71
- package/plugins/devflow-implement/agents/coder.md +0 -135
- package/plugins/devflow-implement/agents/git.md +0 -277
- package/plugins/devflow-implement/agents/scrutinizer.md +0 -82
- package/plugins/devflow-implement/agents/shepherd.md +0 -108
- package/plugins/devflow-implement/agents/simplifier.md +0 -102
- package/plugins/devflow-implement/agents/skimmer.md +0 -143
- package/plugins/devflow-implement/agents/synthesizer.md +0 -211
- package/plugins/devflow-implement/agents/validator.md +0 -86
- package/plugins/devflow-implement/commands/implement-teams.md +0 -620
- package/plugins/devflow-implement/commands/implement.md +0 -430
- package/plugins/devflow-implement/skills/agent-teams/SKILL.md +0 -124
- package/plugins/devflow-implement/skills/agent-teams/references/cleanup.md +0 -104
- package/plugins/devflow-implement/skills/agent-teams/references/communication.md +0 -122
- package/plugins/devflow-implement/skills/agent-teams/references/team-patterns.md +0 -217
- package/plugins/devflow-implement/skills/implementation-patterns/SKILL.md +0 -162
- package/plugins/devflow-implement/skills/knowledge-persistence/SKILL.md +0 -128
- package/plugins/devflow-implement/skills/knowledge-persistence/references/examples.md +0 -44
- package/plugins/devflow-implement/skills/self-review/SKILL.md +0 -149
- package/plugins/devflow-implement/skills/self-review/references/stub-detection.md +0 -135
- package/plugins/devflow-java/.claude-plugin/plugin.json +0 -21
- package/plugins/devflow-java/skills/java/SKILL.md +0 -183
- package/plugins/devflow-java/skills/java/references/modern-java.md +0 -270
- package/plugins/devflow-java/skills/java/references/patterns.md +0 -235
- package/plugins/devflow-java/skills/java/references/violations.md +0 -213
- package/plugins/devflow-python/.claude-plugin/plugin.json +0 -21
- package/plugins/devflow-python/skills/python/SKILL.md +0 -188
- package/plugins/devflow-python/skills/python/references/async.md +0 -220
- package/plugins/devflow-python/skills/python/references/patterns.md +0 -226
- package/plugins/devflow-python/skills/python/references/violations.md +0 -204
- package/plugins/devflow-react/.claude-plugin/plugin.json +0 -21
- package/plugins/devflow-react/skills/react/SKILL.md +0 -276
- package/plugins/devflow-react/skills/react/references/patterns.md +0 -1331
- package/plugins/devflow-react/skills/react/references/violations.md +0 -565
- package/plugins/devflow-resolve/.claude-plugin/plugin.json +0 -29
- package/plugins/devflow-resolve/README.md +0 -65
- package/plugins/devflow-resolve/agents/git.md +0 -277
- package/plugins/devflow-resolve/agents/resolver.md +0 -131
- package/plugins/devflow-resolve/agents/simplifier.md +0 -102
- package/plugins/devflow-resolve/commands/resolve-teams.md +0 -307
- package/plugins/devflow-resolve/commands/resolve.md +0 -246
- package/plugins/devflow-resolve/skills/agent-teams/SKILL.md +0 -124
- package/plugins/devflow-resolve/skills/agent-teams/references/cleanup.md +0 -104
- package/plugins/devflow-resolve/skills/agent-teams/references/communication.md +0 -122
- package/plugins/devflow-resolve/skills/agent-teams/references/team-patterns.md +0 -217
- package/plugins/devflow-resolve/skills/implementation-patterns/SKILL.md +0 -162
- package/plugins/devflow-resolve/skills/implementation-patterns/references/patterns.md +0 -1063
- package/plugins/devflow-resolve/skills/implementation-patterns/references/violations.md +0 -483
- package/plugins/devflow-resolve/skills/knowledge-persistence/SKILL.md +0 -128
- package/plugins/devflow-resolve/skills/knowledge-persistence/references/examples.md +0 -44
- package/plugins/devflow-resolve/skills/security-patterns/SKILL.md +0 -156
- package/plugins/devflow-resolve/skills/security-patterns/references/detection.md +0 -287
- package/plugins/devflow-resolve/skills/security-patterns/references/patterns.md +0 -507
- package/plugins/devflow-resolve/skills/security-patterns/references/violations.md +0 -237
- package/plugins/devflow-rust/.claude-plugin/plugin.json +0 -21
- package/plugins/devflow-rust/skills/rust/SKILL.md +0 -193
- package/plugins/devflow-rust/skills/rust/references/ownership.md +0 -242
- package/plugins/devflow-rust/skills/rust/references/patterns.md +0 -210
- package/plugins/devflow-rust/skills/rust/references/violations.md +0 -191
- package/plugins/devflow-self-review/.claude-plugin/plugin.json +0 -26
- package/plugins/devflow-self-review/README.md +0 -38
- package/plugins/devflow-self-review/agents/scrutinizer.md +0 -82
- package/plugins/devflow-self-review/agents/simplifier.md +0 -102
- package/plugins/devflow-self-review/agents/validator.md +0 -86
- package/plugins/devflow-self-review/commands/self-review.md +0 -132
- package/plugins/devflow-self-review/skills/core-patterns/SKILL.md +0 -162
- package/plugins/devflow-self-review/skills/core-patterns/references/checklist.md +0 -276
- package/plugins/devflow-self-review/skills/core-patterns/references/code-smell-violations.md +0 -144
- package/plugins/devflow-self-review/skills/core-patterns/references/detection.md +0 -303
- package/plugins/devflow-self-review/skills/core-patterns/references/patterns.md +0 -576
- package/plugins/devflow-self-review/skills/core-patterns/references/violations.md +0 -369
- package/plugins/devflow-self-review/skills/self-review/SKILL.md +0 -149
- package/plugins/devflow-self-review/skills/self-review/references/patterns.md +0 -405
- package/plugins/devflow-self-review/skills/self-review/references/report-template.md +0 -253
- package/plugins/devflow-self-review/skills/self-review/references/stub-detection.md +0 -135
- package/plugins/devflow-self-review/skills/self-review/references/violations.md +0 -308
- package/plugins/devflow-specify/.claude-plugin/plugin.json +0 -25
- package/plugins/devflow-specify/README.md +0 -46
- package/plugins/devflow-specify/agents/skimmer.md +0 -143
- package/plugins/devflow-specify/agents/synthesizer.md +0 -211
- package/plugins/devflow-specify/commands/specify-teams.md +0 -321
- package/plugins/devflow-specify/commands/specify.md +0 -186
- package/plugins/devflow-specify/skills/agent-teams/SKILL.md +0 -124
- package/plugins/devflow-specify/skills/agent-teams/references/cleanup.md +0 -104
- package/plugins/devflow-specify/skills/agent-teams/references/communication.md +0 -122
- package/plugins/devflow-specify/skills/agent-teams/references/team-patterns.md +0 -217
- package/plugins/devflow-typescript/.claude-plugin/plugin.json +0 -21
- package/plugins/devflow-typescript/skills/typescript/SKILL.md +0 -176
- package/plugins/devflow-typescript/skills/typescript/references/patterns.md +0 -1105
- package/plugins/devflow-typescript/skills/typescript/references/violations.md +0 -433
- package/scripts/hooks/ambient-prompt +0 -50
- package/scripts/hooks/background-memory-update +0 -257
- package/scripts/hooks/ensure-memory-gitignore +0 -17
- package/scripts/hooks/pre-compact-memory +0 -87
- package/scripts/hooks/run-hook +0 -23
- package/scripts/hooks/session-start-memory +0 -165
- package/scripts/hooks/stop-update-memory +0 -85
- package/scripts/hud/cache.d.ts +0 -14
- package/scripts/hud/cache.d.ts.map +0 -1
- package/scripts/hud/cache.js +0 -54
- package/scripts/hud/cache.js.map +0 -1
- package/scripts/hud/colors.d.ts +0 -23
- package/scripts/hud/colors.d.ts.map +0 -1
- package/scripts/hud/colors.js +0 -62
- package/scripts/hud/colors.js.map +0 -1
- package/scripts/hud/components/config-counts.d.ts +0 -8
- package/scripts/hud/components/config-counts.d.ts.map +0 -1
- package/scripts/hud/components/config-counts.js +0 -91
- package/scripts/hud/components/config-counts.js.map +0 -1
- package/scripts/hud/components/context-usage.d.ts +0 -8
- package/scripts/hud/components/context-usage.d.ts.map +0 -1
- package/scripts/hud/components/context-usage.js +0 -49
- package/scripts/hud/components/context-usage.js.map +0 -1
- package/scripts/hud/components/diff-stats.d.ts +0 -3
- package/scripts/hud/components/diff-stats.d.ts.map +0 -1
- package/scripts/hud/components/diff-stats.js +0 -36
- package/scripts/hud/components/diff-stats.js.map +0 -1
- package/scripts/hud/components/directory.d.ts +0 -3
- package/scripts/hud/components/directory.d.ts.map +0 -1
- package/scripts/hud/components/directory.js +0 -10
- package/scripts/hud/components/directory.js.map +0 -1
- package/scripts/hud/components/git-ahead-behind.d.ts +0 -3
- package/scripts/hud/components/git-ahead-behind.d.ts.map +0 -1
- package/scripts/hud/components/git-ahead-behind.js +0 -16
- package/scripts/hud/components/git-ahead-behind.js.map +0 -1
- package/scripts/hud/components/git-branch.d.ts +0 -3
- package/scripts/hud/components/git-branch.d.ts.map +0 -1
- package/scripts/hud/components/git-branch.js +0 -14
- package/scripts/hud/components/git-branch.js.map +0 -1
- package/scripts/hud/components/model.d.ts +0 -3
- package/scripts/hud/components/model.d.ts.map +0 -1
- package/scripts/hud/components/model.js +0 -21
- package/scripts/hud/components/model.js.map +0 -1
- package/scripts/hud/components/release-info.d.ts +0 -3
- package/scripts/hud/components/release-info.d.ts.map +0 -1
- package/scripts/hud/components/release-info.js +0 -9
- package/scripts/hud/components/release-info.js.map +0 -1
- package/scripts/hud/components/session-cost.d.ts +0 -3
- package/scripts/hud/components/session-cost.d.ts.map +0 -1
- package/scripts/hud/components/session-cost.js +0 -9
- package/scripts/hud/components/session-cost.js.map +0 -1
- package/scripts/hud/components/session-duration.d.ts +0 -3
- package/scripts/hud/components/session-duration.d.ts.map +0 -1
- package/scripts/hud/components/session-duration.js +0 -18
- package/scripts/hud/components/session-duration.js.map +0 -1
- package/scripts/hud/components/todo-progress.d.ts +0 -3
- package/scripts/hud/components/todo-progress.d.ts.map +0 -1
- package/scripts/hud/components/todo-progress.js +0 -11
- package/scripts/hud/components/todo-progress.js.map +0 -1
- package/scripts/hud/components/usage-quota.d.ts +0 -3
- package/scripts/hud/components/usage-quota.d.ts.map +0 -1
- package/scripts/hud/components/usage-quota.js +0 -45
- package/scripts/hud/components/usage-quota.js.map +0 -1
- package/scripts/hud/components/version-badge.d.ts +0 -3
- package/scripts/hud/components/version-badge.d.ts.map +0 -1
- package/scripts/hud/components/version-badge.js +0 -80
- package/scripts/hud/components/version-badge.js.map +0 -1
- package/scripts/hud/components/worktree-count.d.ts +0 -3
- package/scripts/hud/components/worktree-count.d.ts.map +0 -1
- package/scripts/hud/components/worktree-count.js +0 -8
- package/scripts/hud/components/worktree-count.js.map +0 -1
- package/scripts/hud/config.d.ts +0 -10
- package/scripts/hud/config.d.ts.map +0 -1
- package/scripts/hud/config.js +0 -55
- package/scripts/hud/config.js.map +0 -1
- package/scripts/hud/credentials.d.ts +0 -17
- package/scripts/hud/credentials.d.ts.map +0 -1
- package/scripts/hud/credentials.js +0 -99
- package/scripts/hud/credentials.js.map +0 -1
- package/scripts/hud/git.d.ts +0 -7
- package/scripts/hud/git.d.ts.map +0 -1
- package/scripts/hud/git.js +0 -153
- package/scripts/hud/git.js.map +0 -1
- package/scripts/hud/index.d.ts +0 -2
- package/scripts/hud/index.d.ts.map +0 -1
- package/scripts/hud/index.js +0 -81
- package/scripts/hud/index.js.map +0 -1
- package/scripts/hud/render.d.ts +0 -7
- package/scripts/hud/render.d.ts.map +0 -1
- package/scripts/hud/render.js +0 -111
- package/scripts/hud/render.js.map +0 -1
- package/scripts/hud/stdin.d.ts +0 -6
- package/scripts/hud/stdin.d.ts.map +0 -1
- package/scripts/hud/stdin.js +0 -25
- package/scripts/hud/stdin.js.map +0 -1
- package/scripts/hud/transcript.d.ts +0 -7
- package/scripts/hud/transcript.d.ts.map +0 -1
- package/scripts/hud/transcript.js +0 -130
- package/scripts/hud/transcript.js.map +0 -1
- package/scripts/hud/types.d.ts +0 -116
- package/scripts/hud/types.d.ts.map +0 -1
- package/scripts/hud/types.js +0 -2
- package/scripts/hud/types.js.map +0 -1
- package/scripts/hud/usage-api.d.ts +0 -7
- package/scripts/hud/usage-api.d.ts.map +0 -1
- package/scripts/hud/usage-api.js +0 -84
- package/scripts/hud/usage-api.js.map +0 -1
- package/scripts/hud.sh +0 -5
- package/shared/agents/coder.md +0 -135
- package/shared/agents/git.md +0 -277
- package/shared/agents/resolver.md +0 -131
- package/shared/agents/reviewer.md +0 -165
- package/shared/agents/scrutinizer.md +0 -82
- package/shared/agents/shepherd.md +0 -108
- package/shared/agents/simplifier.md +0 -102
- package/shared/agents/skimmer.md +0 -143
- package/shared/agents/synthesizer.md +0 -211
- package/shared/agents/validator.md +0 -86
- package/shared/skills/accessibility/SKILL.md +0 -229
- package/shared/skills/accessibility/references/detection.md +0 -171
- package/shared/skills/accessibility/references/patterns.md +0 -670
- package/shared/skills/accessibility/references/violations.md +0 -419
- package/shared/skills/agent-teams/SKILL.md +0 -124
- package/shared/skills/agent-teams/references/cleanup.md +0 -104
- package/shared/skills/agent-teams/references/communication.md +0 -122
- package/shared/skills/agent-teams/references/team-patterns.md +0 -217
- package/shared/skills/ambient-router/SKILL.md +0 -145
- package/shared/skills/ambient-router/references/skill-catalog.md +0 -74
- package/shared/skills/architecture-patterns/SKILL.md +0 -153
- package/shared/skills/architecture-patterns/references/detection.md +0 -337
- package/shared/skills/architecture-patterns/references/patterns.md +0 -873
- package/shared/skills/architecture-patterns/references/violations.md +0 -575
- package/shared/skills/complexity-patterns/SKILL.md +0 -143
- package/shared/skills/complexity-patterns/references/detection.md +0 -264
- package/shared/skills/complexity-patterns/references/patterns.md +0 -487
- package/shared/skills/complexity-patterns/references/violations.md +0 -361
- package/shared/skills/consistency-patterns/SKILL.md +0 -140
- package/shared/skills/consistency-patterns/references/detection.md +0 -207
- package/shared/skills/consistency-patterns/references/patterns.md +0 -202
- package/shared/skills/consistency-patterns/references/violations.md +0 -213
- package/shared/skills/core-patterns/SKILL.md +0 -162
- package/shared/skills/core-patterns/references/checklist.md +0 -276
- package/shared/skills/core-patterns/references/code-smell-violations.md +0 -144
- package/shared/skills/core-patterns/references/detection.md +0 -303
- package/shared/skills/core-patterns/references/patterns.md +0 -576
- package/shared/skills/core-patterns/references/violations.md +0 -369
- package/shared/skills/database-patterns/SKILL.md +0 -134
- package/shared/skills/database-patterns/references/detection.md +0 -208
- package/shared/skills/database-patterns/references/patterns.md +0 -394
- package/shared/skills/database-patterns/references/violations.md +0 -332
- package/shared/skills/debug-orchestration/SKILL.md +0 -69
- package/shared/skills/dependencies-patterns/SKILL.md +0 -141
- package/shared/skills/dependencies-patterns/references/detection.md +0 -181
- package/shared/skills/dependencies-patterns/references/patterns.md +0 -225
- package/shared/skills/dependencies-patterns/references/violations.md +0 -247
- package/shared/skills/docs-framework/SKILL.md +0 -143
- package/shared/skills/docs-framework/references/patterns.md +0 -346
- package/shared/skills/docs-framework/references/violations.md +0 -221
- package/shared/skills/documentation-patterns/SKILL.md +0 -125
- package/shared/skills/documentation-patterns/references/detection.md +0 -190
- package/shared/skills/documentation-patterns/references/patterns.md +0 -189
- package/shared/skills/documentation-patterns/references/violations.md +0 -163
- package/shared/skills/frontend-design/SKILL.md +0 -254
- package/shared/skills/frontend-design/references/detection.md +0 -184
- package/shared/skills/frontend-design/references/patterns.md +0 -511
- package/shared/skills/frontend-design/references/violations.md +0 -453
- package/shared/skills/git-safety/SKILL.md +0 -122
- package/shared/skills/git-safety/references/detection.md +0 -290
- package/shared/skills/git-safety/references/patterns.md +0 -289
- package/shared/skills/git-safety/references/violations.md +0 -18
- package/shared/skills/git-workflow/SKILL.md +0 -158
- package/shared/skills/git-workflow/references/commit-patterns.md +0 -115
- package/shared/skills/git-workflow/references/commit-violations.md +0 -77
- package/shared/skills/git-workflow/references/pr-patterns.md +0 -127
- package/shared/skills/git-workflow/references/pr-violations.md +0 -96
- package/shared/skills/github-patterns/SKILL.md +0 -153
- package/shared/skills/github-patterns/references/patterns.md +0 -572
- package/shared/skills/github-patterns/references/violations.md +0 -298
- package/shared/skills/go/SKILL.md +0 -187
- package/shared/skills/go/references/concurrency.md +0 -312
- package/shared/skills/go/references/detection.md +0 -129
- package/shared/skills/go/references/patterns.md +0 -232
- package/shared/skills/go/references/violations.md +0 -205
- package/shared/skills/implementation-orchestration/SKILL.md +0 -92
- package/shared/skills/implementation-patterns/SKILL.md +0 -162
- package/shared/skills/implementation-patterns/references/patterns.md +0 -1063
- package/shared/skills/implementation-patterns/references/violations.md +0 -483
- package/shared/skills/input-validation/SKILL.md +0 -148
- package/shared/skills/input-validation/references/detection.md +0 -283
- package/shared/skills/input-validation/references/patterns.md +0 -361
- package/shared/skills/input-validation/references/violations.md +0 -224
- package/shared/skills/java/SKILL.md +0 -183
- package/shared/skills/java/references/detection.md +0 -120
- package/shared/skills/java/references/modern-java.md +0 -270
- package/shared/skills/java/references/patterns.md +0 -235
- package/shared/skills/java/references/violations.md +0 -213
- package/shared/skills/knowledge-persistence/SKILL.md +0 -128
- package/shared/skills/knowledge-persistence/references/examples.md +0 -44
- package/shared/skills/performance-patterns/SKILL.md +0 -154
- package/shared/skills/performance-patterns/references/detection.md +0 -351
- package/shared/skills/performance-patterns/references/patterns.md +0 -503
- package/shared/skills/performance-patterns/references/violations.md +0 -354
- package/shared/skills/plan-orchestration/SKILL.md +0 -71
- package/shared/skills/python/SKILL.md +0 -188
- package/shared/skills/python/references/async.md +0 -220
- package/shared/skills/python/references/detection.md +0 -128
- package/shared/skills/python/references/patterns.md +0 -226
- package/shared/skills/python/references/violations.md +0 -204
- package/shared/skills/react/SKILL.md +0 -276
- package/shared/skills/react/references/patterns.md +0 -1331
- package/shared/skills/react/references/violations.md +0 -565
- package/shared/skills/regression-patterns/SKILL.md +0 -146
- package/shared/skills/regression-patterns/references/detection.md +0 -237
- package/shared/skills/regression-patterns/references/patterns.md +0 -226
- package/shared/skills/regression-patterns/references/violations.md +0 -225
- package/shared/skills/review-methodology/SKILL.md +0 -119
- package/shared/skills/review-methodology/references/patterns.md +0 -186
- package/shared/skills/review-methodology/references/report-template.md +0 -142
- package/shared/skills/review-methodology/references/violations.md +0 -125
- package/shared/skills/rust/SKILL.md +0 -193
- package/shared/skills/rust/references/detection.md +0 -131
- package/shared/skills/rust/references/ownership.md +0 -242
- package/shared/skills/rust/references/patterns.md +0 -210
- package/shared/skills/rust/references/violations.md +0 -191
- package/shared/skills/search-first/SKILL.md +0 -133
- package/shared/skills/search-first/references/evaluation-criteria.md +0 -101
- package/shared/skills/security-patterns/SKILL.md +0 -156
- package/shared/skills/security-patterns/references/detection.md +0 -287
- package/shared/skills/security-patterns/references/patterns.md +0 -507
- package/shared/skills/security-patterns/references/violations.md +0 -237
- package/shared/skills/self-review/SKILL.md +0 -149
- package/shared/skills/self-review/references/patterns.md +0 -405
- package/shared/skills/self-review/references/report-template.md +0 -253
- package/shared/skills/self-review/references/stub-detection.md +0 -135
- package/shared/skills/self-review/references/violations.md +0 -308
- package/shared/skills/test-driven-development/SKILL.md +0 -137
- package/shared/skills/test-driven-development/references/rationalization-prevention.md +0 -111
- package/shared/skills/test-patterns/SKILL.md +0 -183
- package/shared/skills/test-patterns/references/detection.md +0 -149
- package/shared/skills/test-patterns/references/patterns.md +0 -220
- package/shared/skills/test-patterns/references/report-template.md +0 -108
- package/shared/skills/test-patterns/references/violations.md +0 -221
- package/shared/skills/typescript/SKILL.md +0 -176
- package/shared/skills/typescript/references/patterns.md +0 -1105
- package/shared/skills/typescript/references/violations.md +0 -433
- package/src/templates/claudeignore.template +0 -188
- package/src/templates/settings.json +0 -59
- /package/dist/{utils → core}/safe-delete.js +0 -0
- /package/{plugins/devflow-accessibility → src/assets}/skills/accessibility/references/detection.md +0 -0
- /package/{plugins/devflow-code-review/skills/architecture-patterns → src/assets/skills/architecture}/references/detection.md +0 -0
- /package/{plugins/devflow-code-review/skills/complexity-patterns → src/assets/skills/complexity}/references/detection.md +0 -0
- /package/{plugins/devflow-code-review/skills/complexity-patterns → src/assets/skills/complexity}/references/patterns.md +0 -0
- /package/{plugins/devflow-code-review/skills/complexity-patterns → src/assets/skills/complexity}/references/violations.md +0 -0
- /package/{plugins/devflow-code-review/skills/consistency-patterns → src/assets/skills/consistency}/references/detection.md +0 -0
- /package/{plugins/devflow-code-review/skills/consistency-patterns → src/assets/skills/consistency}/references/patterns.md +0 -0
- /package/{plugins/devflow-code-review/skills/consistency-patterns → src/assets/skills/consistency}/references/violations.md +0 -0
- /package/{plugins/devflow-code-review/skills/database-patterns → src/assets/skills/database}/references/detection.md +0 -0
- /package/{plugins/devflow-code-review/skills/database-patterns → src/assets/skills/database}/references/patterns.md +0 -0
- /package/{plugins/devflow-code-review/skills/database-patterns → src/assets/skills/database}/references/violations.md +0 -0
- /package/{plugins/devflow-code-review/skills/dependencies-patterns → src/assets/skills/dependencies}/references/detection.md +0 -0
- /package/{plugins/devflow-code-review/skills/dependencies-patterns → src/assets/skills/dependencies}/references/patterns.md +0 -0
- /package/{plugins/devflow-code-review/skills/dependencies-patterns → src/assets/skills/dependencies}/references/violations.md +0 -0
- /package/{plugins/devflow-code-review/skills/documentation-patterns → src/assets/skills/documentation}/references/detection.md +0 -0
- /package/{plugins/devflow-code-review/skills/documentation-patterns → src/assets/skills/documentation}/references/patterns.md +0 -0
- /package/{plugins/devflow-code-review/skills/documentation-patterns → src/assets/skills/documentation}/references/violations.md +0 -0
- /package/{plugins/devflow-core-skills/skills/git-safety → src/assets/skills/git}/references/detection.md +0 -0
- /package/{plugins/devflow-go → src/assets}/skills/go/references/detection.md +0 -0
- /package/{plugins/devflow-java → src/assets}/skills/java/references/detection.md +0 -0
- /package/{plugins/devflow-implement/skills/implementation-patterns → src/assets/skills/patterns}/references/patterns.md +0 -0
- /package/{plugins/devflow-implement/skills/implementation-patterns → src/assets/skills/patterns}/references/violations.md +0 -0
- /package/{plugins/devflow-code-review/skills/performance-patterns → src/assets/skills/performance}/references/detection.md +0 -0
- /package/{plugins/devflow-python → src/assets}/skills/python/references/detection.md +0 -0
- /package/{plugins/devflow-implement/skills/self-review → src/assets/skills/quality-gates}/references/patterns.md +0 -0
- /package/{plugins/devflow-implement/skills/self-review → src/assets/skills/quality-gates}/references/report-template.md +0 -0
- /package/{plugins/devflow-implement/skills/self-review → src/assets/skills/quality-gates}/references/violations.md +0 -0
- /package/{plugins/devflow-code-review/skills/regression-patterns → src/assets/skills/regression}/references/detection.md +0 -0
- /package/{plugins/devflow-code-review/skills/regression-patterns → src/assets/skills/regression}/references/patterns.md +0 -0
- /package/{plugins/devflow-code-review/skills/regression-patterns → src/assets/skills/regression}/references/violations.md +0 -0
- /package/{plugins/devflow-rust → src/assets}/skills/rust/references/detection.md +0 -0
- /package/{plugins/devflow-code-review/skills/security-patterns → src/assets/skills/security}/references/detection.md +0 -0
- /package/{plugins/devflow-core-skills/skills/core-patterns → src/assets/skills/software-design}/references/detection.md +0 -0
- /package/{plugins/devflow-core-skills → src/assets}/skills/test-driven-development/references/rationalization-prevention.md +0 -0
- /package/{plugins/devflow-code-review/skills/test-patterns → src/assets/skills/testing}/references/detection.md +0 -0
- /package/{plugins/devflow-code-review/skills/test-patterns → src/assets/skills/testing}/references/report-template.md +0 -0
- /package/{plugins/devflow-frontend-design/skills/frontend-design → src/assets/skills/ui-design}/references/detection.md +0 -0
- /package/src/{templates → targets/claude-code/templates}/managed-settings.json +0 -0
|
@@ -0,0 +1,971 @@
|
|
|
1
|
+
import { promises as fs, writeFileSync, unlinkSync } from 'fs';
|
|
2
|
+
import { execSync } from 'child_process';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import * as os from 'os';
|
|
5
|
+
import * as p from '@clack/prompts';
|
|
6
|
+
import { getManagedSettingsPath } from './claude-paths.js';
|
|
7
|
+
import { getGitignoreEntries, getDocsDir } from '../../core/project-paths.js';
|
|
8
|
+
import { writeFileAtomicExclusive } from '../../core/fs-atomic.js';
|
|
9
|
+
function isNodeSystemError(error) {
|
|
10
|
+
return (error instanceof Error &&
|
|
11
|
+
'code' in error &&
|
|
12
|
+
typeof error.code === 'string');
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Replace ${DEVFLOW_DIR} placeholders in a settings template.
|
|
16
|
+
*/
|
|
17
|
+
export function substituteSettingsTemplate(template, devflowDir) {
|
|
18
|
+
return template.replace(/\$\{DEVFLOW_DIR\}/g, devflowDir);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Compute which entries need appending to a .gitignore file.
|
|
22
|
+
* Returns only entries not already present.
|
|
23
|
+
*/
|
|
24
|
+
export function computeGitignoreAppend(existingContent, entries) {
|
|
25
|
+
const existingLines = existingContent.split('\n').map(l => l.trim());
|
|
26
|
+
return entries.filter(entry => !existingLines.includes(entry));
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The shared .devflow/ gitignore block. Everything under .devflow/ is local
|
|
30
|
+
* (memory, learning, docs, locks) EXCEPT:
|
|
31
|
+
* - Feature knowledge bases: index.md and every {slug}/KNOWLEDGE.md are tracked
|
|
32
|
+
* + committed (the Knowledge agent commits them at workflow end).
|
|
33
|
+
* - conventions.md: naming-convention authority written by the Git learn-conventions
|
|
34
|
+
* operation; GIT-TRACKED so the team shares a single naming source.
|
|
35
|
+
*
|
|
36
|
+
* Re-including files under an ignored tree needs a `dir/*` + `!dir/keep` pair at
|
|
37
|
+
* each level — a bare `.devflow/` excludes the directory so git never descends and
|
|
38
|
+
* later negations are dead.
|
|
39
|
+
*
|
|
40
|
+
* Kept BYTE-IDENTICAL to the block emitted by src/assets/scripts/hooks/ensure-root-gitignore
|
|
41
|
+
* so the init-time path and the always-on hook path produce the same file.
|
|
42
|
+
*
|
|
43
|
+
* D-GITIGNORE-V3: v3 of the carve-out block (adds !.devflow/conventions.md).
|
|
44
|
+
*/
|
|
45
|
+
export const DEVFLOW_GITIGNORE_BLOCK = [
|
|
46
|
+
'# Devflow runtime data — local by default (memory, learning, docs, locks).',
|
|
47
|
+
'# Two exceptions are shared via git: feature knowledge bases under .devflow/features/',
|
|
48
|
+
'# (index.md and every {slug}/KNOWLEDGE.md) and .devflow/conventions.md (naming',
|
|
49
|
+
'# authority). To stop sharing, re-add `.devflow/features/` or `.devflow/conventions.md`',
|
|
50
|
+
'# to your own .gitignore.',
|
|
51
|
+
'.devflow/*',
|
|
52
|
+
'!.devflow/features/',
|
|
53
|
+
'.devflow/features/*',
|
|
54
|
+
'!.devflow/features/index.md',
|
|
55
|
+
'!.devflow/features/*/',
|
|
56
|
+
'.devflow/features/*/*',
|
|
57
|
+
'!.devflow/features/*/KNOWLEDGE.md',
|
|
58
|
+
'!.devflow/conventions.md',
|
|
59
|
+
].join('\n');
|
|
60
|
+
/** Sentinel line whose presence means the v3 carve-out block is installed. */
|
|
61
|
+
const DEVFLOW_GITIGNORE_SENTINEL_V3 = '!.devflow/conventions.md';
|
|
62
|
+
/** Sentinel line whose presence means the v2 carve-out block is installed (no conventions.md line). */
|
|
63
|
+
const DEVFLOW_GITIGNORE_SENTINEL_V2 = '!.devflow/features/*/KNOWLEDGE.md';
|
|
64
|
+
/** The legacy wholesale comment our pre-carve-out writers emitted. */
|
|
65
|
+
const LEGACY_DEVFLOW_COMMENT = '# Devflow runtime data (local by default; remove to share via git)';
|
|
66
|
+
/**
|
|
67
|
+
* PURE: given existing .gitignore content, return the content that ignores
|
|
68
|
+
* `.devflow/` with the feature-knowledge + conventions.md carve-out — or `null`
|
|
69
|
+
* when no change is needed. Idempotent: feeding its own output back returns `null`.
|
|
70
|
+
*
|
|
71
|
+
* - v3 sentinel already present → `null` (already at current format).
|
|
72
|
+
* - User-authored `/.devflow/` (leading slash) present → `null` (respect manual config).
|
|
73
|
+
* - v2 sentinel present but not v3 → UPGRADE: append just `!.devflow/conventions.md`.
|
|
74
|
+
* - Legacy bare `.devflow/` present → strip it (+ our old comment), append the full block.
|
|
75
|
+
* - Otherwise → append the full block (or the block alone when content is empty).
|
|
76
|
+
*/
|
|
77
|
+
export function computeDevflowGitignore(existingContent) {
|
|
78
|
+
const lines = existingContent.split('\n');
|
|
79
|
+
const trimmed = lines.map(l => l.trim());
|
|
80
|
+
if (trimmed.includes(DEVFLOW_GITIGNORE_SENTINEL_V3))
|
|
81
|
+
return null;
|
|
82
|
+
if (trimmed.some(l => l === '/.devflow/'))
|
|
83
|
+
return null;
|
|
84
|
+
// v2→v3 upgrade: v2 sentinel present, v3 sentinel absent → append the missing line only.
|
|
85
|
+
// Preserve existing trailing newlines byte-for-byte (matches shell twin's tail -c 1 guard).
|
|
86
|
+
if (trimmed.includes(DEVFLOW_GITIGNORE_SENTINEL_V2)) {
|
|
87
|
+
const sep = existingContent.endsWith('\n') ? '' : '\n';
|
|
88
|
+
return `${existingContent}${sep}${DEVFLOW_GITIGNORE_SENTINEL_V3}\n`;
|
|
89
|
+
}
|
|
90
|
+
const append = (body) => body.trimEnd()
|
|
91
|
+
? `${body.trimEnd()}\n\n${DEVFLOW_GITIGNORE_BLOCK}\n`
|
|
92
|
+
: `${DEVFLOW_GITIGNORE_BLOCK}\n`;
|
|
93
|
+
if (trimmed.some(l => l === '.devflow/')) {
|
|
94
|
+
// Upgrade our legacy wholesale entry: drop the bare line + old comment, append block.
|
|
95
|
+
const kept = lines
|
|
96
|
+
.filter(l => l.trim() !== '.devflow/' && l.trim() !== LEGACY_DEVFLOW_COMMENT)
|
|
97
|
+
.join('\n');
|
|
98
|
+
return append(kept);
|
|
99
|
+
}
|
|
100
|
+
return append(existingContent);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Merge Devflow deny entries into an existing settings JSON object.
|
|
104
|
+
* Preserves existing entries (including allow and sibling keys), deduplicates,
|
|
105
|
+
* and returns the merged JSON string with trailing newline.
|
|
106
|
+
*
|
|
107
|
+
* PURE + idempotent: calling with the same inputs always yields byte-equal output.
|
|
108
|
+
* Non-array `deny` (e.g. a string, null) is treated as empty — neither throws nor spreads chars.
|
|
109
|
+
*
|
|
110
|
+
* @throws {SyntaxError} on malformed JSON — callers must pre-validate (e.g. via detectDenyState)
|
|
111
|
+
* or wrap in try/catch.
|
|
112
|
+
*/
|
|
113
|
+
export function mergeDenyList(existingJson, newDenyEntries) {
|
|
114
|
+
const existing = JSON.parse(existingJson);
|
|
115
|
+
const rawDeny = existing.permissions?.deny;
|
|
116
|
+
const currentDeny = Array.isArray(rawDeny) ? rawDeny : [];
|
|
117
|
+
const merged = [...new Set([...currentDeny, ...newDenyEntries])];
|
|
118
|
+
existing.permissions = { ...(existing.permissions ?? {}), deny: merged };
|
|
119
|
+
return JSON.stringify(existing, null, 2) + '\n';
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Historical superset of every deny entry Devflow has ever shipped.
|
|
123
|
+
* Append every future entry here; never remove entries.
|
|
124
|
+
* Used by stripUserDenyList to identify Devflow-managed entries in legacy installs.
|
|
125
|
+
*
|
|
126
|
+
* Load-time assertion below verifies this is a superset of the current template.
|
|
127
|
+
*/
|
|
128
|
+
// D-SECURITY-01: frozen at module load — any future template entry must appear here too.
|
|
129
|
+
export const DEVFLOW_HISTORICAL_DENY = Object.freeze(new Set([
|
|
130
|
+
// v1 batch — 154 entries shipped in src/targets/claude-code/templates/managed-settings.json
|
|
131
|
+
'Bash(rm -rf /*)',
|
|
132
|
+
'Bash(rm -rf ~*)',
|
|
133
|
+
'Bash(rm -rf .*)',
|
|
134
|
+
'Bash(* rm -rf /*)',
|
|
135
|
+
'Bash(rm -r /*)',
|
|
136
|
+
'Bash(rm -r ~*)',
|
|
137
|
+
'Bash(rm -r .*)',
|
|
138
|
+
'Bash(rm -fr /*)',
|
|
139
|
+
'Bash(rm -fr ~*)',
|
|
140
|
+
'Bash(rm -fr .*)',
|
|
141
|
+
'Bash(rm -f /*)',
|
|
142
|
+
'Bash(rm -f ~*)',
|
|
143
|
+
'Bash(rm -f .*)',
|
|
144
|
+
'Bash(dd if=*)',
|
|
145
|
+
'Bash(dd*of=/dev/*)',
|
|
146
|
+
'Bash(mkfs*)',
|
|
147
|
+
'Bash(fdisk*)',
|
|
148
|
+
'Bash(parted*)',
|
|
149
|
+
'Bash(shred*)',
|
|
150
|
+
'Bash(> /dev/sda*)',
|
|
151
|
+
'Bash(> /dev/nvme*)',
|
|
152
|
+
'Bash(sh -c *)',
|
|
153
|
+
'Bash(bash -c *)',
|
|
154
|
+
'Bash(curl * | bash*)',
|
|
155
|
+
'Bash(curl * | sh*)',
|
|
156
|
+
'Bash(wget * | bash*)',
|
|
157
|
+
'Bash(wget * | sh*)',
|
|
158
|
+
'Bash(fetch | sh*)',
|
|
159
|
+
'Bash(lynx -source | bash*)',
|
|
160
|
+
'Bash(base64 -d | bash*)',
|
|
161
|
+
'Bash(base64 -d | sh*)',
|
|
162
|
+
'Bash(base64 --decode | bash*)',
|
|
163
|
+
'Bash(eval *)',
|
|
164
|
+
'Bash(exec *)',
|
|
165
|
+
'Bash(sudo *)',
|
|
166
|
+
'Bash(su *)',
|
|
167
|
+
'Bash(doas *)',
|
|
168
|
+
'Bash(pkexec *)',
|
|
169
|
+
'Bash(passwd*)',
|
|
170
|
+
'Bash(useradd*)',
|
|
171
|
+
'Bash(userdel*)',
|
|
172
|
+
'Bash(usermod*)',
|
|
173
|
+
'Bash(groupadd*)',
|
|
174
|
+
'Bash(chmod*777*)',
|
|
175
|
+
'Bash(chmod*666*)',
|
|
176
|
+
'Bash(chmod -R 666*)',
|
|
177
|
+
'Bash(chmod a+w*)',
|
|
178
|
+
'Bash(chown*root*)',
|
|
179
|
+
'Bash(chgrp*root*)',
|
|
180
|
+
'Bash(kill -9 *)',
|
|
181
|
+
'Bash(kill -KILL *)',
|
|
182
|
+
'Bash(killall *)',
|
|
183
|
+
'Bash(pkill -9 *)',
|
|
184
|
+
'Bash(pkill *)',
|
|
185
|
+
'Bash(xkill*)',
|
|
186
|
+
'Bash(reboot*)',
|
|
187
|
+
'Bash(shutdown*)',
|
|
188
|
+
'Bash(halt*)',
|
|
189
|
+
'Bash(poweroff*)',
|
|
190
|
+
'Bash(init 0*)',
|
|
191
|
+
'Bash(init 6*)',
|
|
192
|
+
'Bash(systemctl*stop*)',
|
|
193
|
+
'Bash(systemctl*disable*)',
|
|
194
|
+
'Bash(systemctl*mask*)',
|
|
195
|
+
'Bash(service*stop*)',
|
|
196
|
+
'Bash(nc -l*)',
|
|
197
|
+
'Bash(nc -e*)',
|
|
198
|
+
'Bash(netcat -l*)',
|
|
199
|
+
'Bash(ncat -l*)',
|
|
200
|
+
'Bash(socat*)',
|
|
201
|
+
'Bash(telnet*)',
|
|
202
|
+
'Bash(python -c *)',
|
|
203
|
+
'Bash(python3 -c *)',
|
|
204
|
+
'Bash(php -r *)',
|
|
205
|
+
'Bash(perl -e *)',
|
|
206
|
+
'Bash(ruby -rsocket*)',
|
|
207
|
+
'Bash(nmap*)',
|
|
208
|
+
'Bash(masscan*)',
|
|
209
|
+
'Bash(ufw disable*)',
|
|
210
|
+
'Bash(iptables -F*)',
|
|
211
|
+
'Bash(iptables --flush*)',
|
|
212
|
+
'Bash(insmod*)',
|
|
213
|
+
'Bash(rmmod*)',
|
|
214
|
+
'Bash(modprobe*)',
|
|
215
|
+
'Bash(sysctl -w *)',
|
|
216
|
+
'Bash(docker run --privileged*)',
|
|
217
|
+
'Bash(docker run -v /:/host*)',
|
|
218
|
+
'Bash(docker run --pid=host*)',
|
|
219
|
+
'Bash(docker run --net=host*)',
|
|
220
|
+
'Bash(nsenter*)',
|
|
221
|
+
'Bash(crontab*)',
|
|
222
|
+
'Bash(rm /var/log*)',
|
|
223
|
+
'Bash(rm -rf /var/log*)',
|
|
224
|
+
'Bash(rm -r /var/log*)',
|
|
225
|
+
'Bash(rm -f /var/log*)',
|
|
226
|
+
'Bash(rm -fr /var/log*)',
|
|
227
|
+
'Bash(> /var/log*)',
|
|
228
|
+
'Bash(truncate /var/log*)',
|
|
229
|
+
'Bash(history -c*)',
|
|
230
|
+
'Bash(history -w*)',
|
|
231
|
+
'Bash(rm ~/.bash_history*)',
|
|
232
|
+
'Bash(rm -f ~/.bash_history*)',
|
|
233
|
+
'Bash(rm ~/.zsh_history*)',
|
|
234
|
+
'Bash(rm -f ~/.zsh_history*)',
|
|
235
|
+
'Bash(unset HISTFILE*)',
|
|
236
|
+
'Bash(curl 169.254.169.254*)',
|
|
237
|
+
'Bash(wget 169.254.169.254*)',
|
|
238
|
+
'Bash(rsync --daemon*)',
|
|
239
|
+
'Bash(sftp *)',
|
|
240
|
+
'Bash(ssh -o *)',
|
|
241
|
+
'Bash(xmrig*)',
|
|
242
|
+
'Bash(cgminer*)',
|
|
243
|
+
'Bash(bfgminer*)',
|
|
244
|
+
'Bash(ethminer*)',
|
|
245
|
+
'Bash(minerd*)',
|
|
246
|
+
'Bash(npm install -g *)',
|
|
247
|
+
'Bash(npm i -g *)',
|
|
248
|
+
'Bash(pip install --system*)',
|
|
249
|
+
'Bash(pip3 install --system*)',
|
|
250
|
+
'Bash(apt*install*)',
|
|
251
|
+
'Bash(yum*install*)',
|
|
252
|
+
'Bash(brew*install*)',
|
|
253
|
+
'Bash(mount *)',
|
|
254
|
+
'Bash(umount *)',
|
|
255
|
+
'Bash(> /etc/*)',
|
|
256
|
+
'Bash(> /usr/*)',
|
|
257
|
+
'Bash(> /bin/*)',
|
|
258
|
+
'Bash(> /sys/*)',
|
|
259
|
+
'Bash(> /proc/*)',
|
|
260
|
+
'Read(.env)',
|
|
261
|
+
'Read(.env.*)',
|
|
262
|
+
'Read(**/.env)',
|
|
263
|
+
'Read(**/.env.*)',
|
|
264
|
+
'Read(**/secrets/**)',
|
|
265
|
+
'Read(**/credentials/**)',
|
|
266
|
+
'Read(~/.ssh/id_*)',
|
|
267
|
+
'Read(~/.ssh/*.pem)',
|
|
268
|
+
'Read(~/.ssh/config)',
|
|
269
|
+
'Read(~/.aws/credentials)',
|
|
270
|
+
'Read(~/.aws/config)',
|
|
271
|
+
'Read(~/.config/gcloud/**)',
|
|
272
|
+
'Read(**/*.pem)',
|
|
273
|
+
'Read(**/*.key)',
|
|
274
|
+
'Read(**/*.pfx)',
|
|
275
|
+
'Read(**/*.p12)',
|
|
276
|
+
'Read(**/private.key)',
|
|
277
|
+
'Read(**/privkey.pem)',
|
|
278
|
+
'Read(**/id_rsa)',
|
|
279
|
+
'Read(**/id_ed25519)',
|
|
280
|
+
'Read(**/id_ecdsa)',
|
|
281
|
+
'Read(**/id_dsa)',
|
|
282
|
+
'Read(/etc/shadow)',
|
|
283
|
+
'Read(/etc/sudoers)',
|
|
284
|
+
'Read(/etc/passwd)',
|
|
285
|
+
]));
|
|
286
|
+
/**
|
|
287
|
+
* Assert that DEVFLOW_HISTORICAL_DENY is a superset of the provided template entries.
|
|
288
|
+
* Throws if any template entry is missing from the historical set.
|
|
289
|
+
* Call this after loading the template to catch drift where a new template entry
|
|
290
|
+
* was not also added to DEVFLOW_HISTORICAL_DENY.
|
|
291
|
+
*
|
|
292
|
+
* @param templateEntries - the deny array from the current managed-settings template
|
|
293
|
+
*/
|
|
294
|
+
export function assertHistoricalDenySuperset(templateEntries) {
|
|
295
|
+
const missing = templateEntries.filter(e => !DEVFLOW_HISTORICAL_DENY.has(e));
|
|
296
|
+
if (missing.length > 0) {
|
|
297
|
+
throw new Error(`DEVFLOW_HISTORICAL_DENY is missing ${missing.length} template entries. ` +
|
|
298
|
+
`Add these to DEVFLOW_HISTORICAL_DENY in post-install.ts:\n${missing.join('\n')}`);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Strip Devflow-managed deny entries from a user settings JSON string.
|
|
303
|
+
* PURE + idempotent — mirror of removeMemoryHooks in shape.
|
|
304
|
+
*
|
|
305
|
+
* - Parses the JSON; if permissions.deny is absent or not an array → returns input unchanged.
|
|
306
|
+
* - Removes entries that are in historicalSet; preserves user-only entries.
|
|
307
|
+
* - When remaining is empty: deletes permissions.deny; if permissions then has no keys, deletes permissions.
|
|
308
|
+
* - Never deletes the file — may return `{}\n`.
|
|
309
|
+
* - Preserves allow and all sibling keys.
|
|
310
|
+
* - Returns { json, removed[] } where removed is the list of entries actually stripped.
|
|
311
|
+
*
|
|
312
|
+
* @throws {SyntaxError} on malformed JSON — callers must pre-validate (e.g. via detectDenyState)
|
|
313
|
+
* or wrap in try/catch.
|
|
314
|
+
*/
|
|
315
|
+
export function stripUserDenyList(existingJson, historicalSet) {
|
|
316
|
+
const obj = JSON.parse(existingJson);
|
|
317
|
+
const perms = obj.permissions;
|
|
318
|
+
if (!perms)
|
|
319
|
+
return { json: existingJson, removed: [] };
|
|
320
|
+
const rawDeny = perms.deny;
|
|
321
|
+
if (!Array.isArray(rawDeny))
|
|
322
|
+
return { json: existingJson, removed: [] };
|
|
323
|
+
const currentDeny = rawDeny;
|
|
324
|
+
const removed = currentDeny.filter(e => historicalSet.has(e));
|
|
325
|
+
const remaining = currentDeny.filter(e => !historicalSet.has(e));
|
|
326
|
+
if (remaining.length === 0) {
|
|
327
|
+
delete perms.deny;
|
|
328
|
+
if (Object.keys(perms).length === 0) {
|
|
329
|
+
delete obj.permissions;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
perms.deny = remaining;
|
|
334
|
+
}
|
|
335
|
+
return {
|
|
336
|
+
json: JSON.stringify(obj, null, 2) + '\n',
|
|
337
|
+
removed,
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Detect where the Devflow deny list currently lives.
|
|
342
|
+
*
|
|
343
|
+
* - user: ANY historical-set entry in user settings permissions.deny → true (subset installs count).
|
|
344
|
+
* - managed: managedExists AND ANY historical entry in managed content's deny → true.
|
|
345
|
+
* - unknown: user settings is present but unparseable → true (caller skips strip).
|
|
346
|
+
*
|
|
347
|
+
* Guards getManagedSettingsPath() — may throw on unsupported platforms; caught → managed absent.
|
|
348
|
+
*/
|
|
349
|
+
export function detectDenyState(userSettingsJson, managedExists, managedContentJson) {
|
|
350
|
+
let user = false;
|
|
351
|
+
let unknown = false;
|
|
352
|
+
let managed = false;
|
|
353
|
+
if (userSettingsJson !== null) {
|
|
354
|
+
try {
|
|
355
|
+
const obj = JSON.parse(userSettingsJson);
|
|
356
|
+
const rawDeny = obj.permissions?.deny;
|
|
357
|
+
if (Array.isArray(rawDeny)) {
|
|
358
|
+
user = rawDeny.some(e => DEVFLOW_HISTORICAL_DENY.has(e));
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
catch {
|
|
362
|
+
unknown = true;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
if (managedExists && managedContentJson !== null) {
|
|
366
|
+
try {
|
|
367
|
+
const obj = JSON.parse(managedContentJson);
|
|
368
|
+
const rawDeny = obj.permissions?.deny;
|
|
369
|
+
if (Array.isArray(rawDeny)) {
|
|
370
|
+
managed = rawDeny.some(e => DEVFLOW_HISTORICAL_DENY.has(e));
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
catch {
|
|
374
|
+
// Unparseable managed file — treat as not present
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
return { user, managed, unknown };
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Collapse a DetectedMode to the canonical SecurityMode target to keep.
|
|
381
|
+
* 'both' and 'user' prefer user-settings (user-settings-first convention).
|
|
382
|
+
* Called from the three distinct collapse sites in resolveSecurityAction.
|
|
383
|
+
*/
|
|
384
|
+
function keepTargetFor(m) {
|
|
385
|
+
return m === 'managed' ? 'managed' : m === 'none' ? 'none' : 'user';
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Derive DetectedMode from the raw boolean flags returned by detectDenyState.
|
|
389
|
+
* Extracted so the 4-way ternary is named and reusable (pairs with keepTargetFor).
|
|
390
|
+
*/
|
|
391
|
+
function classifyDetected(detected) {
|
|
392
|
+
return detected.user && detected.managed ? 'both'
|
|
393
|
+
: detected.user ? 'user'
|
|
394
|
+
: detected.managed ? 'managed'
|
|
395
|
+
: 'none';
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Describe the action required for the security deny list.
|
|
399
|
+
* PURE — no I/O, no prompting.
|
|
400
|
+
*
|
|
401
|
+
* Resolution order:
|
|
402
|
+
* 1. Explicit `flag` always wins.
|
|
403
|
+
* 2. Manifest field present AND matches detected reality → proceed (merge for enabled, strip for none/disabled).
|
|
404
|
+
* 3. Manifest field disagrees with detected reality (CONFLICT):
|
|
405
|
+
* - TTY → return a prompt descriptor.
|
|
406
|
+
* - Non-TTY → keep detected reality + signal a warning.
|
|
407
|
+
* 4. Fresh (no manifest field) → seed from detected state; default 'user' when nothing detected.
|
|
408
|
+
*/
|
|
409
|
+
export function resolveSecurityAction(flag, manifestMode, detected, isTTY) {
|
|
410
|
+
// 1. Explicit CLI flag wins
|
|
411
|
+
if (flag !== undefined) {
|
|
412
|
+
if (flag === 'none')
|
|
413
|
+
return { target: 'none', action: 'strip' };
|
|
414
|
+
if (flag === 'user')
|
|
415
|
+
return { target: 'user', action: 'merge' };
|
|
416
|
+
if (flag === 'managed')
|
|
417
|
+
return { target: 'managed', action: 'merge' };
|
|
418
|
+
// Exhaustiveness guard — TypeScript ensures SecurityMode is exhausted above.
|
|
419
|
+
const _exhaustive = flag;
|
|
420
|
+
void _exhaustive;
|
|
421
|
+
}
|
|
422
|
+
const detectedMode = classifyDetected(detected);
|
|
423
|
+
// 2. Manifest field present — check alignment with detected reality
|
|
424
|
+
if (manifestMode !== undefined) {
|
|
425
|
+
const manifestEnabled = manifestMode !== 'none';
|
|
426
|
+
const detectedEnabled = detectedMode !== 'none';
|
|
427
|
+
if (manifestEnabled && detectedEnabled) {
|
|
428
|
+
// Both agree something is active — merge/upgrade with current template
|
|
429
|
+
return { target: manifestMode === 'managed' ? 'managed' : 'user', action: 'merge' };
|
|
430
|
+
}
|
|
431
|
+
if (!manifestEnabled && !detectedEnabled) {
|
|
432
|
+
// Both agree it's off — nothing to do
|
|
433
|
+
return { target: 'none', action: 'noop' };
|
|
434
|
+
}
|
|
435
|
+
// CONFLICT: manifest disagrees with reality
|
|
436
|
+
if (isTTY) {
|
|
437
|
+
return {
|
|
438
|
+
target: keepTargetFor(detectedMode),
|
|
439
|
+
action: 'noop',
|
|
440
|
+
prompt: `Security deny list is ${detectedEnabled ? 'present' : 'absent'} but manifest says ${manifestMode}. Keep current state?`,
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
// Non-TTY: preserve detected reality + warn
|
|
444
|
+
return {
|
|
445
|
+
target: keepTargetFor(detectedMode),
|
|
446
|
+
action: detectedEnabled ? 'merge' : 'strip',
|
|
447
|
+
warn: `Security deny list state (manifest=${manifestMode}, detected=${detectedMode}) — keeping detected reality`,
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
// 4. Fresh (no manifest field) — seed from detected state
|
|
451
|
+
if (detectedMode === 'none') {
|
|
452
|
+
// Nothing detected — apply user mode as default
|
|
453
|
+
return { target: 'user', action: 'merge' };
|
|
454
|
+
}
|
|
455
|
+
// Something already installed — keep it, upgrade with current template
|
|
456
|
+
// detectedMode !== 'none' here (handled above), so keepTargetFor yields 'user' | 'managed'.
|
|
457
|
+
return { target: keepTargetFor(detectedMode), action: 'merge' };
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Load the deny entry array from the managed-settings.json template.
|
|
461
|
+
* Canonical single-source helper used by installManagedSettings, removeManagedSettings,
|
|
462
|
+
* init.ts's security step, and security.ts's --enable/--disable paths.
|
|
463
|
+
*
|
|
464
|
+
* Defensive read: treats file as `Record<string, unknown>`, guards with Array.isArray,
|
|
465
|
+
* coerces each element to string. Returns [] on any read or parse failure (never throws).
|
|
466
|
+
*/
|
|
467
|
+
export function loadTemplateDenyEntries(rootDir) {
|
|
468
|
+
const sourceManaged = path.join(rootDir, 'src', 'targets', 'claude-code', 'templates', 'managed-settings.json');
|
|
469
|
+
return fs.readFile(sourceManaged, 'utf-8')
|
|
470
|
+
.then((raw) => {
|
|
471
|
+
const tmpl = JSON.parse(raw);
|
|
472
|
+
const rawDeny = tmpl.permissions?.deny;
|
|
473
|
+
return Array.isArray(rawDeny) ? rawDeny.map(String) : [];
|
|
474
|
+
})
|
|
475
|
+
.catch(() => []);
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Attempt to install managed settings (security deny list) to the system path.
|
|
479
|
+
* Managed settings have highest precedence in Claude Code and cannot be overridden.
|
|
480
|
+
*
|
|
481
|
+
* Strategy:
|
|
482
|
+
* 1. Try direct write (works if running as root or directory is writable)
|
|
483
|
+
* 2. If EACCES in TTY, retry with sudo (caller is responsible for obtaining consent)
|
|
484
|
+
* 3. Returns true if managed settings were written, false if caller should fall back
|
|
485
|
+
*/
|
|
486
|
+
export async function installManagedSettings(rootDir, verbose) {
|
|
487
|
+
let managedPath;
|
|
488
|
+
try {
|
|
489
|
+
managedPath = getManagedSettingsPath();
|
|
490
|
+
}
|
|
491
|
+
catch {
|
|
492
|
+
return false; // Unsupported platform
|
|
493
|
+
}
|
|
494
|
+
const managedDir = path.dirname(managedPath);
|
|
495
|
+
const newDenyEntries = await loadTemplateDenyEntries(rootDir);
|
|
496
|
+
if (newDenyEntries.length === 0) {
|
|
497
|
+
if (verbose) {
|
|
498
|
+
p.log.warn('Could not read managed settings template');
|
|
499
|
+
}
|
|
500
|
+
return false;
|
|
501
|
+
}
|
|
502
|
+
// Build the content to write (merge with existing if present)
|
|
503
|
+
let content;
|
|
504
|
+
try {
|
|
505
|
+
const existing = await fs.readFile(managedPath, 'utf-8');
|
|
506
|
+
content = mergeDenyList(existing, newDenyEntries);
|
|
507
|
+
}
|
|
508
|
+
catch {
|
|
509
|
+
// File doesn't exist — use template as-is
|
|
510
|
+
content = JSON.stringify({ permissions: { deny: newDenyEntries } }, null, 2) + '\n';
|
|
511
|
+
}
|
|
512
|
+
// Attempt 1: direct write
|
|
513
|
+
try {
|
|
514
|
+
await fs.mkdir(managedDir, { recursive: true });
|
|
515
|
+
await fs.writeFile(managedPath, content, 'utf-8');
|
|
516
|
+
if (verbose) {
|
|
517
|
+
p.log.success(`Managed settings written to ${managedPath}`);
|
|
518
|
+
}
|
|
519
|
+
return true;
|
|
520
|
+
}
|
|
521
|
+
catch (error) {
|
|
522
|
+
if (!isNodeSystemError(error) || error.code !== 'EACCES') {
|
|
523
|
+
if (verbose) {
|
|
524
|
+
p.log.warn(`Could not write managed settings: ${error}`);
|
|
525
|
+
}
|
|
526
|
+
return false;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
// Attempt 2: sudo (TTY only — sudo needs terminal for password prompt)
|
|
530
|
+
if (!process.stdin.isTTY) {
|
|
531
|
+
return false;
|
|
532
|
+
}
|
|
533
|
+
try {
|
|
534
|
+
execSync(`sudo mkdir -p '${managedDir}'`, { stdio: 'inherit' });
|
|
535
|
+
// Write via sudo tee to avoid shell quoting issues with the JSON content
|
|
536
|
+
const tmpFile = path.join(rootDir, '.managed-settings-tmp.json');
|
|
537
|
+
await fs.writeFile(tmpFile, content, 'utf-8');
|
|
538
|
+
execSync(`sudo cp '${tmpFile}' '${managedPath}'`, { stdio: 'inherit' });
|
|
539
|
+
await fs.rm(tmpFile, { force: true });
|
|
540
|
+
if (verbose) {
|
|
541
|
+
p.log.success(`Managed settings written to ${managedPath} (via sudo)`);
|
|
542
|
+
}
|
|
543
|
+
return true;
|
|
544
|
+
}
|
|
545
|
+
catch (error) {
|
|
546
|
+
if (verbose) {
|
|
547
|
+
p.log.warn(`sudo write failed: ${error}`);
|
|
548
|
+
}
|
|
549
|
+
return false;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Remove Devflow deny entries from managed settings.
|
|
554
|
+
* If only Devflow entries remain, deletes the file entirely.
|
|
555
|
+
*
|
|
556
|
+
* Mirrors installManagedSettings strategy:
|
|
557
|
+
* 1. Try direct write/delete
|
|
558
|
+
* 2. If EACCES and TTY, ask user before sudo
|
|
559
|
+
* 3. Non-TTY: return false (caller logs preservation message)
|
|
560
|
+
*/
|
|
561
|
+
export async function removeManagedSettings(rootDir, verbose) {
|
|
562
|
+
let managedPath;
|
|
563
|
+
try {
|
|
564
|
+
managedPath = getManagedSettingsPath();
|
|
565
|
+
}
|
|
566
|
+
catch {
|
|
567
|
+
return false;
|
|
568
|
+
}
|
|
569
|
+
let existingContent;
|
|
570
|
+
try {
|
|
571
|
+
existingContent = await fs.readFile(managedPath, 'utf-8');
|
|
572
|
+
}
|
|
573
|
+
catch {
|
|
574
|
+
return false; // File doesn't exist
|
|
575
|
+
}
|
|
576
|
+
// Load our deny entries to identify which to remove
|
|
577
|
+
const devflowDenyEntries = await loadTemplateDenyEntries(rootDir);
|
|
578
|
+
if (devflowDenyEntries.length === 0) {
|
|
579
|
+
return false;
|
|
580
|
+
}
|
|
581
|
+
const existing = JSON.parse(existingContent);
|
|
582
|
+
const currentDeny = existing.permissions?.deny ?? [];
|
|
583
|
+
const devflowSet = new Set(devflowDenyEntries);
|
|
584
|
+
const remaining = currentDeny.filter(entry => !devflowSet.has(entry));
|
|
585
|
+
// Determine the target action: delete file entirely or write updated content
|
|
586
|
+
let shouldDelete = false;
|
|
587
|
+
let updatedContent = null;
|
|
588
|
+
if (remaining.length === 0) {
|
|
589
|
+
const otherKeys = Object.keys(existing).filter(k => k !== 'permissions');
|
|
590
|
+
const hasOtherPermissions = existing.permissions &&
|
|
591
|
+
Object.keys(existing.permissions).filter(k => k !== 'deny').length > 0;
|
|
592
|
+
if (otherKeys.length === 0 && !hasOtherPermissions) {
|
|
593
|
+
shouldDelete = true;
|
|
594
|
+
}
|
|
595
|
+
else {
|
|
596
|
+
delete existing.permissions.deny;
|
|
597
|
+
if (Object.keys(existing.permissions).length === 0) {
|
|
598
|
+
delete existing.permissions;
|
|
599
|
+
}
|
|
600
|
+
updatedContent = JSON.stringify(existing, null, 2) + '\n';
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
else {
|
|
604
|
+
existing.permissions.deny = remaining;
|
|
605
|
+
updatedContent = JSON.stringify(existing, null, 2) + '\n';
|
|
606
|
+
}
|
|
607
|
+
// Attempt 1: direct write/delete
|
|
608
|
+
try {
|
|
609
|
+
if (shouldDelete) {
|
|
610
|
+
unlinkSync(managedPath);
|
|
611
|
+
}
|
|
612
|
+
else {
|
|
613
|
+
writeFileSync(managedPath, updatedContent, 'utf-8');
|
|
614
|
+
}
|
|
615
|
+
if (verbose) {
|
|
616
|
+
p.log.success(shouldDelete ? 'Managed settings file removed' : 'Devflow deny entries removed from managed settings');
|
|
617
|
+
}
|
|
618
|
+
return true;
|
|
619
|
+
}
|
|
620
|
+
catch (error) {
|
|
621
|
+
if (!isNodeSystemError(error) || error.code !== 'EACCES') {
|
|
622
|
+
if (verbose) {
|
|
623
|
+
p.log.warn(`Could not update managed settings: ${error}`);
|
|
624
|
+
}
|
|
625
|
+
return false;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
// Attempt 2: sudo (TTY only, with explicit consent)
|
|
629
|
+
if (!process.stdin.isTTY) {
|
|
630
|
+
return false;
|
|
631
|
+
}
|
|
632
|
+
const managedDir = path.dirname(managedPath);
|
|
633
|
+
const confirmed = await p.confirm({
|
|
634
|
+
message: `Managed settings cleanup requires admin access (${managedDir}). Use sudo?`,
|
|
635
|
+
initialValue: true,
|
|
636
|
+
});
|
|
637
|
+
if (p.isCancel(confirmed) || !confirmed) {
|
|
638
|
+
return false;
|
|
639
|
+
}
|
|
640
|
+
try {
|
|
641
|
+
if (shouldDelete) {
|
|
642
|
+
execSync(`sudo rm '${managedPath}'`, { stdio: 'inherit' });
|
|
643
|
+
}
|
|
644
|
+
else {
|
|
645
|
+
const tmpFile = path.join(rootDir, '.managed-settings-tmp.json');
|
|
646
|
+
await fs.writeFile(tmpFile, updatedContent, 'utf-8');
|
|
647
|
+
execSync(`sudo cp '${tmpFile}' '${managedPath}'`, { stdio: 'inherit' });
|
|
648
|
+
await fs.rm(tmpFile, { force: true });
|
|
649
|
+
}
|
|
650
|
+
if (verbose) {
|
|
651
|
+
p.log.success(shouldDelete ? 'Managed settings file removed' : 'Devflow deny entries removed from managed settings');
|
|
652
|
+
}
|
|
653
|
+
return true;
|
|
654
|
+
}
|
|
655
|
+
catch (error) {
|
|
656
|
+
if (verbose) {
|
|
657
|
+
p.log.warn(`sudo cleanup failed: ${error}`);
|
|
658
|
+
}
|
|
659
|
+
return false;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Apply the Devflow deny list atomically to the user settings file (~/.claude/settings.json).
|
|
664
|
+
* Called by init's dedicated security step when target mode is 'user' (or as a fallback when
|
|
665
|
+
* the managed write fails).
|
|
666
|
+
*
|
|
667
|
+
* Merges currentTemplateDeny into the existing settings file. Idempotent.
|
|
668
|
+
* Returns the merged JSON string written to disk.
|
|
669
|
+
*/
|
|
670
|
+
export async function applyUserSecurityDenyList(settingsPath, currentTemplateDeny) {
|
|
671
|
+
let existing;
|
|
672
|
+
try {
|
|
673
|
+
existing = await fs.readFile(settingsPath, 'utf-8');
|
|
674
|
+
}
|
|
675
|
+
catch {
|
|
676
|
+
existing = '{}';
|
|
677
|
+
}
|
|
678
|
+
const merged = mergeDenyList(existing, currentTemplateDeny);
|
|
679
|
+
await writeFileAtomicExclusive(settingsPath, merged);
|
|
680
|
+
return merged;
|
|
681
|
+
}
|
|
682
|
+
/**
|
|
683
|
+
* Strip Devflow deny entries from the user settings file (~/.claude/settings.json).
|
|
684
|
+
* Colocated with applyUserSecurityDenyList — the remove-side counterpart.
|
|
685
|
+
*
|
|
686
|
+
* Sequence: read → stripUserDenyList → guard (stripped !== existing) →
|
|
687
|
+
* writeFileAtomicExclusive → return { removed }.
|
|
688
|
+
* Atomic write (temp+rename) upholds the never-truncate-on-crash invariant.
|
|
689
|
+
* ENOENT is swallowed (file absent = nothing to strip). Other errors propagate.
|
|
690
|
+
*
|
|
691
|
+
* @returns { removed: string[] } listing the stripped entries,
|
|
692
|
+
* or null when the file is absent (ENOENT) or nothing changed.
|
|
693
|
+
*
|
|
694
|
+
* Callers: init.ts (managed-write success and 'none' branches) and security.ts
|
|
695
|
+
* (--enable --managed self-heal) use this instead of open-coding the sequence.
|
|
696
|
+
*/
|
|
697
|
+
export async function stripUserSecurityDenyList(settingsPath) {
|
|
698
|
+
let existing;
|
|
699
|
+
try {
|
|
700
|
+
existing = await fs.readFile(settingsPath, 'utf-8');
|
|
701
|
+
}
|
|
702
|
+
catch (error) {
|
|
703
|
+
if (isNodeSystemError(error) && error.code === 'ENOENT') {
|
|
704
|
+
return null;
|
|
705
|
+
}
|
|
706
|
+
throw error;
|
|
707
|
+
}
|
|
708
|
+
const { json: stripped, removed } = stripUserDenyList(existing, DEVFLOW_HISTORICAL_DENY);
|
|
709
|
+
if (stripped === existing) {
|
|
710
|
+
return null;
|
|
711
|
+
}
|
|
712
|
+
await writeFileAtomicExclusive(settingsPath, stripped);
|
|
713
|
+
return { removed };
|
|
714
|
+
}
|
|
715
|
+
/**
|
|
716
|
+
* Install or update settings.json with Devflow configuration.
|
|
717
|
+
* Prompts interactively in TTY mode when settings already exist.
|
|
718
|
+
* In non-TTY mode, skips override (safe default).
|
|
719
|
+
*
|
|
720
|
+
* The deny list is handled by init's dedicated security step
|
|
721
|
+
* (applyUserSecurityDenyList / installManagedSettings) after installSettings completes.
|
|
722
|
+
*/
|
|
723
|
+
export async function installSettings(claudeDir, rootDir, devflowDir, verbose) {
|
|
724
|
+
const settingsPath = path.join(claudeDir, 'settings.json');
|
|
725
|
+
const sourceSettingsPath = path.join(rootDir, 'src', 'targets', 'claude-code', 'templates', 'settings.json');
|
|
726
|
+
try {
|
|
727
|
+
const settingsTemplate = await fs.readFile(sourceSettingsPath, 'utf-8');
|
|
728
|
+
const settingsContent = substituteSettingsTemplate(settingsTemplate, devflowDir);
|
|
729
|
+
let settingsExists = false;
|
|
730
|
+
try {
|
|
731
|
+
await fs.access(settingsPath);
|
|
732
|
+
settingsExists = true;
|
|
733
|
+
}
|
|
734
|
+
catch {
|
|
735
|
+
settingsExists = false;
|
|
736
|
+
}
|
|
737
|
+
if (!settingsExists) {
|
|
738
|
+
await fs.writeFile(settingsPath, settingsContent, 'utf-8');
|
|
739
|
+
if (verbose) {
|
|
740
|
+
p.log.success('Settings configured');
|
|
741
|
+
}
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
744
|
+
// Settings exist — check if they already have hooks
|
|
745
|
+
let hasHooks = false;
|
|
746
|
+
try {
|
|
747
|
+
const existing = JSON.parse(await fs.readFile(settingsPath, 'utf-8'));
|
|
748
|
+
hasHooks = !!existing.hooks;
|
|
749
|
+
}
|
|
750
|
+
catch { /* parse error = treat as no hooks */ }
|
|
751
|
+
if (hasHooks) {
|
|
752
|
+
// Settings already configured with hooks — nothing to do
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
755
|
+
// Settings exist without hooks — prompt in TTY, warn in non-TTY
|
|
756
|
+
if (process.stdin.isTTY) {
|
|
757
|
+
const confirmed = await p.confirm({
|
|
758
|
+
message: 'settings.json exists without hooks (Working Memory needs hooks). Override?',
|
|
759
|
+
initialValue: true,
|
|
760
|
+
});
|
|
761
|
+
if (p.isCancel(confirmed)) {
|
|
762
|
+
p.cancel('Installation cancelled.');
|
|
763
|
+
process.exit(0);
|
|
764
|
+
}
|
|
765
|
+
if (confirmed) {
|
|
766
|
+
await fs.writeFile(settingsPath, settingsContent, 'utf-8');
|
|
767
|
+
p.log.success('Settings overridden');
|
|
768
|
+
}
|
|
769
|
+
else {
|
|
770
|
+
p.log.info('Keeping existing settings');
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
else {
|
|
774
|
+
p.log.warn('Settings exist without hooks. Working Memory requires hooks.');
|
|
775
|
+
p.log.info('Re-run interactively to configure, or manually add hooks to settings.json');
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
catch (error) {
|
|
779
|
+
if (verbose) {
|
|
780
|
+
p.log.warn(`Could not configure settings: ${error}`);
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* Create .claudeignore in git repository root (skip if already exists).
|
|
786
|
+
* Returns true if a new file was created, false if it already existed or on error.
|
|
787
|
+
*/
|
|
788
|
+
export async function installClaudeignore(gitRoot, rootDir, verbose) {
|
|
789
|
+
const claudeignorePath = path.join(gitRoot, '.claudeignore');
|
|
790
|
+
const claudeignoreTemplatePath = path.join(rootDir, 'src', 'targets', 'claude-code', 'templates', 'claudeignore.template');
|
|
791
|
+
try {
|
|
792
|
+
const claudeignoreContent = await fs.readFile(claudeignoreTemplatePath, 'utf-8');
|
|
793
|
+
await fs.writeFile(claudeignorePath, claudeignoreContent, { encoding: 'utf-8', flag: 'wx' });
|
|
794
|
+
if (verbose) {
|
|
795
|
+
p.log.success('.claudeignore created');
|
|
796
|
+
}
|
|
797
|
+
return true;
|
|
798
|
+
}
|
|
799
|
+
catch (error) {
|
|
800
|
+
if (isNodeSystemError(error) && error.code === 'EEXIST') {
|
|
801
|
+
// Already exists, skip silently
|
|
802
|
+
}
|
|
803
|
+
else if (verbose) {
|
|
804
|
+
p.log.warn(`Could not create .claudeignore: ${error}`);
|
|
805
|
+
}
|
|
806
|
+
return false;
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
/**
|
|
810
|
+
* Discover git repository roots from Claude's project history.
|
|
811
|
+
* Parses ~/.claude/history.jsonl for unique project paths that are valid git repos.
|
|
812
|
+
* @param homeDir - Override home directory (dependency injection for tests)
|
|
813
|
+
*/
|
|
814
|
+
export async function discoverProjectGitRoots(homeDir) {
|
|
815
|
+
const historyPath = path.join(homeDir ?? os.homedir(), '.claude', 'history.jsonl');
|
|
816
|
+
let content;
|
|
817
|
+
try {
|
|
818
|
+
content = await fs.readFile(historyPath, 'utf-8');
|
|
819
|
+
}
|
|
820
|
+
catch {
|
|
821
|
+
return [];
|
|
822
|
+
}
|
|
823
|
+
const projects = new Set();
|
|
824
|
+
for (const line of content.split('\n')) {
|
|
825
|
+
if (!line.trim())
|
|
826
|
+
continue;
|
|
827
|
+
try {
|
|
828
|
+
const entry = JSON.parse(line);
|
|
829
|
+
if (typeof entry?.project === 'string') {
|
|
830
|
+
projects.add(path.resolve(entry.project));
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
catch {
|
|
834
|
+
// Malformed line — skip
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
const results = await Promise.allSettled([...projects].map(async (project) => {
|
|
838
|
+
await fs.access(path.join(project, '.git'));
|
|
839
|
+
return project;
|
|
840
|
+
}));
|
|
841
|
+
const gitRoots = results
|
|
842
|
+
.filter((r) => r.status === 'fulfilled')
|
|
843
|
+
.map((r) => r.value);
|
|
844
|
+
return gitRoots.sort();
|
|
845
|
+
}
|
|
846
|
+
/**
|
|
847
|
+
* Update .gitignore with Devflow entries (for local scope installs).
|
|
848
|
+
*/
|
|
849
|
+
export async function updateGitignore(gitRoot, verbose) {
|
|
850
|
+
try {
|
|
851
|
+
const gitignorePath = path.join(gitRoot, '.gitignore');
|
|
852
|
+
const entriesToAdd = getGitignoreEntries();
|
|
853
|
+
let gitignoreContent = '';
|
|
854
|
+
try {
|
|
855
|
+
gitignoreContent = await fs.readFile(gitignorePath, 'utf-8');
|
|
856
|
+
}
|
|
857
|
+
catch { /* doesn't exist */ }
|
|
858
|
+
const linesToAdd = computeGitignoreAppend(gitignoreContent, entriesToAdd);
|
|
859
|
+
if (linesToAdd.length > 0) {
|
|
860
|
+
const newContent = gitignoreContent
|
|
861
|
+
? `${gitignoreContent.trimEnd()}\n\n# Devflow local installation\n${linesToAdd.join('\n')}\n`
|
|
862
|
+
: `# Devflow local installation\n${linesToAdd.join('\n')}\n`;
|
|
863
|
+
await fs.writeFile(gitignorePath, newContent, 'utf-8');
|
|
864
|
+
if (verbose) {
|
|
865
|
+
p.log.success('.gitignore updated');
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
catch (error) {
|
|
870
|
+
if (verbose) {
|
|
871
|
+
p.log.warn(`Could not update .gitignore: ${error instanceof Error ? error.message : error}`);
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
/** Current carve-out marker version. Bump when the block format changes. */
|
|
876
|
+
const GITIGNORE_MARKER_V3 = '.root-gitignore-configured-v3';
|
|
877
|
+
/** Previous marker — removed when upgrading to v3. */
|
|
878
|
+
const GITIGNORE_MARKER_V2 = '.root-gitignore-configured-v2';
|
|
879
|
+
/**
|
|
880
|
+
* Deterministically ensure the project root .gitignore applies the `.devflow/`
|
|
881
|
+
* carve-out (local by default, feature knowledge + conventions.md shared via git).
|
|
882
|
+
*
|
|
883
|
+
* Manages ONLY `.devflow/` — never `.claude/` — because user-scope installs must
|
|
884
|
+
* not gitignore `.claude/`. This is the init-time counterpart to the always-on
|
|
885
|
+
* src/assets/scripts/hooks/ensure-root-gitignore shell helper; both write the identical
|
|
886
|
+
* DEVFLOW_GITIGNORE_BLOCK, so the two paths are byte-compatible and mutually
|
|
887
|
+
* idempotent. Called unconditionally (independent of install scope and every
|
|
888
|
+
* feature toggle) whenever a git root is known.
|
|
889
|
+
*
|
|
890
|
+
* Uses a versioned marker file (`.devflow/.root-gitignore-configured-v3`) for fast-path
|
|
891
|
+
* detection — the same pattern as the shell twin. Bumping the version forces existing
|
|
892
|
+
* installs to re-run once and upgrade their block (v2→v3: adds conventions.md line).
|
|
893
|
+
*
|
|
894
|
+
* Idempotent: already-v3 installs return immediately (marker fast-path). Errors are
|
|
895
|
+
* swallowed (verbose-logged) — a gitignore write must never abort init.
|
|
896
|
+
*/
|
|
897
|
+
export async function ensureDevflowGitignore(gitRoot, verbose) {
|
|
898
|
+
try {
|
|
899
|
+
const devflowDir = path.join(gitRoot, '.devflow');
|
|
900
|
+
const markerV3 = path.join(devflowDir, GITIGNORE_MARKER_V3);
|
|
901
|
+
const gitignorePath = path.join(gitRoot, '.gitignore');
|
|
902
|
+
// Fast-path with verification: v3 marker normally means the block is installed,
|
|
903
|
+
// but the marker is a claim, not proof — a merge-conflict resolution may have
|
|
904
|
+
// dropped the block. Even when the marker exists, read .gitignore (one cheap
|
|
905
|
+
// read) and run computeDevflowGitignore; write only when it returns non-null.
|
|
906
|
+
// Idempotent: sentinel present → computeDevflowGitignore returns null → no write.
|
|
907
|
+
let v3Marked = false;
|
|
908
|
+
try {
|
|
909
|
+
await fs.access(markerV3);
|
|
910
|
+
v3Marked = true;
|
|
911
|
+
}
|
|
912
|
+
catch { /* absent */ }
|
|
913
|
+
if (v3Marked) {
|
|
914
|
+
let existingContent = '';
|
|
915
|
+
try {
|
|
916
|
+
existingContent = await fs.readFile(gitignorePath, 'utf-8');
|
|
917
|
+
}
|
|
918
|
+
catch { /* absent */ }
|
|
919
|
+
const healContent = computeDevflowGitignore(existingContent);
|
|
920
|
+
if (healContent !== null) {
|
|
921
|
+
await fs.writeFile(gitignorePath, healContent, 'utf-8');
|
|
922
|
+
if (verbose) {
|
|
923
|
+
p.log.success('.gitignore configured (.devflow/ local; feature knowledge + conventions shared)');
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
return;
|
|
927
|
+
}
|
|
928
|
+
let gitignoreContent = '';
|
|
929
|
+
try {
|
|
930
|
+
gitignoreContent = await fs.readFile(gitignorePath, 'utf-8');
|
|
931
|
+
}
|
|
932
|
+
catch { /* doesn't exist yet */ }
|
|
933
|
+
const newContent = computeDevflowGitignore(gitignoreContent);
|
|
934
|
+
if (newContent !== null) {
|
|
935
|
+
await fs.writeFile(gitignorePath, newContent, 'utf-8');
|
|
936
|
+
if (verbose) {
|
|
937
|
+
p.log.success('.gitignore configured (.devflow/ local; feature knowledge + conventions shared)');
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
// Stamp v3 marker so subsequent runs fast-path; drop the legacy v2 marker.
|
|
941
|
+
await fs.mkdir(devflowDir, { recursive: true });
|
|
942
|
+
await fs.writeFile(markerV3, '', 'utf-8');
|
|
943
|
+
try {
|
|
944
|
+
await fs.rm(path.join(devflowDir, GITIGNORE_MARKER_V2), { force: true });
|
|
945
|
+
}
|
|
946
|
+
catch { /* ok if absent */ }
|
|
947
|
+
}
|
|
948
|
+
catch (error) {
|
|
949
|
+
if (verbose) {
|
|
950
|
+
p.log.warn(`Could not update .gitignore: ${error instanceof Error ? error.message : error}`);
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
/**
|
|
955
|
+
* Create .devflow/docs/ directory structure for Devflow artifacts.
|
|
956
|
+
*/
|
|
957
|
+
export async function createDocsStructure(verbose) {
|
|
958
|
+
const docsDir = getDocsDir(process.cwd());
|
|
959
|
+
try {
|
|
960
|
+
await Promise.all([
|
|
961
|
+
fs.mkdir(path.join(docsDir, 'status', 'compact'), { recursive: true }),
|
|
962
|
+
fs.mkdir(path.join(docsDir, 'reviews'), { recursive: true }),
|
|
963
|
+
fs.mkdir(path.join(docsDir, 'releases'), { recursive: true }),
|
|
964
|
+
]);
|
|
965
|
+
if (verbose) {
|
|
966
|
+
p.log.success('.devflow/docs/ structure ready');
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
catch { /* may already exist */ }
|
|
970
|
+
}
|
|
971
|
+
//# sourceMappingURL=post-install.js.map
|