fluxloop-cli 0.3.5__tar.gz → 0.3.6__tar.gz

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 (70) hide show
  1. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/PKG-INFO +16 -2
  2. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/README.md +15 -1
  3. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/__init__.py +1 -1
  4. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/commands/apikeys.py +4 -1
  5. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/commands/bundles.py +20 -5
  6. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/commands/context.py +4 -1
  7. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/commands/data.py +24 -6
  8. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/commands/evaluate.py +4 -1
  9. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/commands/inputs.py +20 -5
  10. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/commands/personas.py +12 -3
  11. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/commands/projects.py +8 -2
  12. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/commands/scenarios.py +28 -7
  13. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/commands/sync.py +8 -2
  14. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli.egg-info/PKG-INFO +16 -2
  15. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/pyproject.toml +1 -1
  16. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/api_utils.py +0 -0
  17. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/arg_binder.py +0 -0
  18. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/auth_manager.py +0 -0
  19. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/commands/__init__.py +0 -0
  20. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/commands/auth.py +0 -0
  21. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/commands/config.py +0 -0
  22. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/commands/criteria.py +0 -0
  23. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/commands/generate.py +0 -0
  24. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/commands/init.py +0 -0
  25. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/commands/local_context.py +0 -0
  26. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/commands/run.py +0 -0
  27. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/commands/status.py +0 -0
  28. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/commands/test.py +0 -0
  29. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/common_options.py +0 -0
  30. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/config_loader.py +0 -0
  31. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/config_schema.py +0 -0
  32. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/constants.py +0 -0
  33. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/context_manager.py +0 -0
  34. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/conversation_supervisor.py +0 -0
  35. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/environment.py +0 -0
  36. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/http_client.py +0 -0
  37. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/input_generator.py +0 -0
  38. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/llm_generator.py +0 -0
  39. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/main.py +0 -0
  40. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/project_paths.py +0 -0
  41. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/runner.py +0 -0
  42. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/target_loader.py +0 -0
  43. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/templates.py +0 -0
  44. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/testing/__init__.py +0 -0
  45. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/testing/pytest_plugin.py +0 -0
  46. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/testing/types.py +0 -0
  47. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/token_usage.py +0 -0
  48. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/turns.py +0 -0
  49. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli/validators.py +0 -0
  50. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli.egg-info/SOURCES.txt +0 -0
  51. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli.egg-info/dependency_links.txt +0 -0
  52. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli.egg-info/entry_points.txt +0 -0
  53. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli.egg-info/requires.txt +0 -0
  54. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/fluxloop_cli.egg-info/top_level.txt +0 -0
  55. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/setup.cfg +0 -0
  56. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/tests/test_analysis_recommendations.py +0 -0
  57. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/tests/test_arg_binder.py +0 -0
  58. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/tests/test_config_command.py +0 -0
  59. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/tests/test_conversation_supervisor.py +0 -0
  60. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/tests/test_evaluate_command.py +0 -0
  61. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/tests/test_evaluation_llm.py +0 -0
  62. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/tests/test_init_pytest_template.py +0 -0
  63. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/tests/test_input_generator.py +0 -0
  64. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/tests/test_prompt_library.py +0 -0
  65. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/tests/test_pytest_plugin.py +0 -0
  66. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/tests/test_run_command.py +0 -0
  67. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/tests/test_runner_multi_turn.py +0 -0
  68. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/tests/test_success_criteria.py +0 -0
  69. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/tests/test_target_loader.py +0 -0
  70. {fluxloop_cli-0.3.5 → fluxloop_cli-0.3.6}/tests/test_testing_types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fluxloop-cli
3
- Version: 0.3.5
3
+ Version: 0.3.6
4
4
  Summary: FluxLoop CLI for running agent simulations
5
5
  Author-email: FluxLoop Team <team@fluxloop.dev>
6
6
  License: Apache-2.0
@@ -128,6 +128,21 @@ Options:
128
128
  After running the script, open the folder in VSCode and use `FluxLoop: Show Environment Info`
129
129
  or `FluxLoop: Run Doctor` to confirm the environment.
130
130
 
131
+ ## Full Reset Script
132
+
133
+ To remove FluxLoop-only local state (`.fluxloop*`, `~/.fluxloop`), remove
134
+ project deps via `uv remove` (when `pyproject.toml` exists), and uninstall
135
+ `fluxloop-cli` / `fluxloop` from pipx/uv tool/pip:
136
+
137
+ ```bash
138
+ bash reset_fluxloop_env.sh --dry-run
139
+ bash reset_fluxloop_env.sh --yes
140
+ ```
141
+
142
+ Options:
143
+
144
+ - `--project-root PATH` - clean a specific project root
145
+
131
146
  ## Runner Integration Patterns
132
147
 
133
148
  Configure how FluxLoop calls your code in `configs/simulation.yaml`:
@@ -156,4 +171,3 @@ To package the CLI:
156
171
  ```
157
172
  ./build.sh
158
173
  ```
159
-
@@ -85,6 +85,21 @@ Options:
85
85
  After running the script, open the folder in VSCode and use `FluxLoop: Show Environment Info`
86
86
  or `FluxLoop: Run Doctor` to confirm the environment.
87
87
 
88
+ ## Full Reset Script
89
+
90
+ To remove FluxLoop-only local state (`.fluxloop*`, `~/.fluxloop`), remove
91
+ project deps via `uv remove` (when `pyproject.toml` exists), and uninstall
92
+ `fluxloop-cli` / `fluxloop` from pipx/uv tool/pip:
93
+
94
+ ```bash
95
+ bash reset_fluxloop_env.sh --dry-run
96
+ bash reset_fluxloop_env.sh --yes
97
+ ```
98
+
99
+ Options:
100
+
101
+ - `--project-root PATH` - clean a specific project root
102
+
88
103
  ## Runner Integration Patterns
89
104
 
90
105
  Configure how FluxLoop calls your code in `configs/simulation.yaml`:
@@ -113,4 +128,3 @@ To package the CLI:
113
128
  ```
114
129
  ./build.sh
115
130
  ```
116
-
@@ -2,7 +2,7 @@
2
2
  FluxLoop CLI - Command-line interface for running agent simulations.
3
3
  """
4
4
 
5
- __version__ = "0.3.5"
5
+ __version__ = "0.3.6"
6
6
 
7
7
  from .main import app
8
8
 
@@ -109,13 +109,16 @@ def create_api_key(
109
109
  project: Optional[str] = typer.Option(None, "--project", help="Project name (legacy)"),
110
110
  root: Path = typer.Option(Path(DEFAULT_ROOT_DIR_NAME), "--root", help="Root dir"),
111
111
  api_url: Optional[str] = typer.Option(None, "--api-url", help="API base URL"),
112
+ staging: bool = typer.Option(
113
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
114
+ ),
112
115
  ):
113
116
  """Create an API Key for sync operations (pull/upload).
114
117
 
115
118
  Saves to .fluxloop/.env (workspace level) by default.
116
119
  API keys are project-scoped and shared by all scenarios.
117
120
  """
118
- api_url = resolve_api_url(api_url)
121
+ api_url = resolve_api_url(api_url, staging=staging)
119
122
 
120
123
  # Priority: --env-file > workspace .fluxloop/.env > legacy resolution
121
124
  if env_file:
@@ -39,6 +39,9 @@ def publish(
39
39
  api_url: Optional[str] = typer.Option(
40
40
  None, "--api-url", help="FluxLoop API base URL"
41
41
  ),
42
+ staging: bool = typer.Option(
43
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
44
+ ),
42
45
  ):
43
46
  """
44
47
  Create and publish a bundle (combined operation).
@@ -47,7 +50,7 @@ def publish(
47
50
  1. Creates a bundle with status 'draft'
48
51
  2. Updates status to 'published'
49
52
  """
50
- api_url = resolve_api_url(api_url)
53
+ api_url = resolve_api_url(api_url, staging=staging)
51
54
 
52
55
  # Use context if no project_id specified
53
56
  if not project_id:
@@ -153,11 +156,14 @@ def create(
153
156
  api_url: Optional[str] = typer.Option(
154
157
  None, "--api-url", help="FluxLoop API base URL"
155
158
  ),
159
+ staging: bool = typer.Option(
160
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
161
+ ),
156
162
  ):
157
163
  """
158
164
  Create a new bundle (draft status).
159
165
  """
160
- api_url = resolve_api_url(api_url)
166
+ api_url = resolve_api_url(api_url, staging=staging)
161
167
 
162
168
  # Use context if no project_id specified
163
169
  if not project_id:
@@ -223,11 +229,14 @@ def list_bundles(
223
229
  api_url: Optional[str] = typer.Option(
224
230
  None, "--api-url", help="FluxLoop API base URL"
225
231
  ),
232
+ staging: bool = typer.Option(
233
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
234
+ ),
226
235
  ):
227
236
  """
228
237
  List all bundles.
229
238
  """
230
- api_url = resolve_api_url(api_url)
239
+ api_url = resolve_api_url(api_url, staging=staging)
231
240
 
232
241
  # Use context if no project_id specified
233
242
  if not project_id:
@@ -298,11 +307,14 @@ def show(
298
307
  api_url: Optional[str] = typer.Option(
299
308
  None, "--api-url", help="FluxLoop API base URL"
300
309
  ),
310
+ staging: bool = typer.Option(
311
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
312
+ ),
301
313
  ):
302
314
  """
303
315
  Show bundle details.
304
316
  """
305
- api_url = resolve_api_url(api_url)
317
+ api_url = resolve_api_url(api_url, staging=staging)
306
318
 
307
319
  try:
308
320
  client = create_authenticated_client(api_url, use_jwt=True)
@@ -367,11 +379,14 @@ def update(
367
379
  api_url: Optional[str] = typer.Option(
368
380
  None, "--api-url", help="FluxLoop API base URL"
369
381
  ),
382
+ staging: bool = typer.Option(
383
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
384
+ ),
370
385
  ):
371
386
  """
372
387
  Update bundle fields.
373
388
  """
374
- api_url = resolve_api_url(api_url)
389
+ api_url = resolve_api_url(api_url, staging=staging)
375
390
 
376
391
  # Build payload
377
392
  payload: Dict[str, Any] = {}
@@ -41,13 +41,16 @@ def refine(
41
41
  api_url: Optional[str] = typer.Option(
42
42
  None, "--api-url", help="FluxLoop API base URL"
43
43
  ),
44
+ staging: bool = typer.Option(
45
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
46
+ ),
44
47
  ):
45
48
  """
46
49
  Refine intent and extract constraints using AI.
47
50
 
48
51
  Uses current project from context if --project-id is not specified.
49
52
  """
50
- api_url = resolve_api_url(api_url)
53
+ api_url = resolve_api_url(api_url, staging=staging)
51
54
 
52
55
  # Use context if no project_id specified
53
56
  if not project_id:
@@ -108,6 +108,9 @@ def push(
108
108
  "--api-url",
109
109
  help="FluxLoop API base URL",
110
110
  ),
111
+ staging: bool = typer.Option(
112
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
113
+ ),
111
114
  quiet: bool = typer.Option(False, "--quiet", "-q", help="Minimal output"),
112
115
  ):
113
116
  """
@@ -139,7 +142,7 @@ def push(
139
142
  raise typer.Exit(1)
140
143
 
141
144
  # Resolve project
142
- api_url = resolve_api_url(api_url)
145
+ api_url = resolve_api_url(api_url, staging=staging)
143
146
  if not project_id:
144
147
  project_id = get_current_web_project_id()
145
148
  if not project_id:
@@ -293,13 +296,16 @@ def list_data(
293
296
  "--api-url",
294
297
  help="FluxLoop API base URL",
295
298
  ),
299
+ staging: bool = typer.Option(
300
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
301
+ ),
296
302
  ):
297
303
  """
298
304
  List all data in the project library.
299
305
 
300
306
  Shows both KNOWLEDGE (documents) and DATASET entries with their processing status.
301
307
  """
302
- api_url = resolve_api_url(api_url)
308
+ api_url = resolve_api_url(api_url, staging=staging)
303
309
 
304
310
  if not project_id:
305
311
  project_id = get_current_web_project_id()
@@ -390,11 +396,14 @@ def show(
390
396
  "--api-url",
391
397
  help="FluxLoop API base URL",
392
398
  ),
399
+ staging: bool = typer.Option(
400
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
401
+ ),
393
402
  ):
394
403
  """
395
404
  Show details of a specific data record.
396
405
  """
397
- api_url = resolve_api_url(api_url)
406
+ api_url = resolve_api_url(api_url, staging=staging)
398
407
 
399
408
  if not project_id:
400
409
  project_id = get_current_web_project_id()
@@ -498,6 +507,9 @@ def bind(
498
507
  "--api-url",
499
508
  help="FluxLoop API base URL",
500
509
  ),
510
+ staging: bool = typer.Option(
511
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
512
+ ),
501
513
  ):
502
514
  """
503
515
  Bind project data to a scenario.
@@ -505,7 +517,7 @@ def bind(
505
517
  Creates an association between data in the project library and a scenario,
506
518
  allowing the scenario to use this data for testing.
507
519
  """
508
- api_url = resolve_api_url(api_url)
520
+ api_url = resolve_api_url(api_url, staging=staging)
509
521
 
510
522
  if not scenario_id:
511
523
  scenario_id = get_current_scenario_id()
@@ -558,11 +570,14 @@ def unbind(
558
570
  "--api-url",
559
571
  help="FluxLoop API base URL",
560
572
  ),
573
+ staging: bool = typer.Option(
574
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
575
+ ),
561
576
  ):
562
577
  """
563
578
  Remove a data binding from a scenario.
564
579
  """
565
- api_url = resolve_api_url(api_url)
580
+ api_url = resolve_api_url(api_url, staging=staging)
566
581
 
567
582
  if not scenario_id:
568
583
  scenario_id = get_current_scenario_id()
@@ -607,6 +622,9 @@ def reprocess(
607
622
  "--api-url",
608
623
  help="FluxLoop API base URL",
609
624
  ),
625
+ staging: bool = typer.Option(
626
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
627
+ ),
610
628
  ):
611
629
  """
612
630
  Reprocess data with a different category or to fix processing errors.
@@ -615,7 +633,7 @@ def reprocess(
615
633
  - Initial processing failed
616
634
  - You want to change the data category (document ↔ dataset)
617
635
  """
618
- api_url = resolve_api_url(api_url)
636
+ api_url = resolve_api_url(api_url, staging=staging)
619
637
 
620
638
  if not project_id:
621
639
  project_id = get_current_web_project_id()
@@ -57,6 +57,9 @@ def main(
57
57
  api_url: Optional[str] = typer.Option(
58
58
  None, "--api-url", help="FluxLoop API base URL"
59
59
  ),
60
+ staging: bool = typer.Option(
61
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
62
+ ),
60
63
  ):
61
64
  """
62
65
  Trigger server-side evaluation for an experiment.
@@ -64,7 +67,7 @@ def main(
64
67
  Uses the current logged-in user (JWT). If no config is provided, the server
65
68
  will auto-select or use scenario defaults.
66
69
  """
67
- api_url = resolve_api_url(api_url)
70
+ api_url = resolve_api_url(api_url, staging=staging)
68
71
 
69
72
  if not project_id:
70
73
  project_id = get_current_web_project_id()
@@ -85,6 +85,9 @@ def synthesize(
85
85
  api_url: Optional[str] = typer.Option(
86
86
  None, "--api-url", help="FluxLoop API base URL"
87
87
  ),
88
+ staging: bool = typer.Option(
89
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
90
+ ),
88
91
  ):
89
92
  """
90
93
  Synthesize test inputs using Web API.
@@ -92,7 +95,7 @@ def synthesize(
92
95
  Uses current project/scenario from context if not specified.
93
96
  """
94
97
  effective_timeout = timeout_seconds or _get_default_timeout()
95
- api_url = resolve_api_url(api_url)
98
+ api_url = resolve_api_url(api_url, staging=staging)
96
99
 
97
100
  # Use context if no project_id specified
98
101
  if not project_id:
@@ -275,11 +278,14 @@ def refine(
275
278
  api_url: Optional[str] = typer.Option(
276
279
  None, "--api-url", help="FluxLoop API base URL"
277
280
  ),
281
+ staging: bool = typer.Option(
282
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
283
+ ),
278
284
  ):
279
285
  """
280
286
  Refine existing test inputs.
281
287
  """
282
- api_url = resolve_api_url(api_url)
288
+ api_url = resolve_api_url(api_url, staging=staging)
283
289
  effective_timeout = timeout_seconds or _get_default_timeout()
284
290
 
285
291
  # Build payload
@@ -361,11 +367,14 @@ def qc(
361
367
  api_url: Optional[str] = typer.Option(
362
368
  None, "--api-url", help="FluxLoop API base URL"
363
369
  ),
370
+ staging: bool = typer.Option(
371
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
372
+ ),
364
373
  ):
365
374
  """
366
375
  Run quality checks on test inputs.
367
376
  """
368
- api_url = resolve_api_url(api_url)
377
+ api_url = resolve_api_url(api_url, staging=staging)
369
378
  effective_timeout = timeout_seconds or _get_default_timeout()
370
379
 
371
380
  # Build payload
@@ -456,11 +465,14 @@ def list_inputs(
456
465
  api_url: Optional[str] = typer.Option(
457
466
  None, "--api-url", help="FluxLoop API base URL"
458
467
  ),
468
+ staging: bool = typer.Option(
469
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
470
+ ),
459
471
  ):
460
472
  """
461
473
  List all input sets.
462
474
  """
463
- api_url = resolve_api_url(api_url)
475
+ api_url = resolve_api_url(api_url, staging=staging)
464
476
 
465
477
  # Use context if no project_id specified
466
478
  if not project_id:
@@ -525,11 +537,14 @@ def show(
525
537
  api_url: Optional[str] = typer.Option(
526
538
  None, "--api-url", help="FluxLoop API base URL"
527
539
  ),
540
+ staging: bool = typer.Option(
541
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
542
+ ),
528
543
  ):
529
544
  """
530
545
  Show input set details with samples.
531
546
  """
532
- api_url = resolve_api_url(api_url)
547
+ api_url = resolve_api_url(api_url, staging=staging)
533
548
 
534
549
  try:
535
550
  client = create_authenticated_client(api_url, use_jwt=True)
@@ -35,13 +35,16 @@ def suggest(
35
35
  api_url: Optional[str] = typer.Option(
36
36
  None, "--api-url", help="FluxLoop API base URL"
37
37
  ),
38
+ staging: bool = typer.Option(
39
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
40
+ ),
38
41
  ):
39
42
  """
40
43
  Get AI-suggested personas for a scenario.
41
44
 
42
45
  Uses current project from context if --project-id is not specified.
43
46
  """
44
- api_url = resolve_api_url(api_url)
47
+ api_url = resolve_api_url(api_url, staging=staging)
45
48
 
46
49
  # Use context if no project_id specified
47
50
  if not project_id:
@@ -150,11 +153,14 @@ def list_personas(
150
153
  api_url: Optional[str] = typer.Option(
151
154
  None, "--api-url", help="FluxLoop API base URL"
152
155
  ),
156
+ staging: bool = typer.Option(
157
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
158
+ ),
153
159
  ):
154
160
  """
155
161
  List all personas.
156
162
  """
157
- api_url = resolve_api_url(api_url)
163
+ api_url = resolve_api_url(api_url, staging=staging)
158
164
 
159
165
  try:
160
166
  client = create_authenticated_client(api_url, use_jwt=True)
@@ -220,11 +226,14 @@ def create(
220
226
  api_url: Optional[str] = typer.Option(
221
227
  None, "--api-url", help="FluxLoop API base URL"
222
228
  ),
229
+ staging: bool = typer.Option(
230
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
231
+ ),
223
232
  ):
224
233
  """
225
234
  Create a custom persona.
226
235
  """
227
- api_url = resolve_api_url(api_url)
236
+ api_url = resolve_api_url(api_url, staging=staging)
228
237
 
229
238
  # Build payload
230
239
  payload: Dict[str, Any] = {"name": name}
@@ -54,13 +54,16 @@ def list_projects(
54
54
  api_url: Optional[str] = typer.Option(
55
55
  None, "--api-url", help="FluxLoop API base URL"
56
56
  ),
57
+ staging: bool = typer.Option(
58
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
59
+ ),
57
60
  ):
58
61
  """
59
62
  List all Web Projects you have access to.
60
63
 
61
64
  Shows which project is currently selected for this workspace.
62
65
  """
63
- api_url = resolve_api_url(api_url)
66
+ api_url = resolve_api_url(api_url, staging=staging)
64
67
 
65
68
  try:
66
69
  client = create_authenticated_client(api_url, use_jwt=True)
@@ -218,11 +221,14 @@ def show_project(
218
221
  api_url: Optional[str] = typer.Option(
219
222
  None, "--api-url", help="FluxLoop API base URL"
220
223
  ),
224
+ staging: bool = typer.Option(
225
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
226
+ ),
221
227
  ):
222
228
  """
223
229
  Show details of a project.
224
230
  """
225
- api_url = resolve_api_url(api_url)
231
+ api_url = resolve_api_url(api_url, staging=staging)
226
232
 
227
233
  # Use current context if no project_id provided
228
234
  if not project_id:
@@ -45,13 +45,16 @@ def refine(
45
45
  api_url: Optional[str] = typer.Option(
46
46
  None, "--api-url", help="FluxLoop API base URL"
47
47
  ),
48
+ staging: bool = typer.Option(
49
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
50
+ ),
48
51
  ):
49
52
  """
50
53
  Refine scenario goal and constraints using AI.
51
54
 
52
55
  Uses current project from context if --project-id is not specified.
53
56
  """
54
- api_url = resolve_api_url(api_url)
57
+ api_url = resolve_api_url(api_url, staging=staging)
55
58
 
56
59
  # Use context if no project_id specified
57
60
  if not project_id:
@@ -136,6 +139,9 @@ def create(
136
139
  api_url: Optional[str] = typer.Option(
137
140
  None, "--api-url", help="FluxLoop API base URL"
138
141
  ),
142
+ staging: bool = typer.Option(
143
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
144
+ ),
139
145
  select: bool = typer.Option(
140
146
  True, "--select/--no-select", help="Automatically select the created scenario"
141
147
  ),
@@ -163,7 +169,7 @@ def create(
163
169
  --constraint "Response time under 30 seconds" \\
164
170
  --assumption "User has no SQL knowledge"
165
171
  """
166
- api_url = resolve_api_url(api_url)
172
+ api_url = resolve_api_url(api_url, staging=staging)
167
173
 
168
174
  # Use context if no project_id specified
169
175
  if not project_id:
@@ -252,11 +258,14 @@ def generate(
252
258
  api_url: Optional[str] = typer.Option(
253
259
  None, "--api-url", help="FluxLoop API base URL"
254
260
  ),
261
+ staging: bool = typer.Option(
262
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
263
+ ),
255
264
  ):
256
265
  """
257
266
  Generate scenario using Alignment Agent from user intent.
258
267
  """
259
- api_url = resolve_api_url(api_url)
268
+ api_url = resolve_api_url(api_url, staging=staging)
260
269
 
261
270
  # Build payload
262
271
  payload: Dict[str, Any] = {}
@@ -312,13 +321,16 @@ def list_scenarios(
312
321
  api_url: Optional[str] = typer.Option(
313
322
  None, "--api-url", help="FluxLoop API base URL"
314
323
  ),
324
+ staging: bool = typer.Option(
325
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
326
+ ),
315
327
  ):
316
328
  """
317
329
  List all scenarios for a project.
318
330
 
319
331
  Uses current project from context if --project-id is not specified.
320
332
  """
321
- api_url = resolve_api_url(api_url)
333
+ api_url = resolve_api_url(api_url, staging=staging)
322
334
 
323
335
  # Use context if no project_id specified
324
336
  if not project_id:
@@ -397,6 +409,9 @@ def select(
397
409
  api_url: Optional[str] = typer.Option(
398
410
  None, "--api-url", help="FluxLoop API base URL"
399
411
  ),
412
+ staging: bool = typer.Option(
413
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
414
+ ),
400
415
  ):
401
416
  """
402
417
  Select a scenario as the current working scenario.
@@ -404,7 +419,7 @@ def select(
404
419
  Use --local-path to specify which local folder to link.
405
420
  If not specified, tries to find existing folders automatically.
406
421
  """
407
- api_url = resolve_api_url(api_url)
422
+ api_url = resolve_api_url(api_url, staging=staging)
408
423
 
409
424
  try:
410
425
  # Fetch scenario details to get the name
@@ -452,11 +467,14 @@ def show(
452
467
  api_url: Optional[str] = typer.Option(
453
468
  None, "--api-url", help="FluxLoop API base URL"
454
469
  ),
470
+ staging: bool = typer.Option(
471
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
472
+ ),
455
473
  ):
456
474
  """
457
475
  Show scenario details.
458
476
  """
459
- api_url = resolve_api_url(api_url)
477
+ api_url = resolve_api_url(api_url, staging=staging)
460
478
 
461
479
  try:
462
480
  client = create_authenticated_client(api_url, use_jwt=True)
@@ -506,11 +524,14 @@ def update(
506
524
  api_url: Optional[str] = typer.Option(
507
525
  None, "--api-url", help="FluxLoop API base URL"
508
526
  ),
527
+ staging: bool = typer.Option(
528
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
529
+ ),
509
530
  ):
510
531
  """
511
532
  Update scenario fields.
512
533
  """
513
- api_url = resolve_api_url(api_url)
534
+ api_url = resolve_api_url(api_url, staging=staging)
514
535
 
515
536
  # Load payload from file
516
537
  payload = load_payload_file(file)
@@ -520,6 +520,9 @@ def pull(
520
520
  ),
521
521
  scenario: Optional[str] = typer.Option(None, "--scenario", help="Scenario name (defaults to current context)"),
522
522
  api_url: Optional[str] = typer.Option(None, "--api-url", help="Sync API base URL"),
523
+ staging: bool = typer.Option(
524
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
525
+ ),
523
526
  api_key: Optional[str] = typer.Option(None, "--api-key", help="Sync API key"),
524
527
  quiet: bool = typer.Option(False, "--quiet", help="Minimal output"),
525
528
  ):
@@ -535,7 +538,7 @@ def pull(
535
538
  console.print(f"[dim]Using scenario: {scenario}[/dim]")
536
539
 
537
540
  _load_env(scenario)
538
- api_url = resolve_api_url(api_url)
541
+ api_url = resolve_api_url(api_url, staging=staging)
539
542
  api_key = _resolve_api_key(api_key)
540
543
 
541
544
  if not project_id:
@@ -636,6 +639,9 @@ def upload(
636
639
  ),
637
640
  scenario: Optional[str] = typer.Option(None, "--scenario", help="Scenario name (defaults to current context)"),
638
641
  api_url: Optional[str] = typer.Option(None, "--api-url", help="Sync API base URL"),
642
+ staging: bool = typer.Option(
643
+ False, "--staging", help="Use staging API (staging.api.fluxloop.ai)"
644
+ ),
639
645
  api_key: Optional[str] = typer.Option(None, "--api-key", help="Sync API key"),
640
646
  bundle_version_id: Optional[str] = typer.Option(
641
647
  None, "--bundle-version-id", help="Bundle version ID"
@@ -653,7 +659,7 @@ def upload(
653
659
  console.print(f"[dim]Using scenario: {scenario}[/dim]")
654
660
 
655
661
  _load_env(scenario)
656
- api_url = resolve_api_url(api_url)
662
+ api_url = resolve_api_url(api_url, staging=staging)
657
663
  api_key = _resolve_api_key(api_key)
658
664
 
659
665
  scenario_root = _resolve_scenario_dir(scenario)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fluxloop-cli
3
- Version: 0.3.5
3
+ Version: 0.3.6
4
4
  Summary: FluxLoop CLI for running agent simulations
5
5
  Author-email: FluxLoop Team <team@fluxloop.dev>
6
6
  License: Apache-2.0
@@ -128,6 +128,21 @@ Options:
128
128
  After running the script, open the folder in VSCode and use `FluxLoop: Show Environment Info`
129
129
  or `FluxLoop: Run Doctor` to confirm the environment.
130
130
 
131
+ ## Full Reset Script
132
+
133
+ To remove FluxLoop-only local state (`.fluxloop*`, `~/.fluxloop`), remove
134
+ project deps via `uv remove` (when `pyproject.toml` exists), and uninstall
135
+ `fluxloop-cli` / `fluxloop` from pipx/uv tool/pip:
136
+
137
+ ```bash
138
+ bash reset_fluxloop_env.sh --dry-run
139
+ bash reset_fluxloop_env.sh --yes
140
+ ```
141
+
142
+ Options:
143
+
144
+ - `--project-root PATH` - clean a specific project root
145
+
131
146
  ## Runner Integration Patterns
132
147
 
133
148
  Configure how FluxLoop calls your code in `configs/simulation.yaml`:
@@ -156,4 +171,3 @@ To package the CLI:
156
171
  ```
157
172
  ./build.sh
158
173
  ```
159
-
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "fluxloop-cli"
7
- version = "0.3.5"
7
+ version = "0.3.6"
8
8
  description = "FluxLoop CLI for running agent simulations"
9
9
  authors = [
10
10
  {name = "FluxLoop Team", email = "team@fluxloop.dev"}
File without changes