@inspecto-dev/cli 0.3.0-alpha.1 → 0.3.1
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/.turbo/turbo-build.log +20 -19
- package/.turbo/turbo-test.log +92 -0
- package/CHANGELOG.md +11 -3
- package/dist/bin.js +4 -2
- package/dist/{chunk-FZS2TLXQ.js → chunk-PSYZB5GI.js} +12 -3
- package/dist/index.js +1 -1
- package/package.json +2 -2
- package/src/commands/init.ts +5 -1
- package/src/commands/integration-install.ts +3 -1
- package/src/commands/onboard.ts +17 -1
- package/src/onboarding/session.ts +13 -4
- package/tests/apply.test.ts +6 -1
- package/tests/install-wrapper.test.ts +1 -4
- package/tests/onboard.test.ts +98 -0
- package/tests/runner-script.test.ts +72 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
>
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
DTS
|
|
18
|
-
DTS
|
|
19
|
-
DTS dist/
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
> @inspecto-dev/cli@0.3.1 build /Users/bytedance/Works/hugo.felix/inspecto/packages/cli
|
|
4
|
+
> tsup
|
|
5
|
+
|
|
6
|
+
[34mCLI[39m Building entry: src/bin.ts, src/index.ts
|
|
7
|
+
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
8
|
+
[34mCLI[39m tsup v8.5.1
|
|
9
|
+
[34mCLI[39m Using tsup config: /Users/bytedance/Works/hugo.felix/inspecto/packages/cli/tsup.config.ts
|
|
10
|
+
[34mCLI[39m Target: node18
|
|
11
|
+
[34mCLI[39m Cleaning output folder
|
|
12
|
+
[34mESM[39m Build start
|
|
13
|
+
[32mESM[39m [1mdist/bin.js [22m[32m20.39 KB[39m
|
|
14
|
+
[32mESM[39m [1mdist/chunk-PSYZB5GI.js [22m[32m103.68 KB[39m
|
|
15
|
+
[32mESM[39m [1mdist/index.js [22m[32m319.00 B[39m
|
|
16
|
+
[32mESM[39m ⚡️ Build success in 162ms
|
|
17
|
+
DTS Build start
|
|
18
|
+
DTS ⚡️ Build success in 1954ms
|
|
19
|
+
DTS dist/bin.d.ts 185.00 B
|
|
20
|
+
DTS dist/index.d.ts 7.79 KB
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
|
|
2
|
+
> @inspecto-dev/cli@0.3.0 test /Users/bytedance/Works/hugo.felix/inspecto/packages/cli
|
|
3
|
+
> vitest run --passWithNoTests
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
RUN v1.6.1 /Users/bytedance/Works/hugo.felix/inspecto/packages/cli
|
|
7
|
+
|
|
8
|
+
✓ tests/instructions.test.ts (2 tests) 5ms
|
|
9
|
+
✓ tests/ide.test.ts (6 tests) 3ms
|
|
10
|
+
✓ tests/detect.test.ts (1 test) 3ms
|
|
11
|
+
✓ tests/doctor.test.ts (4 tests) 6ms
|
|
12
|
+
✓ tests/logger.test.ts (5 tests) 9ms
|
|
13
|
+
✓ tests/onboard.test.ts (5 tests) 5ms
|
|
14
|
+
- Installing devDependencies via: pnpm add -D @inspecto-dev/plugin @inspecto-dev/core
|
|
15
|
+
stdout | tests/apply.test.ts > apply onboarding flow > applies the supported setup path and returns structured mutations and post-install state
|
|
16
|
+
✔ Installed @inspecto-dev/plugin and @inspecto-dev/core as devDependencies
|
|
17
|
+
✔ Created .inspecto/settings.local.json
|
|
18
|
+
✔ Created .inspecto/prompts.local.json
|
|
19
|
+
|
|
20
|
+
✓ tests/apply.test.ts (9 tests) 16ms
|
|
21
|
+
[32m✔[39m Dependencies installed successfully
|
|
22
|
+
- Installing devDependencies via: pnpm add -D @inspecto-dev/plugin @inspecto-dev/core
|
|
23
|
+
[32m✔[39m Dependencies installed successfully
|
|
24
|
+
- Installing devDependencies via: pnpm add -D @inspecto-dev/plugin @inspecto-dev/core
|
|
25
|
+
[32m✔[39m Dependencies installed successfully
|
|
26
|
+
✓ tests/framework.test.ts (5 tests) 3ms
|
|
27
|
+
✓ tests/build-tool.test.ts (2 tests) 59ms
|
|
28
|
+
✓ tests/workspace-build-tool.test.ts (1 test) 73ms
|
|
29
|
+
✓ tests/init.test.ts (5 tests) 9ms
|
|
30
|
+
stdout | tests/init.test.ts > init in monorepo roots > routes installation and config generation into the selected app instead of the monorepo root
|
|
31
|
+
|
|
32
|
+
✦ Inspecto Setup
|
|
33
|
+
|
|
34
|
+
⚠ Monorepo root detected with multiple candidate apps.
|
|
35
|
+
ℹ Continuing initialization in apps/web
|
|
36
|
+
✔ Detected package manager: pnpm
|
|
37
|
+
✔ Detected framework: react
|
|
38
|
+
✔ Detected: Vite (apps/web/vite.config.ts)
|
|
39
|
+
✔ Selected IDE: vscode
|
|
40
|
+
⚠ No supported AI tools detected
|
|
41
|
+
→ Inspecto works best with Claude Code, Trae CLI, or GitHub Copilot
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
⚡ Ready! Inspecto is set up.
|
|
45
|
+
|
|
46
|
+
ℹ Next:
|
|
47
|
+
→ 1. Start or restart your dev server.
|
|
48
|
+
→ 2. Open your app in the browser.
|
|
49
|
+
→ 3. Hold Alt + Click any element to inspect.
|
|
50
|
+
|
|
51
|
+
stdout | tests/init.test.ts > init in monorepo roots > prints detailed Next.js manual instructions when Next.js is detected
|
|
52
|
+
|
|
53
|
+
✦ Inspecto Setup
|
|
54
|
+
|
|
55
|
+
✔ Detected package manager: pnpm
|
|
56
|
+
✔ Detected framework: react
|
|
57
|
+
⚠ Detected Next.js — automatic plugin injection is not supported in current version
|
|
58
|
+
→ You can still manually configure it by modifying your configuration file
|
|
59
|
+
✔ Selected IDE: vscode
|
|
60
|
+
⚠ No supported AI tools detected
|
|
61
|
+
→ Inspecto works best with Claude Code, Trae CLI, or GitHub Copilot
|
|
62
|
+
|
|
63
|
+
⚠ Dry run complete. No files were modified.
|
|
64
|
+
|
|
65
|
+
stdout | tests/init.test.ts > init in monorepo roots > preserves detected preferred mode for an explicit provider override
|
|
66
|
+
|
|
67
|
+
✦ Inspecto Setup
|
|
68
|
+
|
|
69
|
+
✔ Detected package manager: pnpm
|
|
70
|
+
✔ Detected framework: react
|
|
71
|
+
✔ Detected: Vite (vite.config.ts)
|
|
72
|
+
✔ Selected IDE: vscode
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
⚡ Ready! Inspecto is set up.
|
|
76
|
+
|
|
77
|
+
ℹ Next:
|
|
78
|
+
→ 1. Start or restart your dev server.
|
|
79
|
+
→ 2. Open your app in the browser.
|
|
80
|
+
→ 3. Hold Alt + Click any element to inspect.
|
|
81
|
+
|
|
82
|
+
✓ tests/ast-injector.test.ts (1 test) 3ms
|
|
83
|
+
✓ tests/integration-install.test.ts (12 tests) 824ms
|
|
84
|
+
✓ tests/plan.test.ts (15 tests) 718ms
|
|
85
|
+
✓ tests/install-wrapper.test.ts (1 test) 1276ms
|
|
86
|
+
✓ tests/runner-script.test.ts (3 tests) 2378ms
|
|
87
|
+
|
|
88
|
+
Test Files 16 passed (16)
|
|
89
|
+
Tests 77 passed (77)
|
|
90
|
+
Start at 12:27:25
|
|
91
|
+
Duration 3.02s (transform 2.20s, setup 0ms, collect 4.55s, tests 5.39s, environment 3ms, prepare 2.95s)
|
|
92
|
+
|
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
# @inspecto-dev/cli
|
|
2
2
|
|
|
3
|
-
## 0.3.
|
|
3
|
+
## 0.3.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- fix: polish onboarding and architecture visualization
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @inspecto-dev/types@0.3.1
|
|
10
|
+
|
|
11
|
+
## 0.3.0
|
|
4
12
|
|
|
5
13
|
### Minor Changes
|
|
6
14
|
|
|
7
|
-
-
|
|
15
|
+
- First stable release for Inspecto's browser-first workflow.
|
|
8
16
|
- unify onboarding around assistant-first setup and the single-entry `inspecto onboard --json` contract
|
|
9
17
|
- stabilize the browser UX across `Inspect`, `Annotate`, and `Alt + Click` quick jump
|
|
10
18
|
- tighten prompt and settings schema boundaries and keep evidence toggles built-in
|
|
@@ -14,7 +22,7 @@
|
|
|
14
22
|
### Patch Changes
|
|
15
23
|
|
|
16
24
|
- Updated dependencies
|
|
17
|
-
- @inspecto-dev/types@0.3.0
|
|
25
|
+
- @inspecto-dev/types@0.3.0
|
|
18
26
|
|
|
19
27
|
## 0.2.0-alpha.6
|
|
20
28
|
|
package/dist/bin.js
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
reportCommandError,
|
|
11
11
|
teardown,
|
|
12
12
|
writeFile
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-PSYZB5GI.js";
|
|
14
14
|
|
|
15
15
|
// src/bin.ts
|
|
16
16
|
import { cac } from "cac";
|
|
@@ -352,7 +352,9 @@ async function downloadAsset(source) {
|
|
|
352
352
|
response = await fetch(source);
|
|
353
353
|
} catch (error) {
|
|
354
354
|
const reason = error instanceof Error ? error.message : String(error);
|
|
355
|
-
throw new Error(`Failed to download ${source}: ${reason}
|
|
355
|
+
throw new Error(`Failed to download ${source}: ${reason}`, {
|
|
356
|
+
cause: error
|
|
357
|
+
});
|
|
356
358
|
}
|
|
357
359
|
if (!response.ok) {
|
|
358
360
|
throw new Error(`Failed to download ${source}: ${response.status} ${response.statusText}`);
|
|
@@ -2373,7 +2373,9 @@ function matchesAnyPackage(detection, packages) {
|
|
|
2373
2373
|
}
|
|
2374
2374
|
async function detectFrameworkSupportByPackage(repoRoot, buildTools) {
|
|
2375
2375
|
const packagePaths = Array.from(
|
|
2376
|
-
new Set(
|
|
2376
|
+
new Set(
|
|
2377
|
+
buildTools.map((buildTool) => buildTool.packagePath).filter((value) => !!value)
|
|
2378
|
+
)
|
|
2377
2379
|
);
|
|
2378
2380
|
const supportByPackage = {};
|
|
2379
2381
|
await Promise.all(
|
|
@@ -2800,7 +2802,8 @@ function buildConfirmation(plan2, summary, session, options) {
|
|
|
2800
2802
|
const reasons = [];
|
|
2801
2803
|
if (session.targetWasHeuristic) reasons.push("a monorepo target was preselected");
|
|
2802
2804
|
if (summary.manualFollowUp.length > 0) reasons.push("manual follow-up will remain after setup");
|
|
2803
|
-
if (options.noExtension || options.skipInstall)
|
|
2805
|
+
if (options.noExtension || options.skipInstall)
|
|
2806
|
+
reasons.push("non-core setup steps are being skipped");
|
|
2804
2807
|
if (session.supportedIdeCount > 1 || session.supportedProviderCount > 1) {
|
|
2805
2808
|
reasons.push("multiple IDE or provider choices are still relevant");
|
|
2806
2809
|
}
|
|
@@ -2837,7 +2840,9 @@ function buildPreApplyResult(status, session) {
|
|
|
2837
2840
|
function buildExecutionResult(session, applyResult) {
|
|
2838
2841
|
return {
|
|
2839
2842
|
changedFiles: Array.from(
|
|
2840
|
-
new Set(
|
|
2843
|
+
new Set(
|
|
2844
|
+
applyResult.mutations.map((item) => item.path).filter((value) => !!value)
|
|
2845
|
+
)
|
|
2841
2846
|
),
|
|
2842
2847
|
installedDependencies: applyResult.mutations.map((item) => item.name).filter((value) => !!value),
|
|
2843
2848
|
selectedProviderDefault: session.providerDefault,
|
|
@@ -2999,6 +3004,10 @@ function printOnboardResult(result) {
|
|
|
2999
3004
|
if (result.confirmation.required && result.confirmation.question) {
|
|
3000
3005
|
log.warn(result.confirmation.question);
|
|
3001
3006
|
}
|
|
3007
|
+
const extensionReady = !result.ideExtension?.required || result.ideExtension.installed && !result.ideExtension.manualRequired;
|
|
3008
|
+
if (extensionReady && (result.status === "success" || result.status === "partial_success") && result.verification?.message) {
|
|
3009
|
+
log.info(result.verification.message);
|
|
3010
|
+
}
|
|
3002
3011
|
}
|
|
3003
3012
|
async function onboard(options = {}) {
|
|
3004
3013
|
const root = process.cwd();
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inspecto-dev/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "CLI tools for Inspecto onboarding and lifecycle management",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"inspecto",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"ora": "^9.3.0",
|
|
21
21
|
"picocolors": "^1.0.0",
|
|
22
22
|
"prompts": "^2.4.2",
|
|
23
|
-
"@inspecto-dev/types": "0.3.
|
|
23
|
+
"@inspecto-dev/types": "0.3.1"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@types/node": "^20.0.0",
|
package/src/commands/init.ts
CHANGED
|
@@ -368,7 +368,11 @@ async function detectFrameworkSupportByPackage(
|
|
|
368
368
|
buildTools: BuildToolDetection[],
|
|
369
369
|
): Promise<Record<string, string[]>> {
|
|
370
370
|
const packagePaths = Array.from(
|
|
371
|
-
new Set(
|
|
371
|
+
new Set(
|
|
372
|
+
buildTools
|
|
373
|
+
.map(buildTool => buildTool.packagePath)
|
|
374
|
+
.filter((value): value is string => !!value),
|
|
375
|
+
),
|
|
372
376
|
)
|
|
373
377
|
const supportByPackage: Record<string, string[]> = {}
|
|
374
378
|
|
|
@@ -441,7 +441,9 @@ async function downloadAsset(source: string): Promise<string> {
|
|
|
441
441
|
response = await fetch(source)
|
|
442
442
|
} catch (error) {
|
|
443
443
|
const reason = error instanceof Error ? error.message : String(error)
|
|
444
|
-
throw new Error(`Failed to download ${source}: ${reason}
|
|
444
|
+
throw new Error(`Failed to download ${source}: ${reason}`, {
|
|
445
|
+
cause: error,
|
|
446
|
+
})
|
|
445
447
|
}
|
|
446
448
|
|
|
447
449
|
if (!response.ok) {
|
package/src/commands/onboard.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
resolveOnboardingSession,
|
|
3
|
+
applyResolvedOnboardingSession,
|
|
4
|
+
buildDeferredOnboardResult,
|
|
5
|
+
} from '../onboarding/session.js'
|
|
2
6
|
import { log } from '../utils/logger.js'
|
|
3
7
|
import { writeCommandOutput } from '../utils/output.js'
|
|
4
8
|
import type { OnboardCommandResult } from '../types.js'
|
|
@@ -27,6 +31,18 @@ function printOnboardResult(result: OnboardCommandResult): void {
|
|
|
27
31
|
if (result.confirmation.required && result.confirmation.question) {
|
|
28
32
|
log.warn(result.confirmation.question)
|
|
29
33
|
}
|
|
34
|
+
|
|
35
|
+
const extensionReady =
|
|
36
|
+
!result.ideExtension?.required ||
|
|
37
|
+
(result.ideExtension.installed && !result.ideExtension.manualRequired)
|
|
38
|
+
|
|
39
|
+
if (
|
|
40
|
+
extensionReady &&
|
|
41
|
+
(result.status === 'success' || result.status === 'partial_success') &&
|
|
42
|
+
result.verification?.message
|
|
43
|
+
) {
|
|
44
|
+
log.info(result.verification.message)
|
|
45
|
+
}
|
|
30
46
|
}
|
|
31
47
|
|
|
32
48
|
export async function onboard(options: OnboardCommandOptions = {}): Promise<OnboardCommandResult> {
|
|
@@ -197,7 +197,8 @@ function buildConfirmation(
|
|
|
197
197
|
const reasons: string[] = []
|
|
198
198
|
if (session.targetWasHeuristic) reasons.push('a monorepo target was preselected')
|
|
199
199
|
if (summary.manualFollowUp.length > 0) reasons.push('manual follow-up will remain after setup')
|
|
200
|
-
if (options.noExtension || options.skipInstall)
|
|
200
|
+
if (options.noExtension || options.skipInstall)
|
|
201
|
+
reasons.push('non-core setup steps are being skipped')
|
|
201
202
|
if (session.supportedIdeCount > 1 || session.supportedProviderCount > 1) {
|
|
202
203
|
reasons.push('multiple IDE or provider choices are still relevant')
|
|
203
204
|
}
|
|
@@ -219,7 +220,9 @@ function buildPreApplyResult(
|
|
|
219
220
|
session: ResolvedOnboardingSession,
|
|
220
221
|
): OnboardCommandResult {
|
|
221
222
|
const diagnostics: OnboardingDiagnostics | undefined =
|
|
222
|
-
session.summary.risks.length > 0 ||
|
|
223
|
+
session.summary.risks.length > 0 ||
|
|
224
|
+
session.summary.manualFollowUp.length > 0 ||
|
|
225
|
+
session.plan.blockers.length > 0
|
|
223
226
|
? {
|
|
224
227
|
warnings: session.summary.risks,
|
|
225
228
|
errors: session.plan.blockers.map(item => item.message),
|
|
@@ -248,7 +251,9 @@ function buildExecutionResult(
|
|
|
248
251
|
): OnboardingExecutionResult {
|
|
249
252
|
return {
|
|
250
253
|
changedFiles: Array.from(
|
|
251
|
-
new Set(
|
|
254
|
+
new Set(
|
|
255
|
+
applyResult.mutations.map(item => item.path).filter((value): value is string => !!value),
|
|
256
|
+
),
|
|
252
257
|
),
|
|
253
258
|
installedDependencies: applyResult.mutations
|
|
254
259
|
.map(item => item.name)
|
|
@@ -276,7 +281,11 @@ function buildExecutionDiagnostics(
|
|
|
276
281
|
warnings.push('IDE extension installation still needs manual completion.')
|
|
277
282
|
}
|
|
278
283
|
|
|
279
|
-
if (
|
|
284
|
+
if (
|
|
285
|
+
warnings.length === 0 &&
|
|
286
|
+
errors.length === 0 &&
|
|
287
|
+
applyResult.postInstall.nextSteps.length === 0
|
|
288
|
+
) {
|
|
280
289
|
return undefined
|
|
281
290
|
}
|
|
282
291
|
|
package/tests/apply.test.ts
CHANGED
|
@@ -121,7 +121,12 @@ describe('apply onboarding flow', () => {
|
|
|
121
121
|
'pnpm add -D @inspecto-dev/plugin @inspecto-dev/core',
|
|
122
122
|
'/repo',
|
|
123
123
|
)
|
|
124
|
-
expect(astInjectorUtils.injectPlugin).toHaveBeenCalledWith(
|
|
124
|
+
expect(astInjectorUtils.injectPlugin).toHaveBeenCalledWith(
|
|
125
|
+
'/repo',
|
|
126
|
+
supportedBuild,
|
|
127
|
+
false,
|
|
128
|
+
false,
|
|
129
|
+
)
|
|
125
130
|
expect(fsUtils.writeJSON).toHaveBeenCalledWith('/repo/.inspecto/settings.local.json', {
|
|
126
131
|
ide: 'vscode',
|
|
127
132
|
'provider.default': 'codex.extension',
|
|
@@ -54,10 +54,7 @@ describe('assistant integration bootstrap wrapper', () => {
|
|
|
54
54
|
)
|
|
55
55
|
await fs.chmod(path.join(fakeBin, 'curl'), 0o755)
|
|
56
56
|
|
|
57
|
-
const scriptPath = path.resolve(
|
|
58
|
-
__dirname,
|
|
59
|
-
'../../../assistant-integrations/scripts/install.sh',
|
|
60
|
-
)
|
|
57
|
+
const scriptPath = path.resolve(__dirname, '../../../assistant-integrations/scripts/install.sh')
|
|
61
58
|
|
|
62
59
|
await execFileAsync('bash', [scriptPath, 'copilot', '--force'], {
|
|
63
60
|
cwd: tempRoot,
|
package/tests/onboard.test.ts
CHANGED
|
@@ -255,4 +255,102 @@ describe('onboard command', () => {
|
|
|
255
255
|
expect(applyResolvedOnboardingSession).not.toHaveBeenCalled()
|
|
256
256
|
expect(result.ideExtension?.required).toBe(true)
|
|
257
257
|
})
|
|
258
|
+
|
|
259
|
+
it('prints verification guidance in text mode after successful onboarding', async () => {
|
|
260
|
+
const session: ResolvedOnboardingSession = {
|
|
261
|
+
status: 'success',
|
|
262
|
+
target: {
|
|
263
|
+
status: 'resolved',
|
|
264
|
+
selected: {
|
|
265
|
+
packagePath: '',
|
|
266
|
+
configPath: 'vite.config.ts',
|
|
267
|
+
buildTool: 'vite',
|
|
268
|
+
frameworks: ['react'],
|
|
269
|
+
automaticInjection: true,
|
|
270
|
+
},
|
|
271
|
+
candidates: [
|
|
272
|
+
{
|
|
273
|
+
packagePath: '',
|
|
274
|
+
configPath: 'vite.config.ts',
|
|
275
|
+
buildTool: 'vite',
|
|
276
|
+
frameworks: ['react'],
|
|
277
|
+
automaticInjection: true,
|
|
278
|
+
},
|
|
279
|
+
],
|
|
280
|
+
reason: 'Only one supported target was detected.',
|
|
281
|
+
},
|
|
282
|
+
summary: {
|
|
283
|
+
headline: 'Inspecto is ready to onboard /repo.',
|
|
284
|
+
changes: ['Install dependencies.'],
|
|
285
|
+
risks: [],
|
|
286
|
+
manualFollowUp: [],
|
|
287
|
+
},
|
|
288
|
+
confirmation: { required: false },
|
|
289
|
+
verification: {
|
|
290
|
+
available: true,
|
|
291
|
+
devCommand: 'pnpm dev',
|
|
292
|
+
message: 'Start the local dev server with `pnpm dev` to verify Inspecto in the browser.',
|
|
293
|
+
},
|
|
294
|
+
context: {
|
|
295
|
+
root: '/repo',
|
|
296
|
+
packageManager: 'pnpm',
|
|
297
|
+
buildTools: { supported: [], unsupported: [] },
|
|
298
|
+
frameworks: { supported: ['react'], unsupported: [] },
|
|
299
|
+
ides: [{ ide: 'vscode', supported: true }],
|
|
300
|
+
providers: [{ id: 'codex', label: 'Codex CLI', supported: true, preferredMode: 'cli' }],
|
|
301
|
+
},
|
|
302
|
+
plan: {
|
|
303
|
+
status: 'ok',
|
|
304
|
+
warnings: [],
|
|
305
|
+
blockers: [],
|
|
306
|
+
strategy: 'supported',
|
|
307
|
+
actions: [],
|
|
308
|
+
defaults: {
|
|
309
|
+
provider: 'codex',
|
|
310
|
+
ide: 'vscode',
|
|
311
|
+
shared: false,
|
|
312
|
+
extension: true,
|
|
313
|
+
},
|
|
314
|
+
},
|
|
315
|
+
projectRoot: '/repo',
|
|
316
|
+
selectedIDE: { ide: 'vscode', supported: true },
|
|
317
|
+
providerDefault: 'codex.cli',
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
const applied: OnboardCommandResult = {
|
|
321
|
+
status: 'success',
|
|
322
|
+
target: session.target,
|
|
323
|
+
summary: session.summary,
|
|
324
|
+
confirmation: session.confirmation,
|
|
325
|
+
ideExtension: {
|
|
326
|
+
required: true,
|
|
327
|
+
installed: true,
|
|
328
|
+
manualRequired: false,
|
|
329
|
+
installCommand: 'code --install-extension inspecto.inspecto',
|
|
330
|
+
marketplaceUrl: 'https://marketplace.visualstudio.com/items?itemName=inspecto.inspecto',
|
|
331
|
+
openVsxUrl: 'https://open-vsx.org/extension/inspecto/inspecto',
|
|
332
|
+
},
|
|
333
|
+
verification: session.verification,
|
|
334
|
+
result: {
|
|
335
|
+
changedFiles: ['vite.config.ts'],
|
|
336
|
+
installedDependencies: ['@inspecto-dev/plugin', '@inspecto-dev/core'],
|
|
337
|
+
selectedProviderDefault: 'codex.cli',
|
|
338
|
+
selectedIDE: 'vscode',
|
|
339
|
+
mutations: [],
|
|
340
|
+
},
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
vi.mocked(resolveOnboardingSession).mockResolvedValue(session)
|
|
344
|
+
vi.mocked(applyResolvedOnboardingSession).mockResolvedValue(applied)
|
|
345
|
+
|
|
346
|
+
const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
|
|
347
|
+
const result = await onboard({ json: false })
|
|
348
|
+
|
|
349
|
+
expect(result.status).toBe('success')
|
|
350
|
+
expect(
|
|
351
|
+
consoleSpy.mock.calls.some(call =>
|
|
352
|
+
String(call[0]).includes('Start the local dev server with `pnpm dev`'),
|
|
353
|
+
),
|
|
354
|
+
).toBe(true)
|
|
355
|
+
})
|
|
258
356
|
})
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import fs from 'node:fs/promises'
|
|
2
|
+
import os from 'node:os'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
import { spawnSync } from 'node:child_process'
|
|
5
|
+
import { afterEach, describe, expect, it } from 'vitest'
|
|
6
|
+
|
|
7
|
+
const TEMP_DIRS: string[] = []
|
|
8
|
+
|
|
9
|
+
async function makeTempDir(): Promise<string> {
|
|
10
|
+
const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'inspecto-runner-test-'))
|
|
11
|
+
TEMP_DIRS.push(dir)
|
|
12
|
+
return dir
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async function writeExecutable(filePath: string, content: string): Promise<void> {
|
|
16
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true })
|
|
17
|
+
await fs.writeFile(filePath, content, 'utf8')
|
|
18
|
+
await fs.chmod(filePath, 0o755)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function runRunner(scriptPath: string, cwd: string, pathEnv: string): string {
|
|
22
|
+
const result = spawnSync(scriptPath, ['onboard', '--json'], {
|
|
23
|
+
cwd,
|
|
24
|
+
env: {
|
|
25
|
+
...process.env,
|
|
26
|
+
PATH: pathEnv,
|
|
27
|
+
},
|
|
28
|
+
encoding: 'utf8',
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
expect(result.status).toBe(0)
|
|
32
|
+
return (result.stdout + result.stderr).trim()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
describe('skill runner scripts', () => {
|
|
36
|
+
afterEach(async () => {
|
|
37
|
+
await Promise.all(TEMP_DIRS.splice(0).map(dir => fs.rm(dir, { recursive: true, force: true })))
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it.each([
|
|
41
|
+
'skills/inspecto-onboarding-codex/scripts/run-inspecto.sh',
|
|
42
|
+
'skills/inspecto-onboarding-claude-code/scripts/run-inspecto.sh',
|
|
43
|
+
'skills/inspecto-onboarding-core/scripts/run-inspecto.sh',
|
|
44
|
+
])(
|
|
45
|
+
'prefers an installed inspecto executable before package-manager download paths: %s',
|
|
46
|
+
async scriptRelativePath => {
|
|
47
|
+
const workspaceRoot = path.resolve(__dirname, '../../..')
|
|
48
|
+
const scriptPath = path.join(workspaceRoot, scriptRelativePath)
|
|
49
|
+
const tempDir = await makeTempDir()
|
|
50
|
+
const fakeBin = path.join(tempDir, 'bin')
|
|
51
|
+
|
|
52
|
+
await writeExecutable(
|
|
53
|
+
path.join(fakeBin, 'inspecto'),
|
|
54
|
+
`#!/usr/bin/env bash
|
|
55
|
+
echo "installed-inspecto:$*"
|
|
56
|
+
`,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
await writeExecutable(
|
|
60
|
+
path.join(fakeBin, 'pnpm'),
|
|
61
|
+
`#!/usr/bin/env bash
|
|
62
|
+
echo "pnpm-should-not-run:$*" >&2
|
|
63
|
+
exit 99
|
|
64
|
+
`,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
const output = runRunner(scriptPath, tempDir, `${fakeBin}:${process.env.PATH ?? ''}`)
|
|
68
|
+
expect(output).toContain('installed-inspecto:onboard --json')
|
|
69
|
+
expect(output).not.toContain('pnpm-should-not-run')
|
|
70
|
+
},
|
|
71
|
+
)
|
|
72
|
+
})
|