servicemap 0.1.15 → 0.1.17

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 (2) hide show
  1. package/bin/servicemap.mjs +19 -63
  2. package/package.json +1 -1
@@ -404,62 +404,6 @@ function runTargetSurvey() {
404
404
  });
405
405
  }
406
406
 
407
- function renderInstallMethodSurvey(cursor) {
408
- console.clear();
409
- const methods = [
410
- { id: 'symlink', label: 'Symlink', note: 'Recommended, one stable source for easy updates' },
411
- { id: 'copy', label: 'Copy', note: 'Standalone copies in each selected agent folder' },
412
- ];
413
-
414
- timelineStep(cyan('servicemap'));
415
- timelineStep(`Source: ${repositoryUrl}`);
416
- timelineStep(`Stable source: ${stableSourceRoot()}`);
417
- timelineStep('Agents selected');
418
- timelineActive('Installation method');
419
- methods.forEach((method, index) => {
420
- const pointer = index === cursor ? '>' : ' ';
421
- const selected = index === cursor ? '●' : '○';
422
- timelineLine(`${pointer} ${selected} ${method.label} ${dim(`(${method.note})`)}`);
423
- });
424
- timelineLine(dim('↑/↓ to navigate • Enter to confirm'));
425
- }
426
-
427
- function runInstallMethodSurvey() {
428
- if (!process.stdin.isTTY || !process.stdout.isTTY) {
429
- return Promise.resolve('copy');
430
- }
431
-
432
- const methods = ['symlink', 'copy'];
433
- let cursor = 0;
434
-
435
- return new Promise((resolvePromise) => {
436
- readline.emitKeypressEvents(process.stdin);
437
- process.stdin.setRawMode(true);
438
- renderInstallMethodSurvey(cursor);
439
-
440
- const onKeypress = (_str, key) => {
441
- if (key.name === 'up') cursor = Math.max(0, cursor - 1);
442
- if (key.name === 'down') cursor = Math.min(methods.length - 1, cursor + 1);
443
- if (key.name === 'return') {
444
- process.stdin.setRawMode(false);
445
- process.stdin.off('keypress', onKeypress);
446
- console.log('');
447
- resolvePromise(methods[cursor]);
448
- return;
449
- }
450
- if (key.ctrl && key.name === 'c') {
451
- process.stdin.setRawMode(false);
452
- process.stdin.off('keypress', onKeypress);
453
- process.exit(130);
454
- }
455
-
456
- renderInstallMethodSurvey(cursor);
457
- };
458
-
459
- process.stdin.on('keypress', onKeypress);
460
- });
461
- }
462
-
463
407
  function runSilent(command, args, options = {}) {
464
408
  return new Promise((resolvePromise, reject) => {
465
409
  const child = spawn(command, args, {
@@ -475,7 +419,13 @@ function runSilent(command, args, options = {}) {
475
419
  });
476
420
  }
477
421
 
478
- async function withSpinner(message, action) {
422
+ function wait(ms) {
423
+ return new Promise((resolvePromise) => {
424
+ setTimeout(resolvePromise, ms);
425
+ });
426
+ }
427
+
428
+ async function withSpinner(message, action, minimumMs = 900) {
479
429
  if (!process.stdout.isTTY) {
480
430
  return action();
481
431
  }
@@ -483,15 +433,22 @@ async function withSpinner(message, action) {
483
433
  const frames = ['◒', '◐', '◓', '◑'];
484
434
  let frame = 0;
485
435
  let dots = '';
486
- process.stdout.write('\x1b[?25l');
487
- const interval = setInterval(() => {
436
+ const startedAt = Date.now();
437
+ const writeFrame = () => {
488
438
  process.stdout.write(`\r\x1b[J${frames[frame]} ${message}${dots}`);
489
439
  frame = (frame + 1) % frames.length;
490
440
  if (frame === 0) dots = dots.length >= 5 ? '' : `${dots}.`;
491
- }, 120);
441
+ };
442
+
443
+ process.stdout.write('\x1b[?25l');
444
+ writeFrame();
445
+ const interval = setInterval(writeFrame, 120);
492
446
 
493
447
  try {
494
- return await action();
448
+ const result = await action();
449
+ const remainingMs = minimumMs - (Date.now() - startedAt);
450
+ if (remainingMs > 0) await wait(remainingMs);
451
+ return result;
495
452
  } finally {
496
453
  clearInterval(interval);
497
454
  process.stdout.write('\r\x1b[J\x1b[?25h');
@@ -553,8 +510,7 @@ async function installSkill(options) {
553
510
  ? [{ id: 'universal', label: 'Universal', root: universalRoot }, ...await runTargetSurvey()]
554
511
  : targetsForOptions(options);
555
512
  const roots = skillRootsForTargets(options, selectedTargets);
556
- const method = options.installMethod
557
- ?? (options.survey && !options.yes ? await runInstallMethodSurvey() : 'copy');
513
+ const method = options.installMethod ?? 'symlink';
558
514
 
559
515
  if (!existsSync(source)) {
560
516
  throw new Error(`Bundled skill folder not found: ${source}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "servicemap",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "Generate an internal service map page or desktop app for a software project.",
5
5
  "type": "module",
6
6
  "bin": {