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.
@@ -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 prompt(`Project name [${path.basename(cwd)}]: `)) || path.basename(cwd);
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 = (await prompt(
395
- `How should the agents call you? [${defaultName || 'leave blank'}]: `
396
- )).trim() || defaultName;
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('');