11const { execSync } = require ( 'child_process' ) ;
22const path = require ( 'path' ) ;
3+ const fs = require ( 'fs-extra' ) ;
4+ const os = require ( 'os' ) ;
35const packageJson = require ( '../../package.json' ) ;
46
57describe ( 'CLI Integration Tests' , ( ) => {
68 const cliPath = path . join ( __dirname , '../../bin/contextkit.js' ) ;
9+ let tmpDir ;
10+
11+ beforeEach ( async ( ) => {
12+ tmpDir = await fs . mkdtemp ( path . join ( os . tmpdir ( ) , 'ck-cli-' ) ) ;
13+ } ) ;
14+
15+ afterEach ( async ( ) => {
16+ await fs . remove ( tmpDir ) ;
17+ } ) ;
718
819 describe ( 'version command' , ( ) => {
9- test ( 'should show version' , ( ) => {
20+ test ( '1. --version shows current package version' , ( ) => {
1021 const result = execSync ( `node "${ cliPath } " --version` , { encoding : 'utf8' } ) ;
1122 expect ( result . trim ( ) ) . toBe ( packageJson . version ) ;
1223 } ) ;
1324
14- test ( 'should show version with -v flag' , ( ) => {
25+ test ( '2. -v flag shows current package version ' , ( ) => {
1526 const result = execSync ( `node "${ cliPath } " -v` , { encoding : 'utf8' } ) ;
1627 expect ( result . trim ( ) ) . toBe ( packageJson . version ) ;
1728 } ) ;
1829 } ) ;
1930
2031 describe ( 'help command' , ( ) => {
21- test ( 'should show help' , ( ) => {
32+ test ( '3. -- help shows all core commands ' , ( ) => {
2233 const result = execSync ( `node "${ cliPath } " --help` , { encoding : 'utf8' } ) ;
2334 expect ( result ) . toContain ( 'Context Engineering for AI Development' ) ;
2435 expect ( result ) . toContain ( 'Commands:' ) ;
2536 expect ( result ) . toContain ( 'install' ) ;
2637 expect ( result ) . toContain ( 'status' ) ;
2738 expect ( result ) . toContain ( 'update' ) ;
39+ expect ( result ) . toContain ( 'analyze' ) ;
40+ expect ( result ) . toContain ( 'check' ) ;
41+ expect ( result ) . toContain ( 'note' ) ;
42+ expect ( result ) . toContain ( 'run' ) ;
2843 } ) ;
2944
30- test ( 'should show platform commands in help ' , ( ) => {
45+ test ( '4. --help shows all platform commands ' , ( ) => {
3146 const result = execSync ( `node "${ cliPath } " --help` , { encoding : 'utf8' } ) ;
3247 expect ( result ) . toContain ( 'windsurf' ) ;
3348 expect ( result ) . toContain ( 'codex' ) ;
@@ -38,26 +53,94 @@ describe('CLI Integration Tests', () => {
3853 expect ( result ) . toContain ( 'aider' ) ;
3954 } ) ;
4055
41- test ( 'should show help for install command ' , ( ) => {
56+ test ( '5. install -- help shows install options ' , ( ) => {
4257 const result = execSync ( `node "${ cliPath } " install --help` , { encoding : 'utf8' } ) ;
4358 expect ( result ) . toContain ( 'Initialize ContextKit in the current project directory' ) ;
4459 expect ( result ) . toContain ( '--no-hooks' ) ;
4560 expect ( result ) . toContain ( '--non-interactive' ) ;
4661 } ) ;
62+
63+ test ( '6. update --help shows update description and --force option' , ( ) => {
64+ const result = execSync ( `node "${ cliPath } " update --help` , { encoding : 'utf8' } ) ;
65+ expect ( result ) . toContain ( 'Update to latest version' ) ;
66+ expect ( result ) . toContain ( '--force' ) ;
67+ } ) ;
68+
69+ test ( '7. analyze --help shows analyze description and options' , ( ) => {
70+ const result = execSync ( `node "${ cliPath } " analyze --help` , { encoding : 'utf8' } ) ;
71+ expect ( result ) . toContain ( 'Analyze project' ) ;
72+ expect ( result ) . toContain ( '--ai' ) ;
73+ expect ( result ) . toContain ( '--scope' ) ;
74+ } ) ;
75+
76+ test ( '8. check --help shows check description and options' , ( ) => {
77+ const result = execSync ( `node "${ cliPath } " check --help` , { encoding : 'utf8' } ) ;
78+ expect ( result ) . toContain ( 'Validate ContextKit installation' ) ;
79+ expect ( result ) . toContain ( '--strict' ) ;
80+ expect ( result ) . toContain ( '--verbose' ) ;
81+ } ) ;
82+
83+ test ( '9. note --help shows note description and options' , ( ) => {
84+ const result = execSync ( `node "${ cliPath } " note --help` , { encoding : 'utf8' } ) ;
85+ expect ( result ) . toContain ( 'Add a note' ) ;
86+ expect ( result ) . toContain ( '--priority' ) ;
87+ expect ( result ) . toContain ( '--category' ) ;
88+ } ) ;
89+
90+ test ( '10. run --help shows run description and options' , ( ) => {
91+ const result = execSync ( `node "${ cliPath } " run --help` , { encoding : 'utf8' } ) ;
92+ expect ( result ) . toContain ( 'Run a workflow' ) ;
93+ expect ( result ) . toContain ( '--interactive' ) ;
94+ } ) ;
4795 } ) ;
4896
4997 describe ( 'status command' , ( ) => {
50- test ( 'should run status command ' , ( ) => {
98+ test ( '11. status runs without crashing (installed or not) ' , ( ) => {
5199 const result = execSync ( `node "${ cliPath } " status` , { encoding : 'utf8' } ) ;
52- // CI has no .contextkit/config.yml; local dev has full install
53100 const notInstalled = result . includes ( 'ContextKit is not installed' ) ;
54101 const installed = result . includes ( 'ContextKit Status' ) && result . includes ( 'Installation:' ) ;
55102 expect ( notInstalled || installed ) . toBe ( true ) ;
56103 } ) ;
104+
105+ test ( '12. status reports not installed when run from empty directory' , ( ) => {
106+ const result = execSync ( `node "${ cliPath } " status` , {
107+ encoding : 'utf8' ,
108+ cwd : tmpDir ,
109+ } ) ;
110+ expect ( result ) . toContain ( 'not installed' ) ;
111+ } ) ;
112+ } ) ;
113+
114+ describe ( 'update command' , ( ) => {
115+ test ( '13. update exits cleanly with no .contextkit (not installed)' , ( ) => {
116+ const result = execSync ( `node "${ cliPath } " update` , {
117+ encoding : 'utf8' ,
118+ cwd : tmpDir ,
119+ } ) ;
120+ expect ( result ) . toContain ( 'No ContextKit installation found' ) ;
121+ } ) ;
122+
123+ test ( '14. update suggests install command when not installed' , ( ) => {
124+ const result = execSync ( `node "${ cliPath } " update` , {
125+ encoding : 'utf8' ,
126+ cwd : tmpDir ,
127+ } ) ;
128+ expect ( result ) . toContain ( 'contextkit install' ) ;
129+ } ) ;
130+ } ) ;
131+
132+ describe ( 'check command' , ( ) => {
133+ test ( '15. check exits cleanly with no .contextkit (not installed)' , ( ) => {
134+ const result = execSync ( `node "${ cliPath } " check` , {
135+ encoding : 'utf8' ,
136+ cwd : tmpDir ,
137+ } ) ;
138+ expect ( result ) . toMatch ( / n o t i n s t a l l e d | N o C o n t e x t K i t / i) ;
139+ } ) ;
57140 } ) ;
58141
59142 describe ( 'error handling' , ( ) => {
60- test ( 'should print error and exit non-zero for unknown commands ' , ( ) => {
143+ test ( '16. unknown command prints error and exits non-zero' , ( ) => {
61144 let threw = false ;
62145 try {
63146 execSync ( `node "${ cliPath } " unknown-command` , { encoding : 'utf8' } ) ;
@@ -73,16 +156,15 @@ describe('CLI Integration Tests', () => {
73156 } ) ;
74157
75158 describe ( 'update-notifier' , ( ) => {
76- test ( 'CLI exits with code 0 and notifier does not break output' , ( ) => {
77- // update-notifier is suppressed in CI (CI=true env var); verify the CLI still runs cleanly
159+ test ( '17. CLI exits with code 0 and notifier does not break output' , ( ) => {
78160 const result = execSync ( `node "${ cliPath } " --version` , {
79161 encoding : 'utf8' ,
80162 env : { ...process . env , CI : 'true' } ,
81163 } ) ;
82164 expect ( result . trim ( ) ) . toBe ( packageJson . version ) ;
83165 } ) ;
84166
85- test ( 'CLI --help output is unaffected by notifier' , ( ) => {
167+ test ( '18. --help output is unaffected by notifier' , ( ) => {
86168 const result = execSync ( `node "${ cliPath } " --help` , {
87169 encoding : 'utf8' ,
88170 env : { ...process . env , CI : 'true' } ,
0 commit comments