@respan/cli 0.10.0 → 0.11.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.
- package/dist/commands/setup/doctor.d.ts +0 -1
- package/dist/commands/setup/doctor.js +25 -40
- package/dist/commands/setup/gateway.d.ts +16 -0
- package/dist/commands/setup/gateway.js +33 -0
- package/dist/commands/setup/index.d.ts +4 -33
- package/dist/commands/setup/index.js +11 -762
- package/dist/commands/setup/tracing.d.ts +16 -0
- package/dist/commands/setup/tracing.js +33 -0
- package/dist/lib/agents.d.ts +16 -0
- package/dist/lib/agents.js +75 -0
- package/dist/lib/auth.js +24 -0
- package/dist/lib/colors.d.ts +7 -0
- package/dist/lib/colors.js +10 -0
- package/dist/lib/integrate.d.ts +6 -0
- package/dist/lib/integrate.js +11 -0
- package/dist/lib/setup-base-command.d.ts +84 -0
- package/dist/lib/setup-base-command.js +649 -0
- package/dist/lib/skill-content.d.ts +1 -0
- package/dist/lib/skill-content.js +16 -0
- package/dist/lib/skill-refs.generated.d.ts +3 -2
- package/dist/lib/skill-refs.generated.js +423 -102
- package/oclif.manifest.json +238 -75
- package/package.json +2 -1
|
@@ -5,12 +5,8 @@ import { execSync } from 'node:child_process';
|
|
|
5
5
|
import { Flags } from '@oclif/core';
|
|
6
6
|
import { BaseCommand } from '../../lib/base-command.js';
|
|
7
7
|
import { findProjectRoot, expandHome, readTextFile } from '../../lib/integrate.js';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const YELLOW = '\x1b[33m';
|
|
11
|
-
const DIM = '\x1b[2m';
|
|
12
|
-
const BOLD = '\x1b[1m';
|
|
13
|
-
const RESET = '\x1b[0m';
|
|
8
|
+
import { GREEN, RED, YELLOW, DIM, BOLD, RESET } from '../../lib/colors.js';
|
|
9
|
+
import { isBinaryInstalled } from '../../lib/agents.js';
|
|
14
10
|
class SetupDoctor extends BaseCommand {
|
|
15
11
|
async run() {
|
|
16
12
|
const { flags } = await this.parse(SetupDoctor);
|
|
@@ -43,7 +39,7 @@ class SetupDoctor extends BaseCommand {
|
|
|
43
39
|
this.log('');
|
|
44
40
|
// ── 2. Respan CLI ──────────────────────────────────────────────
|
|
45
41
|
this.log(` ${BOLD}Respan CLI${RESET}`);
|
|
46
|
-
const respanInstalled =
|
|
42
|
+
const respanInstalled = isBinaryInstalled('respan');
|
|
47
43
|
if (respanInstalled) {
|
|
48
44
|
try {
|
|
49
45
|
const version = execSync('respan --version', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
@@ -66,44 +62,44 @@ class SetupDoctor extends BaseCommand {
|
|
|
66
62
|
name: 'Claude Code',
|
|
67
63
|
globalConfigs: ['~/.claude/settings.json'],
|
|
68
64
|
localConfigs: ['.claude/settings.local.json'],
|
|
69
|
-
globalSkills: ['~/.claude/skills/respan/SKILL.md'
|
|
70
|
-
localSkills: ['.claude/skills/respan/SKILL.md'
|
|
65
|
+
globalSkills: ['~/.claude/skills/respan/SKILL.md'],
|
|
66
|
+
localSkills: ['.claude/skills/respan/SKILL.md'],
|
|
71
67
|
},
|
|
72
68
|
'cursor': {
|
|
73
69
|
binary: 'cursor',
|
|
74
70
|
name: 'Cursor',
|
|
75
71
|
globalConfigs: ['~/.cursor/rules'],
|
|
76
72
|
localConfigs: ['.cursor/rules'],
|
|
77
|
-
globalSkills: ['~/.
|
|
78
|
-
localSkills: ['.
|
|
73
|
+
globalSkills: ['~/.agents/skills/respan/SKILL.md', '~/.cursor/skills/respan/SKILL.md'],
|
|
74
|
+
localSkills: ['.agents/skills/respan/SKILL.md', '.cursor/skills/respan/SKILL.md'],
|
|
79
75
|
},
|
|
80
76
|
'codex-cli': {
|
|
81
77
|
binary: 'codex',
|
|
82
78
|
name: 'Codex CLI',
|
|
83
79
|
globalConfigs: ['~/.codex/config.toml'],
|
|
84
80
|
localConfigs: ['.codex/respan.json'],
|
|
85
|
-
globalSkills: ['~/.
|
|
86
|
-
localSkills: ['.
|
|
81
|
+
globalSkills: ['~/.agents/skills/respan/SKILL.md', '~/.codex/skills/respan/SKILL.md'],
|
|
82
|
+
localSkills: ['.agents/skills/respan/SKILL.md', '.codex/skills/respan/SKILL.md'],
|
|
87
83
|
},
|
|
88
84
|
'gemini-cli': {
|
|
89
85
|
binary: 'gemini',
|
|
90
86
|
name: 'Gemini CLI',
|
|
91
87
|
globalConfigs: ['~/.gemini/settings.json'],
|
|
92
88
|
localConfigs: ['.gemini/settings.json'],
|
|
93
|
-
globalSkills: ['~/.
|
|
94
|
-
localSkills: ['.
|
|
89
|
+
globalSkills: ['~/.agents/skills/respan/SKILL.md', '~/.gemini/skills/respan/SKILL.md'],
|
|
90
|
+
localSkills: ['.agents/skills/respan/SKILL.md', '.gemini/skills/respan/SKILL.md'],
|
|
95
91
|
},
|
|
96
92
|
'opencode': {
|
|
97
93
|
binary: 'opencode',
|
|
98
94
|
name: 'OpenCode',
|
|
99
95
|
globalConfigs: ['~/.config/opencode'],
|
|
100
96
|
localConfigs: ['.opencode'],
|
|
101
|
-
globalSkills: ['~/.
|
|
102
|
-
localSkills: ['.
|
|
97
|
+
globalSkills: ['~/.agents/skills/respan/SKILL.md', '~/.config/opencode/skills/respan/SKILL.md'],
|
|
98
|
+
localSkills: ['.agents/skills/respan/SKILL.md', '.opencode/skills/respan/SKILL.md'],
|
|
103
99
|
},
|
|
104
100
|
};
|
|
105
101
|
for (const [id, tool] of Object.entries(tools)) {
|
|
106
|
-
const binaryFound =
|
|
102
|
+
const binaryFound = isBinaryInstalled(tool.binary);
|
|
107
103
|
this.log(` ${BOLD}${tool.name}${RESET} ${DIM}(${tool.binary})${RESET}`);
|
|
108
104
|
// Binary
|
|
109
105
|
if (binaryFound) {
|
|
@@ -129,24 +125,22 @@ class SetupDoctor extends BaseCommand {
|
|
|
129
125
|
}
|
|
130
126
|
}
|
|
131
127
|
}
|
|
132
|
-
// Skills
|
|
128
|
+
// Skills \u2014 each tool only lists dirs it actually reads (the shared
|
|
129
|
+
// ~/.agents, or ~/.claude for Claude Code) plus its own dir as a
|
|
130
|
+
// fallback. Report the first match.
|
|
133
131
|
let hasSkill = false;
|
|
134
132
|
if (checkGlobal) {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
hasSkill = true;
|
|
140
|
-
}
|
|
133
|
+
const found = tool.globalSkills.find((skill) => fs.existsSync(expandHome(skill)));
|
|
134
|
+
if (found) {
|
|
135
|
+
this.log(` ${GREEN}\u2713${RESET} Global skill: ${DIM}${found}${RESET}`);
|
|
136
|
+
hasSkill = true;
|
|
141
137
|
}
|
|
142
138
|
}
|
|
143
139
|
if (checkLocal) {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
hasSkill = true;
|
|
149
|
-
}
|
|
140
|
+
const found = tool.localSkills.find((skill) => fs.existsSync(path.join(projectRoot, skill)));
|
|
141
|
+
if (found) {
|
|
142
|
+
this.log(` ${GREEN}\u2713${RESET} Local skill: ${DIM}${found}${RESET}`);
|
|
143
|
+
hasSkill = true;
|
|
150
144
|
}
|
|
151
145
|
}
|
|
152
146
|
if (binaryFound && !hasSkill) {
|
|
@@ -193,15 +187,6 @@ class SetupDoctor extends BaseCommand {
|
|
|
193
187
|
}
|
|
194
188
|
this.log('');
|
|
195
189
|
}
|
|
196
|
-
isBinaryInstalled(binary) {
|
|
197
|
-
try {
|
|
198
|
-
execSync(`command -v ${binary}`, { stdio: 'pipe' });
|
|
199
|
-
return true;
|
|
200
|
-
}
|
|
201
|
-
catch {
|
|
202
|
-
return false;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
190
|
}
|
|
206
191
|
SetupDoctor.description = 'Diagnose coding-agent setup for Respan';
|
|
207
192
|
SetupDoctor.examples = [
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { SetupBaseCommand } from '../../lib/setup-base-command.js';
|
|
2
|
+
export default class SetupGateway extends SetupBaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
agent: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
'no-instrument': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
csv: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
+
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
|
+
};
|
|
15
|
+
run(): Promise<void>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
|
+
import { SetupBaseCommand } from '../../lib/setup-base-command.js';
|
|
3
|
+
class SetupGateway extends SetupBaseCommand {
|
|
4
|
+
async run() {
|
|
5
|
+
const { flags } = await this.parse(SetupGateway);
|
|
6
|
+
this.globalFlags = flags;
|
|
7
|
+
await this.runSetup('gateway', {
|
|
8
|
+
agent: flags.agent,
|
|
9
|
+
noInstrument: flags['no-instrument'],
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
SetupGateway.description = `Set up Respan gateway routing in this project.
|
|
14
|
+
|
|
15
|
+
Runs the gateway setup flow directly (skips the "Tracing or Gateway?"
|
|
16
|
+
question). Sets up your API key, installs the Respan skill, and optionally
|
|
17
|
+
opens your coding agent to route the detected framework through the gateway.`;
|
|
18
|
+
SetupGateway.examples = [
|
|
19
|
+
'respan setup gateway',
|
|
20
|
+
'respan setup gateway --agent claude-code',
|
|
21
|
+
'respan setup gateway --no-instrument',
|
|
22
|
+
];
|
|
23
|
+
SetupGateway.flags = {
|
|
24
|
+
...SetupBaseCommand.baseFlags,
|
|
25
|
+
agent: Flags.string({
|
|
26
|
+
description: 'Agent to configure (claude-code, cursor, codex-cli, gemini-cli, opencode)',
|
|
27
|
+
}),
|
|
28
|
+
'no-instrument': Flags.boolean({
|
|
29
|
+
description: 'Skip opening the agent after setup',
|
|
30
|
+
default: false,
|
|
31
|
+
}),
|
|
32
|
+
};
|
|
33
|
+
export default SetupGateway;
|
|
@@ -1,45 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export default class Setup extends
|
|
1
|
+
import { SetupBaseCommand } from '../../lib/setup-base-command.js';
|
|
2
|
+
export default class Setup extends SetupBaseCommand {
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
5
|
static flags: {
|
|
6
6
|
agent: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
7
|
'no-instrument': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
csv: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
10
|
'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
11
|
'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
12
|
profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
-
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
-
csv: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
13
|
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
14
|
};
|
|
15
15
|
run(): Promise<void>;
|
|
16
|
-
private askApiKey;
|
|
17
|
-
private verifyApiKey;
|
|
18
|
-
/**
|
|
19
|
-
* Build a rich demo OTLP trace that mimics a customer support agent workflow:
|
|
20
|
-
* workflow: customer_support_pipeline
|
|
21
|
-
* └── agent: support_agent
|
|
22
|
-
* ├── tool: lookup_order
|
|
23
|
-
* ├── chat: openai.chat (classify intent)
|
|
24
|
-
* ├── tool: process_refund
|
|
25
|
-
* ├── chat: openai.chat (generate response)
|
|
26
|
-
* └── task: log_resolution
|
|
27
|
-
*/
|
|
28
|
-
private buildDemoTrace;
|
|
29
|
-
private detectAgents;
|
|
30
|
-
private selectAgent;
|
|
31
|
-
private installSkill;
|
|
32
|
-
private runInstrumentAgent;
|
|
33
|
-
private getSkillMd;
|
|
34
|
-
private logStep;
|
|
35
|
-
private isBinaryInstalled;
|
|
36
|
-
private extractEnvVar;
|
|
37
|
-
private saveToEnv;
|
|
38
|
-
private getGitEmail;
|
|
39
|
-
/**
|
|
40
|
-
* Send a lightweight setup notification (email only).
|
|
41
|
-
* This helps the team know when new users set up Respan so we can
|
|
42
|
-
* reach out and help with onboarding.
|
|
43
|
-
*/
|
|
44
|
-
private notifySetup;
|
|
45
16
|
}
|