@respan/cli 0.9.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.
Files changed (62) hide show
  1. package/dist/commands/datasets/create-span.js +5 -3
  2. package/dist/commands/datasets/create.js +5 -4
  3. package/dist/commands/datasets/get-span.js +5 -1
  4. package/dist/commands/datasets/get.js +1 -1
  5. package/dist/commands/datasets/list.js +5 -1
  6. package/dist/commands/datasets/spans.js +1 -1
  7. package/dist/commands/datasets/update.js +3 -6
  8. package/dist/commands/{datasets/add-spans.d.ts → eval/index.d.ts} +2 -3
  9. package/dist/commands/eval/index.js +26 -0
  10. package/dist/commands/evaluators/create.js +10 -7
  11. package/dist/commands/evaluators/get.js +1 -1
  12. package/dist/commands/evaluators/list.js +1 -1
  13. package/dist/commands/evaluators/run.js +8 -7
  14. package/dist/commands/evaluators/update.js +6 -7
  15. package/dist/commands/experiments/create.js +9 -8
  16. package/dist/commands/experiments/get.js +1 -1
  17. package/dist/commands/experiments/list.js +1 -1
  18. package/dist/commands/logs/create.js +9 -7
  19. package/dist/commands/logs/get.js +1 -1
  20. package/dist/commands/logs/list.js +4 -3
  21. package/dist/commands/logs/summary.js +3 -2
  22. package/dist/commands/prompts/create-version.js +9 -9
  23. package/dist/commands/prompts/create.js +5 -4
  24. package/dist/commands/prompts/get.js +1 -1
  25. package/dist/commands/prompts/list.js +1 -1
  26. package/dist/commands/prompts/update.js +3 -6
  27. package/dist/commands/prompts/versions.js +1 -1
  28. package/dist/commands/setup/doctor.d.ts +0 -1
  29. package/dist/commands/setup/doctor.js +25 -40
  30. package/dist/commands/setup/gateway.d.ts +16 -0
  31. package/dist/commands/setup/gateway.js +33 -0
  32. package/dist/commands/setup/index.d.ts +4 -33
  33. package/dist/commands/setup/index.js +11 -907
  34. package/dist/commands/setup/tracing.d.ts +16 -0
  35. package/dist/commands/setup/tracing.js +33 -0
  36. package/dist/commands/traces/get.js +1 -1
  37. package/dist/commands/traces/list.js +8 -10
  38. package/dist/commands/traces/summary.js +6 -2
  39. package/dist/commands/users/get.js +1 -1
  40. package/dist/commands/users/list.js +5 -7
  41. package/dist/lib/agents.d.ts +16 -0
  42. package/dist/lib/agents.js +75 -0
  43. package/dist/lib/auth.js +24 -0
  44. package/dist/lib/base-command.d.ts +2 -0
  45. package/dist/lib/base-command.js +11 -1
  46. package/dist/lib/colors.d.ts +7 -0
  47. package/dist/lib/colors.js +10 -0
  48. package/dist/lib/eval/runner.d.ts +15 -0
  49. package/dist/lib/eval/runner.js +292 -0
  50. package/dist/lib/eval/schema.d.ts +67 -0
  51. package/dist/lib/eval/schema.js +22 -0
  52. package/dist/lib/integrate.d.ts +6 -0
  53. package/dist/lib/integrate.js +11 -0
  54. package/dist/lib/setup-base-command.d.ts +84 -0
  55. package/dist/lib/setup-base-command.js +649 -0
  56. package/dist/lib/skill-content.d.ts +1 -0
  57. package/dist/lib/skill-content.js +16 -0
  58. package/dist/lib/skill-refs.generated.d.ts +6 -0
  59. package/dist/lib/skill-refs.generated.js +1489 -0
  60. package/oclif.manifest.json +385 -230
  61. package/package.json +8 -3
  62. package/dist/commands/datasets/add-spans.js +0 -24
@@ -0,0 +1,67 @@
1
+ export interface EvalPromptMessage {
2
+ role: 'system' | 'user' | 'assistant';
3
+ content: string;
4
+ }
5
+ export interface EvalPromptBlock {
6
+ id?: string;
7
+ version_id?: string;
8
+ name: string;
9
+ description?: string;
10
+ model: string;
11
+ messages: EvalPromptMessage[];
12
+ temperature?: number;
13
+ max_tokens?: number;
14
+ top_p?: number;
15
+ }
16
+ export interface EvalDatasetBlock {
17
+ id?: string;
18
+ name: string;
19
+ description?: string;
20
+ rows: Record<string, unknown>[];
21
+ }
22
+ export interface EvalEvaluatorBlock {
23
+ evaluator_id?: string;
24
+ workflow_id?: string;
25
+ workflow_version_id?: string;
26
+ workflow_version_deployed?: number;
27
+ name: string;
28
+ type: 'llm' | 'code' | 'human';
29
+ score_value_type: 'numerical' | 'boolean' | 'percentage' | 'single_select' | 'multi_select' | 'json' | 'text' | 'categorical' | 'comment';
30
+ description?: string;
31
+ score_config?: {
32
+ min_score?: number;
33
+ max_score?: number;
34
+ choices?: {
35
+ name?: string;
36
+ value?: string;
37
+ }[];
38
+ };
39
+ passing_conditions?: Record<string, unknown>;
40
+ llm_config?: {
41
+ model: string;
42
+ evaluator_definition: string;
43
+ scoring_rubric?: string;
44
+ temperature?: number;
45
+ max_tokens?: number;
46
+ top_p?: number;
47
+ };
48
+ code_config?: {
49
+ eval_code_snippet: string;
50
+ };
51
+ }
52
+ export interface EvalExperimentBlock {
53
+ id?: string;
54
+ name?: string;
55
+ description?: string;
56
+ evaluators?: EvalEvaluatorBlock[];
57
+ evaluator_slugs?: string[];
58
+ evaluator_workflow_ids?: string[];
59
+ }
60
+ export interface EvalFile {
61
+ name: string;
62
+ experiment_name?: string;
63
+ prompt: EvalPromptBlock;
64
+ dataset: EvalDatasetBlock;
65
+ experiment?: EvalExperimentBlock;
66
+ }
67
+ export declare function parseEvalFile(raw: string): EvalFile;
@@ -0,0 +1,22 @@
1
+ export function parseEvalFile(raw) {
2
+ const data = JSON.parse(raw);
3
+ if (!data.name)
4
+ throw new Error('eval file: `name` is required');
5
+ if (!data.prompt)
6
+ throw new Error('eval file: `prompt` block is required');
7
+ if (!data.prompt.name)
8
+ throw new Error('eval file: `prompt.name` is required');
9
+ if (!data.prompt.model)
10
+ throw new Error('eval file: `prompt.model` is required');
11
+ if (!Array.isArray(data.prompt.messages) || data.prompt.messages.length === 0) {
12
+ throw new Error('eval file: `prompt.messages` must be a non-empty array');
13
+ }
14
+ if (!data.dataset)
15
+ throw new Error('eval file: `dataset` block is required');
16
+ if (!data.dataset.name)
17
+ throw new Error('eval file: `dataset.name` is required');
18
+ if (!Array.isArray(data.dataset.rows)) {
19
+ throw new Error('eval file: `dataset.rows` must be an array');
20
+ }
21
+ return data;
22
+ }
@@ -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
  /**
@@ -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 {};