@respan/cli 0.10.0 → 0.12.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/demo/clear.d.ts +23 -0
- package/dist/commands/demo/clear.js +114 -0
- package/dist/commands/demo/index.d.ts +15 -0
- package/dist/commands/demo/index.js +81 -0
- 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/demo/dataset-fixtures.d.ts +32 -0
- package/dist/lib/demo/dataset-fixtures.js +194 -0
- package/dist/lib/demo/evaluator-fixtures.d.ts +41 -0
- package/dist/lib/demo/evaluator-fixtures.js +251 -0
- package/dist/lib/demo/prompt-fixtures.d.ts +54 -0
- package/dist/lib/demo/prompt-fixtures.js +395 -0
- package/dist/lib/demo/seed-datasets.d.ts +15 -0
- package/dist/lib/demo/seed-datasets.js +107 -0
- package/dist/lib/demo/seed-evaluators.d.ts +22 -0
- package/dist/lib/demo/seed-evaluators.js +180 -0
- package/dist/lib/demo/seed-prompts.d.ts +10 -0
- package/dist/lib/demo/seed-prompts.js +111 -0
- package/dist/lib/demo/seed-traces.d.ts +27 -0
- package/dist/lib/demo/seed-traces.js +158 -0
- package/dist/lib/demo/seeders.d.ts +8 -0
- package/dist/lib/demo/seeders.js +11 -0
- package/dist/lib/demo/trace-fixtures.d.ts +31 -0
- package/dist/lib/demo/trace-fixtures.js +79 -0
- package/dist/lib/demo/types.d.ts +57 -0
- package/dist/lib/demo/types.js +9 -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 +945 -642
- package/package.json +2 -1
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the `respan demo` orchestrator and its per-service seeders.
|
|
3
|
+
*
|
|
4
|
+
* The orchestrator (`commands/demo/*`) is service-agnostic: it knows only the
|
|
5
|
+
* {@link Seeder} contract and aggregates {@link SeederResult}s. Each service
|
|
6
|
+
* (prompts today; traces/datasets/evaluators later) ships its own `seed-*.ts`
|
|
7
|
+
* that implements {@link Seeder}, so adding a service is a drop-in.
|
|
8
|
+
*/
|
|
9
|
+
import { RespanClient } from '@respan/respan-api';
|
|
10
|
+
/** Authed handles every seeder needs to talk to the platform. */
|
|
11
|
+
export interface SeederContext {
|
|
12
|
+
client: RespanClient;
|
|
13
|
+
/** `"Bearer <token>"`, as the SDK request objects expect. */
|
|
14
|
+
authHeader: string;
|
|
15
|
+
/**
|
|
16
|
+
* Resolved API base URL (e.g. `https://api.respan.ai`). Needed by seeders that
|
|
17
|
+
* bypass the SDK — the traces seeder POSTs raw OTLP to `/v2/traces`, which the
|
|
18
|
+
* SDK does not expose. Prompt seeding ignores this.
|
|
19
|
+
*/
|
|
20
|
+
baseUrl: string;
|
|
21
|
+
}
|
|
22
|
+
/** A demo resource that already exists in the account (matched by name). */
|
|
23
|
+
export interface ExistingResource {
|
|
24
|
+
name: string;
|
|
25
|
+
id: string;
|
|
26
|
+
}
|
|
27
|
+
/** Outcome for a single resource. */
|
|
28
|
+
export interface SeedItemResult {
|
|
29
|
+
name: string;
|
|
30
|
+
status: 'created' | 'skipped' | 'deleted';
|
|
31
|
+
/** Resource ID — the new ID when created, the removed ID when deleted. */
|
|
32
|
+
id?: string;
|
|
33
|
+
/** Why it was skipped (e.g. "already exists" / "not found"). */
|
|
34
|
+
reason?: string;
|
|
35
|
+
}
|
|
36
|
+
/** Aggregated outcome for one service's seed or clear run. */
|
|
37
|
+
export interface SeederResult {
|
|
38
|
+
/** Machine key, e.g. `"prompts"`. */
|
|
39
|
+
service: string;
|
|
40
|
+
/** Human label for summaries, e.g. `"Prompts"`. */
|
|
41
|
+
label: string;
|
|
42
|
+
items: SeedItemResult[];
|
|
43
|
+
}
|
|
44
|
+
/** A per-service seeder. Owns its fixtures and all create/find/delete logic for
|
|
45
|
+
* one service, so the orchestrator stays service-agnostic. Both `run` and
|
|
46
|
+
* `clear` must be safely re-runnable (idempotent). */
|
|
47
|
+
export interface Seeder {
|
|
48
|
+
service: string;
|
|
49
|
+
label: string;
|
|
50
|
+
/** Create any missing demo resources, deploying them live. Skips existing. */
|
|
51
|
+
run(ctx: SeederContext): Promise<SeederResult>;
|
|
52
|
+
/** Delete the demo resources this seeder owns (matched by fixture name). */
|
|
53
|
+
clear(ctx: SeederContext): Promise<SeederResult>;
|
|
54
|
+
/** Find demo resources that currently exist in the account (by fixture name),
|
|
55
|
+
* without modifying anything. Used for dedup and for clear previews. */
|
|
56
|
+
findExisting(ctx: SeederContext): Promise<ExistingResource[]>;
|
|
57
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the `respan demo` orchestrator and its per-service seeders.
|
|
3
|
+
*
|
|
4
|
+
* The orchestrator (`commands/demo/*`) is service-agnostic: it knows only the
|
|
5
|
+
* {@link Seeder} contract and aggregates {@link SeederResult}s. Each service
|
|
6
|
+
* (prompts today; traces/datasets/evaluators later) ships its own `seed-*.ts`
|
|
7
|
+
* that implements {@link Seeder}, so adding a service is a drop-in.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
package/dist/lib/integrate.d.ts
CHANGED
|
@@ -51,6 +51,12 @@ export declare function readJsonFile(filePath: string): Record<string, unknown>;
|
|
|
51
51
|
export declare function writeJsonFile(filePath: string, data: Record<string, unknown>): void;
|
|
52
52
|
export declare function readTextFile(filePath: string): string;
|
|
53
53
|
export declare function writeTextFile(filePath: string, content: string): void;
|
|
54
|
+
/**
|
|
55
|
+
* Read a `KEY=value` line from .env-style content. Trims before stripping a
|
|
56
|
+
* single layer of surrounding quotes — the closing quote can sit inside
|
|
57
|
+
* trailing whitespace, so order matters. Returns undefined if absent or empty.
|
|
58
|
+
*/
|
|
59
|
+
export declare function extractEnvVar(content: string, key: string): string | undefined;
|
|
54
60
|
export declare function expandHome(p: string): string;
|
|
55
61
|
export declare function parseAttrs(raw: string): Record<string, string>;
|
|
56
62
|
/**
|
package/dist/lib/integrate.js
CHANGED
|
@@ -148,6 +148,17 @@ export function writeTextFile(filePath, content) {
|
|
|
148
148
|
ensureDir(path.dirname(filePath));
|
|
149
149
|
fs.writeFileSync(filePath, content);
|
|
150
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* Read a `KEY=value` line from .env-style content. Trims before stripping a
|
|
153
|
+
* single layer of surrounding quotes — the closing quote can sit inside
|
|
154
|
+
* trailing whitespace, so order matters. Returns undefined if absent or empty.
|
|
155
|
+
*/
|
|
156
|
+
export function extractEnvVar(content, key) {
|
|
157
|
+
const match = content.match(new RegExp(`^${key}=(.+)$`, 'm'));
|
|
158
|
+
if (!match)
|
|
159
|
+
return undefined;
|
|
160
|
+
return match[1].trim().replace(/^["']|["']$/g, '').trim() || undefined;
|
|
161
|
+
}
|
|
151
162
|
export function expandHome(p) {
|
|
152
163
|
if (p.startsWith('~')) {
|
|
153
164
|
return path.join(os.homedir(), p.slice(1));
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { BaseCommand } from './base-command.js';
|
|
2
|
+
import { CliTool, DetectionSignal } from './agents.js';
|
|
3
|
+
export type SetupMode = 'tracing' | 'gateway';
|
|
4
|
+
interface RunSetupOptions {
|
|
5
|
+
agent?: string;
|
|
6
|
+
noInstrument?: boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Intermediate base class for the `respan setup` family of commands
|
|
10
|
+
* (`setup`, `setup tracing`, `setup gateway`).
|
|
11
|
+
*
|
|
12
|
+
* It deliberately sits between the concrete commands and {@link BaseCommand}
|
|
13
|
+
* so that setup-only concerns (interactive prompts, the agent registry, and
|
|
14
|
+
* multi-kilobyte skill content) never leak onto the root command class that
|
|
15
|
+
* every other command extends.
|
|
16
|
+
*/
|
|
17
|
+
export declare abstract class SetupBaseCommand extends BaseCommand {
|
|
18
|
+
static baseFlags: {
|
|
19
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
20
|
+
csv: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
21
|
+
'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
22
|
+
'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
23
|
+
profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
24
|
+
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Shared setup flow for all three entry points.
|
|
28
|
+
*
|
|
29
|
+
* 1. askApiKey() // .env → global credential → prompt
|
|
30
|
+
* 2. if mode is undefined → ask "Tracing or Gateway?" (interactive only)
|
|
31
|
+
* 3. verifyApiKey(mode) // both re-prompt on a rejected key; can pause setup
|
|
32
|
+
* 4. selectAgent() // drives only the launch
|
|
33
|
+
* 5. installSkill() // full bundle, for all agents, regardless of selection
|
|
34
|
+
* 6. launchAgent(mode) // only if an agent was selected
|
|
35
|
+
*/
|
|
36
|
+
protected runSetup(mode?: SetupMode, opts?: RunSetupOptions): Promise<void>;
|
|
37
|
+
protected askMode(step: number): Promise<SetupMode>;
|
|
38
|
+
protected askApiKey(projectRoot: string): Promise<string>;
|
|
39
|
+
/**
|
|
40
|
+
* Verify the key for the chosen mode. Both paths re-prompt on a rejected key
|
|
41
|
+
* and return false if the user abandons the check, so the caller can pause
|
|
42
|
+
* setup instead of reporting success with a key that doesn't work.
|
|
43
|
+
*/
|
|
44
|
+
protected verifyApiKey(apiKey: string, mode: SetupMode, projectRoot: string): Promise<boolean>;
|
|
45
|
+
/** Prompt for a replacement key and persist it to the project .env. */
|
|
46
|
+
private reenterApiKey;
|
|
47
|
+
private verifyTracingKey;
|
|
48
|
+
/**
|
|
49
|
+
* Gateway verification gates on a real request succeeding: there is no
|
|
50
|
+
* credit-balance endpoint, so a 200 is the only proof of a valid key with a
|
|
51
|
+
* positive balance. A rejected key (401/403) re-prompts; any other failure
|
|
52
|
+
* loops on the user's say-so. Returns true on success, false if abandoned.
|
|
53
|
+
*/
|
|
54
|
+
private verifyGatewayKey;
|
|
55
|
+
/**
|
|
56
|
+
* Build a rich demo OTLP trace that mimics a customer support agent workflow:
|
|
57
|
+
* workflow: customer_support_pipeline
|
|
58
|
+
* └── agent: support_agent
|
|
59
|
+
* ├── tool: lookup_order
|
|
60
|
+
* ├── chat: openai.chat (classify intent)
|
|
61
|
+
* ├── tool: process_refund
|
|
62
|
+
* ├── chat: openai.chat (generate response)
|
|
63
|
+
* └── task: log_resolution
|
|
64
|
+
*/
|
|
65
|
+
protected buildDemoTrace(email?: string): Record<string, unknown>;
|
|
66
|
+
/**
|
|
67
|
+
* Minimal chat completion sent through the gateway to prove auth + routing
|
|
68
|
+
* and drop a real logged request into the user's account.
|
|
69
|
+
*/
|
|
70
|
+
protected buildDemoCompletion(): Record<string, unknown>;
|
|
71
|
+
protected selectAgent(flagAgent: CliTool | undefined, detected: DetectionSignal[]): Promise<CliTool | null>;
|
|
72
|
+
protected installSkill(): Promise<void>;
|
|
73
|
+
protected launchAgent(tool: CliTool, projectRoot: string, mode: SetupMode): Promise<void>;
|
|
74
|
+
protected logStep(num: number, label: string): void;
|
|
75
|
+
protected saveToEnv(envPath: string, existingContent: string, key: string, value: string): void;
|
|
76
|
+
protected getGitEmail(): string | undefined;
|
|
77
|
+
/**
|
|
78
|
+
* Send a lightweight setup notification (email only).
|
|
79
|
+
* This helps the team know when new users set up Respan so we can
|
|
80
|
+
* reach out and help with onboarding.
|
|
81
|
+
*/
|
|
82
|
+
protected notifySetup(email?: string): Promise<void>;
|
|
83
|
+
}
|
|
84
|
+
export {};
|