wize-dev-kit 0.16.0 → 0.16.1

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.
Files changed (228) hide show
  1. package/AGENTS.md +37 -0
  2. package/ARCH.md +77 -24
  3. package/CHANGELOG.md +4 -0
  4. package/DECISIONS.md +27 -1
  5. package/README.es.md +295 -0
  6. package/README.pt-BR.md +293 -0
  7. package/ROSTER.md +11 -3
  8. package/adapters/README.md +8 -7
  9. package/adapters/antigravity/README.md +5 -5
  10. package/adapters/claude-code/README.md +1 -1
  11. package/adapters/codex/README.md +5 -5
  12. package/adapters/codex/adapter.yaml +1 -1
  13. package/adapters/codex/render.js +1 -1
  14. package/adapters/continue/README.md +5 -5
  15. package/adapters/cursor/README.md +2 -2
  16. package/adapters/generic/README.md +1 -1
  17. package/adapters/hermes/README.md +23 -0
  18. package/adapters/hermes/adapter.yaml +8 -0
  19. package/adapters/hermes/render.js +17 -0
  20. package/adapters/kimi-code/README.md +5 -5
  21. package/adapters/kimi-code/render.js +2 -2
  22. package/adapters/opencode/README.md +3 -3
  23. package/adapters/opencode/render.js +27 -1
  24. package/adapters/windsurf/README.md +3 -3
  25. package/docs/harnesses/antigravity.md +20 -0
  26. package/docs/harnesses/antigravity.pt-BR.md +20 -0
  27. package/docs/harnesses/claude-code.md +23 -0
  28. package/docs/harnesses/claude-code.pt-BR.md +23 -0
  29. package/docs/harnesses/codex.md +21 -0
  30. package/docs/harnesses/codex.pt-BR.md +21 -0
  31. package/docs/harnesses/continue.md +21 -0
  32. package/docs/harnesses/continue.pt-BR.md +21 -0
  33. package/docs/harnesses/cursor.md +22 -0
  34. package/docs/harnesses/cursor.pt-BR.md +22 -0
  35. package/docs/harnesses/generic.md +20 -0
  36. package/docs/harnesses/generic.pt-BR.md +20 -0
  37. package/docs/harnesses/hermes.md +26 -0
  38. package/docs/harnesses/hermes.pt-BR.md +26 -0
  39. package/docs/harnesses/kimi-code.md +19 -0
  40. package/docs/harnesses/kimi-code.pt-BR.md +19 -0
  41. package/docs/harnesses/opencode.md +31 -0
  42. package/docs/harnesses/opencode.pt-BR.md +31 -0
  43. package/docs/harnesses/windsurf.md +22 -0
  44. package/docs/harnesses/windsurf.pt-BR.md +22 -0
  45. package/package.json +1 -1
  46. package/schemas/agent.schema.json +2 -2
  47. package/schemas/workflow.schema.json +1 -1
  48. package/src/app-overlay/wize-app-release-channels/workflow.md +2 -0
  49. package/src/app-overlay/wize-app-scaffold/workflow.md +2 -0
  50. package/src/app-overlay/wize-app-store-listing/workflow.md +2 -0
  51. package/src/builder-skills/wize-create-agent/workflow.md +2 -0
  52. package/src/builder-skills/wize-create-skill/workflow.md +2 -0
  53. package/src/builder-skills/wize-create-workflow/workflow.md +2 -0
  54. package/src/core-skills/wize-advanced-elicitation/skill.md +2 -0
  55. package/src/core-skills/wize-brainstorming/skill.md +2 -0
  56. package/src/core-skills/wize-customize/skill.md +116 -0
  57. package/src/core-skills/wize-editorial-review-prose/skill.md +94 -0
  58. package/src/core-skills/wize-editorial-review-structure/skill.md +99 -0
  59. package/src/core-skills/wize-grill/skill.md +77 -0
  60. package/src/core-skills/wize-index-docs/skill.md +119 -0
  61. package/src/core-skills/wize-pre-pr-check/skill.md +134 -0
  62. package/src/core-skills/wize-review-adversarial/skill.md +3 -0
  63. package/src/core-skills/wize-review-edge-case-hunter/skill.md +115 -0
  64. package/src/core-skills/wize-shard-doc/skill.md +2 -0
  65. package/src/core-skills/wize-spec/assets/headless-schemas.md +39 -0
  66. package/src/core-skills/wize-spec/assets/spec-template.md +40 -0
  67. package/src/core-skills/wize-spec/customize.toml +20 -0
  68. package/src/core-skills/wize-spec/skill.md +112 -0
  69. package/src/method-skills/1-analysis/wize-agent-analyst/agent.yaml +3 -0
  70. package/src/method-skills/1-analysis/wize-document-project/documentation-requirements.csv +12 -0
  71. package/src/method-skills/1-analysis/wize-document-project/templates/api-contracts-template.md +38 -0
  72. package/src/method-skills/1-analysis/wize-document-project/templates/architecture-template.md +54 -0
  73. package/src/method-skills/1-analysis/wize-document-project/templates/component-inventory-template.md +40 -0
  74. package/src/method-skills/1-analysis/wize-document-project/templates/contribution-guide-template.md +34 -0
  75. package/src/method-skills/1-analysis/wize-document-project/templates/data-models-template.md +36 -0
  76. package/src/method-skills/1-analysis/wize-document-project/templates/deep-dive-template.md +312 -0
  77. package/src/method-skills/1-analysis/wize-document-project/templates/deployment-guide-template.md +42 -0
  78. package/src/method-skills/1-analysis/wize-document-project/templates/development-guide-template.md +61 -0
  79. package/src/method-skills/1-analysis/wize-document-project/templates/index-template.md +185 -0
  80. package/src/method-skills/1-analysis/wize-document-project/templates/project-overview-template.md +110 -0
  81. package/src/method-skills/1-analysis/wize-document-project/templates/project-scan-report-schema.json +159 -0
  82. package/src/method-skills/1-analysis/wize-document-project/templates/source-tree-template.md +142 -0
  83. package/src/method-skills/1-analysis/wize-document-project/workflow.md +213 -20
  84. package/src/method-skills/1-analysis/wize-domain-research/customize.toml +14 -0
  85. package/src/method-skills/1-analysis/wize-domain-research/domain-steps/step-01-init.md +49 -0
  86. package/src/method-skills/1-analysis/wize-domain-research/domain-steps/step-02-domain-analysis.md +39 -0
  87. package/src/method-skills/1-analysis/wize-domain-research/domain-steps/step-03-competitive-landscape.md +39 -0
  88. package/src/method-skills/1-analysis/wize-domain-research/domain-steps/step-04-regulatory-focus.md +39 -0
  89. package/src/method-skills/1-analysis/wize-domain-research/domain-steps/step-05-technical-trends.md +39 -0
  90. package/src/method-skills/1-analysis/wize-domain-research/domain-steps/step-06-research-synthesis.md +43 -0
  91. package/src/method-skills/1-analysis/wize-domain-research/research.template.md +31 -0
  92. package/src/method-skills/1-analysis/wize-domain-research/workflow.md +58 -0
  93. package/src/method-skills/1-analysis/wize-market-research/customize.toml +14 -0
  94. package/src/method-skills/1-analysis/wize-market-research/research.template.md +31 -0
  95. package/src/method-skills/1-analysis/wize-market-research/steps/step-01-init.md +57 -0
  96. package/src/method-skills/1-analysis/wize-market-research/steps/step-02-customer-behavior.md +39 -0
  97. package/src/method-skills/1-analysis/wize-market-research/steps/step-03-customer-pain-points.md +37 -0
  98. package/src/method-skills/1-analysis/wize-market-research/steps/step-04-customer-decisions.md +39 -0
  99. package/src/method-skills/1-analysis/wize-market-research/steps/step-05-competitive-analysis.md +37 -0
  100. package/src/method-skills/1-analysis/wize-market-research/steps/step-06-research-completion.md +47 -0
  101. package/src/method-skills/1-analysis/wize-market-research/workflow.md +66 -0
  102. package/src/method-skills/1-analysis/wize-prfaq/workflow.md +152 -11
  103. package/src/method-skills/1-analysis/wize-product-brief/workflow.md +92 -19
  104. package/src/method-skills/1-analysis/wize-refresh-knowledge/workflow.md +129 -0
  105. package/src/method-skills/1-analysis/wize-research/workflow.md +39 -12
  106. package/src/method-skills/1-analysis/wize-technical-research/customize.toml +14 -0
  107. package/src/method-skills/1-analysis/wize-technical-research/research.template.md +31 -0
  108. package/src/method-skills/1-analysis/wize-technical-research/technical-steps/step-01-init.md +49 -0
  109. package/src/method-skills/1-analysis/wize-technical-research/technical-steps/step-02-technical-overview.md +45 -0
  110. package/src/method-skills/1-analysis/wize-technical-research/technical-steps/step-03-integration-patterns.md +39 -0
  111. package/src/method-skills/1-analysis/wize-technical-research/technical-steps/step-04-architectural-patterns.md +39 -0
  112. package/src/method-skills/1-analysis/wize-technical-research/technical-steps/step-05-implementation-research.md +42 -0
  113. package/src/method-skills/1-analysis/wize-technical-research/technical-steps/step-06-research-synthesis.md +46 -0
  114. package/src/method-skills/1-analysis/wize-technical-research/workflow.md +60 -0
  115. package/src/method-skills/1-analysis/wize-trigger-map/workflow.md +82 -16
  116. package/src/method-skills/2-plan-workflows/wize-create-prd/workflow.md +135 -23
  117. package/src/method-skills/2-plan-workflows/wize-edit-prd/workflow.md +110 -0
  118. package/src/method-skills/2-plan-workflows/wize-ux-design/workflow.md +134 -28
  119. package/src/method-skills/2-plan-workflows/wize-ux-scenarios/workflow.md +93 -15
  120. package/src/method-skills/2-plan-workflows/wize-validate-prd/workflow.md +108 -12
  121. package/src/method-skills/3-solutioning/wize-check-implementation-readiness/workflow.md +103 -11
  122. package/src/method-skills/3-solutioning/wize-create-architecture/architecture-decision-template.md +41 -0
  123. package/src/method-skills/3-solutioning/wize-create-architecture/customize.toml +20 -0
  124. package/src/method-skills/3-solutioning/wize-create-architecture/steps/step-01-init.md +95 -0
  125. package/src/method-skills/3-solutioning/wize-create-architecture/steps/step-01b-continue.md +32 -0
  126. package/src/method-skills/3-solutioning/wize-create-architecture/steps/step-02-context.md +126 -0
  127. package/src/method-skills/3-solutioning/wize-create-architecture/steps/step-03-starter.md +110 -0
  128. package/src/method-skills/3-solutioning/wize-create-architecture/steps/step-04-decisions.md +129 -0
  129. package/src/method-skills/3-solutioning/wize-create-architecture/steps/step-05-patterns.md +109 -0
  130. package/src/method-skills/3-solutioning/wize-create-architecture/steps/step-06-structure.md +97 -0
  131. package/src/method-skills/3-solutioning/wize-create-architecture/steps/step-07-validation.md +124 -0
  132. package/src/method-skills/3-solutioning/wize-create-architecture/steps/step-08-complete.md +59 -0
  133. package/src/method-skills/3-solutioning/wize-create-architecture/workflow.md +55 -48
  134. package/src/method-skills/3-solutioning/wize-create-epics-and-stories/workflow.md +154 -15
  135. package/src/method-skills/3-solutioning/wize-design-system/workflow.md +184 -22
  136. package/src/method-skills/3-solutioning/wize-nfr-principles/workflow.md +145 -17
  137. package/src/method-skills/3-solutioning/wize-project-context/workflow.md +120 -0
  138. package/src/method-skills/3-solutioning/wize-tech-vision/workflow.md +130 -22
  139. package/src/method-skills/4-implementation/wize-agent-dev/persona.md +12 -0
  140. package/src/method-skills/4-implementation/wize-changelog/workflow.md +184 -0
  141. package/src/method-skills/4-implementation/wize-checkpoint-preview/workflow.md +117 -0
  142. package/src/method-skills/4-implementation/wize-code-review/customize.toml +21 -0
  143. package/src/method-skills/4-implementation/wize-code-review/steps/step-01-gather-context.md +64 -0
  144. package/src/method-skills/4-implementation/wize-code-review/steps/step-02-review.md +40 -0
  145. package/src/method-skills/4-implementation/wize-code-review/steps/step-03-triage.md +43 -0
  146. package/src/method-skills/4-implementation/wize-code-review/steps/step-04-present.md +100 -0
  147. package/src/method-skills/4-implementation/wize-code-review/workflow.md +54 -12
  148. package/src/method-skills/4-implementation/wize-correct-course/workflow.md +93 -0
  149. package/src/method-skills/4-implementation/wize-create-story/workflow.md +154 -10
  150. package/src/method-skills/4-implementation/wize-dev-story/workflow.md +185 -17
  151. package/src/method-skills/4-implementation/wize-investigate/workflow.md +123 -0
  152. package/src/method-skills/4-implementation/wize-quick-dev/workflow.md +136 -18
  153. package/src/method-skills/4-implementation/wize-release/workflow.md +162 -0
  154. package/src/method-skills/4-implementation/wize-retrospective/workflow.md +114 -10
  155. package/src/method-skills/4-implementation/wize-sprint-planning/workflow.md +78 -11
  156. package/src/method-skills/4-implementation/wize-sprint-status/workflow.md +45 -11
  157. package/src/method-skills/module.yaml +28 -0
  158. package/src/orchestrator-skills/module.yaml +7 -1
  159. package/src/orchestrator-skills/wize/skill.md +164 -0
  160. package/src/orchestrator-skills/wize-check/skill.md +98 -0
  161. package/src/orchestrator-skills/wize-help/skill.md +227 -67
  162. package/src/orchestrator-skills/wize-onboarding/workflow.md +78 -14
  163. package/src/orchestrator-skills/wize-orchestrator/agent.yaml +2 -0
  164. package/src/orchestrator-skills/wize-orchestrator/persona.md +44 -3
  165. package/src/orchestrator-skills/wize-party-mode/workflow.md +2 -0
  166. package/src/security-overlay/_shared/allowlist.js +154 -0
  167. package/src/security-overlay/_shared/backlog.js +169 -0
  168. package/src/security-overlay/_shared/cli-runner.js +87 -0
  169. package/src/security-overlay/_shared/cvss.js +108 -0
  170. package/src/security-overlay/_shared/detect.js +125 -0
  171. package/src/security-overlay/_shared/install-script.js +205 -0
  172. package/src/security-overlay/_shared/invoke-phase.js +86 -0
  173. package/src/security-overlay/_shared/owasp.js +56 -0
  174. package/src/security-overlay/_shared/partial.js +225 -0
  175. package/src/security-overlay/_shared/preflight.js +175 -0
  176. package/src/security-overlay/_shared/scope-gate.js +172 -0
  177. package/src/security-overlay/_shared/scope-parser.js +147 -0
  178. package/src/security-overlay/agents/red-teamer/agent.yaml +54 -0
  179. package/src/security-overlay/agents/red-teamer/persona.md +49 -0
  180. package/src/security-overlay/data/common.txt +115 -0
  181. package/src/security-overlay/data/owasp-top10.json +15 -0
  182. package/src/security-overlay/data/tool-allowlist.json +31 -0
  183. package/src/security-overlay/skills/wize-sec-enumerate/scripts/run-enumerate.js +180 -0
  184. package/src/security-overlay/skills/wize-sec-enumerate/skill.md +34 -0
  185. package/src/security-overlay/skills/wize-sec-exploit/data/common.txt +117 -0
  186. package/src/security-overlay/skills/wize-sec-exploit/scripts/run-ffuf.js +147 -0
  187. package/src/security-overlay/skills/wize-sec-exploit/scripts/run-nikto.js +145 -0
  188. package/src/security-overlay/skills/wize-sec-exploit/scripts/run-nuclei.js +176 -0
  189. package/src/security-overlay/skills/wize-sec-exploit/scripts/run-sqlmap.js +139 -0
  190. package/src/security-overlay/skills/wize-sec-pentest/scripts/run-pipeline.js +184 -0
  191. package/src/security-overlay/skills/wize-sec-pentest/skill.md +54 -0
  192. package/src/security-overlay/skills/wize-sec-recon/scripts/run-gitleaks.js +139 -0
  193. package/src/security-overlay/skills/wize-sec-recon/scripts/run-osv.js +227 -0
  194. package/src/security-overlay/skills/wize-sec-recon/scripts/run-recon.js +162 -0
  195. package/src/security-overlay/skills/wize-sec-recon/skill.md +37 -0
  196. package/src/security-overlay/skills/wize-sec-report/scripts/render-report.js +1033 -0
  197. package/src/security-overlay/skills/wize-sec-scope/scripts/generate-scope.js +106 -0
  198. package/src/security-overlay/skills/wize-sec-scope/skill.md +52 -0
  199. package/src/tea-skills/wize-qa-generate-e2e-tests/workflow.md +121 -0
  200. package/src/tea-skills/wize-tea-design/workflow.md +107 -13
  201. package/src/tea-skills/wize-tea-gate/workflow.md +118 -25
  202. package/src/tea-skills/wize-tea-nfr/workflow.md +107 -14
  203. package/src/tea-skills/wize-tea-review/workflow.md +123 -13
  204. package/src/tea-skills/wize-tea-risk/workflow.md +113 -10
  205. package/src/tea-skills/wize-tea-trace/workflow.md +86 -12
  206. package/src/web-overlay/wize-web-deploy/workflow.md +2 -0
  207. package/src/web-overlay/wize-web-scaffold/workflow.md +2 -0
  208. package/src/web-overlay/wize-web-seo-audit/workflow.md +2 -0
  209. package/tools/installer/baseline.js +133 -0
  210. package/tools/installer/commands/agent.js +197 -0
  211. package/tools/installer/commands/doctor.js +320 -0
  212. package/tools/installer/commands/document-project.js +93 -0
  213. package/tools/installer/commands/sync.js +45 -0
  214. package/tools/installer/commands/update.js +172 -0
  215. package/tools/installer/document-project/batch-scanner.js +93 -0
  216. package/tools/installer/document-project/classify.js +170 -0
  217. package/tools/installer/document-project/modes/deep-dive.js +196 -0
  218. package/tools/installer/document-project/modes/full-rescan.js +15 -0
  219. package/tools/installer/document-project/modes/initial-scan.js +100 -0
  220. package/tools/installer/document-project/modes/quick.js +211 -0
  221. package/tools/installer/document-project/render-index.js +101 -0
  222. package/tools/installer/document-project/state.js +110 -0
  223. package/tools/installer/onboarding.js +14 -20
  224. package/tools/installer/render-shared.js +159 -15
  225. package/tools/installer/setup-helpers.js +1 -0
  226. package/tools/installer/validators/run-all.js +3 -2
  227. package/tools/installer/version-check.js +117 -0
  228. package/tools/installer/wize-cli.js +500 -70
@@ -3,9 +3,10 @@
3
3
  * wize-dev-kit — CLI entry point
4
4
  * Subcommands: install, update, uninstall, list, sync, agent, workflow, help
5
5
  *
6
- * This is a v0.1 scaffold. The interactive prompt logic and adapter rendering
7
- * are stubs; the dispatcher and basic install/uninstall create the .wize/
8
- * folder layout so downstream agents can be activated.
6
+ * v0.15.0 — Full-lifecycle CLI with install, update, uninstall, list, sync,
7
+ * agent, workflow, validate, doctor, and document-project commands. Adapters
8
+ * render for 10 IDE targets. Security overlay ships with 8 tools.
9
+ * `install --yes` now enables all harnesses + all overlays by default.
9
10
  */
10
11
  'use strict';
11
12
 
@@ -13,8 +14,16 @@ const fs = require('node:fs');
13
14
  const os = require('node:os');
14
15
  const path = require('node:path');
15
16
  const readline = require('node:readline');
17
+ const { execSync } = require('node:child_process');
16
18
  const prompts = require('prompts');
17
19
  const { applyGitignore, generateUserToml } = require('./setup-helpers.js');
20
+ const { cmdUpdate, loadProjectConfig } = require('./commands/update.js');
21
+ const { printUpdateHintIfAny } = require('./version-check.js');
22
+ const { cmdSync: cmdSyncReal } = require('./commands/sync.js');
23
+ const { cmdAgentList, cmdAgentCreate, cmdAgentEdit } = require('./commands/agent.js');
24
+ const { cmdDoctor, adapterTargetPath } = require('./commands/doctor.js');
25
+ const { cmdDocumentProject } = require('./commands/document-project.js');
26
+ const { compose: composeOnboarding } = require('./onboarding.js');
18
27
 
19
28
  const INTERACTIVE = process.stdout.isTTY && process.stdin.isTTY;
20
29
 
@@ -28,6 +37,7 @@ const TARGETS = [
28
37
  { code: 'codex', label: 'Codex', default: false },
29
38
  { code: 'continue', label: 'Continue', default: false },
30
39
  { code: 'kimi-code', label: 'Kimi Code', default: false },
40
+ { code: 'hermes', label: 'Hermes Agent (.hermes/skills/)', default: false },
31
41
  { code: 'opencode', label: 'OpenCode', default: false },
32
42
  { code: 'antigravity', label: 'Antigravity (CLI + IDE)', default: false },
33
43
  { code: 'generic', label: 'Generic fallback (.wize/agents/)', default: true }
@@ -36,7 +46,8 @@ const TARGETS = [
36
46
  const PROFILES = [
37
47
  { code: 'core', label: 'Wize Dev Core', required: true },
38
48
  { code: 'web-overlay', label: 'Wize Web Dev (overlay)', required: false },
39
- { code: 'app-overlay', label: 'Wize App Development (overlay)', required: false }
49
+ { code: 'app-overlay', label: 'Wize App Development (overlay)', required: false },
50
+ { code: 'security-overlay', label: 'Wize Security (AI Pentester overlay)', required: false }
40
51
  ];
41
52
 
42
53
  // Common BCP-47 short codes. Users can type any other value freely.
@@ -67,6 +78,8 @@ Commands:
67
78
  agent <create|list> Manage agents (built-in or custom).
68
79
  workflow <create|list> Manage workflows.
69
80
  validate Run schema + lint + dry-run validators.
81
+ doctor Diagnose the kit + project state, suggest fixes.
82
+ document-project Document the current repo (quick | initial_scan | full_rescan | deep_dive).
70
83
  help Show this message.
71
84
 
72
85
  Documentation:
@@ -86,18 +99,131 @@ function logo() {
86
99
  ].join('\n');
87
100
  }
88
101
 
102
+ // Pipe-safe line reader.
103
+ //
104
+ // `readline.question()` has two bugs that bite us when stdin is a pipe (e.g.
105
+ // `printf ... | wize-dev-kit install` or our CI smoke test):
106
+ // 1. Opening a new createInterface per call closes stdin on .close().
107
+ // 2. Even with a shared interface, the second `question` after a single
108
+ // empty line ("\n") never resolves — readline's question machinery
109
+ // stalls in non-TTY mode.
110
+ //
111
+ // We replace it with an event-based queue: subscribe to `line` once, push
112
+ // resolved promises in order. Empty lines are propagated as `""`. EOF is
113
+ // treated as end of the queue (remaining waiters resolve with `""`).
114
+ let _rl = null;
115
+ let _queue = [];
116
+ let _waiters = [];
117
+
118
+ function getRl() {
119
+ if (_rl) return _rl;
120
+ _rl = readline.createInterface({ input: process.stdin, terminal: false });
121
+ _rl.on('line', (line) => {
122
+ if (_waiters.length) _waiters.shift()(line);
123
+ else _queue.push(line);
124
+ });
125
+ _rl.on('close', () => {
126
+ while (_waiters.length) _waiters.shift()('');
127
+ });
128
+ process.on('exit', () => { if (_rl) { _rl.close(); _rl = null; } });
129
+ return _rl;
130
+ }
131
+
89
132
  function prompt(question) {
90
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
91
- return new Promise(resolve => rl.question(question, ans => { rl.close(); resolve(ans.trim()); }));
133
+ process.stdout.write(question);
134
+ getRl();
135
+ // In interactive mode, discard any residual lines left by previous
136
+ // prompts (e.g. the prompts library) so this prompt always waits for
137
+ // fresh user input. In non-TTY / piped mode, those queued lines are
138
+ // intentional input and must be consumed in order.
139
+ if (INTERACTIVE) {
140
+ _queue = [];
141
+ }
142
+ if (_queue.length) return Promise.resolve(_queue.shift().trim());
143
+ return new Promise(resolve => _waiters.push((line) => resolve(line.trim())));
92
144
  }
93
145
 
94
146
  async function confirm(question, defaultYes = true) {
147
+ if (INTERACTIVE) {
148
+ const { value } = await prompts({
149
+ type: 'confirm',
150
+ name: 'value',
151
+ message: question,
152
+ initial: defaultYes
153
+ });
154
+ if (value === undefined) process.exit(130);
155
+ return value;
156
+ }
95
157
  const hint = defaultYes ? '[Y/n]' : '[y/N]';
96
158
  const ans = (await prompt(`${question} ${hint} `)).toLowerCase();
97
159
  if (!ans) return defaultYes;
98
160
  return ans.startsWith('y');
99
161
  }
100
162
 
163
+ async function promptText(question, defaultValue = '') {
164
+ if (INTERACTIVE) {
165
+ const { value } = await prompts({
166
+ type: 'text',
167
+ name: 'value',
168
+ message: question,
169
+ initial: defaultValue
170
+ });
171
+ if (value === undefined) process.exit(130);
172
+ return value.trim();
173
+ }
174
+ const ans = (await prompt(`${question} [${defaultValue}]: `)).trim();
175
+ return ans || defaultValue;
176
+ }
177
+
178
+ async function promptTextMandatory(question, defaultValue = '') {
179
+ if (INTERACTIVE) {
180
+ if (defaultValue) {
181
+ const { keep } = await prompts({
182
+ type: 'confirm',
183
+ name: 'keep',
184
+ message: `${question} (use "${defaultValue}"?)`,
185
+ initial: true
186
+ });
187
+ if (keep === undefined) process.exit(130);
188
+ if (keep) return defaultValue;
189
+ }
190
+ const { value } = await prompts({
191
+ type: 'text',
192
+ name: 'value',
193
+ message: question
194
+ });
195
+ if (value === undefined) process.exit(130);
196
+ const trimmed = value.trim();
197
+ if (trimmed) return trimmed;
198
+ if (defaultValue) return defaultValue;
199
+ return promptTextMandatory(question, defaultValue);
200
+ }
201
+ // Non-TTY: keep asking until non-empty.
202
+ for (;;) {
203
+ const ans = (await prompt(`${question}: `)).trim();
204
+ if (ans) return ans;
205
+ if (defaultValue) return defaultValue;
206
+ console.log('Please provide a value.');
207
+ }
208
+ }
209
+
210
+ async function select(label, choices, defaultValue) {
211
+ if (INTERACTIVE) {
212
+ const initial = choices.findIndex(c => c.value === defaultValue);
213
+ const { picked } = await prompts({
214
+ type: 'select',
215
+ name: 'picked',
216
+ message: label,
217
+ choices: choices.map(c => ({ title: c.title, value: c.value, description: c.description })),
218
+ initial: initial === -1 ? 0 : initial
219
+ });
220
+ if (picked === undefined) process.exit(130);
221
+ return picked;
222
+ }
223
+ // Non-TTY fallback: return default.
224
+ return defaultValue;
225
+ }
226
+
101
227
  async function selectLanguage(label, defaultCode = 'en') {
102
228
  if (INTERACTIVE) {
103
229
  const choices = LANGUAGES.map(l => ({
@@ -302,49 +428,169 @@ function renderAdapters({ kitRoot, projectRoot, targets, profiles }) {
302
428
  return results;
303
429
  }
304
430
 
431
+ // Parse --key value and --flag from an argv slice. Returns { flags, positional }.
432
+ function parseArgs(args) {
433
+ const flags = {};
434
+ const positional = [];
435
+ for (let i = 0; i < args.length; i++) {
436
+ const a = args[i];
437
+ if (a.startsWith('--')) {
438
+ const key = a.slice(2);
439
+ if (key.includes('=')) {
440
+ const [k, v] = key.split('=', 2);
441
+ flags[k] = v;
442
+ } else if (i + 1 < args.length && !args[i + 1].startsWith('--')) {
443
+ flags[key] = args[++i];
444
+ } else {
445
+ flags[key] = true;
446
+ }
447
+ } else {
448
+ positional.push(a);
449
+ }
450
+ }
451
+ return { flags, positional };
452
+ }
453
+
454
+ function resolveProfiles(flags) {
455
+ if (!flags.profiles) return null;
456
+ const codes = flags.profiles.split(',').map(s => s.trim()).filter(Boolean);
457
+ const resolved = [];
458
+ for (const c of codes) {
459
+ const p = PROFILES.find(p => p.code === c);
460
+ if (p) resolved.push(p);
461
+ else console.log(`⚠ perfil desconhecido: "${c}" — ignorado`);
462
+ }
463
+ if (resolved.length === 0) return null;
464
+ return resolved;
465
+ }
466
+
467
+ function resolveTargets(flags) {
468
+ if (!flags.targets) return null;
469
+ const codes = flags.targets.split(',').map(s => s.trim()).filter(Boolean);
470
+ const resolved = [];
471
+ for (const c of codes) {
472
+ const t = TARGETS.find(t => t.code === c);
473
+ if (t) resolved.push(t);
474
+ else console.log(`⚠ target desconhecido: "${c}" — ignorado`);
475
+ }
476
+ if (resolved.length === 0) return null;
477
+ return resolved;
478
+ }
479
+
480
+ function resolveLang(flags) {
481
+ if (!flags.lang) return null;
482
+ const code = flags.lang.trim();
483
+ if (/^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})?$/.test(code)) return code;
484
+ console.log(`⚠ código de idioma inválido: "${code}" — usando pt-BR`);
485
+ return null;
486
+ }
487
+
488
+ function resolveName(flags) {
489
+ if (flags.name) return flags.name.trim();
490
+ if (flags.yes) {
491
+ try { return execSync('git config user.name', { encoding: 'utf-8' }).trim(); } catch (_) {}
492
+ return process.env.USER || process.env.USERNAME || 'Developer';
493
+ }
494
+ return null;
495
+ }
496
+
497
+ // --yes quick install: everything on. All harnesses + all overlays, so
498
+ // `npx wize-dev-kit install --yes` is a true one-shot full install.
499
+ function defaultProfiles() {
500
+ return PROFILES.slice();
501
+ }
502
+
503
+ function defaultTargets() {
504
+ return TARGETS.slice();
505
+ }
506
+
305
507
  async function cmdInstall(args) {
306
508
  const cwd = process.cwd();
509
+ const { flags } = parseArgs(args);
510
+ const dryRun = !!flags['dry-run'];
511
+ const nonInteractive = !!flags.yes;
512
+
307
513
  console.log(logo());
308
- console.log('Installing Wize Development Kit into:', cwd);
514
+ if (dryRun) console.log('[DRY-RUN] Nenhum arquivo será modificado.\n');
515
+ console.log('Instalando Wize Development Kit em:', cwd);
516
+
309
517
  if (!isGitRepo(cwd)) {
310
- console.log('\n⚠ not a git repo. Initialize git first or proceed at your own risk.');
311
- const ok = await confirm('Continue anyway?', false);
518
+ console.log('\n⚠ não é um repositório git. Inicialize o git primeiro ou prossiga por sua conta e risco.');
519
+ if (nonInteractive) {
520
+ console.log('Modo não-interativo: abortando. Use --yes apenas em repositórios git.');
521
+ process.exit(1);
522
+ }
523
+ const ok = await confirm('Continuar mesmo assim?', false);
312
524
  if (!ok) process.exit(1);
313
525
  }
314
526
 
315
527
  const detection = detectBrownfield(cwd);
316
528
  if (detection.brownfield) {
317
- console.log(`\nBrownfield signals detected: ${detection.signals.join(', ')}`);
529
+ console.log(`\nSinais de brownfield detectados: ${detection.signals.join(', ')}`);
530
+ } else {
531
+ console.log('\nRepositório greenfield detectado.');
532
+ }
533
+
534
+ // Resolve flags or fall back to interactive prompts.
535
+ let project_name, profiles, targets, communication_language, document_output_language, user_name, wantsGitignore;
536
+
537
+ if (nonInteractive) {
538
+ project_name = flags.name ? resolveName(flags) : (path.basename(cwd));
539
+ profiles = resolveProfiles(flags) || defaultProfiles();
540
+ targets = resolveTargets(flags) || defaultTargets();
541
+ communication_language = resolveLang(flags) || 'pt-BR';
542
+ document_output_language = resolveLang(flags) || communication_language;
543
+ user_name = resolveName(flags);
544
+ wantsGitignore = true;
318
545
  } else {
319
- console.log('\nGreenfield repo detected.');
320
- }
321
-
322
- const project_name = (await prompt(`Project name [${path.basename(cwd)}]: `)) || path.basename(cwd);
323
- const profiles = await multiSelect('Select profile(s) to install', PROFILES);
324
- const targets = await multiSelect('Select IDE target(s)', TARGETS);
325
-
326
- const communication_language = await selectLanguage(
327
- 'Communication language (how agents will talk to you in chat)',
328
- 'en'
329
- );
330
- const document_output_language = await selectLanguage(
331
- `Document output language (language used in generated files; ENTER for "${communication_language}")`,
332
- communication_language
333
- );
334
-
335
- // Personal touch — the user_name lands in .wize/config/user.toml (per-developer).
336
- const defaultName = (os.userInfo().username || '').trim();
337
- const user_name = (await prompt(
338
- `How should the agents call you? [${defaultName || 'leave blank'}]: `
339
- )).trim() || defaultName;
340
-
341
- // Gitignore — opt-in, idempotent.
342
- const wantsGitignore = await confirm(
343
- 'Add the suggested entries to .gitignore (user.toml + scratch + generated adapter outputs)?',
344
- true
345
- );
346
-
347
- console.log('\nCreating .wize/ skeleton...');
546
+ project_name = (await promptText(`Nome do projeto`, path.basename(cwd))) || path.basename(cwd);
547
+ profiles = await multiSelect('Selecione o(s) perfil(is) para instalar', PROFILES);
548
+ targets = await multiSelect('Selecione o(s) IDE target(s)', TARGETS);
549
+
550
+ communication_language = await selectLanguage(
551
+ 'Idioma de comunicação (como os agentes vão falar com você no chat)',
552
+ 'pt-BR'
553
+ );
554
+ document_output_language = await selectLanguage(
555
+ `Idioma dos documentos (idioma usado nos arquivos gerados; ENTER para "${communication_language}")`,
556
+ communication_language
557
+ );
558
+
559
+ const defaultName = (os.userInfo().username || '').trim();
560
+ user_name = await promptTextMandatory(
561
+ 'Como os agentes devem te chamar?',
562
+ defaultName
563
+ );
564
+
565
+ wantsGitignore = await confirm(
566
+ 'Adicionar as entradas sugeridas ao .gitignore (user.toml + scratch + outputs de adapters)?',
567
+ true
568
+ );
569
+ }
570
+
571
+ // Show resolved config.
572
+ console.log(`\nConfiguração:`);
573
+ console.log(` Projeto: ${project_name}`);
574
+ console.log(` Perfis: ${profiles.map(p => p.code).join(', ')}`);
575
+ console.log(` IDE targets: ${targets.map(t => t.code).join(', ')}`);
576
+ console.log(` Idioma comm: ${communication_language}`);
577
+ console.log(` Idioma docs: ${document_output_language}`);
578
+ if (user_name) console.log(` Nome: ${user_name}`);
579
+ if (dryRun) console.log(` Modo: dry-run`);
580
+
581
+ if (dryRun) {
582
+ console.log('\n[DRY-RUN] Criaria estrutura .wize/:');
583
+ for (const dir of WIZE_DIRS) console.log(` - ${dir}/`);
584
+ console.log(`[DRY-RUN] Escreveria .wize/config/project.toml`);
585
+ console.log(`[DRY-RUN] Escreveria .wize/config/user.toml`);
586
+ console.log(`[DRY-RUN] Escreveria .wize/config/tea.toml`);
587
+ if (wantsGitignore) console.log(`[DRY-RUN] Atualizaria .gitignore`);
588
+ console.log(`\n[DRY-RUN] Geraria adapters para: ${targets.map(t => t.code).join(', ')}`);
589
+ console.log('\n[DRY-RUN] Concluído. Nenhum arquivo foi modificado.');
590
+ return;
591
+ }
592
+
593
+ console.log('\nCriando estrutura .wize/...');
348
594
  for (const dir of WIZE_DIRS) mkdirp(path.join(cwd, dir));
349
595
 
350
596
  writeIfMissing(path.join(cwd, '.wize/config/project.toml'), projectToml({
@@ -353,20 +599,26 @@ async function cmdInstall(args) {
353
599
  writeIfMissing(path.join(cwd, '.wize/config/user.toml'), generateUserToml({ name: user_name }));
354
600
  writeIfMissing(path.join(cwd, '.wize/config/tea.toml'), teaToml());
355
601
 
356
- console.log('✓ .wize/ created');
357
- console.log(`✓ profiles: ${profiles.map(p => p.code).join(', ')}`);
602
+ console.log('✓ .wize/ criado');
603
+ console.log(`✓ perfis: ${profiles.map(p => p.code).join(', ')}`);
358
604
  console.log(`✓ ide targets: ${targets.map(t => t.code).join(', ')}`);
359
- if (user_name) console.log(`✓ user.toml: agents will call you "${user_name}"`);
605
+ if (user_name) console.log(`✓ user.toml: agentes vão te chamar de "${user_name}"`);
606
+
607
+ if (profiles.some(p => p.code === 'security-overlay')) {
608
+ console.log('\n⚠ security-overlay selecionado — uso autorizado apenas.');
609
+ console.log(' Uso autorizado. Você é responsável por obter permissão antes de testar alvos que não são seus.');
610
+ console.log(' O kit detecta alvos fora do scope.md e recusa automaticamente; ainda assim, use com responsabilidade.');
611
+ }
360
612
 
361
613
  if (wantsGitignore) {
362
614
  const r = applyGitignore(cwd);
363
- if (r.changed) console.log(`✓ .gitignore ${r.mode} with the wize-dev-kit block`);
364
- else console.log(`= .gitignore already up to date`);
615
+ if (r.changed) console.log(`✓ .gitignore ${r.mode} com o bloco wize-dev-kit`);
616
+ else console.log(`= .gitignore já está atualizado`);
365
617
  } else {
366
- console.log('= .gitignore untouched (you opted out of suggested entries)');
618
+ console.log('= .gitignore não modificado (você optou por não adicionar as entradas sugeridas)');
367
619
  }
368
620
 
369
- console.log('\nGenerating IDE adapters...');
621
+ console.log('\nGerando adapters IDE...');
370
622
  const renderResults = renderAdapters({
371
623
  kitRoot: KIT_ROOT,
372
624
  projectRoot: cwd,
@@ -374,33 +626,191 @@ async function cmdInstall(args) {
374
626
  profiles
375
627
  });
376
628
  for (const r of renderResults) {
377
- if (r.skipped) console.log(` - ${r.code}: skipped (${r.reason})`);
378
- else if (r.written) console.log(` ✓ ${r.code}: ${r.written} skill(s) emitted`);
629
+ if (r.skipped) console.log(` - ${r.code}: pulado (${r.reason})`);
630
+ else if (r.written) console.log(` ✓ ${r.code}: ${r.written} skill(s) emitidas`);
379
631
  else if (r.error) console.log(` ✖ ${r.code}: ${r.error}`);
380
632
  }
381
633
 
382
634
  if (detection.brownfield) {
383
- const baseline = await confirm('\nRun `wize-document-project` to baseline the existing repo now?', true);
384
- if (baseline) {
385
- console.log('(stub) Pepper + Peggy would now produce the baseline docs in .wize/knowledge/document-project/.');
635
+ if (process.env.WIZE_SKIP_BASELINE === '1') {
636
+ console.log('\nWIZE_SKIP_BASELINE=1 — baseline não será executado.');
637
+ } else if (!INTERACTIVE || nonInteractive) {
638
+ console.log('\nInstalação não-interativa detectada; executando baseline rápido...');
639
+ cmdDocumentProject({ kitRoot: KIT_ROOT, projectRoot: cwd, args: ['quick'], opts: { log: console.log } });
640
+ } else {
641
+ const mode = await select(
642
+ 'Documentar o repositório existente agora?',
643
+ [
644
+ { title: 'Baseline rápido (padrão, 6 arquivos)', value: 'quick' },
645
+ { title: 'Scan inicial (documentos de padrão + condicionais)', value: 'initial_scan' },
646
+ { title: 'Rescan completo (arquiva estado anterior, re-executa)', value: 'full_rescan' },
647
+ { title: 'Pular documentação por enquanto', value: 'skip' }
648
+ ],
649
+ 'quick'
650
+ );
651
+ if (mode !== 'skip') {
652
+ cmdDocumentProject({ kitRoot: KIT_ROOT, projectRoot: cwd, args: [mode], opts: { log: console.log } });
653
+ } else {
654
+ console.log('\nDocumentação pulada. Execute `wize-dev-kit document-project` depois.');
655
+ }
386
656
  }
387
657
  }
388
658
 
389
- console.log('\nDone. Activate Wizer in your IDE and say: "Brief me on this project."');
659
+ console.log('\n──────────────────────────────────────────────────────────────');
660
+ console.log('Concluído.');
661
+ console.log('');
662
+ console.log('⚠ Reinicie seu IDE — muitos harnesses carregam skills apenas na inicialização.');
663
+ console.log(composeOnboarding(detection, profiles));
664
+ console.log('');
665
+ console.log('Mantenha o kit sincronizado:');
666
+ console.log(' • `npx wize-dev-kit update` atualizar adapters após nova versão do kit');
667
+ console.log(' • `npx wize-dev-kit sync` re-renderizar adapters após editar config');
668
+ console.log(' • `npx wize-dev-kit agent list | create | edit <code>` gerenciar agentes');
669
+ console.log('──────────────────────────────────────────────────────────────');
670
+ }
671
+
672
+ // AGENTS.md signature — used to detect whether the file was generated by the kit.
673
+ const AGENTS_SIGNATURE = '# Agents — Wize Development Kit';
674
+
675
+ function isKitAgentsMd(filePath) {
676
+ if (!fs.existsSync(filePath)) return false;
677
+ try {
678
+ const head = fs.readFileSync(filePath, 'utf-8').slice(0, 200);
679
+ return head.includes(AGENTS_SIGNATURE);
680
+ } catch { return false; }
681
+ }
682
+
683
+ // Delete wize-* entries from an adapter target directory. Returns count of
684
+ // removed items (files + dirs). Safe: only deletes entries whose name starts
685
+ // with "wize-".
686
+ function cleanAdapterTarget(targetDir) {
687
+ if (!fs.existsSync(targetDir)) return 0;
688
+ let count = 0;
689
+ let entries;
690
+ try { entries = fs.readdirSync(targetDir); } catch { return 0; }
691
+ for (const name of entries) {
692
+ if (!name.startsWith('wize-')) continue;
693
+ const full = path.join(targetDir, name);
694
+ try {
695
+ fs.rmSync(full, { recursive: true, force: true });
696
+ count++;
697
+ } catch { /* skip permission errors */ }
698
+ }
699
+ return count;
390
700
  }
391
701
 
392
- async function cmdUninstall() {
702
+ async function cmdUninstall(args) {
393
703
  const cwd = process.cwd();
394
- const dir = path.join(cwd, '.wize');
395
- if (!fs.existsSync(dir)) {
396
- console.log('No .wize/ folder found here.');
704
+ const { flags } = parseArgs(args || []);
705
+ const dryRun = !!flags['dry-run'];
706
+
707
+ if (dryRun) console.log('[DRY-RUN] Nenhum arquivo será removido.\n');
708
+
709
+ const wizeDir = path.join(cwd, '.wize');
710
+ if (!fs.existsSync(wizeDir)) {
711
+ console.log('Nenhuma pasta .wize/ encontrada aqui.');
397
712
  return;
398
713
  }
399
- const ok = await confirm(`Remove ${dir}? Your project source code is not touched.`, false);
400
- if (!ok) return;
401
- fs.rmSync(dir, { recursive: true, force: true });
402
- console.log('Removed .wize/.');
403
- console.log('(stub) IDE adapter files (.claude/skills/wize-*, .cursor/rules/wize-*) would be cleaned here.');
714
+
715
+ // Read project.toml to discover which IDE targets were configured.
716
+ let ideTargets = [];
717
+ try {
718
+ const cfg = loadProjectConfig(cwd);
719
+ ideTargets = (cfg.install && cfg.install.ide_targets) || [];
720
+ } catch { /* project.toml may be missing or corrupt */ }
721
+
722
+ // Build the list of what would be removed.
723
+ const toRemove = [];
724
+
725
+ // 1. Adapter target dirs (wize-* entries).
726
+ const adapterDirs = [];
727
+ for (const code of ideTargets) {
728
+ const dir = adapterTargetPath(code, cwd);
729
+ if (!dir) continue;
730
+ if (!fs.existsSync(dir)) continue;
731
+ let entries;
732
+ try { entries = fs.readdirSync(dir); } catch { continue; }
733
+ for (const name of entries) {
734
+ if (!name.startsWith('wize-')) continue;
735
+ adapterDirs.push({ target: code, dir, name, full: path.join(dir, name) });
736
+ }
737
+ }
738
+
739
+ // 2. .wize/ directory.
740
+ toRemove.push({ kind: 'diretório', path: wizeDir, label: '.wize/' });
741
+
742
+ // 3. AGENTS.md if kit-generated.
743
+ const agentsMd = path.join(cwd, 'AGENTS.md');
744
+ if (isKitAgentsMd(agentsMd)) {
745
+ toRemove.push({ kind: 'arquivo', path: agentsMd, label: 'AGENTS.md' });
746
+ }
747
+
748
+ // Show what will be removed.
749
+ if (adapterDirs.length > 0) {
750
+ console.log('Arquivos de adapter que serão removidos:');
751
+ const byTarget = {};
752
+ for (const a of adapterDirs) {
753
+ byTarget[a.target] = byTarget[a.target] || [];
754
+ byTarget[a.target].push(a.name);
755
+ }
756
+ for (const [code, names] of Object.entries(byTarget)) {
757
+ console.log(` ${code}: ${names.length} entrada(s) (${names.slice(0, 5).join(', ')}${names.length > 5 ? '...' : ''})`);
758
+ }
759
+ } else {
760
+ console.log('Nenhum arquivo de adapter wize-* encontrado.');
761
+ }
762
+
763
+ console.log(`\nSerá removido:`);
764
+ for (const item of toRemove) {
765
+ console.log(` - ${item.label} (${item.kind})`);
766
+ }
767
+ if (adapterDirs.length > 0) {
768
+ console.log(` - ${adapterDirs.length} entrada(s) wize-* nos diretórios de adapter`);
769
+ }
770
+
771
+ if (dryRun) {
772
+ console.log('\n[DRY-RUN] Concluído. Nenhum arquivo foi removido.');
773
+ return;
774
+ }
775
+
776
+ const totalItems = toRemove.length + adapterDirs.length;
777
+ if (totalItems === 0) {
778
+ console.log('\nNada para remover.');
779
+ return;
780
+ }
781
+
782
+ const ok = await confirm(`\nRemover ${totalItems} item(ns)? O código-fonte do seu projeto não será afetado.`, false);
783
+ if (!ok) {
784
+ console.log('Cancelado.');
785
+ return;
786
+ }
787
+
788
+ // Capture AGENTS.md status before deletion.
789
+ const hadAgentsMd = isKitAgentsMd(agentsMd);
790
+
791
+ // Delete adapter entries first.
792
+ let adapterCount = 0;
793
+ for (const a of adapterDirs) {
794
+ try {
795
+ fs.rmSync(a.full, { recursive: true, force: true });
796
+ adapterCount++;
797
+ } catch (err) {
798
+ console.log(` ✖ erro ao remover ${a.name}: ${err.message}`);
799
+ }
800
+ }
801
+
802
+ // Delete .wize/ and AGENTS.md.
803
+ for (const item of toRemove) {
804
+ try {
805
+ fs.rmSync(item.path, { recursive: true, force: true });
806
+ } catch (err) {
807
+ console.log(` ✖ erro ao remover ${item.label}: ${err.message}`);
808
+ }
809
+ }
810
+
811
+ console.log(`\n✓ Removido: .wize/ + ${adapterCount} entrada(s) de adapter`);
812
+ if (hadAgentsMd) console.log('✓ AGENTS.md removido');
813
+ console.log('\nO código-fonte do seu projeto não foi alterado.');
404
814
  }
405
815
 
406
816
  function cmdList() {
@@ -418,9 +828,10 @@ function cmdList() {
418
828
  ['wize-agent-dev', 'Shuri']
419
829
  ];
420
830
  for (const [code, name] of list) console.log(` ${code.padEnd(36)} ${name}`);
831
+ console.log(` ${'wize-sec-red-teamer'.padEnd(36)} Natasha Romanoff (security-overlay, opt-in)`);
421
832
 
422
833
  console.log('\nWorkflows directories:');
423
- const phases = ['1-analysis', '2-plan-workflows', '3-solutioning', '4-implementation'];
834
+ const phases = ['1-analysis', '2-plan', '3-solutioning', '4-implementation'];
424
835
  for (const phase of phases) {
425
836
  const dir = path.join(KIT_ROOT, 'src/method-skills', phase);
426
837
  if (!fs.existsSync(dir)) continue;
@@ -432,17 +843,18 @@ function cmdList() {
432
843
  }
433
844
 
434
845
  function cmdSync() {
435
- console.log('(stub) Sync would regenerate IDE adapter files for active targets in .wize/config/project.toml.');
846
+ return cmdSyncReal({ kitRoot: KIT_ROOT, projectRoot: process.cwd() });
436
847
  }
437
848
 
438
849
  function cmdAgent(args) {
439
850
  const sub = args[0] || 'list';
440
- if (sub === 'list') return cmdList();
441
- if (sub === 'create') {
442
- console.log('(stub) Interactive agent creation. See src/builder-skills/wize-create-agent/workflow.md.');
443
- return;
444
- }
851
+ const rest = args.slice(1);
852
+ const ctx = { kitRoot: KIT_ROOT, projectRoot: process.cwd() };
853
+ if (sub === 'list') return cmdAgentList(ctx);
854
+ if (sub === 'create') return cmdAgentCreate(ctx);
855
+ if (sub === 'edit') return cmdAgentEdit({ ...ctx, code: rest[0] });
445
856
  console.log(`Unknown agent subcommand: ${sub}`);
857
+ console.log('Available: list | create | edit <code>');
446
858
  }
447
859
 
448
860
  function cmdWorkflow(args) {
@@ -459,21 +871,39 @@ function cmdValidate() {
459
871
  require('./validators/run-all.js')(KIT_ROOT);
460
872
  }
461
873
 
874
+ // Commands worth nudging the user about when a newer version exists. Skipped
875
+ // for `update` (already updating), `install` (already setting up), `uninstall`
876
+ // (already leaving), `validate` (developer-tool), and `version` (the user is
877
+ // already asking about versions).
878
+ const HINT_COMMANDS = new Set(['list', 'sync', 'agent', 'workflow', 'help', 'doctor', 'document-project']);
879
+
462
880
  async function main() {
463
881
  const [cmd, ...rest] = process.argv.slice(2);
464
882
  if (!cmd || cmd === 'help' || cmd === '--help' || cmd === '-h') {
883
+ await printUpdateHintIfAny(KIT_VERSION);
465
884
  console.log(HELP);
466
885
  return;
467
886
  }
887
+ if (HINT_COMMANDS.has(cmd)) {
888
+ await printUpdateHintIfAny(KIT_VERSION);
889
+ }
468
890
  switch (cmd) {
469
891
  case 'install': return cmdInstall(rest);
470
- case 'update': console.log('(stub) Update: diff + preserve customizations. Not yet implemented.'); return;
471
- case 'uninstall': return cmdUninstall();
892
+ case 'update': return cmdUpdate({ kitRoot: KIT_ROOT, projectRoot: process.cwd() });
893
+ case 'uninstall': return cmdUninstall(rest);
472
894
  case 'list': return cmdList();
473
895
  case 'sync': return cmdSync();
474
896
  case 'agent': return cmdAgent(rest);
475
897
  case 'workflow': return cmdWorkflow(rest);
476
898
  case 'validate': return cmdValidate();
899
+ case 'doctor': return cmdDoctor({ kitRoot: KIT_ROOT, projectRoot: process.cwd() });
900
+ case 'document-project':
901
+ return cmdDocumentProject({
902
+ kitRoot: KIT_ROOT,
903
+ projectRoot: process.cwd(),
904
+ args: rest,
905
+ opts: { log: console.log }
906
+ });
477
907
  case 'version':
478
908
  case '--version':
479
909
  case '-v':