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.
- package/package.json +1 -1
- package/src/index.js +109 -16
package/package.json
CHANGED
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
|
-
|
|
868
|
-
|
|
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 };
|