kspec 1.0.14 → 1.0.16

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/package.json +1 -1
  2. package/src/index.js +109 -16
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kspec",
3
- "version": "1.0.14",
3
+ "version": "1.0.16",
4
4
  "description": "Spec-driven development workflow for Kiro CLI",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
+ const os = require('os');
3
4
  const { execSync, spawn } = require('child_process');
4
5
  const readline = require('readline');
5
6
 
@@ -7,6 +8,7 @@ const KSPEC_DIR = '.kspec';
7
8
  const STEERING_DIR = '.kiro/steering';
8
9
  const AGENTS_DIR = '.kiro/agents';
9
10
  const CONFIG_FILE = path.join(KSPEC_DIR, 'config.json');
11
+ const UPDATE_CHECK_FILE = path.join(os.homedir(), '.kspec-update-check');
10
12
 
11
13
  // Default config
12
14
  const defaultConfig = {
@@ -33,6 +35,62 @@ function saveConfig(cfg) {
33
35
  }
34
36
 
35
37
  const config = loadConfig();
38
+ const pkg = require('../package.json');
39
+
40
+ // Update check (non-blocking, cached for 24h)
41
+ function shouldCheckUpdate() {
42
+ try {
43
+ if (fs.existsSync(UPDATE_CHECK_FILE)) {
44
+ const lastCheck = parseInt(fs.readFileSync(UPDATE_CHECK_FILE, 'utf8'), 10);
45
+ const hoursSinceCheck = (Date.now() - lastCheck) / (1000 * 60 * 60);
46
+ return hoursSinceCheck >= 24;
47
+ }
48
+ } catch {}
49
+ return true;
50
+ }
51
+
52
+ function saveUpdateCheck() {
53
+ try {
54
+ fs.writeFileSync(UPDATE_CHECK_FILE, Date.now().toString());
55
+ } catch {}
56
+ }
57
+
58
+ function compareVersions(v1, v2) {
59
+ const parts1 = v1.split('.').map(Number);
60
+ const parts2 = v2.split('.').map(Number);
61
+ for (let i = 0; i < 3; i++) {
62
+ if ((parts1[i] || 0) < (parts2[i] || 0)) return -1;
63
+ if ((parts1[i] || 0) > (parts2[i] || 0)) return 1;
64
+ }
65
+ return 0;
66
+ }
67
+
68
+ async function checkForUpdates() {
69
+ if (!shouldCheckUpdate()) return;
70
+
71
+ try {
72
+ const https = require('https');
73
+ const data = await new Promise((resolve, reject) => {
74
+ const req = https.get('https://registry.npmjs.org/kspec/latest', { timeout: 3000 }, res => {
75
+ let body = '';
76
+ res.on('data', chunk => body += chunk);
77
+ res.on('end', () => resolve(body));
78
+ });
79
+ req.on('error', reject);
80
+ req.on('timeout', () => { req.destroy(); reject(new Error('timeout')); });
81
+ });
82
+
83
+ const latest = JSON.parse(data).version;
84
+ saveUpdateCheck();
85
+
86
+ if (compareVersions(pkg.version, latest) < 0) {
87
+ console.log(`\n Update available: ${pkg.version} → ${latest}`);
88
+ console.log(` Run: npm install -g kspec\n`);
89
+ }
90
+ } catch {
91
+ // Silently fail - don't block user workflow
92
+ }
93
+ }
36
94
 
37
95
  // Helpers
38
96
  function log(msg) { console.log(`[kspec] ${msg}`); }
@@ -334,7 +392,7 @@ Your job:
334
392
  4. Identify risks, tech debt, improvement areas
335
393
 
336
394
  Output a clear analysis report. Propose specific steering doc updates.`,
337
- keyboardShortcut: 'ctrl+a',
395
+ keyboardShortcut: 'ctrl+shift+a',
338
396
  welcomeMessage: 'Analysing codebase...'
339
397
  },
340
398
 
@@ -368,7 +426,7 @@ WORKFLOW (do this autonomously):
368
426
  6. Update .kspec/CONTEXT.md with current state
369
427
 
370
428
  After completion, suggest: "Switch to kspec-tasks agent to generate implementation tasks"`,
371
- keyboardShortcut: 'ctrl+s',
429
+ keyboardShortcut: 'ctrl+shift+s',
372
430
  welcomeMessage: 'Ready to create specification. Describe your feature.'
373
431
  },
374
432
 
@@ -400,7 +458,7 @@ WORKFLOW:
400
458
  Tasks must be atomic and independently verifiable.
401
459
 
402
460
  After completion, suggest: "Switch to kspec-build agent to start implementing tasks"`,
403
- keyboardShortcut: 'ctrl+t',
461
+ keyboardShortcut: 'ctrl+shift+t',
404
462
  welcomeMessage: 'Reading current spec and generating tasks...'
405
463
  },
406
464
 
@@ -437,7 +495,7 @@ CRITICAL:
437
495
  - Use non-interactive flags for commands (--yes, -y)
438
496
 
439
497
  When all tasks complete, suggest: "Switch to kspec-verify agent to verify implementation"`,
440
- keyboardShortcut: 'ctrl+b',
498
+ keyboardShortcut: 'ctrl+shift+b',
441
499
  welcomeMessage: 'Reading current task and building...'
442
500
  },
443
501
 
@@ -477,7 +535,7 @@ VERIFY-IMPLEMENTATION:
477
535
  - List any gaps between spec and implementation
478
536
 
479
537
  Output a clear verification report with pass/fail status.`,
480
- keyboardShortcut: 'ctrl+v',
538
+ keyboardShortcut: 'ctrl+shift+v',
481
539
  welcomeMessage: 'What should I verify?'
482
540
  },
483
541
 
@@ -507,7 +565,7 @@ Your job:
507
565
  4. Provide actionable feedback
508
566
 
509
567
  Output: APPROVE / REQUEST_CHANGES with specific issues.`,
510
- keyboardShortcut: 'ctrl+r',
568
+ keyboardShortcut: 'ctrl+shift+r',
511
569
  welcomeMessage: 'Ready to review. What should I look at?'
512
570
  }
513
571
  };
@@ -807,17 +865,48 @@ kspec Agents
807
865
 
808
866
  Agent Shortcut Purpose
809
867
  ─────────────────────────────────────────────
810
- kspec-analyse Ctrl+A Analyse codebase, update steering
811
- kspec-spec Ctrl+S Create specifications
812
- kspec-tasks Ctrl+T Generate tasks from spec
813
- kspec-build Ctrl+B Execute tasks with TDD
814
- kspec-verify Ctrl+V Verify spec/tasks/implementation
815
- kspec-review Ctrl+R Code review
868
+ kspec-analyse Ctrl+Shift+A Analyse codebase, update steering
869
+ kspec-spec Ctrl+Shift+S Create specifications
870
+ kspec-tasks Ctrl+Shift+T Generate tasks from spec
871
+ kspec-build Ctrl+Shift+B Execute tasks with TDD
872
+ kspec-verify Ctrl+Shift+V Verify spec/tasks/implementation
873
+ kspec-review Ctrl+Shift+R Code review
816
874
 
817
875
  Switch: /agent swap or use keyboard shortcuts
818
876
  `);
819
877
  },
820
878
 
879
+ async update() {
880
+ console.log(`\nkspec v${pkg.version}\n`);
881
+ console.log('Checking for updates...');
882
+
883
+ try {
884
+ const https = require('https');
885
+ const data = await new Promise((resolve, reject) => {
886
+ const req = https.get('https://registry.npmjs.org/kspec/latest', { timeout: 5000 }, res => {
887
+ let body = '';
888
+ res.on('data', chunk => body += chunk);
889
+ res.on('end', () => resolve(body));
890
+ });
891
+ req.on('error', reject);
892
+ req.on('timeout', () => { req.destroy(); reject(new Error('timeout')); });
893
+ });
894
+
895
+ const latest = JSON.parse(data).version;
896
+ saveUpdateCheck();
897
+
898
+ if (compareVersions(pkg.version, latest) < 0) {
899
+ console.log(`\nUpdate available: ${pkg.version} → ${latest}`);
900
+ console.log('\nTo update, run:');
901
+ console.log(' npm install -g kspec\n');
902
+ } else {
903
+ console.log(`\nYou're on the latest version!\n`);
904
+ }
905
+ } catch (err) {
906
+ console.error('\nCould not check for updates. Check your internet connection.\n');
907
+ }
908
+ },
909
+
821
910
  help() {
822
911
  console.log(`
823
912
  kspec - Spec-driven development for Kiro CLI
@@ -847,6 +936,7 @@ Other:
847
936
  kspec list List all specs
848
937
  kspec status Current status
849
938
  kspec agents List agents
939
+ kspec update Check for updates
850
940
  kspec help Show this help
851
941
 
852
942
  Examples:
@@ -858,14 +948,17 @@ Examples:
858
948
  };
859
949
 
860
950
  async function run(args) {
951
+ // Check for updates (non-blocking, cached for 24h)
952
+ checkForUpdates();
953
+
861
954
  // Handle standard CLI flags first
862
955
  if (args.includes('--help') || args.includes('-h')) {
863
956
  return commands.help();
864
957
  }
865
-
958
+
866
959
  if (args.includes('--version') || args.includes('-v')) {
867
- const pkg = require('../package.json');
868
- console.log(pkg.version);
960
+ // Show version and check for updates
961
+ await commands.update();
869
962
  return;
870
963
  }
871
964
 
@@ -879,4 +972,4 @@ async function run(args) {
879
972
  }
880
973
  }
881
974
 
882
- module.exports = { run, commands, loadConfig, detectCli, requireCli, agentTemplates, getTaskStats, refreshContext, getCurrentTask };
975
+ module.exports = { run, commands, loadConfig, detectCli, requireCli, agentTemplates, getTaskStats, refreshContext, getCurrentTask, checkForUpdates, compareVersions };