wize-dev-kit 0.14.0 → 0.16.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/ARCH.md +24 -77
- package/CHANGELOG.md +24 -0
- package/DECISIONS.md +1 -27
- package/README.md +7 -2
- package/ROSTER.md +3 -11
- package/adapters/README.md +7 -7
- package/adapters/antigravity/README.md +5 -5
- package/adapters/claude-code/README.md +1 -1
- package/adapters/codex/README.md +5 -5
- package/adapters/codex/adapter.yaml +1 -1
- package/adapters/codex/render.js +1 -1
- package/adapters/continue/README.md +5 -5
- package/adapters/cursor/README.md +2 -2
- package/adapters/generic/README.md +1 -1
- package/adapters/kimi-code/README.md +5 -5
- package/adapters/kimi-code/render.js +2 -2
- package/adapters/opencode/README.md +3 -3
- package/adapters/opencode/render.js +1 -27
- package/adapters/windsurf/README.md +3 -3
- package/package.json +1 -1
- package/schemas/agent.schema.json +2 -2
- package/schemas/workflow.schema.json +1 -1
- package/src/app-overlay/wize-app-release-channels/workflow.md +0 -2
- package/src/app-overlay/wize-app-scaffold/workflow.md +0 -2
- package/src/app-overlay/wize-app-store-listing/workflow.md +0 -2
- package/src/builder-skills/wize-create-agent/workflow.md +0 -2
- package/src/builder-skills/wize-create-skill/workflow.md +0 -2
- package/src/builder-skills/wize-create-workflow/workflow.md +0 -2
- package/src/core-skills/module.yaml +3 -0
- package/src/core-skills/wize-advanced-elicitation/skill.md +0 -2
- package/src/core-skills/wize-brainstorming/skill.md +0 -2
- package/src/core-skills/wize-eli5/skill.md +72 -0
- package/src/core-skills/wize-review-adversarial/skill.md +0 -3
- package/src/core-skills/wize-shard-doc/skill.md +0 -2
- package/src/method-skills/1-analysis/wize-agent-analyst/agent.yaml +0 -3
- package/src/method-skills/1-analysis/wize-document-project/workflow.md +20 -213
- package/src/method-skills/1-analysis/wize-prfaq/workflow.md +11 -152
- package/src/method-skills/1-analysis/wize-product-brief/workflow.md +19 -92
- package/src/method-skills/1-analysis/wize-research/workflow.md +12 -39
- package/src/method-skills/1-analysis/wize-trigger-map/workflow.md +16 -82
- package/src/method-skills/2-plan-workflows/wize-create-prd/workflow.md +23 -135
- package/src/method-skills/2-plan-workflows/wize-ux-design/workflow.md +28 -134
- package/src/method-skills/2-plan-workflows/wize-ux-scenarios/workflow.md +15 -93
- package/src/method-skills/2-plan-workflows/wize-validate-prd/workflow.md +12 -108
- package/src/method-skills/3-solutioning/wize-check-implementation-readiness/workflow.md +11 -103
- package/src/method-skills/3-solutioning/wize-create-architecture/workflow.md +48 -55
- package/src/method-skills/3-solutioning/wize-create-epics-and-stories/workflow.md +15 -154
- package/src/method-skills/3-solutioning/wize-design-system/workflow.md +22 -184
- package/src/method-skills/3-solutioning/wize-nfr-principles/workflow.md +17 -145
- package/src/method-skills/3-solutioning/wize-tech-vision/workflow.md +22 -130
- package/src/method-skills/4-implementation/wize-agent-dev/persona.md +0 -12
- package/src/method-skills/4-implementation/wize-code-review/workflow.md +12 -54
- package/src/method-skills/4-implementation/wize-create-story/workflow.md +10 -154
- package/src/method-skills/4-implementation/wize-dev-story/workflow.md +17 -185
- package/src/method-skills/4-implementation/wize-quick-dev/workflow.md +18 -136
- package/src/method-skills/4-implementation/wize-retrospective/workflow.md +10 -114
- package/src/method-skills/4-implementation/wize-sprint-planning/workflow.md +11 -78
- package/src/method-skills/4-implementation/wize-sprint-status/workflow.md +11 -45
- package/src/method-skills/module.yaml +0 -28
- package/src/orchestrator-skills/module.yaml +1 -7
- package/src/orchestrator-skills/wize-help/skill.md +67 -227
- package/src/orchestrator-skills/wize-onboarding/workflow.md +14 -78
- package/src/orchestrator-skills/wize-orchestrator/agent.yaml +0 -2
- package/src/orchestrator-skills/wize-orchestrator/persona.md +3 -44
- package/src/orchestrator-skills/wize-party-mode/workflow.md +0 -2
- package/src/tea-skills/wize-tea-design/workflow.md +13 -107
- package/src/tea-skills/wize-tea-gate/workflow.md +25 -118
- package/src/tea-skills/wize-tea-nfr/workflow.md +14 -107
- package/src/tea-skills/wize-tea-review/workflow.md +13 -123
- package/src/tea-skills/wize-tea-risk/workflow.md +10 -113
- package/src/tea-skills/wize-tea-trace/workflow.md +12 -86
- package/src/web-overlay/wize-web-deploy/workflow.md +0 -2
- package/src/web-overlay/wize-web-scaffold/workflow.md +0 -2
- package/src/web-overlay/wize-web-seo-audit/workflow.md +0 -2
- package/tools/check-eli5-all-adapters.js +50 -0
- package/tools/installer/onboarding.js +20 -14
- package/tools/installer/render-shared.js +14 -158
- package/tools/installer/validators/run-all.js +2 -3
- package/tools/installer/wize-cli.js +70 -499
- package/AGENTS.md +0 -37
- package/README.es.md +0 -294
- package/README.pt-BR.md +0 -292
- package/docs/harnesses/antigravity.md +0 -20
- package/docs/harnesses/antigravity.pt-BR.md +0 -20
- package/docs/harnesses/claude-code.md +0 -23
- package/docs/harnesses/claude-code.pt-BR.md +0 -23
- package/docs/harnesses/codex.md +0 -21
- package/docs/harnesses/codex.pt-BR.md +0 -21
- package/docs/harnesses/continue.md +0 -21
- package/docs/harnesses/continue.pt-BR.md +0 -21
- package/docs/harnesses/cursor.md +0 -22
- package/docs/harnesses/cursor.pt-BR.md +0 -22
- package/docs/harnesses/generic.md +0 -20
- package/docs/harnesses/generic.pt-BR.md +0 -20
- package/docs/harnesses/kimi-code.md +0 -19
- package/docs/harnesses/kimi-code.pt-BR.md +0 -19
- package/docs/harnesses/opencode.md +0 -31
- package/docs/harnesses/opencode.pt-BR.md +0 -31
- package/docs/harnesses/windsurf.md +0 -22
- package/docs/harnesses/windsurf.pt-BR.md +0 -22
- package/src/core-skills/wize-customize/skill.md +0 -116
- package/src/core-skills/wize-editorial-review-prose/skill.md +0 -94
- package/src/core-skills/wize-editorial-review-structure/skill.md +0 -99
- package/src/core-skills/wize-grill/skill.md +0 -77
- package/src/core-skills/wize-index-docs/skill.md +0 -119
- package/src/core-skills/wize-pre-pr-check/skill.md +0 -134
- package/src/core-skills/wize-review-edge-case-hunter/skill.md +0 -115
- package/src/core-skills/wize-spec/assets/headless-schemas.md +0 -39
- package/src/core-skills/wize-spec/assets/spec-template.md +0 -40
- package/src/core-skills/wize-spec/customize.toml +0 -20
- package/src/core-skills/wize-spec/skill.md +0 -112
- package/src/method-skills/1-analysis/wize-document-project/documentation-requirements.csv +0 -12
- package/src/method-skills/1-analysis/wize-document-project/templates/api-contracts-template.md +0 -38
- package/src/method-skills/1-analysis/wize-document-project/templates/architecture-template.md +0 -54
- package/src/method-skills/1-analysis/wize-document-project/templates/component-inventory-template.md +0 -40
- package/src/method-skills/1-analysis/wize-document-project/templates/contribution-guide-template.md +0 -34
- package/src/method-skills/1-analysis/wize-document-project/templates/data-models-template.md +0 -36
- package/src/method-skills/1-analysis/wize-document-project/templates/deep-dive-template.md +0 -312
- package/src/method-skills/1-analysis/wize-document-project/templates/deployment-guide-template.md +0 -42
- package/src/method-skills/1-analysis/wize-document-project/templates/development-guide-template.md +0 -61
- package/src/method-skills/1-analysis/wize-document-project/templates/index-template.md +0 -185
- package/src/method-skills/1-analysis/wize-document-project/templates/project-overview-template.md +0 -110
- package/src/method-skills/1-analysis/wize-document-project/templates/project-scan-report-schema.json +0 -159
- package/src/method-skills/1-analysis/wize-document-project/templates/source-tree-template.md +0 -142
- package/src/method-skills/1-analysis/wize-domain-research/customize.toml +0 -14
- package/src/method-skills/1-analysis/wize-domain-research/domain-steps/step-01-init.md +0 -49
- package/src/method-skills/1-analysis/wize-domain-research/domain-steps/step-02-domain-analysis.md +0 -39
- package/src/method-skills/1-analysis/wize-domain-research/domain-steps/step-03-competitive-landscape.md +0 -39
- package/src/method-skills/1-analysis/wize-domain-research/domain-steps/step-04-regulatory-focus.md +0 -39
- package/src/method-skills/1-analysis/wize-domain-research/domain-steps/step-05-technical-trends.md +0 -39
- package/src/method-skills/1-analysis/wize-domain-research/domain-steps/step-06-research-synthesis.md +0 -43
- package/src/method-skills/1-analysis/wize-domain-research/research.template.md +0 -31
- package/src/method-skills/1-analysis/wize-domain-research/workflow.md +0 -58
- package/src/method-skills/1-analysis/wize-market-research/customize.toml +0 -14
- package/src/method-skills/1-analysis/wize-market-research/research.template.md +0 -31
- package/src/method-skills/1-analysis/wize-market-research/steps/step-01-init.md +0 -57
- package/src/method-skills/1-analysis/wize-market-research/steps/step-02-customer-behavior.md +0 -39
- package/src/method-skills/1-analysis/wize-market-research/steps/step-03-customer-pain-points.md +0 -37
- package/src/method-skills/1-analysis/wize-market-research/steps/step-04-customer-decisions.md +0 -39
- package/src/method-skills/1-analysis/wize-market-research/steps/step-05-competitive-analysis.md +0 -37
- package/src/method-skills/1-analysis/wize-market-research/steps/step-06-research-completion.md +0 -47
- package/src/method-skills/1-analysis/wize-market-research/workflow.md +0 -66
- package/src/method-skills/1-analysis/wize-refresh-knowledge/workflow.md +0 -129
- package/src/method-skills/1-analysis/wize-technical-research/customize.toml +0 -14
- package/src/method-skills/1-analysis/wize-technical-research/research.template.md +0 -31
- package/src/method-skills/1-analysis/wize-technical-research/technical-steps/step-01-init.md +0 -49
- package/src/method-skills/1-analysis/wize-technical-research/technical-steps/step-02-technical-overview.md +0 -45
- package/src/method-skills/1-analysis/wize-technical-research/technical-steps/step-03-integration-patterns.md +0 -39
- package/src/method-skills/1-analysis/wize-technical-research/technical-steps/step-04-architectural-patterns.md +0 -39
- package/src/method-skills/1-analysis/wize-technical-research/technical-steps/step-05-implementation-research.md +0 -42
- package/src/method-skills/1-analysis/wize-technical-research/technical-steps/step-06-research-synthesis.md +0 -46
- package/src/method-skills/1-analysis/wize-technical-research/workflow.md +0 -60
- package/src/method-skills/2-plan-workflows/wize-edit-prd/workflow.md +0 -110
- package/src/method-skills/3-solutioning/wize-create-architecture/architecture-decision-template.md +0 -41
- package/src/method-skills/3-solutioning/wize-create-architecture/customize.toml +0 -20
- package/src/method-skills/3-solutioning/wize-create-architecture/steps/step-01-init.md +0 -95
- package/src/method-skills/3-solutioning/wize-create-architecture/steps/step-01b-continue.md +0 -32
- package/src/method-skills/3-solutioning/wize-create-architecture/steps/step-02-context.md +0 -126
- package/src/method-skills/3-solutioning/wize-create-architecture/steps/step-03-starter.md +0 -110
- package/src/method-skills/3-solutioning/wize-create-architecture/steps/step-04-decisions.md +0 -129
- package/src/method-skills/3-solutioning/wize-create-architecture/steps/step-05-patterns.md +0 -109
- package/src/method-skills/3-solutioning/wize-create-architecture/steps/step-06-structure.md +0 -97
- package/src/method-skills/3-solutioning/wize-create-architecture/steps/step-07-validation.md +0 -124
- package/src/method-skills/3-solutioning/wize-create-architecture/steps/step-08-complete.md +0 -59
- package/src/method-skills/3-solutioning/wize-project-context/workflow.md +0 -120
- package/src/method-skills/4-implementation/wize-changelog/workflow.md +0 -184
- package/src/method-skills/4-implementation/wize-checkpoint-preview/workflow.md +0 -117
- package/src/method-skills/4-implementation/wize-code-review/customize.toml +0 -21
- package/src/method-skills/4-implementation/wize-code-review/steps/step-01-gather-context.md +0 -64
- package/src/method-skills/4-implementation/wize-code-review/steps/step-02-review.md +0 -40
- package/src/method-skills/4-implementation/wize-code-review/steps/step-03-triage.md +0 -43
- package/src/method-skills/4-implementation/wize-code-review/steps/step-04-present.md +0 -100
- package/src/method-skills/4-implementation/wize-correct-course/workflow.md +0 -93
- package/src/method-skills/4-implementation/wize-investigate/workflow.md +0 -123
- package/src/method-skills/4-implementation/wize-release/workflow.md +0 -162
- package/src/orchestrator-skills/wize/skill.md +0 -164
- package/src/orchestrator-skills/wize-check/skill.md +0 -98
- package/src/security-overlay/_shared/allowlist.js +0 -154
- package/src/security-overlay/_shared/backlog.js +0 -169
- package/src/security-overlay/_shared/cli-runner.js +0 -87
- package/src/security-overlay/_shared/cvss.js +0 -108
- package/src/security-overlay/_shared/detect.js +0 -125
- package/src/security-overlay/_shared/install-script.js +0 -205
- package/src/security-overlay/_shared/invoke-phase.js +0 -86
- package/src/security-overlay/_shared/owasp.js +0 -56
- package/src/security-overlay/_shared/partial.js +0 -225
- package/src/security-overlay/_shared/preflight.js +0 -175
- package/src/security-overlay/_shared/scope-gate.js +0 -172
- package/src/security-overlay/_shared/scope-parser.js +0 -147
- package/src/security-overlay/agents/red-teamer/agent.yaml +0 -54
- package/src/security-overlay/agents/red-teamer/persona.md +0 -49
- package/src/security-overlay/data/common.txt +0 -115
- package/src/security-overlay/data/owasp-top10.json +0 -15
- package/src/security-overlay/data/tool-allowlist.json +0 -31
- package/src/security-overlay/skills/wize-sec-enumerate/scripts/run-enumerate.js +0 -180
- package/src/security-overlay/skills/wize-sec-enumerate/skill.md +0 -34
- package/src/security-overlay/skills/wize-sec-exploit/data/common.txt +0 -117
- package/src/security-overlay/skills/wize-sec-exploit/scripts/run-ffuf.js +0 -147
- package/src/security-overlay/skills/wize-sec-exploit/scripts/run-nikto.js +0 -145
- package/src/security-overlay/skills/wize-sec-exploit/scripts/run-nuclei.js +0 -176
- package/src/security-overlay/skills/wize-sec-exploit/scripts/run-sqlmap.js +0 -139
- package/src/security-overlay/skills/wize-sec-pentest/scripts/run-pipeline.js +0 -184
- package/src/security-overlay/skills/wize-sec-pentest/skill.md +0 -54
- package/src/security-overlay/skills/wize-sec-recon/scripts/run-gitleaks.js +0 -139
- package/src/security-overlay/skills/wize-sec-recon/scripts/run-osv.js +0 -227
- package/src/security-overlay/skills/wize-sec-recon/scripts/run-recon.js +0 -162
- package/src/security-overlay/skills/wize-sec-recon/skill.md +0 -37
- package/src/security-overlay/skills/wize-sec-report/scripts/render-report.js +0 -1033
- package/src/security-overlay/skills/wize-sec-scope/scripts/generate-scope.js +0 -106
- package/src/security-overlay/skills/wize-sec-scope/skill.md +0 -52
- package/src/tea-skills/wize-qa-generate-e2e-tests/workflow.md +0 -121
- package/tools/installer/baseline.js +0 -128
- package/tools/installer/commands/agent.js +0 -197
- package/tools/installer/commands/doctor.js +0 -319
- package/tools/installer/commands/document-project.js +0 -93
- package/tools/installer/commands/sync.js +0 -45
- package/tools/installer/commands/update.js +0 -172
- package/tools/installer/document-project/batch-scanner.js +0 -93
- package/tools/installer/document-project/classify.js +0 -170
- package/tools/installer/document-project/modes/deep-dive.js +0 -196
- package/tools/installer/document-project/modes/full-rescan.js +0 -15
- package/tools/installer/document-project/modes/initial-scan.js +0 -100
- package/tools/installer/document-project/modes/quick.js +0 -211
- package/tools/installer/document-project/render-index.js +0 -101
- package/tools/installer/document-project/state.js +0 -110
- package/tools/installer/version-check.js +0 -117
|
@@ -1,319 +0,0 @@
|
|
|
1
|
-
// `wize-dev-kit doctor` — single-command diagnose.
|
|
2
|
-
//
|
|
3
|
-
// Prints a structured snapshot of the kit + the project + the surrounding
|
|
4
|
-
// environment, plus a list of actionable suggestions ranked by severity.
|
|
5
|
-
// Designed to be the *first* command a new dev runs in an unfamiliar
|
|
6
|
-
// wize-enabled repo, and the *go-to* command when something looks off.
|
|
7
|
-
//
|
|
8
|
-
// Output is plain text (no colors by default) so it's grep-friendly and pipe-
|
|
9
|
-
// friendly. Sections are stable so editors / dashboards can parse them.
|
|
10
|
-
|
|
11
|
-
'use strict';
|
|
12
|
-
|
|
13
|
-
const fs = require('node:fs');
|
|
14
|
-
const path = require('node:path');
|
|
15
|
-
const { loadProjectConfig, loadInstalledKitVersion } = require('./update.js');
|
|
16
|
-
const { detectHarnessCli } = require('../baseline.js');
|
|
17
|
-
const { getLatestVersion, semverGreater } = require('../version-check.js');
|
|
18
|
-
|
|
19
|
-
function fileExists(p) { try { return fs.statSync(p).isFile(); } catch { return false; } }
|
|
20
|
-
function dirExists(p) { try { return fs.statSync(p).isDirectory(); } catch { return false; } }
|
|
21
|
-
function readSafe(p) { try { return fs.readFileSync(p, 'utf-8'); } catch { return ''; } }
|
|
22
|
-
|
|
23
|
-
function listFilesUnder(root, pattern) {
|
|
24
|
-
if (!dirExists(root)) return [];
|
|
25
|
-
const out = [];
|
|
26
|
-
const stack = [root];
|
|
27
|
-
while (stack.length) {
|
|
28
|
-
const dir = stack.pop();
|
|
29
|
-
let entries; try { entries = fs.readdirSync(dir, { withFileTypes: true }); } catch { continue; }
|
|
30
|
-
for (const e of entries) {
|
|
31
|
-
const full = path.join(dir, e.name);
|
|
32
|
-
if (e.isDirectory()) stack.push(full);
|
|
33
|
-
else if (e.isFile() && pattern.test(e.name)) out.push(full);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return out;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function parseGateStatus(content) {
|
|
40
|
-
// Find a `status: PASS|CONCERNS|FAIL|WAIVED` line in YAML frontmatter.
|
|
41
|
-
const m = content.match(/^status:\s*(PASS|CONCERNS|FAIL|WAIVED)\s*$/m);
|
|
42
|
-
return m ? m[1] : null;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function parseLastRefreshed(content) {
|
|
46
|
-
const m = content.match(/^last_refreshed:\s*([\d-]+)/m);
|
|
47
|
-
return m ? m[1] : null;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function daysAgo(dateStr) {
|
|
51
|
-
const t = Date.parse(dateStr);
|
|
52
|
-
if (Number.isNaN(t)) return null;
|
|
53
|
-
return Math.floor((Date.now() - t) / (24 * 3600 * 1000));
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function adapterTargetPath(targetCode, projectRoot) {
|
|
57
|
-
// Mirror of the adapter render conventions documented in adapters/README.md.
|
|
58
|
-
switch (targetCode) {
|
|
59
|
-
case 'claude-code': return path.join(projectRoot, '.claude/skills');
|
|
60
|
-
case 'antigravity': return path.join(projectRoot, '.agent/skills');
|
|
61
|
-
case 'codex': return path.join(projectRoot, '.agents/skills');
|
|
62
|
-
case 'kimi-code': return path.join(projectRoot, '.kimi/skills');
|
|
63
|
-
case 'cursor': return path.join(projectRoot, '.cursor/rules');
|
|
64
|
-
case 'windsurf': return path.join(projectRoot, '.windsurf/rules');
|
|
65
|
-
case 'continue': return path.join(projectRoot, '.continue/prompts');
|
|
66
|
-
case 'opencode': return path.join(projectRoot, '.opencode/agents');
|
|
67
|
-
case 'generic': return path.join(projectRoot, '.wize/agents');
|
|
68
|
-
default: return null;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function countAdapterFiles(targetCode, projectRoot) {
|
|
73
|
-
const dir = adapterTargetPath(targetCode, projectRoot);
|
|
74
|
-
if (!dir || !dirExists(dir)) return 0;
|
|
75
|
-
// Be permissive on file extension; .mdc, .md, .prompt, and SKILL.md dirs all count.
|
|
76
|
-
let count = 0;
|
|
77
|
-
const stack = [dir];
|
|
78
|
-
while (stack.length) {
|
|
79
|
-
const d = stack.pop();
|
|
80
|
-
let entries; try { entries = fs.readdirSync(d, { withFileTypes: true }); } catch { continue; }
|
|
81
|
-
for (const e of entries) {
|
|
82
|
-
const full = path.join(d, e.name);
|
|
83
|
-
if (e.isDirectory()) stack.push(full);
|
|
84
|
-
else if (e.isFile()) count++;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return count;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function detectPhase(projectRoot) {
|
|
91
|
-
const has = (p) => fileExists(path.join(projectRoot, p)) || dirExists(path.join(projectRoot, p));
|
|
92
|
-
if (!dirExists(path.join(projectRoot, '.wize'))) return 'no-install';
|
|
93
|
-
if (!has('.wize/planning/brief.md')) return '1-analysis (brief pending)';
|
|
94
|
-
if (!has('.wize/planning/ux/trigger-map.md')) return '1-analysis (trigger map pending)';
|
|
95
|
-
if (!has('.wize/planning/prd.md')) return '2-plan (PRD pending)';
|
|
96
|
-
if (!has('.wize/planning/ux/ux-scenarios.md')) return '2-plan (UX scenarios pending)';
|
|
97
|
-
if (!has('.wize/planning/tech-vision.md')) return '2→3 boundary (Fury pending)';
|
|
98
|
-
if (!has('.wize/solutioning/architecture.md')) return '3-solutioning (architecture pending)';
|
|
99
|
-
if (!dirExists(path.join(projectRoot, '.wize/solutioning/stories')) ||
|
|
100
|
-
listFilesUnder(path.join(projectRoot, '.wize/solutioning/stories'), /\.md$/).length === 0)
|
|
101
|
-
return '3-solutioning (stories pending)';
|
|
102
|
-
if (!has('.wize/implementation/tea/risk-profile.md')) return '3-closeout (risk profile pending)';
|
|
103
|
-
if (!has('.wize/implementation/sprint-status.md')) return '4-implementation (sprint planning pending)';
|
|
104
|
-
return '4-implementation';
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function gateStats(projectRoot) {
|
|
108
|
-
const root = path.join(projectRoot, '.wize/implementation/tea');
|
|
109
|
-
const files = listFilesUnder(root, /^gate\.md$/);
|
|
110
|
-
const stats = { PASS: 0, CONCERNS: 0, FAIL: 0, WAIVED: 0, total: files.length };
|
|
111
|
-
for (const f of files) {
|
|
112
|
-
const s = parseGateStatus(readSafe(f));
|
|
113
|
-
if (s && stats[s] !== undefined) stats[s]++;
|
|
114
|
-
}
|
|
115
|
-
return stats;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
function knowledgeStatus(projectRoot) {
|
|
119
|
-
const root = path.join(projectRoot, '.wize/knowledge/document-project');
|
|
120
|
-
const exists = dirExists(root);
|
|
121
|
-
if (!exists) return { exists: false };
|
|
122
|
-
const files = ['overview.md', 'architecture-snapshot.md', 'conventions.md', 'dependencies.md', 'risk-spots.md']
|
|
123
|
-
.map(name => path.join(root, name))
|
|
124
|
-
.filter(fileExists);
|
|
125
|
-
const refreshed = files.map(f => ({
|
|
126
|
-
name: path.basename(f),
|
|
127
|
-
days: daysAgo(parseLastRefreshed(readSafe(f)))
|
|
128
|
-
}));
|
|
129
|
-
const pendingFile = path.join(root, '_pending.md');
|
|
130
|
-
const pendingLines = fileExists(pendingFile)
|
|
131
|
-
? readSafe(pendingFile).split('\n').filter(l => l.trim() && !l.startsWith('#')).length
|
|
132
|
-
: 0;
|
|
133
|
-
|
|
134
|
-
const indexPath = path.join(root, 'index.md');
|
|
135
|
-
const indexContent = fileExists(indexPath) ? readSafe(indexPath) : '';
|
|
136
|
-
const toBeGeneratedMarkers = (indexContent.match(/_\(To be generated\)_/g) || []).length;
|
|
137
|
-
|
|
138
|
-
const statePath = path.join(root, 'project-scan-report.json');
|
|
139
|
-
const stateExists = fileExists(statePath);
|
|
140
|
-
const stateContent = stateExists ? readSafe(statePath) : '';
|
|
141
|
-
let stateAgeDays = null;
|
|
142
|
-
try {
|
|
143
|
-
const state = JSON.parse(stateContent);
|
|
144
|
-
stateAgeDays = daysAgo(state.timestamps && state.timestamps.last_updated);
|
|
145
|
-
} catch (_) {}
|
|
146
|
-
|
|
147
|
-
return { exists: true, files: refreshed, pendingLines, toBeGeneratedMarkers, stateExists, stateAgeDays };
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
function gitInfo(projectRoot) {
|
|
151
|
-
const dotGit = path.join(projectRoot, '.git');
|
|
152
|
-
if (!dirExists(dotGit)) return { isRepo: false };
|
|
153
|
-
let branch = '?'; let head = '?';
|
|
154
|
-
try {
|
|
155
|
-
const HEAD = readSafe(path.join(dotGit, 'HEAD')).trim();
|
|
156
|
-
if (HEAD.startsWith('ref: ')) {
|
|
157
|
-
branch = HEAD.slice(5).replace('refs/heads/', '');
|
|
158
|
-
} else {
|
|
159
|
-
head = HEAD.slice(0, 7);
|
|
160
|
-
}
|
|
161
|
-
} catch (_) {}
|
|
162
|
-
return { isRepo: true, branch, head };
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
function severityIcon(level) {
|
|
166
|
-
return level === 'error' ? '✖' : level === 'warn' ? '⚠' : 'ℹ';
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
async function cmdDoctor({ kitRoot, projectRoot, opts = {} } = {}) {
|
|
170
|
-
const log = opts.log || console.log;
|
|
171
|
-
const cwd = projectRoot;
|
|
172
|
-
const cfg = loadProjectConfig(cwd);
|
|
173
|
-
const installed = loadInstalledKitVersion(kitRoot);
|
|
174
|
-
const phase = detectPhase(cwd);
|
|
175
|
-
const gates = gateStats(cwd);
|
|
176
|
-
const knowledge = knowledgeStatus(cwd);
|
|
177
|
-
const git = gitInfo(cwd);
|
|
178
|
-
const targets = (cfg.install && cfg.install.ide_targets) || [];
|
|
179
|
-
const profiles = (cfg.install && cfg.install.profiles) || [];
|
|
180
|
-
const harnesses = detectHarnessCli({ preferIde: targets });
|
|
181
|
-
|
|
182
|
-
// Try registry — best-effort, never blocks.
|
|
183
|
-
let registryLatest = null;
|
|
184
|
-
try { registryLatest = await getLatestVersion(); } catch (_) {}
|
|
185
|
-
|
|
186
|
-
const suggestions = [];
|
|
187
|
-
|
|
188
|
-
// -- Section: Kit --
|
|
189
|
-
log('');
|
|
190
|
-
log('Wize Dev Kit — Doctor');
|
|
191
|
-
log('─────────────────────');
|
|
192
|
-
log(`Kit version (installed): ${installed || '?'}`);
|
|
193
|
-
log(`Kit version (project): ${cfg.project && cfg.project.kit_version || '— (no install)'}`);
|
|
194
|
-
log(`Kit version (registry): ${registryLatest || '(offline or skipped)'}`);
|
|
195
|
-
if (installed && cfg.project && cfg.project.kit_version && installed !== cfg.project.kit_version) {
|
|
196
|
-
suggestions.push({ level: 'warn', text: `Project pinned to ${cfg.project.kit_version} but ${installed} is installed. Run \`npx wize-dev-kit update\` to refresh adapters.` });
|
|
197
|
-
}
|
|
198
|
-
if (registryLatest && installed && semverGreater(registryLatest, installed)) {
|
|
199
|
-
suggestions.push({ level: 'info', text: `Registry has ${registryLatest}; you're on ${installed}. Run \`npx wize-dev-kit@latest update\` to pick it up.` });
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// -- Section: Project --
|
|
203
|
-
log('');
|
|
204
|
-
log('Project');
|
|
205
|
-
log('───────');
|
|
206
|
-
if (!cfg.project) {
|
|
207
|
-
log('No .wize/config/project.toml — kit is not installed here.');
|
|
208
|
-
suggestions.push({ level: 'error', text: 'Run `npx wize-dev-kit install` to set the kit up in this repo.' });
|
|
209
|
-
} else {
|
|
210
|
-
log(`Name: ${cfg.project.name || '?'}`);
|
|
211
|
-
log(`Profiles: ${profiles.join(', ') || '(none)'}`);
|
|
212
|
-
log(`IDE targets: ${targets.join(', ') || '(none)'}`);
|
|
213
|
-
log(`Communication lang: ${cfg.language && cfg.language.communication || '?'}`);
|
|
214
|
-
log(`Document lang: ${cfg.language && cfg.language.document_output || '?'}`);
|
|
215
|
-
log(`Current phase: ${phase}`);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// -- Section: Adapters --
|
|
219
|
-
if (cfg.install) {
|
|
220
|
-
log('');
|
|
221
|
-
log('IDE Adapters');
|
|
222
|
-
log('────────────');
|
|
223
|
-
for (const t of targets) {
|
|
224
|
-
const dir = adapterTargetPath(t, cwd);
|
|
225
|
-
const count = countAdapterFiles(t, cwd);
|
|
226
|
-
const status = count > 0 ? `✓ ${count} files` : '✖ none';
|
|
227
|
-
log(` ${t.padEnd(14)} ${status.padEnd(15)} ${dir ? path.relative(cwd, dir) : '(no path)'}`);
|
|
228
|
-
if (count === 0) suggestions.push({ level: 'warn', text: `Adapter "${t}" has no rendered files. Run \`npx wize-dev-kit sync\`.` });
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
// -- Section: TEA gates --
|
|
233
|
-
if (gates.total > 0) {
|
|
234
|
-
log('');
|
|
235
|
-
log('TEA gates');
|
|
236
|
-
log('─────────');
|
|
237
|
-
log(`Total gate.md files: ${gates.total}`);
|
|
238
|
-
log(`PASS: ${gates.PASS}`);
|
|
239
|
-
log(`CONCERNS: ${gates.CONCERNS}`);
|
|
240
|
-
log(`FAIL: ${gates.FAIL}`);
|
|
241
|
-
log(`WAIVED: ${gates.WAIVED}`);
|
|
242
|
-
if (gates.FAIL > 0) suggestions.push({ level: 'error', text: `${gates.FAIL} story gate(s) at FAIL. Stories must not merge until resolved (advisory mode) or are blocking (enforcing mode).` });
|
|
243
|
-
if (gates.CONCERNS > 0) suggestions.push({ level: 'warn', text: `${gates.CONCERNS} story gate(s) at CONCERNS. Review findings before next sprint.` });
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
// -- Section: Knowledge --
|
|
247
|
-
if (knowledge.exists) {
|
|
248
|
-
log('');
|
|
249
|
-
log('Knowledge baseline (`document-project/`)');
|
|
250
|
-
log('────────────────────────────────────────');
|
|
251
|
-
for (const f of knowledge.files) {
|
|
252
|
-
const age = f.days == null ? 'no last_refreshed' : `${f.days}d ago`;
|
|
253
|
-
log(` ${f.name.padEnd(28)} ${age}`);
|
|
254
|
-
if (f.days != null && f.days > 60) {
|
|
255
|
-
suggestions.push({ level: 'warn', text: `\`${f.name}\` last refreshed ${f.days}d ago. Run \`/wize-refresh-knowledge\` after current sprint.` });
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
if (knowledge.pendingLines > 0) {
|
|
259
|
-
log(` _pending.md: ${knowledge.pendingLines} inline note(s) waiting consolidation`);
|
|
260
|
-
if (knowledge.pendingLines >= 5) {
|
|
261
|
-
suggestions.push({ level: 'info', text: `${knowledge.pendingLines} notes piled up in _pending.md. Time to run \`/wize-refresh-knowledge\`.` });
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
const markerText = knowledge.toBeGeneratedMarkers > 0 ? `${knowledge.toBeGeneratedMarkers} marker(s)` : 'none';
|
|
265
|
-
log(` To be generated markers: ${markerText}`);
|
|
266
|
-
if (knowledge.toBeGeneratedMarkers >= 5) {
|
|
267
|
-
suggestions.push({ level: 'warn', text: `${knowledge.toBeGeneratedMarkers} docs marked "To be generated" in index.md. Run \`wize-dev-kit document-project initial_scan deep\` to fill them.` });
|
|
268
|
-
}
|
|
269
|
-
const stateText = knowledge.stateExists
|
|
270
|
-
? (knowledge.stateAgeDays == null ? 'project-scan-report.json exists (age unknown)' : `project-scan-report.json ${knowledge.stateAgeDays}d old`)
|
|
271
|
-
: 'no project-scan-report.json';
|
|
272
|
-
log(` Scan state: ${stateText}`);
|
|
273
|
-
if (!knowledge.stateExists) {
|
|
274
|
-
suggestions.push({ level: 'info', text: 'No scan state file found. Run `wize-dev-kit document-project quick` to create a baseline + state.' });
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
// -- Section: Harness CLIs --
|
|
279
|
-
log('');
|
|
280
|
-
log('AI Harness CLIs on PATH');
|
|
281
|
-
log('───────────────────────');
|
|
282
|
-
if (harnesses.length === 0) {
|
|
283
|
-
log(' (none detected)');
|
|
284
|
-
suggestions.push({ level: 'info', text: 'No harness CLI detected. Brownfield baseline + auto-run features only work in your IDE; the headless flow is unavailable.' });
|
|
285
|
-
} else {
|
|
286
|
-
for (const h of harnesses) log(` ${h.binary.padEnd(10)} ${h.path}`);
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
// -- Section: Git --
|
|
290
|
-
log('');
|
|
291
|
-
log('Git');
|
|
292
|
-
log('───');
|
|
293
|
-
if (!git.isRepo) {
|
|
294
|
-
log(' (not a git repo)');
|
|
295
|
-
suggestions.push({ level: 'warn', text: 'Not a git repository. Run `git init` before installing the kit so version history is recorded.' });
|
|
296
|
-
} else {
|
|
297
|
-
log(` branch: ${git.branch}`);
|
|
298
|
-
log(` head: ${git.head}`);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
// -- Section: Suggestions --
|
|
302
|
-
log('');
|
|
303
|
-
log('Suggestions');
|
|
304
|
-
log('───────────');
|
|
305
|
-
if (suggestions.length === 0) {
|
|
306
|
-
log(' ✓ Everything looks good.');
|
|
307
|
-
} else {
|
|
308
|
-
for (const s of suggestions) log(` ${severityIcon(s.level)} ${s.text}`);
|
|
309
|
-
}
|
|
310
|
-
log('');
|
|
311
|
-
|
|
312
|
-
return { suggestions, phase, gates, knowledge, targets, profiles, installed, registryLatest };
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
module.exports = {
|
|
316
|
-
cmdDoctor,
|
|
317
|
-
// exported for tests:
|
|
318
|
-
detectPhase, gateStats, knowledgeStatus, gitInfo, adapterTargetPath, countAdapterFiles
|
|
319
|
-
};
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
// `wize-dev-kit document-project` — CLI command entry point.
|
|
2
|
-
//
|
|
3
|
-
// Parses mode + flags and delegates to the appropriate scan implementation.
|
|
4
|
-
// Non-quick modes are stubs here; later stories fill them in.
|
|
5
|
-
|
|
6
|
-
'use strict';
|
|
7
|
-
|
|
8
|
-
const fs = require('node:fs');
|
|
9
|
-
const path = require('node:path');
|
|
10
|
-
const { runQuick } = require('../document-project/modes/quick.js');
|
|
11
|
-
const { runInitialScan } = require('../document-project/modes/initial-scan.js');
|
|
12
|
-
const { runFullRescan } = require('../document-project/modes/full-rescan.js');
|
|
13
|
-
const { runDeepDive } = require('../document-project/modes/deep-dive.js');
|
|
14
|
-
const { loadState, archiveOldState } = require('../document-project/state.js');
|
|
15
|
-
|
|
16
|
-
const VALID_MODES = new Set(['quick', 'initial_scan', 'full_rescan', 'deep_dive']);
|
|
17
|
-
const VALID_SCAN_LEVELS = new Set(['quick', 'deep', 'exhaustive']);
|
|
18
|
-
|
|
19
|
-
function parseMode(args) {
|
|
20
|
-
let mode = 'quick';
|
|
21
|
-
let resume = false;
|
|
22
|
-
let scanLevel = 'quick';
|
|
23
|
-
let target = null;
|
|
24
|
-
|
|
25
|
-
for (let i = 0; i < args.length; i++) {
|
|
26
|
-
const arg = args[i];
|
|
27
|
-
if (arg === '--resume') {
|
|
28
|
-
resume = true;
|
|
29
|
-
continue;
|
|
30
|
-
}
|
|
31
|
-
if (arg === '--target') {
|
|
32
|
-
target = args[i + 1];
|
|
33
|
-
i++;
|
|
34
|
-
continue;
|
|
35
|
-
}
|
|
36
|
-
if (arg.startsWith('--')) {
|
|
37
|
-
return { mode: null, error: `unknown option: ${arg}` };
|
|
38
|
-
}
|
|
39
|
-
if (VALID_SCAN_LEVELS.has(arg)) {
|
|
40
|
-
scanLevel = arg;
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
|
-
if (mode === 'quick' && VALID_MODES.has(arg)) {
|
|
44
|
-
mode = arg;
|
|
45
|
-
} else if (mode === 'quick') {
|
|
46
|
-
return { mode: null, error: `unknown mode: ${arg}. Valid modes: ${[...VALID_MODES].join(', ')}` };
|
|
47
|
-
} else {
|
|
48
|
-
return { mode: null, error: `unexpected extra argument: ${arg}` };
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (!VALID_MODES.has(mode)) {
|
|
53
|
-
return { mode: null, error: `unknown mode: ${mode}. Valid modes: ${[...VALID_MODES].join(', ')}` };
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return { mode, resume, scanLevel, target };
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function cmdDocumentProject({ kitRoot, projectRoot, args = [], opts = {} }) {
|
|
60
|
-
const log = opts.log || console.log;
|
|
61
|
-
const parsed = parseMode(args);
|
|
62
|
-
|
|
63
|
-
if (parsed.mode === null) {
|
|
64
|
-
log(parsed.error);
|
|
65
|
-
return { ok: false, error: parsed.error, exitCode: 1 };
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (parsed.mode === 'quick') {
|
|
69
|
-
const r = runQuick(projectRoot, { log });
|
|
70
|
-
return { ok: true, mode: 'quick', ...r };
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if (parsed.mode === 'initial_scan') {
|
|
74
|
-
const r = runInitialScan(projectRoot, { scanLevel: parsed.scanLevel, log });
|
|
75
|
-
return { ok: true, mode: 'initial_scan', ...r };
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
if (parsed.mode === 'full_rescan') {
|
|
79
|
-
const r = runFullRescan(projectRoot, { scanLevel: parsed.scanLevel, log });
|
|
80
|
-
return { ok: true, mode: 'full_rescan', ...r };
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (parsed.mode === 'deep_dive') {
|
|
84
|
-
const r = runDeepDive(projectRoot, { target: parsed.target, log });
|
|
85
|
-
return r;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
log(`document-project ${parsed.mode} not implemented`);
|
|
89
|
-
return { ok: false, error: 'not implemented', exitCode: 1 };
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
module.exports = { cmdDocumentProject, parseMode };
|
|
93
|
-
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
// `wize-dev-kit sync` — regenerate adapter outputs for the IDE targets the
|
|
2
|
-
// project opted into. Useful after editing .wize/config/project.toml,
|
|
3
|
-
// running `agent create`, or pulling kit changes that don't bump version.
|
|
4
|
-
|
|
5
|
-
'use strict';
|
|
6
|
-
|
|
7
|
-
const fs = require('node:fs');
|
|
8
|
-
const path = require('node:path');
|
|
9
|
-
const { loadProjectConfig } = require('./update.js');
|
|
10
|
-
|
|
11
|
-
function cmdSync({ kitRoot, projectRoot, opts = {} } = {}) {
|
|
12
|
-
const log = opts.log || console.log;
|
|
13
|
-
const cfg = loadProjectConfig(projectRoot);
|
|
14
|
-
if (!cfg.project) {
|
|
15
|
-
log('No .wize/config/project.toml found here. Run `wize-dev-kit install` first.');
|
|
16
|
-
return { changed: false };
|
|
17
|
-
}
|
|
18
|
-
const ideTargets = (cfg.install && cfg.install.ide_targets) || ['claude-code', 'generic'];
|
|
19
|
-
const profiles = (cfg.install && cfg.install.profiles) || ['core'];
|
|
20
|
-
log(`Syncing ${ideTargets.length} adapter(s) for profile(s) ${profiles.join(' + ')}:`);
|
|
21
|
-
|
|
22
|
-
const results = [];
|
|
23
|
-
for (const code of ideTargets) {
|
|
24
|
-
const renderPath = path.join(kitRoot, 'adapters', code, 'render.js');
|
|
25
|
-
if (!fs.existsSync(renderPath)) {
|
|
26
|
-
log(` - ${code}: skipped (adapter missing in installed kit)`);
|
|
27
|
-
results.push({ code, skipped: true });
|
|
28
|
-
continue;
|
|
29
|
-
}
|
|
30
|
-
delete require.cache[require.resolve(renderPath)];
|
|
31
|
-
try {
|
|
32
|
-
const out = require(renderPath).render(kitRoot, projectRoot, { profiles });
|
|
33
|
-
const n = out && Array.isArray(out.written) ? out.written.length : 0;
|
|
34
|
-
log(` ✓ ${code}: ${n} file(s) emitted`);
|
|
35
|
-
results.push({ code, written: n });
|
|
36
|
-
} catch (err) {
|
|
37
|
-
log(` ✖ ${code}: ${err.message}`);
|
|
38
|
-
results.push({ code, error: err.message });
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
log('\nDone. Restart your IDE if it caches skills at startup.');
|
|
42
|
-
return { changed: true, adapters: results };
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
module.exports = { cmdSync };
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
// `wize-dev-kit update` — refresh an installed kit to the version currently
|
|
2
|
-
// resolved by `node_modules/wize-dev-kit`. Preserves .wize/config/user.toml,
|
|
3
|
-
// re-runs the active IDE adapters, and re-applies the .gitignore block when
|
|
4
|
-
// it was opted-in originally.
|
|
5
|
-
|
|
6
|
-
'use strict';
|
|
7
|
-
|
|
8
|
-
const fs = require('node:fs');
|
|
9
|
-
const path = require('node:path');
|
|
10
|
-
const { applyGitignore } = require('../setup-helpers.js');
|
|
11
|
-
|
|
12
|
-
// Minimal TOML reader for the subset we write — handles `[section]` headers,
|
|
13
|
-
// `key = "value"` scalars, and `key = ["a", "b"]` string arrays.
|
|
14
|
-
function readToml(file) {
|
|
15
|
-
if (!fs.existsSync(file)) return {};
|
|
16
|
-
const content = fs.readFileSync(file, 'utf-8');
|
|
17
|
-
const out = {};
|
|
18
|
-
let section = null;
|
|
19
|
-
for (const raw of content.split('\n')) {
|
|
20
|
-
const line = raw.replace(/#.*$/, '').trim();
|
|
21
|
-
if (!line) continue;
|
|
22
|
-
const head = line.match(/^\[([^\]]+)\]$/);
|
|
23
|
-
if (head) { section = head[1]; out[section] = out[section] || {}; continue; }
|
|
24
|
-
const kv = line.match(/^([a-zA-Z_][\w-]*)\s*=\s*(.+)$/);
|
|
25
|
-
if (!kv) continue;
|
|
26
|
-
const [, key, valRaw] = kv;
|
|
27
|
-
const v = parseTomlValue(valRaw.trim());
|
|
28
|
-
if (section) out[section][key] = v;
|
|
29
|
-
else out[key] = v;
|
|
30
|
-
}
|
|
31
|
-
return out;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function parseTomlValue(raw) {
|
|
35
|
-
if (raw.startsWith('"') && raw.endsWith('"')) return raw.slice(1, -1);
|
|
36
|
-
if (raw.startsWith("'") && raw.endsWith("'")) return raw.slice(1, -1);
|
|
37
|
-
if (raw.startsWith('[') && raw.endsWith(']')) {
|
|
38
|
-
return raw.slice(1, -1).split(',').map(s => s.trim().replace(/^["']|["']$/g, '')).filter(Boolean);
|
|
39
|
-
}
|
|
40
|
-
if (raw === 'true') return true;
|
|
41
|
-
if (raw === 'false') return false;
|
|
42
|
-
if (!isNaN(Number(raw))) return Number(raw);
|
|
43
|
-
return raw;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function loadProjectConfig(projectRoot) {
|
|
47
|
-
return readToml(path.join(projectRoot, '.wize/config/project.toml'));
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function loadInstalledKitVersion(kitRoot) {
|
|
51
|
-
try { return require(path.join(kitRoot, 'package.json')).version; }
|
|
52
|
-
catch { return null; }
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Returns a list of CHANGELOG entries (markdown blocks) for versions strictly
|
|
56
|
-
// between `from` and `to`. Best-effort — if CHANGELOG layout is unusual,
|
|
57
|
-
// returns an empty list and falls back to a generic note.
|
|
58
|
-
function changelogBetween(kitRoot, fromVersion, toVersion) {
|
|
59
|
-
const file = path.join(kitRoot, 'CHANGELOG.md');
|
|
60
|
-
if (!fs.existsSync(file)) return [];
|
|
61
|
-
const content = fs.readFileSync(file, 'utf-8');
|
|
62
|
-
const versionRe = /^## \[(\d+\.\d+\.\d+)\][^\n]*\n/gm;
|
|
63
|
-
const matches = [];
|
|
64
|
-
let m;
|
|
65
|
-
while ((m = versionRe.exec(content)) !== null) {
|
|
66
|
-
matches.push({ v: m[1], start: m.index, headerEnd: versionRe.lastIndex });
|
|
67
|
-
}
|
|
68
|
-
for (let i = 0; i < matches.length; i++) {
|
|
69
|
-
matches[i].end = i + 1 < matches.length ? matches[i + 1].start : content.length;
|
|
70
|
-
}
|
|
71
|
-
return matches
|
|
72
|
-
.filter(x => compare(x.v, fromVersion) > 0 && compare(x.v, toVersion) <= 0)
|
|
73
|
-
.map(x => content.slice(x.start, x.end).trim());
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function compare(a, b) {
|
|
77
|
-
const pa = a.split('.').map(Number);
|
|
78
|
-
const pb = b.split('.').map(Number);
|
|
79
|
-
for (let i = 0; i < 3; i++) {
|
|
80
|
-
if ((pa[i] || 0) !== (pb[i] || 0)) return (pa[i] || 0) - (pb[i] || 0);
|
|
81
|
-
}
|
|
82
|
-
return 0;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// Re-runs every adapter that the project opted into at install time, using
|
|
86
|
-
// the current versions of the kit's renderers.
|
|
87
|
-
function rerunAdapters({ kitRoot, projectRoot, ideTargets, profiles, log }) {
|
|
88
|
-
const results = [];
|
|
89
|
-
for (const code of ideTargets) {
|
|
90
|
-
const renderPath = path.join(kitRoot, 'adapters', code, 'render.js');
|
|
91
|
-
if (!fs.existsSync(renderPath)) {
|
|
92
|
-
results.push({ code, skipped: true, reason: 'adapter missing in this kit version' });
|
|
93
|
-
log(` - ${code}: skipped (adapter no longer exists)`);
|
|
94
|
-
continue;
|
|
95
|
-
}
|
|
96
|
-
delete require.cache[require.resolve(renderPath)]; // make `update` idempotent in the same process
|
|
97
|
-
try {
|
|
98
|
-
const mod = require(renderPath);
|
|
99
|
-
const out = mod.render(kitRoot, projectRoot, { profiles });
|
|
100
|
-
const n = out && Array.isArray(out.written) ? out.written.length : 0;
|
|
101
|
-
results.push({ code, written: n });
|
|
102
|
-
log(` ✓ ${code}: ${n} file(s) refreshed`);
|
|
103
|
-
} catch (err) {
|
|
104
|
-
results.push({ code, error: err.message });
|
|
105
|
-
log(` ✖ ${code}: ${err.message}`);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
return results;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function writeUpdatedProjectToml(projectRoot, currentToml, newKitVersion) {
|
|
112
|
-
// Surgical rewrite — only updates `kit_version = ...` under `[project]`.
|
|
113
|
-
// Leaves everything else as the user/team configured it.
|
|
114
|
-
const file = path.join(projectRoot, '.wize/config/project.toml');
|
|
115
|
-
if (!fs.existsSync(file)) return false;
|
|
116
|
-
const content = fs.readFileSync(file, 'utf-8');
|
|
117
|
-
const updated = content.replace(/^kit_version\s*=\s*".*"$/m, `kit_version = "${newKitVersion}"`);
|
|
118
|
-
if (updated === content) return false;
|
|
119
|
-
fs.writeFileSync(file, updated, 'utf-8');
|
|
120
|
-
return true;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
async function cmdUpdate({ kitRoot, projectRoot, opts = {} } = {}) {
|
|
124
|
-
const log = opts.log || console.log;
|
|
125
|
-
const cfg = loadProjectConfig(projectRoot);
|
|
126
|
-
if (!cfg.project) {
|
|
127
|
-
log('No .wize/config/project.toml found here.');
|
|
128
|
-
log('Run `wize-dev-kit install` first.');
|
|
129
|
-
return { changed: false };
|
|
130
|
-
}
|
|
131
|
-
const fromVersion = cfg.project.kit_version || '0.0.0';
|
|
132
|
-
const toVersion = loadInstalledKitVersion(kitRoot) || 'unknown';
|
|
133
|
-
if (toVersion === 'unknown') {
|
|
134
|
-
log('Could not read kit version from node_modules. Aborting.');
|
|
135
|
-
return { changed: false };
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
log(`Wize Dev Kit update: ${fromVersion} → ${toVersion}`);
|
|
139
|
-
if (fromVersion === toVersion) {
|
|
140
|
-
log('Already on the same version. Re-rendering adapters anyway (idempotent).');
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const ideTargets = (cfg.install && cfg.install.ide_targets) || ['claude-code', 'generic'];
|
|
144
|
-
const profiles = (cfg.install && cfg.install.profiles) || ['core'];
|
|
145
|
-
|
|
146
|
-
log('\nRe-rendering active IDE adapters:');
|
|
147
|
-
const adapterResults = rerunAdapters({ kitRoot, projectRoot, ideTargets, profiles, log });
|
|
148
|
-
|
|
149
|
-
if (opts.refreshGitignore !== false) {
|
|
150
|
-
const r = applyGitignore(projectRoot);
|
|
151
|
-
if (r.changed) log(`\n✓ .gitignore ${r.mode}`);
|
|
152
|
-
else log('\n= .gitignore already up to date');
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
writeUpdatedProjectToml(projectRoot, cfg, toVersion);
|
|
156
|
-
log(`\n✓ project.toml kit_version → ${toVersion}`);
|
|
157
|
-
|
|
158
|
-
const entries = changelogBetween(kitRoot, fromVersion, toVersion);
|
|
159
|
-
if (entries.length) {
|
|
160
|
-
log(`\nWhat changed (excerpt from CHANGELOG):`);
|
|
161
|
-
for (const e of entries) {
|
|
162
|
-
log(e.split('\n').slice(0, 4).map(l => ' ' + l).join('\n'));
|
|
163
|
-
log(' …');
|
|
164
|
-
}
|
|
165
|
-
log(`\nFull details: ${path.join(kitRoot, 'CHANGELOG.md')}`);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
log('\nDone. Restart your IDE so the refreshed slash commands are picked up.');
|
|
169
|
-
return { changed: true, from: fromVersion, to: toVersion, adapters: adapterResults };
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
module.exports = { cmdUpdate, loadProjectConfig, loadInstalledKitVersion, changelogBetween };
|