servicemap 0.1.17 → 0.1.19

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 +33 -16
  2. package/package.json +1 -1
@@ -298,6 +298,7 @@ const additionalAgentWindowSize = 8;
298
298
  const dim = (value) => `\x1b[2m${value}\x1b[22m`;
299
299
  const green = (value) => `\x1b[32m${value}\x1b[39m`;
300
300
  const cyan = (value) => `\x1b[36m${value}\x1b[39m`;
301
+ let stableSourceStatus = '';
301
302
 
302
303
  function timelineStep(text) {
303
304
  console.log(`${green('◇')} ${text}`);
@@ -318,6 +319,9 @@ function renderSurvey(selected, cursor) {
318
319
  timelineStep(cyan('servicemap'));
319
320
  timelineStep(`Source: ${repositoryUrl}`);
320
321
  timelineStep(`Stable source: ${stableSourceRoot()}`);
322
+ if (stableSourceStatus) {
323
+ timelineStep(stableSourceStatus);
324
+ }
321
325
  timelineActive('Which agents do you want to install Servicemap to?');
322
326
  timelineLine('Universal (.agents/skills) — always included');
323
327
  for (const agent of universalAgents.slice(0, visibleUniversalLimit)) {
@@ -425,19 +429,28 @@ function wait(ms) {
425
429
  });
426
430
  }
427
431
 
428
- async function withSpinner(message, action, minimumMs = 900) {
429
- if (!process.stdout.isTTY) {
430
- return action();
431
- }
432
-
432
+ async function withSpinner(message, action, minimumMs = 1400) {
433
433
  const frames = ['◒', '◐', '◓', '◑'];
434
434
  let frame = 0;
435
435
  let dots = '';
436
436
  const startedAt = Date.now();
437
- const writeFrame = () => {
438
- process.stdout.write(`\r\x1b[J${frames[frame]} ${message}${dots}`);
437
+ const nextText = () => {
438
+ const text = `${dim('│')} ${frames[frame]} ${message}${dots}`;
439
439
  frame = (frame + 1) % frames.length;
440
440
  if (frame === 0) dots = dots.length >= 5 ? '' : `${dots}.`;
441
+ return text;
442
+ };
443
+
444
+ if (!process.stdout.isTTY) {
445
+ console.log(nextText());
446
+ const result = await action();
447
+ const remainingMs = minimumMs - (Date.now() - startedAt);
448
+ if (remainingMs > 0) await wait(remainingMs);
449
+ return result;
450
+ }
451
+
452
+ const writeFrame = () => {
453
+ process.stdout.write(`\r\x1b[J${nextText()}`);
441
454
  };
442
455
 
443
456
  process.stdout.write('\x1b[?25l');
@@ -468,15 +481,18 @@ async function prepareStableSource(options) {
468
481
  try {
469
482
  if (existsSync(join(sourceRoot, '.git'))) {
470
483
  await withSpinner('Updating repository…', () => runSilent('git', ['pull', '--ff-only'], { cwd: sourceRoot }));
484
+ stableSourceStatus = 'Repository updated';
471
485
  timelineStep('Repository updated');
472
486
  } else {
473
487
  await rm(sourceRoot, { recursive: true, force: true });
474
488
  await withSpinner('Cloning repository…', () => runSilent('git', ['clone', '--depth', '1', repositoryUrl, sourceRoot]));
489
+ stableSourceStatus = 'Repository cloned';
475
490
  timelineStep('Repository cloned');
476
491
  }
477
492
  } catch (_error) {
478
493
  await rm(sourceRoot, { recursive: true, force: true });
479
494
  await cp(packageRoot, sourceRoot, { recursive: true });
495
+ stableSourceStatus = 'Repository unavailable; copied packaged source';
480
496
  timelineStep('Repository unavailable; copied packaged source');
481
497
  }
482
498
 
@@ -506,21 +522,12 @@ async function installIntoRoot(root, source, method, options) {
506
522
 
507
523
  async function installSkill(options) {
508
524
  let source = resolve(packageRoot, 'servicemap');
509
- const selectedTargets = options.survey && !options.yes
510
- ? [{ id: 'universal', label: 'Universal', root: universalRoot }, ...await runTargetSurvey()]
511
- : targetsForOptions(options);
512
- const roots = skillRootsForTargets(options, selectedTargets);
513
525
  const method = options.installMethod ?? 'symlink';
514
526
 
515
527
  if (!existsSync(source)) {
516
528
  throw new Error(`Bundled skill folder not found: ${source}`);
517
529
  }
518
530
 
519
- if (roots.length === 0) {
520
- console.log('No targets selected. Nothing was installed.');
521
- return;
522
- }
523
-
524
531
  if (!['copy', 'symlink'].includes(method)) {
525
532
  throw new Error(`Unknown install method "${method}". Use copy or symlink.`);
526
533
  }
@@ -532,6 +539,16 @@ async function installSkill(options) {
532
539
  }
533
540
  }
534
541
 
542
+ const selectedTargets = options.survey && !options.yes
543
+ ? [{ id: 'universal', label: 'Universal', root: universalRoot }, ...await runTargetSurvey()]
544
+ : targetsForOptions(options);
545
+ const roots = skillRootsForTargets(options, selectedTargets);
546
+
547
+ if (roots.length === 0) {
548
+ console.log('No targets selected. Nothing was installed.');
549
+ return;
550
+ }
551
+
535
552
  for (const root of roots) {
536
553
  await installIntoRoot(root, source, method, options);
537
554
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "servicemap",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "description": "Generate an internal service map page or desktop app for a software project.",
5
5
  "type": "module",
6
6
  "bin": {