@respan/cli 0.4.1 → 0.5.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.
@@ -81,6 +81,38 @@ def save_state(state: Dict[str, Any]) -> None:
81
81
  STATE_FILE.write_text(json.dumps(state, indent=2), encoding="utf-8")
82
82
 
83
83
 
84
+ # Known config keys in respan.json that map to span fields.
85
+ # Anything else is treated as a custom property (goes into metadata).
86
+ KNOWN_CONFIG_KEYS = {"customer_id", "span_name", "workflow_name"}
87
+
88
+
89
+ def load_respan_config(cwd: str) -> Dict[str, Any]:
90
+ """Load .claude/respan.json from the project directory.
91
+
92
+ Returns a dict with two keys:
93
+ - "fields": known span fields (customer_id, span_name, workflow_name)
94
+ - "properties": everything else (custom properties → metadata)
95
+ """
96
+ config_path = Path(cwd) / ".claude" / "respan.json"
97
+ if not config_path.exists():
98
+ return {"fields": {}, "properties": {}}
99
+ try:
100
+ raw = json.loads(config_path.read_text(encoding="utf-8"))
101
+ if not isinstance(raw, dict):
102
+ return {"fields": {}, "properties": {}}
103
+ fields = {}
104
+ properties = {}
105
+ for k, v in raw.items():
106
+ if k in KNOWN_CONFIG_KEYS:
107
+ fields[k] = v
108
+ else:
109
+ properties[k] = v
110
+ return {"fields": fields, "properties": properties}
111
+ except (json.JSONDecodeError, IOError) as e:
112
+ debug(f"Failed to load respan.json from {config_path}: {e}")
113
+ return {"fields": {}, "properties": {}}
114
+
115
+
84
116
  def get_content(msg: Dict[str, Any]) -> Any:
85
117
  """Extract content from a message."""
86
118
  if isinstance(msg, dict):
@@ -317,6 +349,7 @@ def create_respan_spans(
317
349
  user_msg: Dict[str, Any],
318
350
  assistant_msgs: List[Dict[str, Any]],
319
351
  tool_results: List[Dict[str, Any]],
352
+ config: Optional[Dict[str, Any]] = None,
320
353
  ) -> List[Dict[str, Any]]:
321
354
  """Create Respan span logs for a single turn with all available metadata.
322
355
 
@@ -395,16 +428,20 @@ def create_respan_spans(
395
428
  if final_output:
396
429
  completion_message = {"role": "assistant", "content": final_output}
397
430
 
398
- # IDs
431
+ # IDs — respan.json fields, then env var overrides
432
+ cfg_fields = (config or {}).get("fields", {})
433
+ cfg_props = (config or {}).get("properties", {})
434
+
399
435
  trace_unique_id = f"{session_id}_turn_{turn_num}"
400
- workflow_name = "claude-code"
401
- user_preview = (user_text[:60] + "...") if user_text and len(user_text) > 60 else (user_text or f"turn_{turn_num}")
402
- root_span_name = f"Turn {turn_num}: {user_preview}"
436
+ workflow_name = os.environ.get("RESPAN_WORKFLOW_NAME") or cfg_fields.get("workflow_name") or "claude-code"
437
+ root_span_name = os.environ.get("RESPAN_SPAN_NAME") or cfg_fields.get("span_name") or "claude-code"
403
438
  thread_id = f"claudecode_{session_id}"
404
- customer_id = os.environ.get("RESPAN_CUSTOMER_ID", "claude-code")
439
+ customer_id = os.environ.get("RESPAN_CUSTOMER_ID") or cfg_fields.get("customer_id") or ""
405
440
 
406
- # Metadata
441
+ # Metadata — custom properties from respan.json, then env overrides
407
442
  metadata: Dict[str, Any] = {"claude_code_turn": turn_num}
443
+ if cfg_props:
444
+ metadata.update(cfg_props)
408
445
  if request_id:
409
446
  metadata["request_id"] = request_id
410
447
  if stop_reason:
@@ -454,8 +491,8 @@ def create_respan_spans(
454
491
  "span_unique_id": root_span_id,
455
492
  "span_name": root_span_name,
456
493
  "span_workflow_name": workflow_name,
494
+ "model": model,
457
495
  "span_path": "",
458
- "log_type": "agent",
459
496
  "input": json.dumps(prompt_messages) if prompt_messages else "",
460
497
  "output": json.dumps(completion_message) if completion_message else "",
461
498
  "timestamp": timestamp_str,
@@ -485,7 +522,6 @@ def create_respan_spans(
485
522
  "span_name": "claude.chat",
486
523
  "span_workflow_name": workflow_name,
487
524
  "span_path": "claude_chat",
488
- "log_type": "generation",
489
525
  "model": model,
490
526
  "provider_id": "anthropic",
491
527
  "input": json.dumps(prompt_messages) if prompt_messages else "",
@@ -524,7 +560,6 @@ def create_respan_spans(
524
560
  "span_name": f"Thinking {thinking_num}",
525
561
  "span_workflow_name": workflow_name,
526
562
  "span_path": "thinking",
527
- "log_type": "generation",
528
563
  "input": "",
529
564
  "output": thinking_text,
530
565
  "timestamp": thinking_ts,
@@ -575,7 +610,6 @@ def create_respan_spans(
575
610
  "span_name": f"Tool: {td['name']}",
576
611
  "span_workflow_name": workflow_name,
577
612
  "span_path": f"tool_{td['name'].lower()}",
578
- "log_type": "tool",
579
613
  "input": format_tool_input(td["name"], td["input"]),
580
614
  "output": format_tool_output(td["name"], td.get("output")),
581
615
  "timestamp": tool_ts,
@@ -588,6 +622,26 @@ def create_respan_spans(
588
622
  tool_span["latency"] = duration_ms / 1000.0
589
623
  spans.append(tool_span)
590
624
 
625
+ # Add required Respan platform fields to every span.
626
+ # The backend expects these on all spans (per official SDK examples).
627
+ respan_defaults = {
628
+ "warnings": "",
629
+ "encoding_format": "float",
630
+ "disable_fallback": False,
631
+ "respan_params": {
632
+ "has_webhook": False,
633
+ "environment": os.environ.get("RESPAN_ENVIRONMENT", "prod"),
634
+ },
635
+ "field_name": "data: ",
636
+ "delimiter": "\n\n",
637
+ "disable_log": False,
638
+ "request_breakdown": False,
639
+ }
640
+ for span in spans:
641
+ for key, value in respan_defaults.items():
642
+ if key not in span:
643
+ span[key] = value
644
+
591
645
  return spans
592
646
 
593
647
 
@@ -597,36 +651,49 @@ def send_spans(
597
651
  base_url: str,
598
652
  turn_num: int,
599
653
  ) -> None:
600
- """Send spans to Respan with timeout and one retry on transient errors."""
654
+ """Send spans to Respan as a single batch (matches official SDK behaviour).
655
+
656
+ The official Respan tracing SDK sends all spans for a trace in one
657
+ POST request to ``/v1/traces/ingest``. We do the same here, with
658
+ simple retry logic for transient server errors.
659
+ """
601
660
  url = f"{base_url}/v1/traces/ingest"
602
661
  headers = {"Authorization": f"Bearer {api_key}"}
603
662
 
604
- for attempt in range(2):
663
+ span_names = [s.get("span_name", "?") for s in spans]
664
+ payload_json = json.dumps(spans)
665
+ payload_size = len(payload_json)
666
+ debug(f"Sending {len(spans)} spans ({payload_size} bytes) for turn {turn_num}: {span_names}")
667
+ if DEBUG:
668
+ debug_file = LOG_FILE.parent / f"respan_spans_turn_{turn_num}.json"
669
+ debug_file.write_text(payload_json, encoding="utf-8")
670
+ debug(f"Dumped spans to {debug_file}")
671
+
672
+ for attempt in range(3):
605
673
  try:
606
674
  response = requests.post(url, json=spans, headers=headers, timeout=30)
607
675
  if response.status_code < 400:
608
- debug(f"Sent {len(spans)} spans for turn {turn_num}")
676
+ resp_text = response.text[:300] if response.text else ""
677
+ debug(f"Sent {len(spans)} spans for turn {turn_num} "
678
+ f"(attempt {attempt + 1}): {resp_text}")
609
679
  return
610
680
  if response.status_code < 500:
611
- # 4xx not retryable
612
- log("ERROR", f"Failed to send spans for turn {turn_num}: HTTP {response.status_code}")
681
+ log("ERROR", f"Spans rejected for turn {turn_num}: "
682
+ f"HTTP {response.status_code} - {response.text[:200]}")
613
683
  return
614
- # 5xx — retryable
615
- if attempt == 0:
616
- debug(f"Server error {response.status_code} for turn {turn_num}, retrying...")
617
- time.sleep(1)
618
- continue
619
- log("ERROR", f"Failed to send spans for turn {turn_num} after retry: HTTP {response.status_code}")
620
- except (requests.exceptions.Timeout, requests.exceptions.ConnectionError) as e:
621
- if attempt == 0:
622
- debug(f"Transient error for turn {turn_num}: {e}, retrying...")
623
- time.sleep(1)
624
- continue
625
- log("ERROR", f"Failed to send spans for turn {turn_num} after retry: {e}")
684
+ # 5xx — retry after short delay
685
+ debug(f"Server error for turn {turn_num} "
686
+ f"(attempt {attempt + 1}), retrying...")
687
+ time.sleep(1.0)
688
+ except (requests.exceptions.Timeout, requests.exceptions.ConnectionError):
689
+ time.sleep(1.0)
626
690
  except Exception as e:
627
691
  log("ERROR", f"Failed to send spans for turn {turn_num}: {e}")
628
692
  return
629
693
 
694
+ log("ERROR", f"Failed to send {len(spans)} spans for turn {turn_num} "
695
+ f"after 3 attempts")
696
+
630
697
 
631
698
  def process_transcript(
632
699
  session_id: str,
@@ -634,6 +701,7 @@ def process_transcript(
634
701
  state: Dict[str, Any],
635
702
  api_key: str,
636
703
  base_url: str,
704
+ config: Optional[Dict[str, Any]] = None,
637
705
  ) -> int:
638
706
  """Process a transcript file and create traces for new turns."""
639
707
  # Get previous state for this session
@@ -683,7 +751,8 @@ def process_transcript(
683
751
  turns_processed += 1
684
752
  turn_num = turn_count + turns_processed
685
753
  spans = create_respan_spans(
686
- session_id, turn_num, current_user, current_assistants, current_tool_results
754
+ session_id, turn_num, current_user, current_assistants, current_tool_results,
755
+ config=config,
687
756
  )
688
757
  send_spans(spans, api_key, base_url, turn_num)
689
758
  last_committed_line = total_lines # safe default, refined below
@@ -745,8 +814,17 @@ def process_transcript(
745
814
  current_assistants.append(merged)
746
815
 
747
816
  if current_user and current_assistants:
748
- _commit_turn()
749
- last_committed_line = total_lines
817
+ # Check if the turn has actual text output. The Stop hook can fire
818
+ # before the final assistant text block is flushed to disk, leaving
819
+ # only thinking/tool_use blocks. If no text content is found, treat
820
+ # the turn as incomplete so the retry logic re-reads it.
821
+ has_text = any(get_text_content(m) for m in current_assistants)
822
+ if has_text:
823
+ _commit_turn()
824
+ last_committed_line = total_lines
825
+ else:
826
+ last_committed_line = current_user_line
827
+ debug(f"Turn has assistant msgs but no text output yet (likely not flushed), will retry")
750
828
  else:
751
829
  # Incomplete turn — rewind so the next run re-reads from the
752
830
  # unmatched user message (or from where we left off if no user).
@@ -859,13 +937,32 @@ def main():
859
937
  debug("Tracing disabled (TRACE_TO_RESPAN != true)")
860
938
  sys.exit(0)
861
939
 
862
- # Check for required environment variables
940
+ # Resolve API key: env var > ~/.config/respan/credentials.json
863
941
  api_key = os.getenv("RESPAN_API_KEY")
864
- # Default: api.respan.ai | Enterprise: endpoint.respan.ai (set RESPAN_BASE_URL)
865
942
  base_url = os.getenv("RESPAN_BASE_URL", "https://api.respan.ai/api")
866
943
 
867
944
  if not api_key:
868
- log("ERROR", "Respan API key not set (RESPAN_API_KEY)")
945
+ creds_file = Path.home() / ".config" / "respan" / "credentials.json"
946
+ if creds_file.exists():
947
+ try:
948
+ creds = json.loads(creds_file.read_text(encoding="utf-8"))
949
+ # Find the active profile's credential
950
+ config_file = Path.home() / ".config" / "respan" / "config.json"
951
+ profile = "default"
952
+ if config_file.exists():
953
+ cfg = json.loads(config_file.read_text(encoding="utf-8"))
954
+ profile = cfg.get("activeProfile", "default")
955
+ cred = creds.get(profile, {})
956
+ api_key = cred.get("apiKey") or cred.get("accessToken")
957
+ if not base_url or base_url == "https://api.respan.ai/api":
958
+ base_url = cred.get("baseUrl", base_url)
959
+ if api_key:
960
+ debug(f"Using API key from credentials.json (profile: {profile})")
961
+ except (json.JSONDecodeError, IOError) as e:
962
+ debug(f"Failed to read credentials.json: {e}")
963
+
964
+ if not api_key:
965
+ log("ERROR", "No API key found. Run: respan auth login")
869
966
  sys.exit(0)
870
967
 
871
968
  # Try stdin payload first, fall back to filesystem scan
@@ -884,11 +981,49 @@ def main():
884
981
 
885
982
  debug(f"Processing session: {session_id}")
886
983
 
887
- # Process the transcript under file lock
984
+ # Load respan.json config from the project directory.
985
+ # Extract the project CWD from the first user message in the transcript.
986
+ config: Dict[str, Any] = {"fields": {}, "properties": {}}
987
+ try:
988
+ first_line = transcript_file.read_text(encoding="utf-8").split("\n")[0]
989
+ if first_line:
990
+ first_msg = json.loads(first_line)
991
+ cwd = first_msg.get("cwd")
992
+ if not cwd:
993
+ # Try second line (first is often file-history-snapshot)
994
+ lines = transcript_file.read_text(encoding="utf-8").split("\n")
995
+ for line in lines[:5]:
996
+ if line.strip():
997
+ msg = json.loads(line)
998
+ cwd = msg.get("cwd")
999
+ if cwd:
1000
+ break
1001
+ if cwd:
1002
+ config = load_respan_config(cwd)
1003
+ debug(f"Loaded respan.json config from {cwd}: {config}")
1004
+ except Exception as e:
1005
+ debug(f"Failed to extract CWD or load config: {e}")
1006
+
1007
+ # Process the transcript under file lock.
1008
+ # Retry up to 3 times with a short delay — the Stop hook can fire
1009
+ # before Claude Code finishes flushing the assistant response to
1010
+ # the transcript file, causing an incomplete turn on the first read.
1011
+ max_attempts = 3
1012
+ turns = 0
888
1013
  try:
889
- with state_lock():
890
- state = load_state()
891
- turns = process_transcript(session_id, transcript_file, state, api_key, base_url)
1014
+ for attempt in range(max_attempts):
1015
+ with state_lock():
1016
+ state = load_state()
1017
+ turns = process_transcript(session_id, transcript_file, state, api_key, base_url, config=config)
1018
+
1019
+ if turns > 0:
1020
+ break
1021
+
1022
+ if attempt < max_attempts - 1:
1023
+ delay = 0.5 * (attempt + 1)
1024
+ debug(f"No turns processed (attempt {attempt + 1}/{max_attempts}), "
1025
+ f"retrying in {delay}s...")
1026
+ time.sleep(delay)
892
1027
 
893
1028
  # Log execution time
894
1029
  duration = (datetime.now() - script_start).total_seconds()
@@ -8,6 +8,9 @@ export default class IntegrateClaudeCode extends BaseCommand {
8
8
  'project-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
9
  'base-url': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
10
  attrs: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
11
+ 'customer-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ 'span-name': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
+ 'workflow-name': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
14
  'dry-run': import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
15
  'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
16
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
@@ -1,15 +1,19 @@
1
1
  import * as fs from 'node:fs';
2
2
  import { execSync } from 'node:child_process';
3
3
  import { BaseCommand } from '../../lib/base-command.js';
4
- import { integrateFlags, deepMerge, readJsonFile, writeJsonFile, writeTextFile, expandHome, parseAttrs, getHookScript, resolveScope, findProjectRoot, DEFAULT_BASE_URL, } from '../../lib/integrate.js';
4
+ import { integrateFlags, deepMerge, readJsonFile, writeJsonFile, writeTextFile, expandHome, parseAttrs, getHookScript, resolveScope, findProjectRoot, } from '../../lib/integrate.js';
5
5
  class IntegrateClaudeCode extends BaseCommand {
6
6
  async run() {
7
7
  const { flags } = await this.parse(IntegrateClaudeCode);
8
8
  this.globalFlags = flags;
9
9
  try {
10
- const apiKey = this.resolveApiKey();
10
+ // Verify the user is authenticated (key is read by hook from ~/.config/respan/)
11
+ this.resolveApiKey();
11
12
  const baseUrl = flags['base-url'];
12
13
  const projectId = flags['project-id'];
14
+ const customerId = flags['customer-id'];
15
+ const spanName = flags['span-name'];
16
+ const workflowName = flags['workflow-name'];
13
17
  const attrs = parseAttrs(flags.attrs);
14
18
  const dryRun = flags['dry-run'];
15
19
  // Claude Code default: both global + local
@@ -89,20 +93,10 @@ class IntegrateClaudeCode extends BaseCommand {
89
93
  const projectRoot = findProjectRoot();
90
94
  const localSettingsPath = `${projectRoot}/.claude/settings.local.json`;
91
95
  const localSettings = readJsonFile(localSettingsPath);
96
+ // settings.local.json: enable flag only (API key from ~/.config/respan/)
92
97
  const envBlock = {
93
98
  TRACE_TO_RESPAN: 'true',
94
- RESPAN_API_KEY: apiKey,
95
99
  };
96
- if (baseUrl !== DEFAULT_BASE_URL) {
97
- envBlock.RESPAN_BASE_URL = baseUrl;
98
- }
99
- const metadata = { ...attrs };
100
- if (projectId) {
101
- metadata.project_id = projectId;
102
- }
103
- if (Object.keys(metadata).length > 0) {
104
- envBlock.RESPAN_METADATA = JSON.stringify(metadata);
105
- }
106
100
  const mergedLocal = deepMerge(localSettings, { env: envBlock });
107
101
  if (dryRun) {
108
102
  this.log(`[dry-run] Would update: ${localSettingsPath}`);
@@ -112,6 +106,36 @@ class IntegrateClaudeCode extends BaseCommand {
112
106
  writeJsonFile(localSettingsPath, mergedLocal);
113
107
  this.log(`Updated project settings: ${localSettingsPath}`);
114
108
  }
109
+ // respan.json: non-secret config (known fields + custom properties)
110
+ const respanConfigPath = `${projectRoot}/.claude/respan.json`;
111
+ const respanConfig = readJsonFile(respanConfigPath);
112
+ const newConfig = { ...respanConfig };
113
+ if (customerId) {
114
+ newConfig.customer_id = customerId;
115
+ }
116
+ if (spanName) {
117
+ newConfig.span_name = spanName;
118
+ }
119
+ if (workflowName) {
120
+ newConfig.workflow_name = workflowName;
121
+ }
122
+ if (projectId) {
123
+ newConfig.project_id = projectId;
124
+ }
125
+ // Custom attrs go as top-level keys (unknown keys = custom properties)
126
+ for (const [k, v] of Object.entries(attrs)) {
127
+ newConfig[k] = v;
128
+ }
129
+ if (Object.keys(newConfig).length > 0) {
130
+ if (dryRun) {
131
+ this.log(`[dry-run] Would write: ${respanConfigPath}`);
132
+ this.log(JSON.stringify(newConfig, null, 2));
133
+ }
134
+ else {
135
+ writeJsonFile(respanConfigPath, newConfig);
136
+ this.log(`Wrote Respan config: ${respanConfigPath}`);
137
+ }
138
+ }
115
139
  }
116
140
  // ── Done ──────────────────────────────────────────────────────
117
141
  this.log('');
@@ -126,7 +150,15 @@ class IntegrateClaudeCode extends BaseCommand {
126
150
  this.log('Claude Code tracing enabled for this project.');
127
151
  }
128
152
  this.log('');
129
- this.log('Set dynamic metadata before a session:');
153
+ this.log('Auth: ~/.config/respan/credentials.json (from `respan auth login`)');
154
+ this.log('Config: .claude/respan.json (shareable, non-secret)');
155
+ this.log('');
156
+ this.log('Set properties via integrate flags or edit .claude/respan.json:');
157
+ this.log(' respan integrate claude-code --customer-id "frank" --span-name "my-app"');
158
+ this.log(' respan integrate claude-code --attrs \'{"team":"platform","env":"staging"}\'');
159
+ this.log('');
160
+ this.log('Override per-session with env vars:');
161
+ this.log(' export RESPAN_CUSTOMER_ID="your-name"');
130
162
  this.log(" export RESPAN_METADATA='{\"task_id\":\"T-123\"}'");
131
163
  }
132
164
  catch (error) {
@@ -8,6 +8,9 @@ export default class IntegrateCodexCli extends BaseCommand {
8
8
  'project-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
9
  'base-url': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
10
  attrs: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
11
+ 'customer-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ 'span-name': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
+ 'workflow-name': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
14
  'dry-run': import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
15
  'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
16
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
@@ -8,6 +8,9 @@ export default class IntegrateGeminiCli extends BaseCommand {
8
8
  'project-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
9
  'base-url': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
10
  attrs: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
11
+ 'customer-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ 'span-name': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
+ 'workflow-name': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
14
  'dry-run': import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
15
  'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
16
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
@@ -8,6 +8,9 @@ export default class IntegrateOpencode extends BaseCommand {
8
8
  'project-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
9
  'base-url': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
10
  attrs: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
11
+ 'customer-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ 'span-name': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
+ 'workflow-name': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
14
  'dry-run': import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
15
  'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
16
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
@@ -6,6 +6,9 @@ export declare const integrateFlags: {
6
6
  'project-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
7
  'base-url': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
8
8
  attrs: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
9
+ 'customer-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ 'span-name': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ 'workflow-name': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
12
  'dry-run': import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
13
  };
11
14
  export type Scope = 'local' | 'global' | 'both';
@@ -31,6 +31,16 @@ export const integrateFlags = {
31
31
  description: "Custom attributes JSON (e.g. '{\"env\":\"prod\"}')",
32
32
  default: '{}',
33
33
  }),
34
+ 'customer-id': Flags.string({
35
+ description: 'Customer/user identifier for traces (e.g. your name or email)',
36
+ env: 'RESPAN_CUSTOMER_ID',
37
+ }),
38
+ 'span-name': Flags.string({
39
+ description: 'Root span name for traces (default: claude-code)',
40
+ }),
41
+ 'workflow-name': Flags.string({
42
+ description: 'Workflow name for traces (default: claude-code)',
43
+ }),
34
44
  'dry-run': Flags.boolean({
35
45
  description: 'Preview changes without writing files',
36
46
  default: false,
@@ -428,16 +428,10 @@
428
428
  "set.js"
429
429
  ]
430
430
  },
431
- "datasets:add-spans": {
431
+ "evaluators:create": {
432
432
  "aliases": [],
433
- "args": {
434
- "dataset-id": {
435
- "description": "Dataset ID",
436
- "name": "dataset-id",
437
- "required": true
438
- }
439
- },
440
- "description": "Add existing spans to a dataset",
433
+ "args": {},
434
+ "description": "Create a new evaluator",
441
435
  "flags": {
442
436
  "api-key": {
443
437
  "description": "API key (env: RESPAN_API_KEY)",
@@ -473,18 +467,39 @@
473
467
  "allowNo": false,
474
468
  "type": "boolean"
475
469
  },
476
- "span-ids": {
477
- "description": "Comma-separated span IDs",
478
- "name": "span-ids",
470
+ "name": {
471
+ "description": "Evaluator name",
472
+ "name": "name",
479
473
  "required": true,
480
474
  "hasDynamicHelp": false,
481
475
  "multiple": false,
482
476
  "type": "option"
477
+ },
478
+ "type": {
479
+ "description": "Evaluator type",
480
+ "name": "type",
481
+ "hasDynamicHelp": false,
482
+ "multiple": false,
483
+ "type": "option"
484
+ },
485
+ "description": {
486
+ "description": "Evaluator description",
487
+ "name": "description",
488
+ "hasDynamicHelp": false,
489
+ "multiple": false,
490
+ "type": "option"
491
+ },
492
+ "config": {
493
+ "description": "Evaluator config as JSON string",
494
+ "name": "config",
495
+ "hasDynamicHelp": false,
496
+ "multiple": false,
497
+ "type": "option"
483
498
  }
484
499
  },
485
500
  "hasDynamicHelp": false,
486
501
  "hiddenAliases": [],
487
- "id": "datasets:add-spans",
502
+ "id": "evaluators:create",
488
503
  "pluginAlias": "@respan/cli",
489
504
  "pluginName": "@respan/cli",
490
505
  "pluginType": "core",
@@ -494,20 +509,20 @@
494
509
  "relativePath": [
495
510
  "dist",
496
511
  "commands",
497
- "datasets",
498
- "add-spans.js"
512
+ "evaluators",
513
+ "create.js"
499
514
  ]
500
515
  },
501
- "datasets:create-span": {
516
+ "evaluators:get": {
502
517
  "aliases": [],
503
518
  "args": {
504
- "dataset-id": {
505
- "description": "Dataset ID",
506
- "name": "dataset-id",
519
+ "id": {
520
+ "description": "Evaluator ID",
521
+ "name": "id",
507
522
  "required": true
508
523
  }
509
524
  },
510
- "description": "Create a span in a dataset",
525
+ "description": "Get a specific evaluator",
511
526
  "flags": {
512
527
  "api-key": {
513
528
  "description": "API key (env: RESPAN_API_KEY)",
@@ -542,19 +557,11 @@
542
557
  "name": "verbose",
543
558
  "allowNo": false,
544
559
  "type": "boolean"
545
- },
546
- "body": {
547
- "description": "Span body as JSON string",
548
- "name": "body",
549
- "required": true,
550
- "hasDynamicHelp": false,
551
- "multiple": false,
552
- "type": "option"
553
560
  }
554
561
  },
555
562
  "hasDynamicHelp": false,
556
563
  "hiddenAliases": [],
557
- "id": "datasets:create-span",
564
+ "id": "evaluators:get",
558
565
  "pluginAlias": "@respan/cli",
559
566
  "pluginName": "@respan/cli",
560
567
  "pluginType": "core",
@@ -564,14 +571,14 @@
564
571
  "relativePath": [
565
572
  "dist",
566
573
  "commands",
567
- "datasets",
568
- "create-span.js"
574
+ "evaluators",
575
+ "get.js"
569
576
  ]
570
577
  },
571
- "datasets:create": {
578
+ "evaluators:list": {
572
579
  "aliases": [],
573
580
  "args": {},
574
- "description": "Create a new dataset",
581
+ "description": "List evaluators",
575
582
  "flags": {
576
583
  "api-key": {
577
584
  "description": "API key (env: RESPAN_API_KEY)",
@@ -607,17 +614,18 @@
607
614
  "allowNo": false,
608
615
  "type": "boolean"
609
616
  },
610
- "name": {
611
- "description": "Dataset name",
612
- "name": "name",
613
- "required": true,
617
+ "limit": {
618
+ "description": "Number of results per page",
619
+ "name": "limit",
620
+ "default": 20,
614
621
  "hasDynamicHelp": false,
615
622
  "multiple": false,
616
623
  "type": "option"
617
624
  },
618
- "description": {
619
- "description": "Dataset description",
620
- "name": "description",
625
+ "page": {
626
+ "description": "Page number",
627
+ "name": "page",
628
+ "default": 1,
621
629
  "hasDynamicHelp": false,
622
630
  "multiple": false,
623
631
  "type": "option"
@@ -625,7 +633,7 @@
625
633
  },
626
634
  "hasDynamicHelp": false,
627
635
  "hiddenAliases": [],
628
- "id": "datasets:create",
636
+ "id": "evaluators:list",
629
637
  "pluginAlias": "@respan/cli",
630
638
  "pluginName": "@respan/cli",
631
639
  "pluginType": "core",
@@ -635,25 +643,20 @@
635
643
  "relativePath": [
636
644
  "dist",
637
645
  "commands",
638
- "datasets",
639
- "create.js"
646
+ "evaluators",
647
+ "list.js"
640
648
  ]
641
649
  },
642
- "datasets:get-span": {
650
+ "evaluators:run": {
643
651
  "aliases": [],
644
652
  "args": {
645
- "dataset-id": {
646
- "description": "Dataset ID",
647
- "name": "dataset-id",
648
- "required": true
649
- },
650
- "span-id": {
651
- "description": "Span ID",
652
- "name": "span-id",
653
+ "id": {
654
+ "description": "Evaluator ID",
655
+ "name": "id",
653
656
  "required": true
654
657
  }
655
658
  },
656
- "description": "Get a specific span from a dataset",
659
+ "description": "Run an evaluator",
657
660
  "flags": {
658
661
  "api-key": {
659
662
  "description": "API key (env: RESPAN_API_KEY)",
@@ -688,11 +691,32 @@
688
691
  "name": "verbose",
689
692
  "allowNo": false,
690
693
  "type": "boolean"
694
+ },
695
+ "dataset-id": {
696
+ "description": "Dataset ID to evaluate against",
697
+ "name": "dataset-id",
698
+ "hasDynamicHelp": false,
699
+ "multiple": false,
700
+ "type": "option"
701
+ },
702
+ "log-ids": {
703
+ "description": "Comma-separated log/span IDs to evaluate",
704
+ "name": "log-ids",
705
+ "hasDynamicHelp": false,
706
+ "multiple": false,
707
+ "type": "option"
708
+ },
709
+ "params": {
710
+ "description": "Additional parameters as JSON string",
711
+ "name": "params",
712
+ "hasDynamicHelp": false,
713
+ "multiple": false,
714
+ "type": "option"
691
715
  }
692
716
  },
693
717
  "hasDynamicHelp": false,
694
718
  "hiddenAliases": [],
695
- "id": "datasets:get-span",
719
+ "id": "evaluators:run",
696
720
  "pluginAlias": "@respan/cli",
697
721
  "pluginName": "@respan/cli",
698
722
  "pluginType": "core",
@@ -702,20 +726,20 @@
702
726
  "relativePath": [
703
727
  "dist",
704
728
  "commands",
705
- "datasets",
706
- "get-span.js"
729
+ "evaluators",
730
+ "run.js"
707
731
  ]
708
732
  },
709
- "datasets:get": {
733
+ "evaluators:update": {
710
734
  "aliases": [],
711
735
  "args": {
712
736
  "id": {
713
- "description": "Dataset ID",
737
+ "description": "Evaluator ID",
714
738
  "name": "id",
715
739
  "required": true
716
740
  }
717
741
  },
718
- "description": "Get a specific dataset",
742
+ "description": "Update an evaluator",
719
743
  "flags": {
720
744
  "api-key": {
721
745
  "description": "API key (env: RESPAN_API_KEY)",
@@ -750,11 +774,32 @@
750
774
  "name": "verbose",
751
775
  "allowNo": false,
752
776
  "type": "boolean"
777
+ },
778
+ "name": {
779
+ "description": "Evaluator name",
780
+ "name": "name",
781
+ "hasDynamicHelp": false,
782
+ "multiple": false,
783
+ "type": "option"
784
+ },
785
+ "description": {
786
+ "description": "Evaluator description",
787
+ "name": "description",
788
+ "hasDynamicHelp": false,
789
+ "multiple": false,
790
+ "type": "option"
791
+ },
792
+ "config": {
793
+ "description": "Evaluator config as JSON string",
794
+ "name": "config",
795
+ "hasDynamicHelp": false,
796
+ "multiple": false,
797
+ "type": "option"
753
798
  }
754
799
  },
755
800
  "hasDynamicHelp": false,
756
801
  "hiddenAliases": [],
757
- "id": "datasets:get",
802
+ "id": "evaluators:update",
758
803
  "pluginAlias": "@respan/cli",
759
804
  "pluginName": "@respan/cli",
760
805
  "pluginType": "core",
@@ -764,14 +809,20 @@
764
809
  "relativePath": [
765
810
  "dist",
766
811
  "commands",
767
- "datasets",
768
- "get.js"
812
+ "evaluators",
813
+ "update.js"
769
814
  ]
770
815
  },
771
- "datasets:list": {
816
+ "datasets:add-spans": {
772
817
  "aliases": [],
773
- "args": {},
774
- "description": "List datasets",
818
+ "args": {
819
+ "dataset-id": {
820
+ "description": "Dataset ID",
821
+ "name": "dataset-id",
822
+ "required": true
823
+ }
824
+ },
825
+ "description": "Add existing spans to a dataset",
775
826
  "flags": {
776
827
  "api-key": {
777
828
  "description": "API key (env: RESPAN_API_KEY)",
@@ -807,18 +858,10 @@
807
858
  "allowNo": false,
808
859
  "type": "boolean"
809
860
  },
810
- "limit": {
811
- "description": "Number of results per page",
812
- "name": "limit",
813
- "default": 50,
814
- "hasDynamicHelp": false,
815
- "multiple": false,
816
- "type": "option"
817
- },
818
- "page": {
819
- "description": "Page number",
820
- "name": "page",
821
- "default": 1,
861
+ "span-ids": {
862
+ "description": "Comma-separated span IDs",
863
+ "name": "span-ids",
864
+ "required": true,
822
865
  "hasDynamicHelp": false,
823
866
  "multiple": false,
824
867
  "type": "option"
@@ -826,7 +869,7 @@
826
869
  },
827
870
  "hasDynamicHelp": false,
828
871
  "hiddenAliases": [],
829
- "id": "datasets:list",
872
+ "id": "datasets:add-spans",
830
873
  "pluginAlias": "@respan/cli",
831
874
  "pluginName": "@respan/cli",
832
875
  "pluginType": "core",
@@ -837,10 +880,10 @@
837
880
  "dist",
838
881
  "commands",
839
882
  "datasets",
840
- "list.js"
883
+ "add-spans.js"
841
884
  ]
842
885
  },
843
- "datasets:spans": {
886
+ "datasets:create-span": {
844
887
  "aliases": [],
845
888
  "args": {
846
889
  "dataset-id": {
@@ -849,7 +892,7 @@
849
892
  "required": true
850
893
  }
851
894
  },
852
- "description": "List spans in a dataset",
895
+ "description": "Create a span in a dataset",
853
896
  "flags": {
854
897
  "api-key": {
855
898
  "description": "API key (env: RESPAN_API_KEY)",
@@ -884,11 +927,19 @@
884
927
  "name": "verbose",
885
928
  "allowNo": false,
886
929
  "type": "boolean"
930
+ },
931
+ "body": {
932
+ "description": "Span body as JSON string",
933
+ "name": "body",
934
+ "required": true,
935
+ "hasDynamicHelp": false,
936
+ "multiple": false,
937
+ "type": "option"
887
938
  }
888
939
  },
889
940
  "hasDynamicHelp": false,
890
941
  "hiddenAliases": [],
891
- "id": "datasets:spans",
942
+ "id": "datasets:create-span",
892
943
  "pluginAlias": "@respan/cli",
893
944
  "pluginName": "@respan/cli",
894
945
  "pluginType": "core",
@@ -899,19 +950,13 @@
899
950
  "dist",
900
951
  "commands",
901
952
  "datasets",
902
- "spans.js"
953
+ "create-span.js"
903
954
  ]
904
955
  },
905
- "datasets:update": {
956
+ "datasets:create": {
906
957
  "aliases": [],
907
- "args": {
908
- "id": {
909
- "description": "Dataset ID",
910
- "name": "id",
911
- "required": true
912
- }
913
- },
914
- "description": "Update a dataset",
958
+ "args": {},
959
+ "description": "Create a new dataset",
915
960
  "flags": {
916
961
  "api-key": {
917
962
  "description": "API key (env: RESPAN_API_KEY)",
@@ -950,6 +995,7 @@
950
995
  "name": {
951
996
  "description": "Dataset name",
952
997
  "name": "name",
998
+ "required": true,
953
999
  "hasDynamicHelp": false,
954
1000
  "multiple": false,
955
1001
  "type": "option"
@@ -964,7 +1010,7 @@
964
1010
  },
965
1011
  "hasDynamicHelp": false,
966
1012
  "hiddenAliases": [],
967
- "id": "datasets:update",
1013
+ "id": "datasets:create",
968
1014
  "pluginAlias": "@respan/cli",
969
1015
  "pluginName": "@respan/cli",
970
1016
  "pluginType": "core",
@@ -975,13 +1021,24 @@
975
1021
  "dist",
976
1022
  "commands",
977
1023
  "datasets",
978
- "update.js"
1024
+ "create.js"
979
1025
  ]
980
1026
  },
981
- "evaluators:create": {
1027
+ "datasets:get-span": {
982
1028
  "aliases": [],
983
- "args": {},
984
- "description": "Create a new evaluator",
1029
+ "args": {
1030
+ "dataset-id": {
1031
+ "description": "Dataset ID",
1032
+ "name": "dataset-id",
1033
+ "required": true
1034
+ },
1035
+ "span-id": {
1036
+ "description": "Span ID",
1037
+ "name": "span-id",
1038
+ "required": true
1039
+ }
1040
+ },
1041
+ "description": "Get a specific span from a dataset",
985
1042
  "flags": {
986
1043
  "api-key": {
987
1044
  "description": "API key (env: RESPAN_API_KEY)",
@@ -1016,40 +1073,11 @@
1016
1073
  "name": "verbose",
1017
1074
  "allowNo": false,
1018
1075
  "type": "boolean"
1019
- },
1020
- "name": {
1021
- "description": "Evaluator name",
1022
- "name": "name",
1023
- "required": true,
1024
- "hasDynamicHelp": false,
1025
- "multiple": false,
1026
- "type": "option"
1027
- },
1028
- "type": {
1029
- "description": "Evaluator type",
1030
- "name": "type",
1031
- "hasDynamicHelp": false,
1032
- "multiple": false,
1033
- "type": "option"
1034
- },
1035
- "description": {
1036
- "description": "Evaluator description",
1037
- "name": "description",
1038
- "hasDynamicHelp": false,
1039
- "multiple": false,
1040
- "type": "option"
1041
- },
1042
- "config": {
1043
- "description": "Evaluator config as JSON string",
1044
- "name": "config",
1045
- "hasDynamicHelp": false,
1046
- "multiple": false,
1047
- "type": "option"
1048
1076
  }
1049
1077
  },
1050
1078
  "hasDynamicHelp": false,
1051
1079
  "hiddenAliases": [],
1052
- "id": "evaluators:create",
1080
+ "id": "datasets:get-span",
1053
1081
  "pluginAlias": "@respan/cli",
1054
1082
  "pluginName": "@respan/cli",
1055
1083
  "pluginType": "core",
@@ -1059,20 +1087,20 @@
1059
1087
  "relativePath": [
1060
1088
  "dist",
1061
1089
  "commands",
1062
- "evaluators",
1063
- "create.js"
1090
+ "datasets",
1091
+ "get-span.js"
1064
1092
  ]
1065
1093
  },
1066
- "evaluators:get": {
1094
+ "datasets:get": {
1067
1095
  "aliases": [],
1068
1096
  "args": {
1069
1097
  "id": {
1070
- "description": "Evaluator ID",
1098
+ "description": "Dataset ID",
1071
1099
  "name": "id",
1072
1100
  "required": true
1073
1101
  }
1074
1102
  },
1075
- "description": "Get a specific evaluator",
1103
+ "description": "Get a specific dataset",
1076
1104
  "flags": {
1077
1105
  "api-key": {
1078
1106
  "description": "API key (env: RESPAN_API_KEY)",
@@ -1111,7 +1139,7 @@
1111
1139
  },
1112
1140
  "hasDynamicHelp": false,
1113
1141
  "hiddenAliases": [],
1114
- "id": "evaluators:get",
1142
+ "id": "datasets:get",
1115
1143
  "pluginAlias": "@respan/cli",
1116
1144
  "pluginName": "@respan/cli",
1117
1145
  "pluginType": "core",
@@ -1121,14 +1149,14 @@
1121
1149
  "relativePath": [
1122
1150
  "dist",
1123
1151
  "commands",
1124
- "evaluators",
1152
+ "datasets",
1125
1153
  "get.js"
1126
1154
  ]
1127
1155
  },
1128
- "evaluators:list": {
1156
+ "datasets:list": {
1129
1157
  "aliases": [],
1130
1158
  "args": {},
1131
- "description": "List evaluators",
1159
+ "description": "List datasets",
1132
1160
  "flags": {
1133
1161
  "api-key": {
1134
1162
  "description": "API key (env: RESPAN_API_KEY)",
@@ -1167,7 +1195,7 @@
1167
1195
  "limit": {
1168
1196
  "description": "Number of results per page",
1169
1197
  "name": "limit",
1170
- "default": 20,
1198
+ "default": 50,
1171
1199
  "hasDynamicHelp": false,
1172
1200
  "multiple": false,
1173
1201
  "type": "option"
@@ -1183,7 +1211,7 @@
1183
1211
  },
1184
1212
  "hasDynamicHelp": false,
1185
1213
  "hiddenAliases": [],
1186
- "id": "evaluators:list",
1214
+ "id": "datasets:list",
1187
1215
  "pluginAlias": "@respan/cli",
1188
1216
  "pluginName": "@respan/cli",
1189
1217
  "pluginType": "core",
@@ -1193,20 +1221,20 @@
1193
1221
  "relativePath": [
1194
1222
  "dist",
1195
1223
  "commands",
1196
- "evaluators",
1224
+ "datasets",
1197
1225
  "list.js"
1198
1226
  ]
1199
1227
  },
1200
- "evaluators:run": {
1228
+ "datasets:spans": {
1201
1229
  "aliases": [],
1202
1230
  "args": {
1203
- "id": {
1204
- "description": "Evaluator ID",
1205
- "name": "id",
1231
+ "dataset-id": {
1232
+ "description": "Dataset ID",
1233
+ "name": "dataset-id",
1206
1234
  "required": true
1207
1235
  }
1208
1236
  },
1209
- "description": "Run an evaluator",
1237
+ "description": "List spans in a dataset",
1210
1238
  "flags": {
1211
1239
  "api-key": {
1212
1240
  "description": "API key (env: RESPAN_API_KEY)",
@@ -1241,32 +1269,11 @@
1241
1269
  "name": "verbose",
1242
1270
  "allowNo": false,
1243
1271
  "type": "boolean"
1244
- },
1245
- "dataset-id": {
1246
- "description": "Dataset ID to evaluate against",
1247
- "name": "dataset-id",
1248
- "hasDynamicHelp": false,
1249
- "multiple": false,
1250
- "type": "option"
1251
- },
1252
- "log-ids": {
1253
- "description": "Comma-separated log/span IDs to evaluate",
1254
- "name": "log-ids",
1255
- "hasDynamicHelp": false,
1256
- "multiple": false,
1257
- "type": "option"
1258
- },
1259
- "params": {
1260
- "description": "Additional parameters as JSON string",
1261
- "name": "params",
1262
- "hasDynamicHelp": false,
1263
- "multiple": false,
1264
- "type": "option"
1265
1272
  }
1266
1273
  },
1267
1274
  "hasDynamicHelp": false,
1268
1275
  "hiddenAliases": [],
1269
- "id": "evaluators:run",
1276
+ "id": "datasets:spans",
1270
1277
  "pluginAlias": "@respan/cli",
1271
1278
  "pluginName": "@respan/cli",
1272
1279
  "pluginType": "core",
@@ -1276,20 +1283,20 @@
1276
1283
  "relativePath": [
1277
1284
  "dist",
1278
1285
  "commands",
1279
- "evaluators",
1280
- "run.js"
1286
+ "datasets",
1287
+ "spans.js"
1281
1288
  ]
1282
1289
  },
1283
- "evaluators:update": {
1290
+ "datasets:update": {
1284
1291
  "aliases": [],
1285
1292
  "args": {
1286
1293
  "id": {
1287
- "description": "Evaluator ID",
1294
+ "description": "Dataset ID",
1288
1295
  "name": "id",
1289
1296
  "required": true
1290
1297
  }
1291
1298
  },
1292
- "description": "Update an evaluator",
1299
+ "description": "Update a dataset",
1293
1300
  "flags": {
1294
1301
  "api-key": {
1295
1302
  "description": "API key (env: RESPAN_API_KEY)",
@@ -1326,30 +1333,23 @@
1326
1333
  "type": "boolean"
1327
1334
  },
1328
1335
  "name": {
1329
- "description": "Evaluator name",
1336
+ "description": "Dataset name",
1330
1337
  "name": "name",
1331
1338
  "hasDynamicHelp": false,
1332
1339
  "multiple": false,
1333
1340
  "type": "option"
1334
1341
  },
1335
1342
  "description": {
1336
- "description": "Evaluator description",
1343
+ "description": "Dataset description",
1337
1344
  "name": "description",
1338
1345
  "hasDynamicHelp": false,
1339
1346
  "multiple": false,
1340
1347
  "type": "option"
1341
- },
1342
- "config": {
1343
- "description": "Evaluator config as JSON string",
1344
- "name": "config",
1345
- "hasDynamicHelp": false,
1346
- "multiple": false,
1347
- "type": "option"
1348
1348
  }
1349
1349
  },
1350
1350
  "hasDynamicHelp": false,
1351
1351
  "hiddenAliases": [],
1352
- "id": "evaluators:update",
1352
+ "id": "datasets:update",
1353
1353
  "pluginAlias": "@respan/cli",
1354
1354
  "pluginName": "@respan/cli",
1355
1355
  "pluginType": "core",
@@ -1359,7 +1359,7 @@
1359
1359
  "relativePath": [
1360
1360
  "dist",
1361
1361
  "commands",
1362
- "evaluators",
1362
+ "datasets",
1363
1363
  "update.js"
1364
1364
  ]
1365
1365
  },
@@ -1671,6 +1671,28 @@
1671
1671
  "multiple": false,
1672
1672
  "type": "option"
1673
1673
  },
1674
+ "customer-id": {
1675
+ "description": "Customer/user identifier for traces (e.g. your name or email)",
1676
+ "env": "RESPAN_CUSTOMER_ID",
1677
+ "name": "customer-id",
1678
+ "hasDynamicHelp": false,
1679
+ "multiple": false,
1680
+ "type": "option"
1681
+ },
1682
+ "span-name": {
1683
+ "description": "Root span name for traces (default: claude-code)",
1684
+ "name": "span-name",
1685
+ "hasDynamicHelp": false,
1686
+ "multiple": false,
1687
+ "type": "option"
1688
+ },
1689
+ "workflow-name": {
1690
+ "description": "Workflow name for traces (default: claude-code)",
1691
+ "name": "workflow-name",
1692
+ "hasDynamicHelp": false,
1693
+ "multiple": false,
1694
+ "type": "option"
1695
+ },
1674
1696
  "dry-run": {
1675
1697
  "description": "Preview changes without writing files",
1676
1698
  "name": "dry-run",
@@ -1781,6 +1803,28 @@
1781
1803
  "multiple": false,
1782
1804
  "type": "option"
1783
1805
  },
1806
+ "customer-id": {
1807
+ "description": "Customer/user identifier for traces (e.g. your name or email)",
1808
+ "env": "RESPAN_CUSTOMER_ID",
1809
+ "name": "customer-id",
1810
+ "hasDynamicHelp": false,
1811
+ "multiple": false,
1812
+ "type": "option"
1813
+ },
1814
+ "span-name": {
1815
+ "description": "Root span name for traces (default: claude-code)",
1816
+ "name": "span-name",
1817
+ "hasDynamicHelp": false,
1818
+ "multiple": false,
1819
+ "type": "option"
1820
+ },
1821
+ "workflow-name": {
1822
+ "description": "Workflow name for traces (default: claude-code)",
1823
+ "name": "workflow-name",
1824
+ "hasDynamicHelp": false,
1825
+ "multiple": false,
1826
+ "type": "option"
1827
+ },
1784
1828
  "dry-run": {
1785
1829
  "description": "Preview changes without writing files",
1786
1830
  "name": "dry-run",
@@ -1891,6 +1935,28 @@
1891
1935
  "multiple": false,
1892
1936
  "type": "option"
1893
1937
  },
1938
+ "customer-id": {
1939
+ "description": "Customer/user identifier for traces (e.g. your name or email)",
1940
+ "env": "RESPAN_CUSTOMER_ID",
1941
+ "name": "customer-id",
1942
+ "hasDynamicHelp": false,
1943
+ "multiple": false,
1944
+ "type": "option"
1945
+ },
1946
+ "span-name": {
1947
+ "description": "Root span name for traces (default: claude-code)",
1948
+ "name": "span-name",
1949
+ "hasDynamicHelp": false,
1950
+ "multiple": false,
1951
+ "type": "option"
1952
+ },
1953
+ "workflow-name": {
1954
+ "description": "Workflow name for traces (default: claude-code)",
1955
+ "name": "workflow-name",
1956
+ "hasDynamicHelp": false,
1957
+ "multiple": false,
1958
+ "type": "option"
1959
+ },
1894
1960
  "dry-run": {
1895
1961
  "description": "Preview changes without writing files",
1896
1962
  "name": "dry-run",
@@ -2001,6 +2067,28 @@
2001
2067
  "multiple": false,
2002
2068
  "type": "option"
2003
2069
  },
2070
+ "customer-id": {
2071
+ "description": "Customer/user identifier for traces (e.g. your name or email)",
2072
+ "env": "RESPAN_CUSTOMER_ID",
2073
+ "name": "customer-id",
2074
+ "hasDynamicHelp": false,
2075
+ "multiple": false,
2076
+ "type": "option"
2077
+ },
2078
+ "span-name": {
2079
+ "description": "Root span name for traces (default: claude-code)",
2080
+ "name": "span-name",
2081
+ "hasDynamicHelp": false,
2082
+ "multiple": false,
2083
+ "type": "option"
2084
+ },
2085
+ "workflow-name": {
2086
+ "description": "Workflow name for traces (default: claude-code)",
2087
+ "name": "workflow-name",
2088
+ "hasDynamicHelp": false,
2089
+ "multiple": false,
2090
+ "type": "option"
2091
+ },
2004
2092
  "dry-run": {
2005
2093
  "description": "Preview changes without writing files",
2006
2094
  "name": "dry-run",
@@ -3370,5 +3458,5 @@
3370
3458
  ]
3371
3459
  }
3372
3460
  },
3373
- "version": "0.4.1"
3461
+ "version": "0.5.0"
3374
3462
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@respan/cli",
3
- "version": "0.4.1",
3
+ "version": "0.5.0",
4
4
  "description": "Respan CLI - manage your LLM observability from the command line",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",