wize-dev-kit 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +43 -0
- package/package.json +1 -1
- package/src/core-skills/wize-customize/skill.md +114 -0
- package/src/core-skills/wize-editorial-review-prose/skill.md +92 -0
- package/src/core-skills/wize-editorial-review-structure/skill.md +97 -0
- package/src/core-skills/wize-index-docs/skill.md +117 -0
- package/src/core-skills/wize-review-edge-case-hunter/skill.md +112 -0
- package/src/method-skills/2-plan-workflows/wize-edit-prd/workflow.md +108 -0
- package/src/method-skills/3-solutioning/wize-project-context/workflow.md +118 -0
- package/src/method-skills/4-implementation/wize-checkpoint-preview/workflow.md +115 -0
- package/src/method-skills/4-implementation/wize-correct-course/workflow.md +89 -0
- package/src/method-skills/4-implementation/wize-investigate/workflow.md +121 -0
- package/src/method-skills/4-implementation/wize-sprint-planning/workflow.md +58 -71
- package/src/method-skills/4-implementation/wize-sprint-status/workflow.md +29 -82
- package/src/orchestrator-skills/wize-onboarding/workflow.md +76 -14
- package/src/tea-skills/wize-qa-generate-e2e-tests/workflow.md +119 -0
- package/tools/installer/render-shared.js +46 -3
- package/tools/installer/wize-cli.js +98 -4
|
@@ -21,6 +21,7 @@ const { cmdSync: cmdSyncReal } = require('./commands/sync.js');
|
|
|
21
21
|
const { cmdAgentList, cmdAgentCreate, cmdAgentEdit } = require('./commands/agent.js');
|
|
22
22
|
const { cmdDoctor } = require('./commands/doctor.js');
|
|
23
23
|
const { cmdDocumentProject } = require('./commands/document-project.js');
|
|
24
|
+
const { detectHarnessCli, manualInstructions } = require('./baseline.js');
|
|
24
25
|
|
|
25
26
|
const INTERACTIVE = process.stdout.isTTY && process.stdin.isTTY;
|
|
26
27
|
|
|
@@ -127,17 +128,81 @@ function getRl() {
|
|
|
127
128
|
function prompt(question) {
|
|
128
129
|
process.stdout.write(question);
|
|
129
130
|
getRl();
|
|
131
|
+
// In interactive mode, discard any residual lines left by previous
|
|
132
|
+
// prompts (e.g. the prompts library) so this prompt always waits for
|
|
133
|
+
// fresh user input. In non-TTY / piped mode, those queued lines are
|
|
134
|
+
// intentional input and must be consumed in order.
|
|
135
|
+
if (INTERACTIVE) {
|
|
136
|
+
_queue = [];
|
|
137
|
+
}
|
|
130
138
|
if (_queue.length) return Promise.resolve(_queue.shift().trim());
|
|
131
139
|
return new Promise(resolve => _waiters.push((line) => resolve(line.trim())));
|
|
132
140
|
}
|
|
133
141
|
|
|
134
142
|
async function confirm(question, defaultYes = true) {
|
|
143
|
+
if (INTERACTIVE) {
|
|
144
|
+
const { value } = await prompts({
|
|
145
|
+
type: 'confirm',
|
|
146
|
+
name: 'value',
|
|
147
|
+
message: question,
|
|
148
|
+
initial: defaultYes
|
|
149
|
+
});
|
|
150
|
+
if (value === undefined) process.exit(130);
|
|
151
|
+
return value;
|
|
152
|
+
}
|
|
135
153
|
const hint = defaultYes ? '[Y/n]' : '[y/N]';
|
|
136
154
|
const ans = (await prompt(`${question} ${hint} `)).toLowerCase();
|
|
137
155
|
if (!ans) return defaultYes;
|
|
138
156
|
return ans.startsWith('y');
|
|
139
157
|
}
|
|
140
158
|
|
|
159
|
+
async function promptText(question, defaultValue = '') {
|
|
160
|
+
if (INTERACTIVE) {
|
|
161
|
+
const { value } = await prompts({
|
|
162
|
+
type: 'text',
|
|
163
|
+
name: 'value',
|
|
164
|
+
message: question,
|
|
165
|
+
initial: defaultValue
|
|
166
|
+
});
|
|
167
|
+
if (value === undefined) process.exit(130);
|
|
168
|
+
return value.trim();
|
|
169
|
+
}
|
|
170
|
+
const ans = (await prompt(`${question} [${defaultValue}]: `)).trim();
|
|
171
|
+
return ans || defaultValue;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
async function promptTextMandatory(question, defaultValue = '') {
|
|
175
|
+
if (INTERACTIVE) {
|
|
176
|
+
if (defaultValue) {
|
|
177
|
+
const { keep } = await prompts({
|
|
178
|
+
type: 'confirm',
|
|
179
|
+
name: 'keep',
|
|
180
|
+
message: `${question} (use "${defaultValue}"?)`,
|
|
181
|
+
initial: true
|
|
182
|
+
});
|
|
183
|
+
if (keep === undefined) process.exit(130);
|
|
184
|
+
if (keep) return defaultValue;
|
|
185
|
+
}
|
|
186
|
+
const { value } = await prompts({
|
|
187
|
+
type: 'text',
|
|
188
|
+
name: 'value',
|
|
189
|
+
message: question
|
|
190
|
+
});
|
|
191
|
+
if (value === undefined) process.exit(130);
|
|
192
|
+
const trimmed = value.trim();
|
|
193
|
+
if (trimmed) return trimmed;
|
|
194
|
+
if (defaultValue) return defaultValue;
|
|
195
|
+
return promptTextMandatory(question, defaultValue);
|
|
196
|
+
}
|
|
197
|
+
// Non-TTY: keep asking until non-empty.
|
|
198
|
+
for (;;) {
|
|
199
|
+
const ans = (await prompt(`${question}: `)).trim();
|
|
200
|
+
if (ans) return ans;
|
|
201
|
+
if (defaultValue) return defaultValue;
|
|
202
|
+
console.log('Please provide a value.');
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
141
206
|
async function select(label, choices, defaultValue) {
|
|
142
207
|
if (INTERACTIVE) {
|
|
143
208
|
const initial = choices.findIndex(c => c.value === defaultValue);
|
|
@@ -376,7 +441,7 @@ async function cmdInstall(args) {
|
|
|
376
441
|
console.log('\nGreenfield repo detected.');
|
|
377
442
|
}
|
|
378
443
|
|
|
379
|
-
const project_name = (await
|
|
444
|
+
const project_name = (await promptText(`Project name`, path.basename(cwd))) || path.basename(cwd);
|
|
380
445
|
const profiles = await multiSelect('Select profile(s) to install', PROFILES);
|
|
381
446
|
const targets = await multiSelect('Select IDE target(s)', TARGETS);
|
|
382
447
|
|
|
@@ -390,10 +455,13 @@ async function cmdInstall(args) {
|
|
|
390
455
|
);
|
|
391
456
|
|
|
392
457
|
// Personal touch — the user_name lands in .wize/config/user.toml (per-developer).
|
|
458
|
+
// Always ask; do not silently accept the OS username, because the install must
|
|
459
|
+
// feel personal and avoid misnaming the user in agent conversations.
|
|
393
460
|
const defaultName = (os.userInfo().username || '').trim();
|
|
394
|
-
const user_name =
|
|
395
|
-
|
|
396
|
-
|
|
461
|
+
const user_name = await promptTextMandatory(
|
|
462
|
+
'How should the agents call you?',
|
|
463
|
+
defaultName
|
|
464
|
+
);
|
|
397
465
|
|
|
398
466
|
// Gitignore — opt-in, idempotent.
|
|
399
467
|
const wantsGitignore = await confirm(
|
|
@@ -461,6 +529,32 @@ async function cmdInstall(args) {
|
|
|
461
529
|
}
|
|
462
530
|
}
|
|
463
531
|
|
|
532
|
+
// Offer to open a detected AI harness interactively.
|
|
533
|
+
if (INTERACTIVE) {
|
|
534
|
+
const ideTargetCodes = targets.map(t => t.code);
|
|
535
|
+
const harnesses = detectHarnessCli({ preferIde: ideTargetCodes });
|
|
536
|
+
if (harnesses.length) {
|
|
537
|
+
const primary = harnesses[0];
|
|
538
|
+
const { cmd, args } = primary.buildCmd('/wize-orchestrator');
|
|
539
|
+
const shown = `${cmd} ${args.map(a => /\s/.test(a) ? '"' + a + '"' : a).join(' ')}`;
|
|
540
|
+
const openHarness = await confirm(
|
|
541
|
+
`\nA harness was detected: ${primary.code} (${primary.path}).\n` +
|
|
542
|
+
`Open it now with Wizer? (runs: ${shown})`,
|
|
543
|
+
true
|
|
544
|
+
);
|
|
545
|
+
if (openHarness) {
|
|
546
|
+
const { spawnSync } = require('node:child_process');
|
|
547
|
+
console.log(`\nLaunching ${shown}...`);
|
|
548
|
+
spawnSync(cmd, args, { cwd, stdio: 'inherit' });
|
|
549
|
+
} else {
|
|
550
|
+
console.log(manualInstructions(primary).replace('/wize-document-project', '/wize-orchestrator'));
|
|
551
|
+
}
|
|
552
|
+
} else {
|
|
553
|
+
console.log('\nNo AI harness CLI detected on PATH (claude / codex / opencode).');
|
|
554
|
+
console.log('Open your IDE in this repo and run: /wize-orchestrator');
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
464
558
|
console.log('\n──────────────────────────────────────────────────────────────');
|
|
465
559
|
console.log('Done.');
|
|
466
560
|
console.log('');
|