@inspecto-dev/cli 0.3.1 → 0.3.3
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 +7 -7
- package/.turbo/turbo-test.log +5160 -92
- package/CHANGELOG.md +20 -0
- package/README.md +126 -6
- package/dist/bin.js +59 -361
- package/dist/{chunk-PSYZB5GI.js → chunk-LJOKPCPD.js} +1389 -91
- package/dist/index.d.ts +74 -1
- package/dist/index.js +3 -1
- package/package.json +2 -2
- package/src/bin.ts +85 -6
- package/src/commands/integration-automation.ts +485 -0
- package/src/commands/integration-dispatch-mode.ts +92 -0
- package/src/commands/integration-doctor.ts +117 -0
- package/src/commands/integration-host-ide.ts +156 -0
- package/src/commands/integration-install.ts +262 -101
- package/src/commands/onboard.ts +19 -0
- package/src/index.ts +1 -0
- package/src/inject/extension.ts +144 -24
- package/src/integrations/capabilities.ts +131 -0
- package/src/utils/process.ts +3 -0
- package/tests/extension-installer.test.ts +205 -0
- package/tests/install-wrapper.test.ts +45 -4
- package/tests/integration-automation.test.ts +491 -0
- package/tests/integration-dispatch-mode.test.ts +203 -0
- package/tests/integration-doctor.test.ts +165 -0
- package/tests/integration-host-ide.test.ts +172 -0
- package/tests/integration-install.test.ts +282 -20
- package/tests/onboard.test.ts +118 -0
- package/tests/shared-capabilities.test.ts +45 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @inspecto-dev/cli
|
|
2
2
|
|
|
3
|
+
## 0.3.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Stabilize onboarding and browser-to-IDE dispatch flows across CLI and IDE integrations.
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @inspecto-dev/types@0.3.3
|
|
10
|
+
|
|
11
|
+
## 0.3.2
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- - feat: migrate all 7 integrations to Native Agent Skills
|
|
16
|
+
- feat: add automated onboarding experience via URI schemes
|
|
17
|
+
- refactor: use shared capabilities strategy for tool detection
|
|
18
|
+
- docs: synchronize english and chinese documentation
|
|
19
|
+
- fix: update travis and action test configurations
|
|
20
|
+
- Updated dependencies
|
|
21
|
+
- @inspecto-dev/types@0.3.2
|
|
22
|
+
|
|
3
23
|
## 0.3.1
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -7,19 +7,26 @@ The official command-line interface for Inspecto. This tool automates the proces
|
|
|
7
7
|
For most users, the preferred setup path is assistant-first onboarding via the integrations documented in:
|
|
8
8
|
`packages/docs/integrations/onboarding-skills.md`
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Run the install command for your assistant from the target project root:
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
|
-
npx @inspecto-dev/cli integrations install
|
|
13
|
+
npx @inspecto-dev/cli integrations install codex --host-ide vscode
|
|
14
|
+
npx @inspecto-dev/cli integrations install claude-code --scope project --host-ide vscode
|
|
15
|
+
npx @inspecto-dev/cli integrations install copilot --host-ide vscode
|
|
16
|
+
npx @inspecto-dev/cli integrations install cursor --host-ide cursor
|
|
17
|
+
npx @inspecto-dev/cli integrations install gemini --host-ide vscode
|
|
18
|
+
npx @inspecto-dev/cli integrations install trae --host-ide trae-cn
|
|
19
|
+
npx @inspecto-dev/cli integrations install coco --host-ide trae-cn
|
|
14
20
|
```
|
|
15
21
|
|
|
16
22
|
Supported assistants currently include `codex`, `claude-code`, `copilot`, `cursor`, `gemini`, `trae`, and `coco`.
|
|
17
23
|
|
|
24
|
+
`--host-ide` values: `vscode`, `cursor`, `trae`, `trae-cn`.
|
|
25
|
+
|
|
18
26
|
Inspect available integration targets with:
|
|
19
27
|
|
|
20
28
|
```bash
|
|
21
29
|
npx @inspecto-dev/cli integrations list
|
|
22
|
-
npx @inspecto-dev/cli integrations install codex
|
|
23
30
|
npx @inspecto-dev/cli integrations path <assistant>
|
|
24
31
|
```
|
|
25
32
|
|
|
@@ -93,10 +100,123 @@ Manages assistant integration assets for the current project.
|
|
|
93
100
|
Examples:
|
|
94
101
|
|
|
95
102
|
```bash
|
|
96
|
-
inspecto integrations install codex
|
|
103
|
+
inspecto integrations install codex --host-ide vscode
|
|
97
104
|
inspecto integrations path codex
|
|
98
|
-
inspecto integrations install claude-code --scope project
|
|
99
|
-
inspecto integrations install cursor --
|
|
105
|
+
inspecto integrations install claude-code --scope project --host-ide vscode
|
|
106
|
+
inspecto integrations install cursor --host-ide cursor
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
#### `inspecto integrations doctor`
|
|
110
|
+
|
|
111
|
+
Runs integration preflight checks for a selected assistant without writing files, installing extensions, opening IDE windows, or launching onboarding.
|
|
112
|
+
|
|
113
|
+
Examples:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
inspecto integrations doctor codex --host-ide cursor
|
|
117
|
+
inspecto integrations doctor gemini --host-ide trae-cn --compact
|
|
118
|
+
inspecto integrations doctor codex --host-ide cursor --json
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Use `--compact` when you want a shorter human-readable summary. Use `--json` when the result will be consumed by tooling or CI.
|
|
122
|
+
|
|
123
|
+
Recommended workflow:
|
|
124
|
+
|
|
125
|
+
1. Run `inspecto integrations install <assistant> --host-ide <ide>` from the target project root.
|
|
126
|
+
2. Use `inspecto integrations doctor <assistant> --host-ide <ide> --compact` only when you want to check blockers before install.
|
|
127
|
+
3. Use `--json` instead of `--compact` when the result is consumed by scripts or CI.
|
|
128
|
+
|
|
129
|
+
##### JSON contract
|
|
130
|
+
|
|
131
|
+
`inspecto integrations doctor <assistant> --json` prints a single JSON object with this shape:
|
|
132
|
+
|
|
133
|
+
```json
|
|
134
|
+
{
|
|
135
|
+
"schemaVersion": "1",
|
|
136
|
+
"status": "ok",
|
|
137
|
+
"assistant": "codex",
|
|
138
|
+
"assets": [".agents/skills/inspecto-onboarding-codex/SKILL.md"],
|
|
139
|
+
"message": "Preview complete. Inspecto did not write files or open IDE windows. Review the resolved setup below, then rerun without --preview to apply it.",
|
|
140
|
+
"nextStep": "Run the same command again without --preview to apply the integration and launch onboarding.",
|
|
141
|
+
"automation": {
|
|
142
|
+
"status": "preview",
|
|
143
|
+
"message": "Preview complete. Inspecto did not write files or open IDE windows. Review the resolved setup below, then rerun without --preview to apply it.",
|
|
144
|
+
"nextStep": "Run the same command again without --preview to apply the integration and launch onboarding.",
|
|
145
|
+
"details": {
|
|
146
|
+
"hostIde": {
|
|
147
|
+
"id": "cursor",
|
|
148
|
+
"label": "Cursor",
|
|
149
|
+
"source": "from --host-ide",
|
|
150
|
+
"confidence": "high",
|
|
151
|
+
"candidates": ["cursor"]
|
|
152
|
+
},
|
|
153
|
+
"inspectoExtension": {
|
|
154
|
+
"source": "marketplace",
|
|
155
|
+
"reference": "inspecto.inspecto",
|
|
156
|
+
"binaryAvailable": true,
|
|
157
|
+
"binaryPath": "cursor",
|
|
158
|
+
"status": "preview_ready"
|
|
159
|
+
},
|
|
160
|
+
"runtime": {
|
|
161
|
+
"assistant": "Codex",
|
|
162
|
+
"ready": true,
|
|
163
|
+
"mode": "cli"
|
|
164
|
+
},
|
|
165
|
+
"workspace": {
|
|
166
|
+
"path": "/repo",
|
|
167
|
+
"attempted": true
|
|
168
|
+
},
|
|
169
|
+
"onboarding": {
|
|
170
|
+
"uri": "cursor://inspecto.inspecto/send?...",
|
|
171
|
+
"autoSend": true
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Top-level fields:
|
|
179
|
+
|
|
180
|
+
- `schemaVersion`: Contract version for `inspecto integrations doctor --json`. The current documented value is `1`.
|
|
181
|
+
- `status`: `ok` or `blocked`. This is the field most callers should branch on.
|
|
182
|
+
- `assistant`: The requested integration target.
|
|
183
|
+
- `assets`: The integration files that `inspecto integrations install <assistant>` would write.
|
|
184
|
+
- `message`: Human-readable summary of the preflight result.
|
|
185
|
+
- `nextStep`: Present when the flow is blocked or when there is a recommended follow-up action.
|
|
186
|
+
- `automation`: The underlying preflight result from the IDE/runtime automation layer.
|
|
187
|
+
|
|
188
|
+
`automation.status` values:
|
|
189
|
+
|
|
190
|
+
- `preview`: Preflight succeeded. The flow is runnable.
|
|
191
|
+
- `preview_blocked`: Preflight found blocking issues before launch.
|
|
192
|
+
- `blocked`: Host IDE resolution failed before preflight could complete.
|
|
193
|
+
|
|
194
|
+
`automation.details` fields:
|
|
195
|
+
|
|
196
|
+
- `hostIde`: Resolved host IDE, confidence, resolution source, and alternative candidates.
|
|
197
|
+
- `inspectoExtension`: How Inspecto would be installed into the host IDE.
|
|
198
|
+
`source` is `marketplace` or `local_vsix`.
|
|
199
|
+
`status` is one of:
|
|
200
|
+
`preview_ready`, `missing_host_ide_binary`, `missing_local_vsix`.
|
|
201
|
+
- `runtime`: Resolved assistant runtime.
|
|
202
|
+
`mode` is the selected runtime mode such as `extension` or `cli`.
|
|
203
|
+
`ready=false` means the assistant cannot run yet in the chosen host IDE.
|
|
204
|
+
- `workspace`: Target workspace routing information.
|
|
205
|
+
- `onboarding`: Final onboarding URI and whether `autoSend` would be requested.
|
|
206
|
+
|
|
207
|
+
##### Exit codes
|
|
208
|
+
|
|
209
|
+
- Exit code `0`: `status=ok`
|
|
210
|
+
- Exit code `1`: `status=blocked`
|
|
211
|
+
|
|
212
|
+
This makes `inspecto integrations doctor` safe to use directly in CI and shell conditionals:
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
if inspecto integrations doctor codex --host-ide cursor --json; then
|
|
216
|
+
echo "integration is runnable"
|
|
217
|
+
else
|
|
218
|
+
echo "integration is blocked"
|
|
219
|
+
fi
|
|
100
220
|
```
|
|
101
221
|
|
|
102
222
|
### `inspecto doctor`
|
package/dist/bin.js
CHANGED
|
@@ -2,371 +2,25 @@ import {
|
|
|
2
2
|
apply,
|
|
3
3
|
detect,
|
|
4
4
|
doctor,
|
|
5
|
-
exists,
|
|
6
5
|
init,
|
|
7
|
-
|
|
6
|
+
installIntegration,
|
|
7
|
+
integrationDoctor,
|
|
8
8
|
onboard,
|
|
9
9
|
plan,
|
|
10
|
+
printIntegrationList,
|
|
11
|
+
printIntegrationPath,
|
|
10
12
|
reportCommandError,
|
|
11
|
-
teardown
|
|
12
|
-
|
|
13
|
-
} from "./chunk-PSYZB5GI.js";
|
|
13
|
+
teardown
|
|
14
|
+
} from "./chunk-LJOKPCPD.js";
|
|
14
15
|
|
|
15
16
|
// src/bin.ts
|
|
16
17
|
import { cac } from "cac";
|
|
17
|
-
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
18
|
-
import { createRequire } from "module";
|
|
19
|
-
|
|
20
|
-
// src/commands/integration-install.ts
|
|
21
|
-
import fs from "fs/promises";
|
|
22
|
-
import { homedir } from "os";
|
|
23
|
-
import path from "path";
|
|
24
18
|
import { fileURLToPath } from "url";
|
|
25
|
-
|
|
26
|
-
var INTEGRATION_MANIFESTS = [
|
|
27
|
-
{
|
|
28
|
-
assistant: "codex",
|
|
29
|
-
type: "native-skill",
|
|
30
|
-
installTarget: "~/.codex/skills/",
|
|
31
|
-
preferredInstall: "npx @inspecto-dev/cli integrations install codex",
|
|
32
|
-
cliSupported: true
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
assistant: "claude-code",
|
|
36
|
-
type: "native-skill",
|
|
37
|
-
installTarget: ".claude/skills/ or ~/.claude/skills/",
|
|
38
|
-
preferredInstall: "npx @inspecto-dev/cli integrations install claude-code --scope project",
|
|
39
|
-
cliSupported: true
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
assistant: "copilot",
|
|
43
|
-
type: "instruction-template",
|
|
44
|
-
installTarget: ".github/copilot-instructions.md or AGENTS.md",
|
|
45
|
-
preferredInstall: "npx @inspecto-dev/cli integrations install copilot",
|
|
46
|
-
cliSupported: true
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
assistant: "cursor",
|
|
50
|
-
type: "rule-template",
|
|
51
|
-
installTarget: ".cursor/rules/inspecto-onboarding.mdc or AGENTS.md",
|
|
52
|
-
preferredInstall: "npx @inspecto-dev/cli integrations install cursor --mode rules",
|
|
53
|
-
cliSupported: true
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
assistant: "gemini",
|
|
57
|
-
type: "context-template",
|
|
58
|
-
installTarget: "GEMINI.md",
|
|
59
|
-
preferredInstall: "npx @inspecto-dev/cli integrations install gemini",
|
|
60
|
-
cliSupported: true
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
assistant: "trae",
|
|
64
|
-
type: "compatibility-template",
|
|
65
|
-
installTarget: "AGENTS.md",
|
|
66
|
-
preferredInstall: "npx @inspecto-dev/cli integrations install trae",
|
|
67
|
-
cliSupported: true
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
assistant: "coco",
|
|
71
|
-
type: "compatibility-template",
|
|
72
|
-
installTarget: "AGENTS.md",
|
|
73
|
-
preferredInstall: "npx @inspecto-dev/cli integrations install coco",
|
|
74
|
-
cliSupported: true
|
|
75
|
-
}
|
|
76
|
-
];
|
|
77
|
-
async function installIntegration(assistant, options = {}) {
|
|
78
|
-
const plan2 = resolveInstallPlan(assistant, options);
|
|
79
|
-
log.header("Inspecto Integration Install");
|
|
80
|
-
for (const asset of plan2.assets) {
|
|
81
|
-
if (await exists(asset.target) && !options.force) {
|
|
82
|
-
throw new Error(
|
|
83
|
-
`Refusing to overwrite existing file: ${asset.target}. Re-run with --force if you want to replace it.`
|
|
84
|
-
);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
const downloadedAssets = [];
|
|
88
|
-
for (const asset of plan2.assets) {
|
|
89
|
-
const content = await loadAsset(asset);
|
|
90
|
-
downloadedAssets.push({ asset, content });
|
|
91
|
-
}
|
|
92
|
-
for (const { asset, content } of downloadedAssets) {
|
|
93
|
-
await writeFile(asset.target, content);
|
|
94
|
-
if (asset.executable) {
|
|
95
|
-
await fs.chmod(asset.target, 493);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
log.success(plan2.successMessage);
|
|
99
|
-
log.hint(plan2.nextStep);
|
|
100
|
-
}
|
|
101
|
-
function describeIntegration(assistant, options = {}) {
|
|
102
|
-
const manifest = getIntegrationManifest(assistant);
|
|
103
|
-
const targets = manifest.cliSupported ? resolveInstallPlan(assistant, options).assets.map((asset) => asset.target) : [manifest.installTarget];
|
|
104
|
-
return {
|
|
105
|
-
assistant: manifest.assistant,
|
|
106
|
-
type: manifest.type,
|
|
107
|
-
targets,
|
|
108
|
-
preferredInstall: manifest.preferredInstall,
|
|
109
|
-
cliSupported: manifest.cliSupported
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
function printIntegrationList() {
|
|
113
|
-
log.header("Inspecto Integrations");
|
|
114
|
-
for (const manifest of INTEGRATION_MANIFESTS) {
|
|
115
|
-
const support = manifest.cliSupported ? "CLI" : "native installer";
|
|
116
|
-
log.info(`${manifest.assistant} \u2014 ${manifest.type} \u2014 ${manifest.installTarget} \u2014 ${support}`);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
function printIntegrationPath(assistant, options = {}) {
|
|
120
|
-
const description = describeIntegration(assistant, options);
|
|
121
|
-
log.header(`Inspecto Integration Paths: ${description.assistant}`);
|
|
122
|
-
for (const target of description.targets) {
|
|
123
|
-
log.info(target);
|
|
124
|
-
}
|
|
125
|
-
if (description.cliSupported) {
|
|
126
|
-
log.hint(`Preferred install: ${description.preferredInstall}`);
|
|
127
|
-
} else {
|
|
128
|
-
log.hint(`Native install required: ${description.preferredInstall}`);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
function resolveInstallPlan(assistant, options) {
|
|
132
|
-
switch (assistant) {
|
|
133
|
-
case "codex":
|
|
134
|
-
return resolveCodexPlan(options);
|
|
135
|
-
case "claude-code":
|
|
136
|
-
return resolveClaudeCodePlan(options);
|
|
137
|
-
case "copilot":
|
|
138
|
-
return resolveCopilotPlan(options);
|
|
139
|
-
case "cursor":
|
|
140
|
-
return resolveCursorPlan(options);
|
|
141
|
-
case "gemini":
|
|
142
|
-
return {
|
|
143
|
-
assets: [
|
|
144
|
-
{
|
|
145
|
-
source: `${REPO_RAW_BASE}/assistant-integrations/gemini/GEMINI.md`,
|
|
146
|
-
target: "GEMINI.md",
|
|
147
|
-
localSource: "assistant-integrations/gemini/GEMINI.md"
|
|
148
|
-
}
|
|
149
|
-
],
|
|
150
|
-
successMessage: "Installed Gemini context to GEMINI.md",
|
|
151
|
-
nextStep: "Start a new Gemini CLI session."
|
|
152
|
-
};
|
|
153
|
-
case "trae":
|
|
154
|
-
return {
|
|
155
|
-
assets: [
|
|
156
|
-
{
|
|
157
|
-
source: `${REPO_RAW_BASE}/assistant-integrations/trae/AGENTS.md`,
|
|
158
|
-
target: "AGENTS.md",
|
|
159
|
-
localSource: "assistant-integrations/trae/AGENTS.md"
|
|
160
|
-
}
|
|
161
|
-
],
|
|
162
|
-
successMessage: "Installed Trae compatibility instructions to AGENTS.md",
|
|
163
|
-
nextStep: "Open a new Trae chat."
|
|
164
|
-
};
|
|
165
|
-
case "coco":
|
|
166
|
-
return {
|
|
167
|
-
assets: [
|
|
168
|
-
{
|
|
169
|
-
source: `${REPO_RAW_BASE}/assistant-integrations/coco/AGENTS.md`,
|
|
170
|
-
target: "AGENTS.md",
|
|
171
|
-
localSource: "assistant-integrations/coco/AGENTS.md"
|
|
172
|
-
}
|
|
173
|
-
],
|
|
174
|
-
successMessage: "Installed Coco compatibility instructions to AGENTS.md",
|
|
175
|
-
nextStep: "Start a new Coco session."
|
|
176
|
-
};
|
|
177
|
-
default:
|
|
178
|
-
throw new Error(`Unknown assistant: ${assistant}`);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
function getIntegrationManifest(assistant) {
|
|
182
|
-
const manifest = INTEGRATION_MANIFESTS.find((item) => item.assistant === assistant);
|
|
183
|
-
if (!manifest) {
|
|
184
|
-
throw new Error(
|
|
185
|
-
`Unknown assistant: ${assistant}. Run 'inspecto integrations list' to see available targets.`
|
|
186
|
-
);
|
|
187
|
-
}
|
|
188
|
-
return manifest;
|
|
189
|
-
}
|
|
190
|
-
function resolveCodexPlan(options) {
|
|
191
|
-
if (options.scope !== void 0) {
|
|
192
|
-
throw new Error("`--scope` is not supported for codex.");
|
|
193
|
-
}
|
|
194
|
-
if (options.mode !== void 0) {
|
|
195
|
-
throw new Error("`--mode` is not supported for codex.");
|
|
196
|
-
}
|
|
197
|
-
const baseDir = path.join(homedir(), ".codex/skills/inspecto-onboarding-codex");
|
|
198
|
-
return {
|
|
199
|
-
assets: [
|
|
200
|
-
{
|
|
201
|
-
source: `${REPO_RAW_BASE}/skills/inspecto-onboarding-codex/SKILL.md`,
|
|
202
|
-
target: path.join(baseDir, "SKILL.md"),
|
|
203
|
-
localSource: "skills/inspecto-onboarding-codex/SKILL.md"
|
|
204
|
-
},
|
|
205
|
-
{
|
|
206
|
-
source: `${REPO_RAW_BASE}/skills/inspecto-onboarding-codex/agents/openai.yaml`,
|
|
207
|
-
target: path.join(baseDir, "agents/openai.yaml"),
|
|
208
|
-
localSource: "skills/inspecto-onboarding-codex/agents/openai.yaml"
|
|
209
|
-
},
|
|
210
|
-
{
|
|
211
|
-
source: `${REPO_RAW_BASE}/skills/inspecto-onboarding-codex/scripts/run-inspecto.sh`,
|
|
212
|
-
target: path.join(baseDir, "scripts/run-inspecto.sh"),
|
|
213
|
-
executable: true,
|
|
214
|
-
localSource: "skills/inspecto-onboarding-codex/scripts/run-inspecto.sh"
|
|
215
|
-
}
|
|
216
|
-
],
|
|
217
|
-
successMessage: `Installed Codex skill to ${baseDir}`,
|
|
218
|
-
nextStep: "Restart Codex or start a new Codex session to load the skill."
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
function resolveClaudeCodePlan(options) {
|
|
222
|
-
const scope = options.scope ?? "project";
|
|
223
|
-
const unsupportedMode = options.mode !== void 0;
|
|
224
|
-
if (unsupportedMode) {
|
|
225
|
-
throw new Error(
|
|
226
|
-
"`--mode` is not supported for claude-code. Use `--scope project|user` instead."
|
|
227
|
-
);
|
|
228
|
-
}
|
|
229
|
-
if (scope !== "project" && scope !== "user") {
|
|
230
|
-
throw new Error(`Unknown Claude Code scope: ${scope}`);
|
|
231
|
-
}
|
|
232
|
-
const baseDir = scope === "user" ? path.join(homedir(), ".claude/skills/inspecto-onboarding-claude-code") : ".claude/skills/inspecto-onboarding-claude-code";
|
|
233
|
-
return {
|
|
234
|
-
assets: [
|
|
235
|
-
{
|
|
236
|
-
source: `${REPO_RAW_BASE}/skills/inspecto-onboarding-claude-code/SKILL.md`,
|
|
237
|
-
target: path.join(baseDir, "SKILL.md"),
|
|
238
|
-
localSource: "skills/inspecto-onboarding-claude-code/SKILL.md"
|
|
239
|
-
},
|
|
240
|
-
{
|
|
241
|
-
source: `${REPO_RAW_BASE}/skills/inspecto-onboarding-claude-code/agents/openai.yaml`,
|
|
242
|
-
target: path.join(baseDir, "agents/openai.yaml"),
|
|
243
|
-
localSource: "skills/inspecto-onboarding-claude-code/agents/openai.yaml"
|
|
244
|
-
},
|
|
245
|
-
{
|
|
246
|
-
source: `${REPO_RAW_BASE}/skills/inspecto-onboarding-claude-code/scripts/run-inspecto.sh`,
|
|
247
|
-
target: path.join(baseDir, "scripts/run-inspecto.sh"),
|
|
248
|
-
executable: true,
|
|
249
|
-
localSource: "skills/inspecto-onboarding-claude-code/scripts/run-inspecto.sh"
|
|
250
|
-
}
|
|
251
|
-
],
|
|
252
|
-
successMessage: `Installed Claude Code skill to ${baseDir}`,
|
|
253
|
-
nextStep: "Restart Claude Code to load the new skill."
|
|
254
|
-
};
|
|
255
|
-
}
|
|
256
|
-
function resolveCopilotPlan(options) {
|
|
257
|
-
const mode = options.mode ?? "instructions";
|
|
258
|
-
if (options.scope !== void 0) {
|
|
259
|
-
throw new Error(
|
|
260
|
-
"`--scope` is not supported for copilot. Use `--mode instructions|agents` instead."
|
|
261
|
-
);
|
|
262
|
-
}
|
|
263
|
-
switch (mode) {
|
|
264
|
-
case "instructions":
|
|
265
|
-
return {
|
|
266
|
-
assets: [
|
|
267
|
-
{
|
|
268
|
-
source: `${REPO_RAW_BASE}/assistant-integrations/copilot/.github/copilot-instructions.md`,
|
|
269
|
-
target: ".github/copilot-instructions.md",
|
|
270
|
-
localSource: "assistant-integrations/copilot/.github/copilot-instructions.md"
|
|
271
|
-
}
|
|
272
|
-
],
|
|
273
|
-
successMessage: "Installed Copilot instructions to .github/copilot-instructions.md",
|
|
274
|
-
nextStep: "Open a new Copilot chat or agent session."
|
|
275
|
-
};
|
|
276
|
-
case "agents":
|
|
277
|
-
return {
|
|
278
|
-
assets: [
|
|
279
|
-
{
|
|
280
|
-
source: `${REPO_RAW_BASE}/assistant-integrations/copilot/AGENTS.md`,
|
|
281
|
-
target: "AGENTS.md",
|
|
282
|
-
localSource: "assistant-integrations/copilot/AGENTS.md"
|
|
283
|
-
}
|
|
284
|
-
],
|
|
285
|
-
successMessage: "Installed Copilot compatibility instructions to AGENTS.md",
|
|
286
|
-
nextStep: "Open a new Copilot chat or agent session."
|
|
287
|
-
};
|
|
288
|
-
default:
|
|
289
|
-
throw new Error(`Unknown Copilot mode: ${mode}`);
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
function resolveCursorPlan(options) {
|
|
293
|
-
const mode = options.mode ?? "rules";
|
|
294
|
-
if (options.scope !== void 0) {
|
|
295
|
-
throw new Error("`--scope` is not supported for cursor. Use `--mode rules|agents` instead.");
|
|
296
|
-
}
|
|
297
|
-
switch (mode) {
|
|
298
|
-
case "rules":
|
|
299
|
-
return {
|
|
300
|
-
assets: [
|
|
301
|
-
{
|
|
302
|
-
source: `${REPO_RAW_BASE}/assistant-integrations/cursor/.cursor/rules/inspecto-onboarding.mdc`,
|
|
303
|
-
target: ".cursor/rules/inspecto-onboarding.mdc",
|
|
304
|
-
localSource: "assistant-integrations/cursor/.cursor/rules/inspecto-onboarding.mdc"
|
|
305
|
-
}
|
|
306
|
-
],
|
|
307
|
-
successMessage: "Installed Cursor rule to .cursor/rules/inspecto-onboarding.mdc",
|
|
308
|
-
nextStep: "Open a new Cursor chat."
|
|
309
|
-
};
|
|
310
|
-
case "agents":
|
|
311
|
-
return {
|
|
312
|
-
assets: [
|
|
313
|
-
{
|
|
314
|
-
source: `${REPO_RAW_BASE}/assistant-integrations/cursor/AGENTS.md`,
|
|
315
|
-
target: "AGENTS.md",
|
|
316
|
-
localSource: "assistant-integrations/cursor/AGENTS.md"
|
|
317
|
-
}
|
|
318
|
-
],
|
|
319
|
-
successMessage: "Installed Cursor compatibility instructions to AGENTS.md",
|
|
320
|
-
nextStep: "Open a new Cursor chat."
|
|
321
|
-
};
|
|
322
|
-
default:
|
|
323
|
-
throw new Error(`Unknown Cursor mode: ${mode}`);
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
async function loadAsset(asset) {
|
|
327
|
-
if (asset.localSource) {
|
|
328
|
-
const localPath = await resolveBundledAssetPath(asset.localSource);
|
|
329
|
-
if (localPath) {
|
|
330
|
-
return await fs.readFile(localPath, "utf-8");
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
return await downloadAsset(asset.source);
|
|
334
|
-
}
|
|
335
|
-
async function resolveBundledAssetPath(relativePath) {
|
|
336
|
-
const startDir = path.dirname(fileURLToPath(import.meta.url));
|
|
337
|
-
let currentDir = startDir;
|
|
338
|
-
for (let depth = 0; depth < 8; depth += 1) {
|
|
339
|
-
const candidate = path.join(currentDir, relativePath);
|
|
340
|
-
if (await exists(candidate)) {
|
|
341
|
-
return candidate;
|
|
342
|
-
}
|
|
343
|
-
const parent = path.dirname(currentDir);
|
|
344
|
-
if (parent === currentDir) break;
|
|
345
|
-
currentDir = parent;
|
|
346
|
-
}
|
|
347
|
-
return null;
|
|
348
|
-
}
|
|
349
|
-
async function downloadAsset(source) {
|
|
350
|
-
let response;
|
|
351
|
-
try {
|
|
352
|
-
response = await fetch(source);
|
|
353
|
-
} catch (error) {
|
|
354
|
-
const reason = error instanceof Error ? error.message : String(error);
|
|
355
|
-
throw new Error(`Failed to download ${source}: ${reason}`, {
|
|
356
|
-
cause: error
|
|
357
|
-
});
|
|
358
|
-
}
|
|
359
|
-
if (!response.ok) {
|
|
360
|
-
throw new Error(`Failed to download ${source}: ${response.status} ${response.statusText}`);
|
|
361
|
-
}
|
|
362
|
-
return await response.text();
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
// src/bin.ts
|
|
19
|
+
import { createRequire } from "module";
|
|
366
20
|
var require2 = createRequire(import.meta.url);
|
|
367
21
|
var { version } = require2("../package.json");
|
|
368
22
|
var integrationScopes = ["project", "user"];
|
|
369
|
-
var integrationModes = ["instructions", "agents", "rules"];
|
|
23
|
+
var integrationModes = ["skills", "instructions", "agents", "rules"];
|
|
370
24
|
function exitWithError(error, options = {}) {
|
|
371
25
|
reportCommandError(error, {
|
|
372
26
|
debug: options.debug ?? false,
|
|
@@ -451,20 +105,20 @@ function createCli(_argv = process.argv) {
|
|
|
451
105
|
exitWithError(error, options);
|
|
452
106
|
}
|
|
453
107
|
});
|
|
454
|
-
cli.command("integrations [...args]", "Manage assistant integration assets").option(
|
|
108
|
+
cli.command("integrations [...args]", "Manage assistant integration assets").option("--json", "Print machine-readable JSON output", { default: false }).option(
|
|
455
109
|
"--scope <scope>",
|
|
456
110
|
"Set install scope for supported assistants (e.g. claude-code: project|user)"
|
|
457
111
|
).option(
|
|
458
112
|
"--mode <mode>",
|
|
459
|
-
"Set install mode for supported assistants (e.g. copilot: instructions|agents)"
|
|
460
|
-
).option("--force", "Overwrite existing integration files", { default: false }).option("--debug", "Enable debug mode to show full error traces", { default: false }).action(async (args, options) => {
|
|
113
|
+
"Set install mode for supported assistants (e.g. copilot: skills|instructions|agents)"
|
|
114
|
+
).option("--host-ide <ide>", "Choose the host IDE for automatic extension install and launch").option("--inspecto-vsix <path>", "Install the Inspecto extension from a local .vsix path").option("--compact", "Print a shorter text summary for integration doctor").option("--preview", "Preview integration changes and IDE automation without executing them").option("--force", "Overwrite existing integration files", { default: false }).option("--debug", "Enable debug mode to show full error traces", { default: false }).action(async (args, options) => {
|
|
461
115
|
try {
|
|
462
116
|
const [subcommand, assistant, ...rest] = args;
|
|
463
117
|
const integrationOptions = buildIntegrationOptions(options);
|
|
464
118
|
if (subcommand === "list") {
|
|
465
|
-
if (assistant || rest.length > 0 || options.scope || options.mode || options.force) {
|
|
119
|
+
if (assistant || rest.length > 0 || options.scope || options.mode || options.hostIde || options.inspectoVsix || options.compact || options.json || options.preview || options.force) {
|
|
466
120
|
throw new Error(
|
|
467
|
-
"The `list` subcommand does not accept assistant names, --scope, --mode, or --force."
|
|
121
|
+
"The `list` subcommand does not accept assistant names, --scope, --mode, --host-ide, --inspecto-vsix, --compact, --json, --preview, or --force."
|
|
468
122
|
);
|
|
469
123
|
}
|
|
470
124
|
printIntegrationList();
|
|
@@ -477,16 +131,45 @@ function createCli(_argv = process.argv) {
|
|
|
477
131
|
if (options.force) {
|
|
478
132
|
throw new Error("The `path` subcommand does not support `--force`.");
|
|
479
133
|
}
|
|
134
|
+
if (options.hostIde) {
|
|
135
|
+
throw new Error("The `path` subcommand does not support `--host-ide`.");
|
|
136
|
+
}
|
|
137
|
+
if (options.inspectoVsix) {
|
|
138
|
+
throw new Error("The `path` subcommand does not support `--inspecto-vsix`.");
|
|
139
|
+
}
|
|
140
|
+
if (options.preview) {
|
|
141
|
+
throw new Error("The `path` subcommand does not support `--preview`.");
|
|
142
|
+
}
|
|
143
|
+
if (options.compact) {
|
|
144
|
+
throw new Error("The `path` subcommand does not support `--compact`.");
|
|
145
|
+
}
|
|
146
|
+
if (options.json) {
|
|
147
|
+
throw new Error("The `path` subcommand does not support `--json`.");
|
|
148
|
+
}
|
|
480
149
|
printIntegrationPath(assistant, integrationOptions);
|
|
481
150
|
return;
|
|
482
151
|
}
|
|
152
|
+
if (subcommand === "doctor" && assistant) {
|
|
153
|
+
if (rest.length > 0) {
|
|
154
|
+
throw new Error("The `doctor` subcommand accepts exactly one assistant argument.");
|
|
155
|
+
}
|
|
156
|
+
if (options.force) {
|
|
157
|
+
throw new Error("The `doctor` subcommand does not support `--force`.");
|
|
158
|
+
}
|
|
159
|
+
if (options.preview) {
|
|
160
|
+
throw new Error("The `doctor` subcommand does not support `--preview`.");
|
|
161
|
+
}
|
|
162
|
+
await integrationDoctor(assistant, { ...integrationOptions, failOnBlocked: true });
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
483
165
|
if (subcommand !== "install" || !assistant) {
|
|
484
166
|
throw new Error(
|
|
485
167
|
[
|
|
486
168
|
"Usage:",
|
|
487
169
|
" inspecto integrations list",
|
|
488
170
|
" inspecto integrations path <assistant> [--scope <scope>] [--mode <mode>]",
|
|
489
|
-
" inspecto integrations
|
|
171
|
+
" inspecto integrations doctor <assistant> [--scope <scope>] [--mode <mode>] [--host-ide <ide>] [--inspecto-vsix <path>] [--compact] [--json]",
|
|
172
|
+
" inspecto integrations install <assistant> [--scope <scope>] [--mode <mode>] [--host-ide <ide>] [--inspecto-vsix <path>] [--preview] [--json] [--force]"
|
|
490
173
|
].join("\n")
|
|
491
174
|
);
|
|
492
175
|
}
|
|
@@ -521,6 +204,21 @@ function buildIntegrationOptions(options) {
|
|
|
521
204
|
throw new Error(`Unknown integration mode: ${options.mode}`);
|
|
522
205
|
}
|
|
523
206
|
}
|
|
207
|
+
if (options.hostIde) {
|
|
208
|
+
resolved.ide = options.hostIde;
|
|
209
|
+
}
|
|
210
|
+
if (options.inspectoVsix) {
|
|
211
|
+
resolved.inspectoVsix = options.inspectoVsix;
|
|
212
|
+
}
|
|
213
|
+
if (options.compact) {
|
|
214
|
+
resolved.compact = options.compact;
|
|
215
|
+
}
|
|
216
|
+
if (options.preview) {
|
|
217
|
+
resolved.preview = options.preview;
|
|
218
|
+
}
|
|
219
|
+
if (options.json) {
|
|
220
|
+
resolved.json = options.json;
|
|
221
|
+
}
|
|
524
222
|
return resolved;
|
|
525
223
|
}
|
|
526
224
|
function isIntegrationScope(value) {
|
|
@@ -539,7 +237,7 @@ async function runCli(argv = process.argv) {
|
|
|
539
237
|
}
|
|
540
238
|
}
|
|
541
239
|
var entryPath = process.argv[1];
|
|
542
|
-
if (entryPath &&
|
|
240
|
+
if (entryPath && fileURLToPath(import.meta.url) === entryPath) {
|
|
543
241
|
void runCli();
|
|
544
242
|
}
|
|
545
243
|
export {
|