@uluops/cli 0.10.1 → 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.
Files changed (91) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +18 -69
  3. package/dist/cli.js +17 -17
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/analytics.d.ts +1 -1
  6. package/dist/commands/analytics.d.ts.map +1 -1
  7. package/dist/commands/analytics.js +135 -32
  8. package/dist/commands/analytics.js.map +1 -1
  9. package/dist/commands/auth.d.ts +1 -1
  10. package/dist/commands/auth.d.ts.map +1 -1
  11. package/dist/commands/auth.js +86 -21
  12. package/dist/commands/auth.js.map +1 -1
  13. package/dist/commands/completion.d.ts +1 -1
  14. package/dist/commands/completion.d.ts.map +1 -1
  15. package/dist/commands/completion.js +15 -7
  16. package/dist/commands/completion.js.map +1 -1
  17. package/dist/commands/definitions.d.ts +1 -1
  18. package/dist/commands/definitions.d.ts.map +1 -1
  19. package/dist/commands/definitions.js +68 -16
  20. package/dist/commands/definitions.js.map +1 -1
  21. package/dist/commands/deps.d.ts +1 -1
  22. package/dist/commands/deps.d.ts.map +1 -1
  23. package/dist/commands/deps.js +14 -4
  24. package/dist/commands/deps.js.map +1 -1
  25. package/dist/commands/exec.d.ts +1 -1
  26. package/dist/commands/exec.d.ts.map +1 -1
  27. package/dist/commands/exec.js +44 -19
  28. package/dist/commands/exec.js.map +1 -1
  29. package/dist/commands/executions.d.ts +1 -1
  30. package/dist/commands/executions.d.ts.map +1 -1
  31. package/dist/commands/executions.js +11 -4
  32. package/dist/commands/executions.js.map +1 -1
  33. package/dist/commands/forks.d.ts +1 -1
  34. package/dist/commands/forks.d.ts.map +1 -1
  35. package/dist/commands/forks.js +20 -10
  36. package/dist/commands/forks.js.map +1 -1
  37. package/dist/commands/issues.d.ts +1 -1
  38. package/dist/commands/issues.d.ts.map +1 -1
  39. package/dist/commands/issues.js +56 -15
  40. package/dist/commands/issues.js.map +1 -1
  41. package/dist/commands/languages.d.ts +6 -0
  42. package/dist/commands/languages.d.ts.map +1 -0
  43. package/dist/commands/languages.js +72 -0
  44. package/dist/commands/languages.js.map +1 -0
  45. package/dist/commands/models.d.ts +1 -1
  46. package/dist/commands/models.d.ts.map +1 -1
  47. package/dist/commands/models.js +6 -26
  48. package/dist/commands/models.js.map +1 -1
  49. package/dist/commands/projects.d.ts +1 -1
  50. package/dist/commands/projects.d.ts.map +1 -1
  51. package/dist/commands/projects.js +62 -14
  52. package/dist/commands/projects.js.map +1 -1
  53. package/dist/commands/runs.d.ts +1 -1
  54. package/dist/commands/runs.d.ts.map +1 -1
  55. package/dist/commands/runs.js +52 -20
  56. package/dist/commands/runs.js.map +1 -1
  57. package/dist/commands/taxonomy.d.ts +1 -1
  58. package/dist/commands/taxonomy.d.ts.map +1 -1
  59. package/dist/commands/taxonomy.js +5 -2
  60. package/dist/commands/taxonomy.js.map +1 -1
  61. package/dist/commands/translation.d.ts +1 -1
  62. package/dist/commands/translation.d.ts.map +1 -1
  63. package/dist/commands/translation.js +16 -5
  64. package/dist/commands/translation.js.map +1 -1
  65. package/dist/commands/versions.d.ts +1 -1
  66. package/dist/commands/versions.d.ts.map +1 -1
  67. package/dist/commands/versions.js +10 -4
  68. package/dist/commands/versions.js.map +1 -1
  69. package/dist/context.d.ts +1 -1
  70. package/dist/context.d.ts.map +1 -1
  71. package/dist/context.js +30 -15
  72. package/dist/context.js.map +1 -1
  73. package/dist/formatters/core.d.ts +1 -1
  74. package/dist/formatters/core.d.ts.map +1 -1
  75. package/dist/formatters/core.js +20 -5
  76. package/dist/formatters/core.js.map +1 -1
  77. package/dist/formatters/ops.d.ts +1 -1
  78. package/dist/formatters/ops.d.ts.map +1 -1
  79. package/dist/formatters/ops.js +38 -8
  80. package/dist/formatters/ops.js.map +1 -1
  81. package/dist/formatters/registry.d.ts +1 -1
  82. package/dist/formatters/registry.d.ts.map +1 -1
  83. package/dist/formatters/registry.js +32 -18
  84. package/dist/formatters/registry.js.map +1 -1
  85. package/dist/formatters/table.d.ts.map +1 -1
  86. package/dist/formatters/table.js.map +1 -1
  87. package/dist/utils.d.ts +3 -5
  88. package/dist/utils.d.ts.map +1 -1
  89. package/dist/utils.js +11 -27
  90. package/dist/utils.js.map +1 -1
  91. package/package.json +8 -8
package/CHANGELOG.md CHANGED
@@ -4,6 +4,42 @@ All notable changes to `@uluops/cli` will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
+ ## [0.12.0] - 2026-06-01
8
+
9
+ ### Changed
10
+
11
+ - Bumps `@uluops/sdk-core` to `0.11.0`, `@uluops/ops-sdk` to `3.0.0`, `@uluops/registry-sdk`
12
+ to `0.30.0`, `@uluops/core` to `0.18.0` (all exact pins). Aligns with the sdk-core
13
+ schema-removal cascade.
14
+
15
+ ### Fixed
16
+
17
+ - `ulu definitions publish` now correctly destructures the `PublishResult` (registry-sdk
18
+ 0.29.0 changed the return type from `Definition` to `{ definition, warnings }`).
19
+ Surfaces non-fatal publish warnings instead of crashing with `Cannot read properties of
20
+ undefined`.
21
+ - `ulu forks lineage` was reading `result.chain` and `result.current` (untyped) through
22
+ the typed `ForkLineage` interface, which only declares `{ isFork, fork, source }`.
23
+ Refactored to use the `asFlexibleResponse` cast it already had imported, with explicit
24
+ inner types for the legacy `chain`/`current` shape.
25
+
26
+ ## [0.11.0] - 2026-05-27
27
+
28
+ ### Added
29
+
30
+ - **`ulu languages` command** (alias: `ulu lang`) — browse definition language schemas. `ulu lang` lists all 4 languages with current versions. `ulu lang adl` shows metadata for a specific language. `ulu lang adl --json` returns full schema content. `ulu lang adl -o schema.json` writes the JSON Schema to a file.
31
+
32
+ ## [0.10.2] - 2026-05-27
33
+
34
+ ### Removed
35
+
36
+ - **`ulu config` command** — profile-based configuration (`config list`, `config set`, `config get`, `config unset`, `config profiles`, `config use`, `config path`) has been removed. The feature was structurally complete but mostly hollow — only `defaultProject` was consumed at runtime, while `opsBaseUrl`, `registryBaseUrl`, `json`, `quiet`, and `debug` stored in profiles had no effect on CLI behavior. Use environment variables and CLI flags instead.
37
+ - **`defaultProject` profile fallback** — `resolveProject` no longer reads `~/.uluops/profiles.json`. Pass `--project <name>` explicitly.
38
+
39
+ ### Fixed
40
+
41
+ - **Removed stale `models sync` test** — test referenced a subcommand that was removed from the implementation but not the test suite.
42
+
7
43
  ## [0.10.1] - 2026-05-27
8
44
 
9
45
  ### Fixed
package/README.md CHANGED
@@ -11,7 +11,7 @@
11
11
 
12
12
  Unified CLI for UluOps — validation tracking and registry management from a single command. Wraps both the [ops-sdk](https://www.npmjs.com/package/@uluops/ops-sdk) and [registry-sdk](https://www.npmjs.com/package/@uluops/registry-sdk) into an ergonomic terminal interface.
13
13
 
14
- **Current version: 0.10.1** | [Changelog](./CHANGELOG.md)
14
+ **Current version: 0.11.0** | [Changelog](./CHANGELOG.md)
15
15
 
16
16
  ## Quick Start
17
17
 
@@ -41,11 +41,10 @@ ulu exec agent code-validator -t ./src --model sonnet --project my-project
41
41
  - [Features](#features)
42
42
  - [Installation](#installation)
43
43
  - [Authentication](#authentication)
44
- - [Configuration](#configuration)
44
+ - [Configuration](#configuration) — Config files & environment
45
45
  - [Global Options](#global-options)
46
46
  - [Command Reference](#command-reference)
47
47
  - [Auth](#auth) — Authentication & credential management
48
- - [Config](#config) — CLI configuration & profiles
49
48
  - [Projects](#projects) (`ulu p`) — Project lifecycle management
50
49
  - [Runs](#runs) (`ulu r`) — Validation run management
51
50
  - [Issues](#issues) (`ulu i`) — Issue tracking & management
@@ -56,6 +55,7 @@ ulu exec agent code-validator -t ./src --model sonnet --project my-project
56
55
  - [Versions](#versions) — Definition version history
57
56
  - [Deps](#deps) — Dependency graphs
58
57
  - [Forks](#forks) — Definition forking
58
+ - [Languages](#languages) (`ulu lang`) — Definition language schemas
59
59
  - [Models](#models) — AI model catalog
60
60
  - [Exec](#exec) (`ulu x`) — Execute agents, commands, workflows, and pipelines
61
61
  - [Executions](#executions) — Execution tracking
@@ -72,7 +72,6 @@ ulu exec agent code-validator -t ./src --model sonnet --project my-project
72
72
 
73
73
  - **Unified interface**: Single `ulu` command covers both the validation tracker (ops) and definition registry APIs
74
74
  - **Command aliases**: `ulu p` (projects), `ulu r` (runs), `ulu i` (issues), `ulu a` (analytics), `ulu x` (exec), `ulu def` (definitions)
75
- - **Profile-based configuration**: Multiple environments via named profiles with independent credentials
76
75
  - **Flexible authentication**: API key, session token, or email/password — same credential chain as the SDKs
77
76
  - **Machine-friendly output**: `--json` flag on every command for scripting and CI/CD integration
78
77
  - **Shell completion**: Tab completion for bash, zsh, and fish
@@ -143,51 +142,11 @@ The CLI resolves credentials in this order:
143
142
 
144
143
  ## Configuration
145
144
 
146
- ### Config Files
147
-
148
145
  | File | Purpose |
149
146
  |------|---------|
150
- | `~/.uluops/profiles.json` | Profile settings (base URLs, default project, output preferences) |
151
147
  | `~/.uluops/credentials.json` | Credentials per profile (API keys, session tokens) |
152
148
  | `./.env` | Project-level environment overrides |
153
149
 
154
- ### Profiles
155
-
156
- Profiles let you maintain separate configurations for different environments:
157
-
158
- ```bash
159
- # Set config values on the default profile
160
- ulu config set opsBaseUrl https://api.uluops.com/api/v1
161
- ulu config set defaultProject my-project
162
-
163
- # Create and switch to a new profile
164
- ulu config use staging
165
- ulu config set opsBaseUrl https://staging-api.uluops.com/api/v1
166
-
167
- # Switch back
168
- ulu config use default
169
-
170
- # Use a profile for a single command
171
- ulu projects list --profile staging
172
-
173
- # View current config
174
- ulu config list
175
-
176
- # List all profiles
177
- ulu config profiles
178
- ```
179
-
180
- ### Config Keys
181
-
182
- | Key | Description | Default |
183
- |-----|-------------|---------|
184
- | `opsBaseUrl` | Validation tracker API URL | `http://localhost:3100/api/v1` |
185
- | `registryBaseUrl` | Registry API URL | `http://localhost:3001/api/v1` |
186
- | `defaultProject` | Default project for commands that accept `<project>` | - |
187
- | `json` | Always output JSON | `false` |
188
- | `quiet` | Suppress spinners | `false` |
189
- | `debug` | Enable debug output | `false` |
190
-
191
150
  ## Global Options
192
151
 
193
152
  Every command accepts these flags:
@@ -243,22 +202,6 @@ ulu auth whoami
243
202
 
244
203
  ---
245
204
 
246
- ### Config
247
-
248
- CLI configuration and profile management.
249
-
250
- ```bash
251
- ulu config list # Show resolved config for active profile
252
- ulu config get <key> # Get a config value
253
- ulu config set <key> <value> # Set a config value
254
- ulu config unset <key> # Remove a config value
255
- ulu config profiles # List all profiles
256
- ulu config use <profile> # Switch active profile
257
- ulu config path # Show config file locations
258
- ```
259
-
260
- ---
261
-
262
205
  ### Projects
263
206
 
264
207
  Project lifecycle management. Alias: `p`.
@@ -578,6 +521,19 @@ ulu forks lineage <type> <name> <version> # Show fork ancestry chain
578
521
 
579
522
  ---
580
523
 
524
+ ### Languages
525
+
526
+ Definition language schemas. Alias: `lang`.
527
+
528
+ ```bash
529
+ ulu lang # List all languages with versions
530
+ ulu lang adl # Get ADL metadata
531
+ ulu lang adl --json # Full output with JSON Schema content
532
+ ulu lang adl -o adl-schema.json # Write JSON Schema to file
533
+ ```
534
+
535
+ ---
536
+
581
537
  ### Models
582
538
 
583
539
  AI model catalog.
@@ -588,7 +544,6 @@ ulu models get <provider> <id> # Get model details
588
544
  ulu models providers # List providers
589
545
  ulu models aliases # List model aliases
590
546
  ulu models resolve <alias> # Resolve alias to concrete model
591
- ulu models sync # Sync from providers (admin only)
592
547
  ```
593
548
 
594
549
  ---
@@ -786,16 +741,13 @@ All errors include the HTTP status code and server error code when available. Us
786
741
  # Verify your credentials are set
787
742
  echo $ULUOPS_API_KEY
788
743
  ulu auth whoami
789
-
790
- # Check which profile is active
791
- ulu config list
792
744
  ```
793
745
 
794
746
  ### "Connection refused" errors
795
747
 
796
748
  ```bash
797
749
  # Check the configured base URL
798
- ulu config get opsBaseUrl
750
+ echo $ULUOPS_BASE_URL
799
751
 
800
752
  # Test server connectivity
801
753
  curl http://localhost:3100/api/v1/health
@@ -804,11 +756,8 @@ curl http://localhost:3100/api/v1/health
804
756
  ### Commands targeting the wrong environment
805
757
 
806
758
  ```bash
807
- # Check active profile
808
- ulu config profiles
809
-
810
759
  # Override for a single command
811
- ulu projects list --profile production --base-url https://api.uluops.com/api/v1
760
+ ulu projects list --base-url https://api.uluops.com/api/v1
812
761
  ```
813
762
 
814
763
  ### Shell completion not working
package/dist/cli.js CHANGED
@@ -1,30 +1,30 @@
1
1
  #!/usr/bin/env node
2
- import { Command } from 'commander';
3
2
  import { readFileSync } from 'node:fs';
4
- import { fileURLToPath } from 'node:url';
5
3
  import { dirname, join } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ // Load .env files early so all SDK contexts see them
6
+ import { loadEnvFiles } from '@uluops/ops-sdk';
7
+ import { Command } from 'commander';
8
+ import { registerAnalyticsCommands } from './commands/analytics.js';
6
9
  // Ops commands
7
10
  import { registerAuthCommands } from './commands/auth.js';
8
- import { registerProjectCommands } from './commands/projects.js';
9
- import { registerRunCommands } from './commands/runs.js';
10
- import { registerIssueCommands } from './commands/issues.js';
11
- import { registerAnalyticsCommands } from './commands/analytics.js';
12
- import { registerTaxonomyCommands } from './commands/taxonomy.js';
11
+ // Infrastructure commands
12
+ import { registerCompletionCommands } from './commands/completion.js';
13
13
  // Registry commands
14
14
  import { registerDefinitionCommands } from './commands/definitions.js';
15
- import { registerVersionCommands } from './commands/versions.js';
16
15
  import { registerDepsCommands } from './commands/deps.js';
16
+ // Core SDK commands
17
+ import { registerExecCommands } from './commands/exec.js';
18
+ import { registerExecutionCommands } from './commands/executions.js';
17
19
  import { registerForkCommands } from './commands/forks.js';
20
+ import { registerIssueCommands } from './commands/issues.js';
21
+ import { registerLanguageCommands } from './commands/languages.js';
18
22
  import { registerModelCommands } from './commands/models.js';
19
- import { registerExecutionCommands } from './commands/executions.js';
23
+ import { registerProjectCommands } from './commands/projects.js';
24
+ import { registerRunCommands } from './commands/runs.js';
25
+ import { registerTaxonomyCommands } from './commands/taxonomy.js';
20
26
  import { registerTranslationCommands } from './commands/translation.js';
21
- // Core SDK commands
22
- import { registerExecCommands } from './commands/exec.js';
23
- // Infrastructure commands
24
- import { registerConfigCommands } from './commands/config.js';
25
- import { registerCompletionCommands } from './commands/completion.js';
26
- // Load .env files early so all SDK contexts see them
27
- import { loadEnvFiles } from '@uluops/ops-sdk';
27
+ import { registerVersionCommands } from './commands/versions.js';
28
28
  loadEnvFiles();
29
29
  // Handle EPIPE gracefully (e.g., piping to head, or broken pipe)
30
30
  process.stdout.on('error', (err) => {
@@ -97,10 +97,10 @@ registerForkCommands(program);
97
97
  registerModelCommands(program);
98
98
  registerExecutionCommands(program);
99
99
  registerTranslationCommands(program);
100
+ registerLanguageCommands(program);
100
101
  // Core SDK commands
101
102
  registerExecCommands(program);
102
103
  // Infrastructure commands
103
- registerConfigCommands(program);
104
104
  registerCompletionCommands(program);
105
105
  // Default action when no command is provided
106
106
  program.action(() => {
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,eAAe;AACf,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAEpE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAElE,oBAAoB;AACpB,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AAExE,oBAAoB;AACpB,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,0BAA0B;AAC1B,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AAEtE,qDAAqD;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,YAAY,EAAE,CAAC;AAEf,iEAAiE;AACjE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;IACjC,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1C,MAAM,GAAG,CAAC;AACZ,CAAC,CAAC,CAAC;AACH,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;IACjC,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1C,MAAM,GAAG,CAAC;AACZ,CAAC,CAAC,CAAC;AAEH,2EAA2E;AAC3E,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;IACxB,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IAC/B,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACpB,CAAC,CAAC,CAAC;AACH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;IACzB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACpB,CAAC,CAAC,CAAC;AAEH,wDAAwD;AACxD,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,EAAE;IAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC/C,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;IACtD,IAAI,KAAK,IAAI,MAAM,YAAY,KAAK,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACrD,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAChD,CAAC;SAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,+BAA+B;AAC/B,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACtC,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;AAC9D,IAAI,OAAO,GAAG,OAAO,CAAC;AACtB,IAAI,CAAC;IACH,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC;IACvE,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC;AAChC,CAAC;AAAC,MAAM,CAAC;IACP,wCAAwC;AAC1C,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,KAAK,CAAC;KACX,WAAW,CAAC,0DAA0D,CAAC;KACvE,OAAO,CAAC,OAAO,EAAE,eAAe,EAAE,2BAA2B,CAAC;KAC9D,MAAM,CAAC,iBAAiB,EAAE,0CAA0C,CAAC;KACrE,MAAM,CAAC,kBAAkB,EAAE,uBAAuB,EAAE,SAAS,CAAC;KAC9D,MAAM,CAAC,kBAAkB,EAAE,cAAc,CAAC;KAC1C,MAAM,CAAC,gBAAgB,EAAE,kDAAkD,CAAC;KAC5E,MAAM,CAAC,QAAQ,EAAE,qCAAqC,CAAC;KACvD,MAAM,CAAC,SAAS,EAAE,qBAAqB,CAAC;KACxC,MAAM,CAAC,aAAa,EAAE,4CAA4C,CAAC;KACnE,kBAAkB,CAAC,IAAI,CAAC,CAAC;AAE5B,eAAe;AACf,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACjC,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,yBAAyB,CAAC,OAAO,CAAC,CAAC;AAEnC,wBAAwB,CAAC,OAAO,CAAC,CAAC;AAElC,oBAAoB;AACpB,0BAA0B,CAAC,OAAO,CAAC,CAAC;AACpC,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACjC,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,yBAAyB,CAAC,OAAO,CAAC,CAAC;AACnC,2BAA2B,CAAC,OAAO,CAAC,CAAC;AAErC,oBAAoB;AACpB,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAE9B,0BAA0B;AAC1B,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAChC,0BAA0B,CAAC,OAAO,CAAC,CAAC;AAEpC,6CAA6C;AAC7C,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE;IAClB,OAAO,CAAC,IAAI,EAAE,CAAC;AACjB,CAAC,CAAC,CAAC;AAEH,oBAAoB;AACpB,OAAO,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { Command } from 'commander';
1
+ import type { Command } from 'commander';
2
2
  /**
3
3
  * Register analytics commands
4
4
  */
@@ -1 +1 @@
1
- {"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../../src/commands/analytics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkfhE"}
1
+ {"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../../src/commands/analytics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAczC;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkpBhE"}
@@ -1,6 +1,6 @@
1
- import { createOpsContext, handleOpsError } from '../context.js';
2
- import { withSpinner, getFlexibleProperty, parseIntOption, parseFloatOption } from '../utils.js';
1
+ import { createOpsContext, handleOpsError, } from '../context.js';
3
2
  import { formatTable } from '../formatters/table.js';
3
+ import { getFlexibleProperty, parseFloatOption, parseIntOption, withSpinner, } from '../utils.js';
4
4
  /**
5
5
  * Register analytics commands
6
6
  */
@@ -29,7 +29,10 @@ Examples:
29
29
  const globalOpts = cmd.optsWithGlobals();
30
30
  const ctx = createOpsContext(globalOpts);
31
31
  try {
32
- const data = await withSpinner(ctx, { start: 'Fetching agent performance...', failure: 'Failed to fetch agent performance' }, () => ctx.client.analytics.getAgentPerformance({
32
+ const data = await withSpinner(ctx, {
33
+ start: 'Fetching agent performance...',
34
+ failure: 'Failed to fetch agent performance',
35
+ }, () => ctx.client.analytics.getAgentPerformance({
33
36
  project: options.project,
34
37
  days: parseIntOption(options.days, '--days'),
35
38
  limit: parseIntOption(options.limit, '--limit'),
@@ -43,9 +46,24 @@ Examples:
43
46
  else {
44
47
  const columns = [
45
48
  { header: 'AGENT', accessor: 'name', width: 25 },
46
- { header: 'RUNS', accessor: (v) => String(v.totalRuns), width: 8, align: 'right' },
47
- { header: 'AVG SCORE', accessor: (v) => v.averageScore?.toFixed(1) ?? '-', width: 10, align: 'right' },
48
- { header: 'PASS RATE', accessor: (v) => `${v.passRate.toFixed(0)}%`, width: 10, align: 'right' },
49
+ {
50
+ header: 'RUNS',
51
+ accessor: (v) => String(v.totalRuns),
52
+ width: 8,
53
+ align: 'right',
54
+ },
55
+ {
56
+ header: 'AVG SCORE',
57
+ accessor: (v) => v.averageScore?.toFixed(1) ?? '-',
58
+ width: 10,
59
+ align: 'right',
60
+ },
61
+ {
62
+ header: 'PASS RATE',
63
+ accessor: (v) => `${v.passRate.toFixed(0)}%`,
64
+ width: 10,
65
+ align: 'right',
66
+ },
49
67
  ];
50
68
  console.log(formatTable(data, columns));
51
69
  }
@@ -65,7 +83,10 @@ Examples:
65
83
  const globalOpts = cmd.optsWithGlobals();
66
84
  const ctx = createOpsContext(globalOpts);
67
85
  try {
68
- const data = await withSpinner(ctx, { start: 'Fetching reliability stats...', failure: 'Failed to fetch reliability stats' }, () => ctx.client.analytics.getAgentReliability({
86
+ const data = await withSpinner(ctx, {
87
+ start: 'Fetching reliability stats...',
88
+ failure: 'Failed to fetch reliability stats',
89
+ }, () => ctx.client.analytics.getAgentReliability({
69
90
  agent: options.agent,
70
91
  project: options.project,
71
92
  days: parseIntOption(options.days, '--days'),
@@ -79,18 +100,33 @@ Examples:
79
100
  else {
80
101
  const columns = [
81
102
  { header: 'AGENT', accessor: 'name', width: 25 },
82
- { header: 'FALSE POS', accessor: (v) => {
103
+ {
104
+ header: 'FALSE POS',
105
+ accessor: (v) => {
83
106
  const rate = getFlexibleProperty(v, 'falsePositiveRate', null);
84
107
  return `${rate?.toFixed(1) ?? '-'}%`;
85
- }, width: 10, align: 'right' },
86
- { header: 'RESOLUTION', accessor: (v) => {
108
+ },
109
+ width: 10,
110
+ align: 'right',
111
+ },
112
+ {
113
+ header: 'RESOLUTION',
114
+ accessor: (v) => {
87
115
  const rate = getFlexibleProperty(v, 'resolutionRate', null);
88
116
  return `${rate?.toFixed(1) ?? '-'}%`;
89
- }, width: 12, align: 'right' },
90
- { header: 'RELIABILITY', accessor: (v) => {
117
+ },
118
+ width: 12,
119
+ align: 'right',
120
+ },
121
+ {
122
+ header: 'RELIABILITY',
123
+ accessor: (v) => {
91
124
  const score = getFlexibleProperty(v, 'reliabilityScore', null);
92
125
  return score?.toFixed(1) ?? '-';
93
- }, width: 12, align: 'right' },
126
+ },
127
+ width: 12,
128
+ align: 'right',
129
+ },
94
130
  ];
95
131
  console.log(formatTable(data.agents, columns));
96
132
  }
@@ -110,7 +146,10 @@ Examples:
110
146
  const globalOpts = cmd.optsWithGlobals();
111
147
  const ctx = createOpsContext(globalOpts);
112
148
  try {
113
- const data = await withSpinner(ctx, { start: 'Fetching file hotspots...', failure: 'Failed to fetch hotspots' }, () => ctx.client.analytics.getFileHotspots({
149
+ const data = await withSpinner(ctx, {
150
+ start: 'Fetching file hotspots...',
151
+ failure: 'Failed to fetch hotspots',
152
+ }, () => ctx.client.analytics.getFileHotspots({
114
153
  project: options.project,
115
154
  days: parseIntOption(options.days, '--days'),
116
155
  limit: parseIntOption(options.limit, '--limit'),
@@ -123,11 +162,20 @@ Examples:
123
162
  }
124
163
  else {
125
164
  const columns = [
126
- { header: 'FILE', accessor: (h) => truncatePath(h.filePath, 45), width: 45 },
127
- { header: 'ISSUES', accessor: (h) => {
165
+ {
166
+ header: 'FILE',
167
+ accessor: (h) => truncatePath(h.filePath, 45),
168
+ width: 45,
169
+ },
170
+ {
171
+ header: 'ISSUES',
172
+ accessor: (h) => {
128
173
  const count = getFlexibleProperty(h, 'issueCount', h.totalIssues ?? 0);
129
174
  return String(count);
130
- }, width: 8, align: 'right' },
175
+ },
176
+ width: 8,
177
+ align: 'right',
178
+ },
131
179
  ];
132
180
  console.log(formatTable(data, columns));
133
181
  }
@@ -147,7 +195,10 @@ Examples:
147
195
  const globalOpts = cmd.optsWithGlobals();
148
196
  const ctx = createOpsContext(globalOpts);
149
197
  try {
150
- const data = await withSpinner(ctx, { start: 'Fetching burndown data...', failure: 'Failed to fetch burndown' }, () => ctx.client.analytics.getBurndown({
198
+ const data = await withSpinner(ctx, {
199
+ start: 'Fetching burndown data...',
200
+ failure: 'Failed to fetch burndown',
201
+ }, () => ctx.client.analytics.getBurndown({
151
202
  project: options.project,
152
203
  days: parseIntOption(options.days, '--days'),
153
204
  granularity: options.granularity,
@@ -161,7 +212,11 @@ Examples:
161
212
  for (const domain of ['STR', 'SEM', 'PRA', 'EPI']) {
162
213
  const trend = data.trends[domain];
163
214
  if (trend) {
164
- const arrow = trend.trend === 'improving' ? '↓' : trend.trend === 'degrading' ? '↑' : '→';
215
+ const arrow = trend.trend === 'improving'
216
+ ? '↓'
217
+ : trend.trend === 'degrading'
218
+ ? '↑'
219
+ : '→';
165
220
  console.log(` ${domain}: ${trend.netChange >= 0 ? '+' : ''}${trend.netChange} (${arrow} ${trend.trend})`);
166
221
  }
167
222
  }
@@ -186,7 +241,10 @@ Examples:
186
241
  const globalOpts = cmd.optsWithGlobals();
187
242
  const ctx = createOpsContext(globalOpts);
188
243
  try {
189
- const data = await withSpinner(ctx, { start: 'Fetching velocity metrics...', failure: 'Failed to fetch velocity' }, () => ctx.client.analytics.getVelocity({
244
+ const data = await withSpinner(ctx, {
245
+ start: 'Fetching velocity metrics...',
246
+ failure: 'Failed to fetch velocity',
247
+ }, () => ctx.client.analytics.getVelocity({
190
248
  project: options.project,
191
249
  days: parseIntOption(options.days, '--days'),
192
250
  alertThreshold: parseFloatOption(options.threshold, '--threshold'),
@@ -199,7 +257,9 @@ Examples:
199
257
  if (data.items && data.items.length > 0) {
200
258
  for (const item of data.items.slice(0, 10)) {
201
259
  const alert = item.alert ? ' ⚠️' : '';
202
- const velocity = item.velocityPercent >= 0 ? `+${item.velocityPercent.toFixed(0)}%` : `${item.velocityPercent.toFixed(0)}%`;
260
+ const velocity = item.velocityPercent >= 0
261
+ ? `+${item.velocityPercent.toFixed(0)}%`
262
+ : `${item.velocityPercent.toFixed(0)}%`;
203
263
  console.log(` ${item.failureCode}: ${velocity}${alert}`);
204
264
  }
205
265
  if (data.items.length > 10) {
@@ -229,7 +289,10 @@ Examples:
229
289
  const globalOpts = cmd.optsWithGlobals();
230
290
  const ctx = createOpsContext(globalOpts);
231
291
  try {
232
- const data = await withSpinner(ctx, { start: 'Fetching discovery timeline...', failure: 'Failed to fetch discovery data' }, () => ctx.client.analytics.getDiscovery({
292
+ const data = await withSpinner(ctx, {
293
+ start: 'Fetching discovery timeline...',
294
+ failure: 'Failed to fetch discovery data',
295
+ }, () => ctx.client.analytics.getDiscovery({
233
296
  project: options.project,
234
297
  days: parseIntOption(options.days, '--days'),
235
298
  groupBy: options.groupBy,
@@ -266,7 +329,10 @@ Examples:
266
329
  const globalOpts = cmd.optsWithGlobals();
267
330
  const ctx = createOpsContext(globalOpts);
268
331
  try {
269
- const data = await withSpinner(ctx, { start: 'Fetching agent matrix...', failure: 'Failed to fetch agent matrix' }, () => ctx.client.analytics.getAgentMatrix({
332
+ const data = await withSpinner(ctx, {
333
+ start: 'Fetching agent matrix...',
334
+ failure: 'Failed to fetch agent matrix',
335
+ }, () => ctx.client.analytics.getAgentMatrix({
270
336
  project: options.project,
271
337
  days: parseIntOption(options.days, '--days'),
272
338
  minIssues: parseIntOption(options.minIssues, '--min-issues'),
@@ -306,7 +372,10 @@ Examples:
306
372
  const globalOpts = cmd.optsWithGlobals();
307
373
  const ctx = createOpsContext(globalOpts);
308
374
  try {
309
- const data = await withSpinner(ctx, { start: 'Fetching resolution rates...', failure: 'Failed to fetch resolution rates' }, () => ctx.client.analytics.getResolutionRates({
375
+ const data = await withSpinner(ctx, {
376
+ start: 'Fetching resolution rates...',
377
+ failure: 'Failed to fetch resolution rates',
378
+ }, () => ctx.client.analytics.getResolutionRates({
310
379
  days: parseIntOption(options.days, '--days'),
311
380
  limit: parseIntOption(options.limit, '--limit'),
312
381
  }));
@@ -319,9 +388,24 @@ Examples:
319
388
  else {
320
389
  const columns = [
321
390
  { header: 'PROJECT', accessor: 'project', width: 25 },
322
- { header: 'RESOLVED', accessor: (r) => String(r.resolvedIssues), width: 10, align: 'right' },
323
- { header: 'TOTAL', accessor: (r) => String(r.totalIssues), width: 8, align: 'right' },
324
- { header: 'RATE', accessor: (r) => `${r.resolutionRate.toFixed(1)}%`, width: 8, align: 'right' },
391
+ {
392
+ header: 'RESOLVED',
393
+ accessor: (r) => String(r.resolvedIssues),
394
+ width: 10,
395
+ align: 'right',
396
+ },
397
+ {
398
+ header: 'TOTAL',
399
+ accessor: (r) => String(r.totalIssues),
400
+ width: 8,
401
+ align: 'right',
402
+ },
403
+ {
404
+ header: 'RATE',
405
+ accessor: (r) => `${r.resolutionRate.toFixed(1)}%`,
406
+ width: 8,
407
+ align: 'right',
408
+ },
325
409
  ];
326
410
  console.log(formatTable(data, columns));
327
411
  }
@@ -341,7 +425,10 @@ Examples:
341
425
  const globalOpts = cmd.optsWithGlobals();
342
426
  const ctx = createOpsContext(globalOpts);
343
427
  try {
344
- const data = await withSpinner(ctx, { start: 'Fetching taxonomy distribution...', failure: 'Failed to fetch taxonomy distribution' }, () => ctx.client.analytics.getTaxonomyDistribution({
428
+ const data = await withSpinner(ctx, {
429
+ start: 'Fetching taxonomy distribution...',
430
+ failure: 'Failed to fetch taxonomy distribution',
431
+ }, () => ctx.client.analytics.getTaxonomyDistribution({
345
432
  project: options.project,
346
433
  days: parseIntOption(options.days, '--days'),
347
434
  limit: parseIntOption(options.limit, '--limit'),
@@ -355,8 +442,18 @@ Examples:
355
442
  else {
356
443
  const columns = [
357
444
  { header: 'DOMAIN', accessor: (d) => d.domain ?? '-', width: 10 },
358
- { header: 'COUNT', accessor: (d) => String(d.count ?? 0), width: 8, align: 'right' },
359
- { header: '%', accessor: (d) => `${d.percentage?.toFixed(1) ?? '-'}%`, width: 8, align: 'right' },
445
+ {
446
+ header: 'COUNT',
447
+ accessor: (d) => String(d.count ?? 0),
448
+ width: 8,
449
+ align: 'right',
450
+ },
451
+ {
452
+ header: '%',
453
+ accessor: (d) => `${d.percentage?.toFixed(1) ?? '-'}%`,
454
+ width: 8,
455
+ align: 'right',
456
+ },
360
457
  ];
361
458
  console.log(formatTable(data, columns));
362
459
  }
@@ -376,7 +473,10 @@ Examples:
376
473
  const globalOpts = cmd.optsWithGlobals();
377
474
  const ctx = createOpsContext(globalOpts);
378
475
  try {
379
- const result = await withSpinner(ctx, { start: 'Fetching full taxonomy...', failure: 'Failed to fetch full taxonomy' }, () => ctx.client.analytics.getFullTaxonomy({
476
+ const result = await withSpinner(ctx, {
477
+ start: 'Fetching full taxonomy...',
478
+ failure: 'Failed to fetch full taxonomy',
479
+ }, () => ctx.client.analytics.getFullTaxonomy({
380
480
  project: options.project,
381
481
  days: parseIntOption(options.days, '--days'),
382
482
  limit: parseIntOption(options.limit, '--limit'),
@@ -421,7 +521,10 @@ Examples:
421
521
  const globalOpts = cmd.optsWithGlobals();
422
522
  const ctx = createOpsContext(globalOpts);
423
523
  try {
424
- const data = await withSpinner(ctx, { start: 'Fetching trend summary...', failure: 'Failed to fetch trend summary' }, () => ctx.client.analytics.getTrendSummary({
524
+ const data = await withSpinner(ctx, {
525
+ start: 'Fetching trend summary...',
526
+ failure: 'Failed to fetch trend summary',
527
+ }, () => ctx.client.analytics.getTrendSummary({
425
528
  project: options.project,
426
529
  days: parseIntOption(options.days, '--days'),
427
530
  limit: parseIntOption(options.limit, '--limit'),