@soleri/cli 9.7.2 → 9.9.0

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 (70) hide show
  1. package/dist/commands/add-domain.js +1 -0
  2. package/dist/commands/add-domain.js.map +1 -1
  3. package/dist/commands/add-pack.js +7 -147
  4. package/dist/commands/add-pack.js.map +1 -1
  5. package/dist/commands/agent.js +130 -0
  6. package/dist/commands/agent.js.map +1 -1
  7. package/dist/commands/create.js +96 -4
  8. package/dist/commands/create.js.map +1 -1
  9. package/dist/commands/dev.js +13 -3
  10. package/dist/commands/dev.js.map +1 -1
  11. package/dist/commands/doctor.js +2 -0
  12. package/dist/commands/doctor.js.map +1 -1
  13. package/dist/commands/extend.js +17 -0
  14. package/dist/commands/extend.js.map +1 -1
  15. package/dist/commands/install-knowledge.js +1 -0
  16. package/dist/commands/install-knowledge.js.map +1 -1
  17. package/dist/commands/install.d.ts +2 -0
  18. package/dist/commands/install.js +79 -20
  19. package/dist/commands/install.js.map +1 -1
  20. package/dist/commands/test.js +140 -1
  21. package/dist/commands/test.js.map +1 -1
  22. package/dist/commands/vault.d.ts +9 -0
  23. package/dist/commands/vault.js +66 -0
  24. package/dist/commands/vault.js.map +1 -0
  25. package/dist/hook-packs/flock-guard/manifest.json +2 -1
  26. package/dist/hook-packs/marketing-research/manifest.json +2 -1
  27. package/dist/hook-packs/registry.d.ts +2 -0
  28. package/dist/hook-packs/registry.js.map +1 -1
  29. package/dist/hook-packs/registry.ts +2 -0
  30. package/dist/main.js +7 -0
  31. package/dist/main.js.map +1 -1
  32. package/dist/prompts/create-wizard.d.ts +16 -2
  33. package/dist/prompts/create-wizard.js +84 -11
  34. package/dist/prompts/create-wizard.js.map +1 -1
  35. package/dist/utils/checks.d.ts +8 -5
  36. package/dist/utils/checks.js +105 -10
  37. package/dist/utils/checks.js.map +1 -1
  38. package/dist/utils/format-paths.d.ts +14 -0
  39. package/dist/utils/format-paths.js +27 -0
  40. package/dist/utils/format-paths.js.map +1 -0
  41. package/dist/utils/git.d.ts +29 -0
  42. package/dist/utils/git.js +88 -0
  43. package/dist/utils/git.js.map +1 -0
  44. package/dist/utils/logger.d.ts +1 -0
  45. package/dist/utils/logger.js +4 -0
  46. package/dist/utils/logger.js.map +1 -1
  47. package/package.json +1 -1
  48. package/src/__tests__/create-wizard-git.test.ts +208 -0
  49. package/src/__tests__/git-utils.test.ts +268 -0
  50. package/src/__tests__/install.test.ts +88 -0
  51. package/src/__tests__/scaffold-git-e2e.test.ts +112 -0
  52. package/src/commands/add-domain.ts +1 -0
  53. package/src/commands/add-pack.ts +10 -163
  54. package/src/commands/agent.ts +161 -0
  55. package/src/commands/create.ts +109 -5
  56. package/src/commands/dev.ts +13 -3
  57. package/src/commands/doctor.ts +1 -0
  58. package/src/commands/extend.ts +20 -1
  59. package/src/commands/install-knowledge.ts +1 -0
  60. package/src/commands/install.ts +87 -20
  61. package/src/commands/test.ts +141 -2
  62. package/src/commands/vault.ts +79 -0
  63. package/src/hook-packs/flock-guard/manifest.json +2 -1
  64. package/src/hook-packs/marketing-research/manifest.json +2 -1
  65. package/src/hook-packs/registry.ts +2 -0
  66. package/src/main.ts +10 -0
  67. package/src/prompts/create-wizard.ts +109 -14
  68. package/src/utils/checks.ts +122 -13
  69. package/src/utils/git.ts +118 -0
  70. package/src/utils/logger.ts +5 -0
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Health check utilities for the doctor command.
3
3
  */
4
- import { existsSync, readFileSync } from 'node:fs';
4
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
5
5
  import { join } from 'node:path';
6
6
  import { execFileSync } from 'node:child_process';
7
7
  import { homedir } from 'node:os';
@@ -45,9 +45,17 @@ export function checkAgentProject(dir) {
45
45
  if (!ctx) {
46
46
  return { status: 'warn', label: 'Agent project', detail: 'not detected in current directory' };
47
47
  }
48
- return { status: 'pass', label: 'Agent project', detail: `${ctx.agentId} (${ctx.packageName})` };
48
+ const formatLabel = ctx.format === 'filetree' ? 'file-tree' : 'typescript';
49
+ return {
50
+ status: 'pass',
51
+ label: 'Agent project',
52
+ detail: `${ctx.agentId} (${ctx.packageName}, ${formatLabel})`,
53
+ };
49
54
  }
50
- export function checkAgentBuild(dir) {
55
+ export function checkAgentBuild(dir, format) {
56
+ if (format === 'filetree') {
57
+ return { status: 'skip', label: 'Agent build', detail: 'not applicable for file-tree agents' };
58
+ }
51
59
  const ctx = detectAgent(dir);
52
60
  if (!ctx)
53
61
  return { status: 'warn', label: 'Agent build', detail: 'no agent detected' };
@@ -63,7 +71,14 @@ export function checkAgentBuild(dir) {
63
71
  }
64
72
  return { status: 'pass', label: 'Agent build', detail: 'dist/index.js exists' };
65
73
  }
66
- export function checkNodeModules(dir) {
74
+ export function checkNodeModules(dir, format) {
75
+ if (format === 'filetree') {
76
+ return {
77
+ status: 'skip',
78
+ label: 'Dependencies',
79
+ detail: 'not applicable for file-tree agents',
80
+ };
81
+ }
67
82
  const ctx = detectAgent(dir);
68
83
  if (!ctx)
69
84
  return { status: 'warn', label: 'Dependencies', detail: 'no agent detected' };
@@ -76,6 +91,77 @@ export function checkNodeModules(dir) {
76
91
  }
77
92
  return { status: 'pass', label: 'Dependencies', detail: 'node_modules/ exists' };
78
93
  }
94
+ export function checkAgentYaml(agentPath) {
95
+ const yamlPath = join(agentPath, 'agent.yaml');
96
+ if (!existsSync(yamlPath)) {
97
+ return { status: 'fail', label: 'agent.yaml', detail: 'not found' };
98
+ }
99
+ try {
100
+ const content = readFileSync(yamlPath, 'utf-8');
101
+ // Light validation: check for required fields without pulling in a YAML parser
102
+ // (detectAgent already parsed it, but we verify the raw content for diagnostics)
103
+ const hasId = /^id\s*:/m.test(content);
104
+ const hasName = /^name\s*:/m.test(content);
105
+ if (!hasId && !hasName) {
106
+ return {
107
+ status: 'fail',
108
+ label: 'agent.yaml',
109
+ detail: 'missing required fields: id, name',
110
+ };
111
+ }
112
+ if (!hasId) {
113
+ return { status: 'fail', label: 'agent.yaml', detail: 'missing required field: id' };
114
+ }
115
+ if (!hasName) {
116
+ return { status: 'fail', label: 'agent.yaml', detail: 'missing required field: name' };
117
+ }
118
+ return { status: 'pass', label: 'agent.yaml', detail: 'valid (id, name present)' };
119
+ }
120
+ catch {
121
+ return { status: 'fail', label: 'agent.yaml', detail: 'failed to read file' };
122
+ }
123
+ }
124
+ export function checkInstructionsDir(agentPath) {
125
+ const instrDir = join(agentPath, 'instructions');
126
+ if (!existsSync(instrDir)) {
127
+ return {
128
+ status: 'fail',
129
+ label: 'Instructions',
130
+ detail: 'instructions/ directory not found',
131
+ };
132
+ }
133
+ try {
134
+ const files = readdirSync(instrDir).filter((f) => f.endsWith('.md'));
135
+ if (files.length === 0) {
136
+ return {
137
+ status: 'warn',
138
+ label: 'Instructions',
139
+ detail: 'instructions/ exists but contains no .md files',
140
+ };
141
+ }
142
+ return {
143
+ status: 'pass',
144
+ label: 'Instructions',
145
+ detail: `${files.length} instruction file${files.length === 1 ? '' : 's'}`,
146
+ };
147
+ }
148
+ catch {
149
+ return { status: 'fail', label: 'Instructions', detail: 'failed to read instructions/' };
150
+ }
151
+ }
152
+ export function checkEngineReachable() {
153
+ try {
154
+ require.resolve('@soleri/core/package.json');
155
+ return { status: 'pass', label: 'Engine', detail: '@soleri/core reachable' };
156
+ }
157
+ catch {
158
+ return {
159
+ status: 'fail',
160
+ label: 'Engine',
161
+ detail: '@soleri/core not found — engine is required for file-tree agents',
162
+ };
163
+ }
164
+ }
79
165
  function checkMcpRegistration(dir) {
80
166
  const ctx = detectAgent(dir);
81
167
  if (!ctx)
@@ -145,16 +231,25 @@ function checkHookPacks() {
145
231
  };
146
232
  }
147
233
  export function runAllChecks(dir) {
148
- return [
234
+ const ctx = detectAgent(dir);
235
+ const format = ctx?.format;
236
+ // Common checks for all agent formats
237
+ const results = [
149
238
  checkNodeVersion(),
150
239
  checkNpm(),
151
240
  checkTsx(),
152
241
  checkAgentProject(dir),
153
- checkNodeModules(dir),
154
- checkAgentBuild(dir),
155
- checkMcpRegistration(dir),
156
- checkHookPacks(),
157
- checkCognee(),
158
242
  ];
243
+ if (format === 'filetree') {
244
+ // File-tree agent checks
245
+ results.push(checkAgentYaml(ctx.agentPath), checkInstructionsDir(ctx.agentPath), checkEngineReachable(), checkNodeModules(dir, format), checkAgentBuild(dir, format));
246
+ }
247
+ else {
248
+ // TypeScript agent checks (or no agent detected)
249
+ results.push(checkNodeModules(dir, format), checkAgentBuild(dir, format));
250
+ }
251
+ // Shared checks
252
+ results.push(checkMcpRegistration(dir), checkHookPacks(), checkCognee());
253
+ return results;
159
254
  }
160
255
  //# sourceMappingURL=checks.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"checks.js","sourceRoot":"","sources":["../../src/utils/checks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"checks.js","sourceRoot":"","sources":["../../src/utils/checks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export interface FormatPaths {
2
+ knowledgeDir: string;
3
+ extensionsDir: string;
4
+ facadesDir: string;
5
+ agentConfigFile: string;
6
+ entryPoint: string;
7
+ }
8
+ export declare function getFormatPaths(ctx: {
9
+ format: 'filetree' | 'typescript';
10
+ agentPath: string;
11
+ }): FormatPaths;
12
+ export declare function isFileTree(ctx: {
13
+ format: string;
14
+ }): boolean;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Format-aware path resolution for filetree vs typescript agents.
3
+ */
4
+ import { join } from 'node:path';
5
+ export function getFormatPaths(ctx) {
6
+ const { format, agentPath } = ctx;
7
+ if (format === 'filetree') {
8
+ return {
9
+ knowledgeDir: join(agentPath, 'knowledge'),
10
+ extensionsDir: join(agentPath, 'extensions'),
11
+ facadesDir: '',
12
+ agentConfigFile: join(agentPath, 'agent.yaml'),
13
+ entryPoint: join(agentPath, 'agent.yaml'),
14
+ };
15
+ }
16
+ return {
17
+ knowledgeDir: join(agentPath, 'src', 'intelligence', 'data'),
18
+ extensionsDir: join(agentPath, 'src', 'extensions'),
19
+ facadesDir: join(agentPath, 'src', 'facades'),
20
+ agentConfigFile: join(agentPath, 'package.json'),
21
+ entryPoint: join(agentPath, 'src', 'index.ts'),
22
+ };
23
+ }
24
+ export function isFileTree(ctx) {
25
+ return ctx.format === 'filetree';
26
+ }
27
+ //# sourceMappingURL=format-paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-paths.js","sourceRoot":"","sources":["../../src/utils/format-paths.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAUjC,MAAM,UAAU,cAAc,CAAC,GAG9B;IACC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC;IAElC,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;QAC1B,OAAO;YACL,YAAY,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC;YAC1C,aAAa,EAAE,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC;YAC5C,UAAU,EAAE,EAAE;YACd,eAAe,EAAE,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC;YAC9C,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC;SAC1C,CAAC;IACJ,CAAC;IAED,OAAO;QACL,YAAY,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,CAAC;QAC5D,aAAa,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,YAAY,CAAC;QACnD,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC;QAC7C,eAAe,EAAE,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC;QAChD,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,UAAU,CAAC;KAC/C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAuB;IAChD,OAAO,GAAG,CAAC,MAAM,KAAK,UAAU,CAAC;AACnC,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Git utility functions for the Soleri CLI scaffold flow.
3
+ *
4
+ * Uses child_process.execFile (not exec) for security — no shell interpolation.
5
+ * Never throws — all functions return { ok, error? } for graceful handling.
6
+ */
7
+ export interface GitResult {
8
+ ok: boolean;
9
+ error?: string;
10
+ }
11
+ /** Check if the `git` binary is available on PATH. */
12
+ export declare function isGitInstalled(): Promise<boolean>;
13
+ /** Check if the `gh` (GitHub CLI) binary is available on PATH. */
14
+ export declare function isGhInstalled(): Promise<boolean>;
15
+ /** Run `git init` in the given directory. */
16
+ export declare function gitInit(dir: string): Promise<GitResult>;
17
+ /** Stage all files and create an initial commit. */
18
+ export declare function gitInitialCommit(dir: string, message: string): Promise<GitResult>;
19
+ /** Add a remote origin URL. */
20
+ export declare function gitAddRemote(dir: string, url: string): Promise<GitResult>;
21
+ /** Push to origin main with the -u flag. */
22
+ export declare function gitPush(dir: string): Promise<GitResult>;
23
+ /** Create a GitHub repo using the `gh` CLI. */
24
+ export declare function ghCreateRepo(name: string, options: {
25
+ visibility: 'public' | 'private';
26
+ dir: string;
27
+ }): Promise<GitResult & {
28
+ url?: string;
29
+ }>;
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Git utility functions for the Soleri CLI scaffold flow.
3
+ *
4
+ * Uses child_process.execFile (not exec) for security — no shell interpolation.
5
+ * Never throws — all functions return { ok, error? } for graceful handling.
6
+ */
7
+ import { execFile } from 'node:child_process';
8
+ /** Default timeout for local git operations (30s). */
9
+ const LOCAL_TIMEOUT = 30_000;
10
+ /** Timeout for network operations — push, gh create (60s). */
11
+ const NETWORK_TIMEOUT = 60_000;
12
+ /**
13
+ * Run a command via execFile and return stdout on success, or an error string on failure.
14
+ */
15
+ function run(cmd, args, options) {
16
+ return new Promise((resolve) => {
17
+ try {
18
+ execFile(cmd, args, {
19
+ cwd: options.cwd,
20
+ signal: AbortSignal.timeout(options.timeout),
21
+ }, (error, stdout, stderr) => {
22
+ if (error) {
23
+ resolve({ stdout: '', error: stderr?.trim() || error.message });
24
+ }
25
+ else {
26
+ resolve({ stdout: stdout ?? '' });
27
+ }
28
+ });
29
+ }
30
+ catch (err) {
31
+ // execFile itself can throw (e.g. ENOENT)
32
+ const msg = err instanceof Error ? err.message : String(err);
33
+ resolve({ stdout: '', error: msg });
34
+ }
35
+ });
36
+ }
37
+ /** Check if the `git` binary is available on PATH. */
38
+ export async function isGitInstalled() {
39
+ const { error } = await run('which', ['git'], { timeout: LOCAL_TIMEOUT });
40
+ return !error;
41
+ }
42
+ /** Check if the `gh` (GitHub CLI) binary is available on PATH. */
43
+ export async function isGhInstalled() {
44
+ const { error } = await run('which', ['gh'], { timeout: LOCAL_TIMEOUT });
45
+ return !error;
46
+ }
47
+ /** Run `git init` in the given directory. */
48
+ export async function gitInit(dir) {
49
+ const { error } = await run('git', ['init'], { cwd: dir, timeout: LOCAL_TIMEOUT });
50
+ return error ? { ok: false, error } : { ok: true };
51
+ }
52
+ /** Stage all files and create an initial commit. */
53
+ export async function gitInitialCommit(dir, message) {
54
+ const add = await run('git', ['add', '.'], { cwd: dir, timeout: LOCAL_TIMEOUT });
55
+ if (add.error)
56
+ return { ok: false, error: add.error };
57
+ const commit = await run('git', ['commit', '-m', message], { cwd: dir, timeout: LOCAL_TIMEOUT });
58
+ if (commit.error)
59
+ return { ok: false, error: commit.error };
60
+ return { ok: true };
61
+ }
62
+ /** Add a remote origin URL. */
63
+ export async function gitAddRemote(dir, url) {
64
+ const { error } = await run('git', ['remote', 'add', 'origin', url], {
65
+ cwd: dir,
66
+ timeout: LOCAL_TIMEOUT,
67
+ });
68
+ return error ? { ok: false, error } : { ok: true };
69
+ }
70
+ /** Push to origin main with the -u flag. */
71
+ export async function gitPush(dir) {
72
+ const { error } = await run('git', ['push', '-u', 'origin', 'main'], {
73
+ cwd: dir,
74
+ timeout: NETWORK_TIMEOUT,
75
+ });
76
+ return error ? { ok: false, error } : { ok: true };
77
+ }
78
+ /** Create a GitHub repo using the `gh` CLI. */
79
+ export async function ghCreateRepo(name, options) {
80
+ const visFlag = options.visibility === 'public' ? '--public' : '--private';
81
+ const { stdout, error } = await run('gh', ['repo', 'create', name, visFlag, `--source=${options.dir}`, '--remote=origin', '--push'], { cwd: options.dir, timeout: NETWORK_TIMEOUT });
82
+ if (error)
83
+ return { ok: false, error };
84
+ // gh repo create prints the repo URL on stdout
85
+ const url = stdout.trim() || undefined;
86
+ return { ok: true, url };
87
+ }
88
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,7 @@
5
5
  export declare function pass(label: string, detail?: string): void;
6
6
  export declare function fail(label: string, detail?: string): void;
7
7
  export declare function warn(label: string, detail?: string): void;
8
+ export declare function skip(label: string, detail?: string): void;
8
9
  export declare function info(message: string): void;
9
10
  export declare function heading(title: string): void;
10
11
  export declare function dim(message: string): void;
@@ -21,6 +21,10 @@ export function warn(label, detail) {
21
21
  const suffix = detail ? ` ${DIM}${detail}${RESET}` : '';
22
22
  console.log(` ${YELLOW}!${RESET} ${label}${suffix}`);
23
23
  }
24
+ export function skip(label, detail) {
25
+ const suffix = detail ? ` ${DIM}${detail}${RESET}` : '';
26
+ console.log(` ${DIM}–${RESET} ${label}${suffix}`);
27
+ }
24
28
  export function info(message) {
25
29
  console.log(` ${CYAN}ℹ${RESET} ${message}`);
26
30
  }
@@ -1 +1 @@
1
- {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,KAAK,GAAG,SAAS,CAAC;AACxB,MAAM,KAAK,GAAG,UAAU,CAAC;AACzB,MAAM,GAAG,GAAG,UAAU,CAAC;AACvB,MAAM,MAAM,GAAG,UAAU,CAAC;AAC1B,MAAM,IAAI,GAAG,UAAU,CAAC;AACxB,MAAM,GAAG,GAAG,SAAS,CAAC;AACtB,MAAM,IAAI,GAAG,SAAS,CAAC;AAEvB,MAAM,UAAU,IAAI,CAAC,KAAa,EAAE,MAAe;IACjD,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,MAAM,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,IAAI,KAAK,IAAI,KAAK,GAAG,MAAM,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,KAAa,EAAE,MAAe;IACjD,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,MAAM,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,KAAK,IAAI,KAAK,GAAG,MAAM,EAAE,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,KAAa,EAAE,MAAe;IACjD,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,MAAM,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,IAAI,KAAK,IAAI,KAAK,GAAG,MAAM,EAAE,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,OAAe;IAClC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,KAAK,IAAI,OAAO,EAAE,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,KAAa;IACnC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,KAAK,GAAG,KAAK,IAAI,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,OAAe;IACjC,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,OAAO,GAAG,KAAK,EAAE,CAAC,CAAC;AAC5C,CAAC"}
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,KAAK,GAAG,SAAS,CAAC;AACxB,MAAM,KAAK,GAAG,UAAU,CAAC;AACzB,MAAM,GAAG,GAAG,UAAU,CAAC;AACvB,MAAM,MAAM,GAAG,UAAU,CAAC;AAC1B,MAAM,IAAI,GAAG,UAAU,CAAC;AACxB,MAAM,GAAG,GAAG,SAAS,CAAC;AACtB,MAAM,IAAI,GAAG,SAAS,CAAC;AAEvB,MAAM,UAAU,IAAI,CAAC,KAAa,EAAE,MAAe;IACjD,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,MAAM,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,IAAI,KAAK,IAAI,KAAK,GAAG,MAAM,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,KAAa,EAAE,MAAe;IACjD,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,MAAM,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,KAAK,IAAI,KAAK,GAAG,MAAM,EAAE,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,KAAa,EAAE,MAAe;IACjD,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,MAAM,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,IAAI,KAAK,IAAI,KAAK,GAAG,MAAM,EAAE,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,KAAa,EAAE,MAAe;IACjD,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,MAAM,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,KAAK,IAAI,KAAK,GAAG,MAAM,EAAE,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,OAAe;IAClC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,KAAK,IAAI,OAAO,EAAE,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,KAAa;IACnC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,KAAK,GAAG,KAAK,IAAI,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,OAAe;IACjC,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,OAAO,GAAG,KAAK,EAAE,CAAC,CAAC;AAC5C,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soleri/cli",
3
- "version": "9.7.2",
3
+ "version": "9.9.0",
4
4
  "description": "Developer CLI for creating and managing Soleri AI agents.",
5
5
  "keywords": [
6
6
  "agent",
@@ -0,0 +1,208 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+
3
+ /**
4
+ * Mock @clack/prompts — every prompt function the wizard uses.
5
+ */
6
+ vi.mock('@clack/prompts', () => ({
7
+ confirm: vi.fn(),
8
+ select: vi.fn(),
9
+ text: vi.fn(),
10
+ intro: vi.fn(),
11
+ note: vi.fn(),
12
+ isCancel: vi.fn().mockReturnValue(false),
13
+ }));
14
+
15
+ /**
16
+ * Mock the git utility so we control gh availability.
17
+ */
18
+ vi.mock('../utils/git.js', () => ({
19
+ isGhInstalled: vi.fn().mockReturnValue(true),
20
+ }));
21
+
22
+ import * as p from '@clack/prompts';
23
+ import { isGhInstalled } from '../utils/git.js';
24
+ import { runCreateWizard } from '../prompts/create-wizard.js';
25
+ import type { CreateWizardResult, WizardGitConfig } from '../prompts/create-wizard.js';
26
+
27
+ const mockText = p.text as unknown as ReturnType<typeof vi.fn>;
28
+ const mockSelect = p.select as unknown as ReturnType<typeof vi.fn>;
29
+ const mockConfirm = p.confirm as unknown as ReturnType<typeof vi.fn>;
30
+ const mockIsCancel = p.isCancel as unknown as ReturnType<typeof vi.fn>;
31
+ const mockGhInstalled = isGhInstalled as unknown as ReturnType<typeof vi.fn>;
32
+
33
+ /**
34
+ * Helper: set up the standard wizard prompts that precede git questions.
35
+ * Returns after the "Create this agent?" confirm (step 4).
36
+ *
37
+ * Call order:
38
+ * 1. text — agent name
39
+ * 2. select — persona choice
40
+ * 3. note — summary (no return value needed)
41
+ * 4. confirm — create confirmation
42
+ */
43
+ function mockBaseWizard() {
44
+ mockText.mockResolvedValueOnce('TestAgent'); // name
45
+ mockSelect.mockResolvedValueOnce('default'); // persona
46
+ mockConfirm.mockResolvedValueOnce(true); // create confirm
47
+ }
48
+
49
+ describe('create-wizard git prompts', () => {
50
+ beforeEach(() => {
51
+ vi.clearAllMocks();
52
+ mockIsCancel.mockReturnValue(false);
53
+ mockGhInstalled.mockReturnValue(true);
54
+ });
55
+
56
+ // ── 1. Git init defaults to true ──────────────────────────────
57
+ it('should default git init to true when user accepts all defaults', async () => {
58
+ mockBaseWizard();
59
+ mockConfirm.mockResolvedValueOnce(true); // git init = yes
60
+ mockConfirm.mockResolvedValueOnce(false); // push to remote = no
61
+
62
+ const result = (await runCreateWizard()) as CreateWizardResult;
63
+
64
+ expect(result).not.toBeNull();
65
+ expect(result.git.init).toBe(true);
66
+ expect(result.git.remote).toBeUndefined();
67
+ });
68
+
69
+ // ── 2. Git init can be declined ───────────────────────────────
70
+ it('should set git.init to false when user declines', async () => {
71
+ mockBaseWizard();
72
+ mockConfirm.mockResolvedValueOnce(false); // git init = no
73
+
74
+ const result = (await runCreateWizard()) as CreateWizardResult;
75
+
76
+ expect(result).not.toBeNull();
77
+ expect(result.git.init).toBe(false);
78
+ expect(result.git.remote).toBeUndefined();
79
+ // No push prompt should have been called — only 2 confirms total
80
+ // (create + git init)
81
+ expect(mockConfirm).toHaveBeenCalledTimes(2);
82
+ });
83
+
84
+ // ── 3. Remote prompts only when init=true, no push ────────────
85
+ it('should leave remote undefined when init=true but push=false', async () => {
86
+ mockBaseWizard();
87
+ mockConfirm.mockResolvedValueOnce(true); // git init
88
+ mockConfirm.mockResolvedValueOnce(false); // push to remote = no
89
+
90
+ const result = (await runCreateWizard()) as CreateWizardResult;
91
+
92
+ expect(result).not.toBeNull();
93
+ expect(result.git.init).toBe(true);
94
+ expect(result.git.remote).toBeUndefined();
95
+ });
96
+
97
+ // ── 4. gh path: GitHub repo creation ──────────────────────────
98
+ it('should configure gh remote when user selects gh path', async () => {
99
+ mockBaseWizard();
100
+ mockConfirm.mockResolvedValueOnce(true); // git init
101
+ mockConfirm.mockResolvedValueOnce(true); // push to remote
102
+ mockSelect.mockResolvedValueOnce('gh'); // remote choice
103
+ mockSelect.mockResolvedValueOnce('public'); // visibility
104
+
105
+ const result = (await runCreateWizard()) as CreateWizardResult;
106
+
107
+ expect(result).not.toBeNull();
108
+ expect(result.git.remote).toEqual({
109
+ type: 'gh',
110
+ visibility: 'public',
111
+ });
112
+ });
113
+
114
+ // ── 5. gh path: private by default ────────────────────────────
115
+ it('should default visibility to private when selecting gh', async () => {
116
+ mockBaseWizard();
117
+ mockConfirm.mockResolvedValueOnce(true); // git init
118
+ mockConfirm.mockResolvedValueOnce(true); // push to remote
119
+ mockSelect.mockResolvedValueOnce('gh'); // remote choice
120
+ mockSelect.mockResolvedValueOnce('private'); // visibility = private
121
+
122
+ const result = (await runCreateWizard()) as CreateWizardResult;
123
+
124
+ expect(result).not.toBeNull();
125
+ expect(result.git.remote!.type).toBe('gh');
126
+ expect(result.git.remote!.visibility).toBe('private');
127
+ });
128
+
129
+ // ── 6. Manual path: URL input ─────────────────────────────────
130
+ it('should configure manual remote with URL when user selects manual', async () => {
131
+ mockBaseWizard();
132
+ mockConfirm.mockResolvedValueOnce(true); // git init
133
+ mockConfirm.mockResolvedValueOnce(true); // push to remote
134
+ mockSelect.mockResolvedValueOnce('manual'); // remote choice
135
+ mockText.mockResolvedValueOnce('https://github.com/test/repo.git'); // URL
136
+
137
+ const result = (await runCreateWizard()) as CreateWizardResult;
138
+
139
+ expect(result).not.toBeNull();
140
+ expect(result.git.remote).toEqual({
141
+ type: 'manual',
142
+ url: 'https://github.com/test/repo.git',
143
+ });
144
+ });
145
+
146
+ // ── 7. Manual path forced when gh not available ───────────────
147
+ it('should skip gh/manual select and go straight to URL when gh is not installed', async () => {
148
+ mockGhInstalled.mockReturnValue(false);
149
+
150
+ mockBaseWizard();
151
+ mockConfirm.mockResolvedValueOnce(true); // git init
152
+ mockConfirm.mockResolvedValueOnce(true); // push to remote
153
+ // No select for gh/manual — goes straight to text for URL
154
+ mockText.mockResolvedValueOnce('https://gitlab.com/test/repo.git');
155
+
156
+ const result = (await runCreateWizard()) as CreateWizardResult;
157
+
158
+ expect(result).not.toBeNull();
159
+ expect(result.git.remote).toEqual({
160
+ type: 'manual',
161
+ url: 'https://gitlab.com/test/repo.git',
162
+ });
163
+ // select should only be called once (persona), not twice
164
+ expect(mockSelect).toHaveBeenCalledTimes(1);
165
+ });
166
+
167
+ // ── 8. Cancellation at git init prompt ────────────────────────
168
+ it('should return null when user cancels at git init prompt', async () => {
169
+ mockBaseWizard();
170
+ // The third confirm call (git init) returns a cancel symbol
171
+ const cancelSymbol = Symbol('cancel');
172
+ mockConfirm.mockResolvedValueOnce(cancelSymbol);
173
+ mockIsCancel.mockImplementation((val) => val === cancelSymbol);
174
+
175
+ const result = await runCreateWizard();
176
+
177
+ expect(result).toBeNull();
178
+ });
179
+
180
+ // ── 9. Cancellation at push prompt ────────────────────────────
181
+ it('should return null when user cancels at push prompt', async () => {
182
+ mockBaseWizard();
183
+ mockConfirm.mockResolvedValueOnce(true); // git init = yes
184
+
185
+ const cancelSymbol = Symbol('cancel');
186
+ mockConfirm.mockResolvedValueOnce(cancelSymbol); // push = cancel
187
+ mockIsCancel.mockImplementation((val) => val === cancelSymbol);
188
+
189
+ const result = await runCreateWizard();
190
+
191
+ expect(result).toBeNull();
192
+ });
193
+
194
+ // ── 10. Cancellation at remote choice ─────────────────────────
195
+ it('should return null when user cancels at remote choice prompt', async () => {
196
+ mockBaseWizard();
197
+ mockConfirm.mockResolvedValueOnce(true); // git init
198
+ mockConfirm.mockResolvedValueOnce(true); // push to remote
199
+
200
+ const cancelSymbol = Symbol('cancel');
201
+ mockSelect.mockResolvedValueOnce(cancelSymbol); // remote choice = cancel
202
+ mockIsCancel.mockImplementation((val) => val === cancelSymbol);
203
+
204
+ const result = await runCreateWizard();
205
+
206
+ expect(result).toBeNull();
207
+ });
208
+ });