@uluops/core 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.
Files changed (167) hide show
  1. package/README.md +543 -0
  2. package/definitions/starter/code-validator.agent.yaml +134 -0
  3. package/definitions/starter/docs-validator.agent.yaml +142 -0
  4. package/definitions/starter/public-interface-validator.agent.yaml +138 -0
  5. package/definitions/starter/security-analyst.agent.yaml +144 -0
  6. package/definitions/starter/test-architect.agent.yaml +137 -0
  7. package/dist/ai/AIProvider.d.ts +198 -0
  8. package/dist/ai/AIProvider.d.ts.map +1 -0
  9. package/dist/ai/AIProvider.js +557 -0
  10. package/dist/ai/AIProvider.js.map +1 -0
  11. package/dist/ai/ModelCatalog.d.ts +78 -0
  12. package/dist/ai/ModelCatalog.d.ts.map +1 -0
  13. package/dist/ai/ModelCatalog.js +193 -0
  14. package/dist/ai/ModelCatalog.js.map +1 -0
  15. package/dist/ai/ShellExecutor.d.ts +42 -0
  16. package/dist/ai/ShellExecutor.d.ts.map +1 -0
  17. package/dist/ai/ShellExecutor.js +62 -0
  18. package/dist/ai/ShellExecutor.js.map +1 -0
  19. package/dist/ai/TokenBudgetTracker.d.ts +49 -0
  20. package/dist/ai/TokenBudgetTracker.d.ts.map +1 -0
  21. package/dist/ai/TokenBudgetTracker.js +61 -0
  22. package/dist/ai/TokenBudgetTracker.js.map +1 -0
  23. package/dist/ai/ToolAdapter.d.ts +25 -0
  24. package/dist/ai/ToolAdapter.d.ts.map +1 -0
  25. package/dist/ai/ToolAdapter.js +135 -0
  26. package/dist/ai/ToolAdapter.js.map +1 -0
  27. package/dist/ai/index.d.ts +6 -0
  28. package/dist/ai/index.d.ts.map +1 -0
  29. package/dist/ai/index.js +4 -0
  30. package/dist/ai/index.js.map +1 -0
  31. package/dist/client/UluOpsClient.d.ts +111 -0
  32. package/dist/client/UluOpsClient.d.ts.map +1 -0
  33. package/dist/client/UluOpsClient.js +329 -0
  34. package/dist/client/UluOpsClient.js.map +1 -0
  35. package/dist/constants.d.ts +6 -0
  36. package/dist/constants.d.ts.map +1 -0
  37. package/dist/constants.js +9 -0
  38. package/dist/constants.js.map +1 -0
  39. package/dist/errors/UluOpsError.d.ts +10 -0
  40. package/dist/errors/UluOpsError.d.ts.map +1 -0
  41. package/dist/errors/UluOpsError.js +13 -0
  42. package/dist/errors/UluOpsError.js.map +1 -0
  43. package/dist/errors/index.d.ts +64 -0
  44. package/dist/errors/index.d.ts.map +1 -0
  45. package/dist/errors/index.js +93 -0
  46. package/dist/errors/index.js.map +1 -0
  47. package/dist/executor/AgentExecutor.d.ts +57 -0
  48. package/dist/executor/AgentExecutor.d.ts.map +1 -0
  49. package/dist/executor/AgentExecutor.js +331 -0
  50. package/dist/executor/AgentExecutor.js.map +1 -0
  51. package/dist/executor/CommandExecutor.d.ts +33 -0
  52. package/dist/executor/CommandExecutor.d.ts.map +1 -0
  53. package/dist/executor/CommandExecutor.js +183 -0
  54. package/dist/executor/CommandExecutor.js.map +1 -0
  55. package/dist/executor/PipelineExecutor.d.ts +55 -0
  56. package/dist/executor/PipelineExecutor.d.ts.map +1 -0
  57. package/dist/executor/PipelineExecutor.js +273 -0
  58. package/dist/executor/PipelineExecutor.js.map +1 -0
  59. package/dist/executor/ToolHandler.d.ts +47 -0
  60. package/dist/executor/ToolHandler.d.ts.map +1 -0
  61. package/dist/executor/ToolHandler.js +615 -0
  62. package/dist/executor/ToolHandler.js.map +1 -0
  63. package/dist/executor/WorkflowExecutor.d.ts +55 -0
  64. package/dist/executor/WorkflowExecutor.d.ts.map +1 -0
  65. package/dist/executor/WorkflowExecutor.js +368 -0
  66. package/dist/executor/WorkflowExecutor.js.map +1 -0
  67. package/dist/executor/preflight.d.ts +8 -0
  68. package/dist/executor/preflight.d.ts.map +1 -0
  69. package/dist/executor/preflight.js +102 -0
  70. package/dist/executor/preflight.js.map +1 -0
  71. package/dist/executor/symbols.d.ts +13 -0
  72. package/dist/executor/symbols.d.ts.map +1 -0
  73. package/dist/executor/symbols.js +102 -0
  74. package/dist/executor/symbols.js.map +1 -0
  75. package/dist/index.d.ts +32 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +25 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/parser/OutputExtractor.d.ts +52 -0
  80. package/dist/parser/OutputExtractor.d.ts.map +1 -0
  81. package/dist/parser/OutputExtractor.js +818 -0
  82. package/dist/parser/OutputExtractor.js.map +1 -0
  83. package/dist/parser/outputSchemas.d.ts +223 -0
  84. package/dist/parser/outputSchemas.d.ts.map +1 -0
  85. package/dist/parser/outputSchemas.js +73 -0
  86. package/dist/parser/outputSchemas.js.map +1 -0
  87. package/dist/registry/RegistryClient.d.ts +75 -0
  88. package/dist/registry/RegistryClient.d.ts.map +1 -0
  89. package/dist/registry/RegistryClient.js +419 -0
  90. package/dist/registry/RegistryClient.js.map +1 -0
  91. package/dist/registry/index.d.ts +2 -0
  92. package/dist/registry/index.d.ts.map +1 -0
  93. package/dist/registry/index.js +2 -0
  94. package/dist/registry/index.js.map +1 -0
  95. package/dist/types/agent.d.ts +406 -0
  96. package/dist/types/agent.d.ts.map +1 -0
  97. package/dist/types/agent.js +2 -0
  98. package/dist/types/agent.js.map +1 -0
  99. package/dist/types/ai.d.ts +14 -0
  100. package/dist/types/ai.d.ts.map +1 -0
  101. package/dist/types/ai.js +2 -0
  102. package/dist/types/ai.js.map +1 -0
  103. package/dist/types/command.d.ts +153 -0
  104. package/dist/types/command.d.ts.map +1 -0
  105. package/dist/types/command.js +2 -0
  106. package/dist/types/command.js.map +1 -0
  107. package/dist/types/config.d.ts +136 -0
  108. package/dist/types/config.d.ts.map +1 -0
  109. package/dist/types/config.js +2 -0
  110. package/dist/types/config.js.map +1 -0
  111. package/dist/types/execution.d.ts +172 -0
  112. package/dist/types/execution.d.ts.map +1 -0
  113. package/dist/types/execution.js +2 -0
  114. package/dist/types/execution.js.map +1 -0
  115. package/dist/types/index.d.ts +12 -0
  116. package/dist/types/index.d.ts.map +1 -0
  117. package/dist/types/index.js +2 -0
  118. package/dist/types/index.js.map +1 -0
  119. package/dist/types/parser.d.ts +75 -0
  120. package/dist/types/parser.d.ts.map +1 -0
  121. package/dist/types/parser.js +2 -0
  122. package/dist/types/parser.js.map +1 -0
  123. package/dist/types/pipeline.d.ts +155 -0
  124. package/dist/types/pipeline.d.ts.map +1 -0
  125. package/dist/types/pipeline.js +2 -0
  126. package/dist/types/pipeline.js.map +1 -0
  127. package/dist/types/registry.d.ts +232 -0
  128. package/dist/types/registry.d.ts.map +1 -0
  129. package/dist/types/registry.js +2 -0
  130. package/dist/types/registry.js.map +1 -0
  131. package/dist/types/tools.d.ts +29 -0
  132. package/dist/types/tools.d.ts.map +1 -0
  133. package/dist/types/tools.js +2 -0
  134. package/dist/types/tools.js.map +1 -0
  135. package/dist/types/validation.d.ts +237 -0
  136. package/dist/types/validation.d.ts.map +1 -0
  137. package/dist/types/validation.js +2 -0
  138. package/dist/types/validation.js.map +1 -0
  139. package/dist/types/workflow.d.ts +131 -0
  140. package/dist/types/workflow.d.ts.map +1 -0
  141. package/dist/types/workflow.js +2 -0
  142. package/dist/types/workflow.js.map +1 -0
  143. package/dist/utils/formatError.d.ts +6 -0
  144. package/dist/utils/formatError.d.ts.map +1 -0
  145. package/dist/utils/formatError.js +10 -0
  146. package/dist/utils/formatError.js.map +1 -0
  147. package/dist/utils/parseRef.d.ts +11 -0
  148. package/dist/utils/parseRef.d.ts.map +1 -0
  149. package/dist/utils/parseRef.js +16 -0
  150. package/dist/utils/parseRef.js.map +1 -0
  151. package/dist/utils/sumTokenMetrics.d.ts +9 -0
  152. package/dist/utils/sumTokenMetrics.d.ts.map +1 -0
  153. package/dist/utils/sumTokenMetrics.js +20 -0
  154. package/dist/utils/sumTokenMetrics.js.map +1 -0
  155. package/dist/utils/topoSort.d.ts +24 -0
  156. package/dist/utils/topoSort.d.ts.map +1 -0
  157. package/dist/utils/topoSort.js +60 -0
  158. package/dist/utils/topoSort.js.map +1 -0
  159. package/dist/validation/ValidationClient.d.ts +51 -0
  160. package/dist/validation/ValidationClient.d.ts.map +1 -0
  161. package/dist/validation/ValidationClient.js +179 -0
  162. package/dist/validation/ValidationClient.js.map +1 -0
  163. package/dist/validation/index.d.ts +2 -0
  164. package/dist/validation/index.d.ts.map +1 -0
  165. package/dist/validation/index.js +2 -0
  166. package/dist/validation/index.js.map +1 -0
  167. package/package.json +76 -0
package/README.md ADDED
@@ -0,0 +1,543 @@
1
+ **[UluOps](https://uluops.ai)** · Operating Intelligence as Infrastructure
2
+
3
+ ---
4
+
5
+ # @uluops/core
6
+
7
+ [![npm version](https://img.shields.io/npm/v/@uluops/core.svg)](https://www.npmjs.com/package/@uluops/core)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
9
+ [![Node.js Version](https://img.shields.io/node/v/@uluops/core)](https://nodejs.org)
10
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.7+-blue.svg)](https://www.typescriptlang.org/)
11
+ [![Tests](https://img.shields.io/badge/tests-passing-brightgreen)](test/)
12
+
13
+ The foundational execution engine for UluOps. Orchestrates AI-powered code analysis through a 4-layer execution hierarchy (Agent > Command > Workflow > Pipeline), manages LLM tool loops via Vercel AI SDK, and integrates with UluOps Registry and Validation services.
14
+
15
+ ## Quick Start
16
+
17
+ Requires `ULUOPS_API_KEY` and at least one AI provider key (e.g. `ANTHROPIC_API_KEY`):
18
+
19
+ ```typescript
20
+ import { UluOpsClient } from '@uluops/core';
21
+
22
+ const client = new UluOpsClient({
23
+ apiKey: process.env.ULUOPS_API_KEY,
24
+ });
25
+
26
+ // Run a single agent
27
+ const result = await client.runAgent('code-validator', './src', {
28
+ model: 'sonnet',
29
+ thresholds: { pass: 80 },
30
+ });
31
+
32
+ console.log(`Score: ${result.score} | Decision: ${result.decision}`);
33
+ ```
34
+
35
+ ## Table of Contents
36
+
37
+ - [Overview](#overview)
38
+ - [Installation](#installation)
39
+ - [Authentication](#authentication)
40
+ - [Usage](#usage)
41
+ - [Agent Execution](#agent-execution)
42
+ - [Command Execution](#command-execution)
43
+ - [Workflow Execution](#workflow-execution)
44
+ - [Pipeline Execution](#pipeline-execution)
45
+ - [Convenience Methods](#convenience-methods)
46
+ - [Discovery](#discovery)
47
+ - [Validation Tracking](#validation-tracking)
48
+ - [Architecture](#architecture)
49
+ - [Execution Hierarchy](#execution-hierarchy)
50
+ - [Configuration](#configuration)
51
+ - [TypeScript Support](#typescript-support)
52
+ - [Error Handling](#error-handling)
53
+ - [Dependencies](#dependencies)
54
+ - [Development](#development)
55
+
56
+ ## Overview
57
+
58
+ The `@uluops/core` SDK provides:
59
+
60
+ - **4-Layer Execution Hierarchy** - Agent > Command > Workflow > Pipeline orchestration
61
+ - **AI SDK v6 Integration** - Vercel AI SDK for LLM communication with automatic tool loops (`maxSteps`) and built-in retry
62
+ - **Registry-Backed Model Resolution** - Model aliases resolved via UluOps Registry with provider metadata
63
+ - **Multi-Provider AI** - Anthropic + OpenAI + Google bundled; Mistral, Cohere, and others supported via dynamic `@ai-sdk/*` import
64
+ - **Filesystem Sandboxing** - ToolHandler restricts LLM file access to the target directory
65
+ - **Content-Addressed Integrity** - SHA-256 hash verification on all definitions
66
+ - **Structured Output Extraction** - 3-strategy fallback: JSON code fence > inline JSON > regex text parsing
67
+ - **Validation Tracking** - Automatic result submission with issue correlation, regression detection, and analytics
68
+ - **Local Development Support** - Load definitions from local YAML files with registry fallback
69
+ - **Bundled Starter Agents** - 5 built-in agents for immediate use without registry access
70
+
71
+ ## Installation
72
+
73
+ Requires Node.js 18+.
74
+
75
+ ```bash
76
+ npm install @uluops/core
77
+ ```
78
+
79
+ ### Bundled Starter Agents
80
+
81
+ Get started without registry access using the bundled agent definitions:
82
+
83
+ ```typescript
84
+ import { UluOpsClient, STARTER_DEFINITIONS_DIR } from '@uluops/core';
85
+
86
+ const client = new UluOpsClient({
87
+ apiKey: process.env.ULUOPS_API_KEY,
88
+ localDefinitions: STARTER_DEFINITIONS_DIR,
89
+ });
90
+ ```
91
+
92
+ Includes: `code-validator`, `docs-validator`, `public-interface-validator`, `security-analyst`, `test-architect`.
93
+
94
+ ## Authentication
95
+
96
+ ### UluOps API Key
97
+
98
+ Required for registry and validation service access:
99
+
100
+ ```bash
101
+ # Environment variable (recommended)
102
+ export ULUOPS_API_KEY=ulr_your_api_key_here
103
+ ```
104
+
105
+ Or pass directly in config:
106
+
107
+ ```typescript
108
+ const client = new UluOpsClient({ apiKey: 'ulr_your-key' });
109
+ ```
110
+
111
+ The SDK checks for `ULUOPS_API_KEY` then `ULU_API_KEY` environment variables. Keys use a `ulr_` prefix. Generate one at [app.uluops.ai](https://app.uluops.ai).
112
+
113
+ ### AI Provider Keys
114
+
115
+ Set environment variables for the providers you want to use. The SDK auto-detects configured providers:
116
+
117
+ ```bash
118
+ export ANTHROPIC_API_KEY=your_anthropic_key
119
+ export OPENAI_API_KEY=your_openai_key # optional
120
+ export GOOGLE_API_KEY=your_google_key # optional (also accepts GOOGLE_GENERATIVE_AI_API_KEY)
121
+ ```
122
+
123
+ Or configure explicitly:
124
+
125
+ ```typescript
126
+ const client = new UluOpsClient({
127
+ apiKey: process.env.ULUOPS_API_KEY,
128
+ ai: {
129
+ providers: {
130
+ anthropic: { apiKey: process.env.ANTHROPIC_API_KEY },
131
+ openai: { apiKey: process.env.OPENAI_API_KEY },
132
+ google: { apiKey: process.env.GOOGLE_API_KEY },
133
+ },
134
+ defaultProvider: 'anthropic',
135
+ },
136
+ });
137
+ ```
138
+
139
+ ## Usage
140
+
141
+ ### Agent Execution
142
+
143
+ Direct agent execution with call-time options. Best for interactive/ad-hoc validation:
144
+
145
+ ```typescript
146
+ const result = await client.runAgent('code-validator', './src', {
147
+ model: 'sonnet',
148
+ thresholds: { pass: 80, warn: 60 },
149
+ trackResults: true,
150
+ project: 'my-project',
151
+ });
152
+
153
+ console.log(`Score: ${result.score} | Decision: ${result.decision}`);
154
+ console.log(`Recommendations: ${result.recommendations.length}`);
155
+ ```
156
+
157
+ ### Command Execution
158
+
159
+ Execute saved command configurations. Uses model, thresholds, and aggregation from the command definition. Ideal for CI/CD:
160
+
161
+ ```typescript
162
+ const result = await client.runCommand('validate', { target: './src' });
163
+
164
+ console.log(`Score: ${result.score}`);
165
+ console.log(`Categories:`, result.categories);
166
+ ```
167
+
168
+ ### Workflow Execution
169
+
170
+ DAG-based multi-phase orchestration with quality gates. Independent phases execute in parallel; dependent phases wait for their dependencies:
171
+
172
+ ```typescript
173
+ const result = await client.runWorkflow('ship', { target: './src' });
174
+
175
+ console.log(`Overall: ${result.decision} (score: ${result.score})`);
176
+
177
+ for (const phase of result.phases) {
178
+ // decision: 'passed' | 'warned' | 'blocked' | 'skipped' | 'aborted'
179
+ console.log(` ${phase.name}: ${phase.decision} (${phase.score})`);
180
+ }
181
+
182
+ // Metrics break down phase outcomes
183
+ const { phasesExecuted, phasesPassed, phasesBlocked, phasesAborted } = result.metrics;
184
+ ```
185
+
186
+ Workflows define phase dependencies and failure behaviors in their WDL definition:
187
+
188
+ ```yaml
189
+ orchestration:
190
+ on_failure: stop # stop | abort | continue | warn
191
+ max_parallel: 3 # optional concurrency limit
192
+ phases:
193
+ - id: lint
194
+ commands: [lint-validator@latest]
195
+ - id: test
196
+ commands: [test-architect@latest]
197
+ - id: security
198
+ commands: [security-analyst@latest]
199
+ depends_on: [lint, test] # DAG dependency — waits for lint + test
200
+ gate:
201
+ threshold: 85
202
+ on_fail: abort
203
+ ```
204
+
205
+ ### Auto-Routing
206
+
207
+ Universal execution — auto-detects definition type and routes to the correct executor:
208
+
209
+ ```typescript
210
+ // Routes automatically based on whether name resolves to agent, command, workflow, or pipeline
211
+ const result = await client.run('code-validator', { target: './src' });
212
+ console.log(`Decision: ${result.decision}`);
213
+ ```
214
+
215
+ ### Pipeline Execution
216
+
217
+ Async multi-stage pipelines with dependency resolution:
218
+
219
+ ```typescript
220
+ // Start async pipeline
221
+ const handle = await client.startPipeline('full-validation', {
222
+ target: './src',
223
+ });
224
+
225
+ // Monitor progress
226
+ const status = await handle.status();
227
+ console.log(`Stage ${status.stages.length} of pipeline`);
228
+
229
+ // Wait for completion
230
+ const result = await handle.wait();
231
+
232
+ // Or cancel
233
+ await handle.cancel();
234
+ ```
235
+
236
+ ### Convenience Methods
237
+
238
+ Shorthand methods for common workflows:
239
+
240
+ ```typescript
241
+ // Run the built-in validate command
242
+ const result = await client.validate('./src');
243
+
244
+ // Security audit
245
+ const secResult = await client.security('./src');
246
+
247
+ // Code optimization analysis
248
+ const optResult = await client.optimize('./src');
249
+
250
+ // Ship workflow (full pre-release validation)
251
+ const shipResult = await client.ship('./src');
252
+
253
+ // Post-implementation validation
254
+ const postResult = await client.postImplementation('./src');
255
+ ```
256
+
257
+ ### Discovery
258
+
259
+ ```typescript
260
+ // List available definitions
261
+ const definitions = await client.list({ type: 'agent', domain: 'software' });
262
+
263
+ // Inspect a definition
264
+ const info = await client.describe('code-validator');
265
+ console.log(info.name, info.version, info.interface);
266
+ ```
267
+
268
+ ### Validation Tracking
269
+
270
+ Submit execution results, preview submissions, and query run history:
271
+
272
+ ```typescript
273
+ // Automatic tracking: results are submitted automatically when trackingEnabled is true
274
+ const result = await client.runAgent('code-validator', './src', {
275
+ trackResults: true,
276
+ project: 'my-project',
277
+ });
278
+
279
+ // Manual submission: submit results from a custom execution
280
+ const response = await client.submitResults('my-project', 'post-implementation', result);
281
+ console.log(`Run #${response.runNumber}: ${response.dashboardUrl}`);
282
+ console.log(`New issues: ${response.correlation.newIssues}, Regressions: ${response.correlation.regressions}`);
283
+
284
+ // Dry run: preview what a submission would do without saving
285
+ const preview = await client.validateRun('my-project', 'post-implementation', result);
286
+ if (preview.validationErrors.length > 0) {
287
+ console.error('Validation errors:', preview.validationErrors);
288
+ }
289
+
290
+ // Query history: list past runs for a project
291
+ const history = await client.getHistory('my-project');
292
+ for (const entry of history) {
293
+ console.log(`Run #${entry.runNumber} — ${entry.workflowType} — Score: ${entry.averageScore}`);
294
+ }
295
+
296
+ // Run details: fetch full details for a specific run
297
+ const run = await client.getRun('run-uuid');
298
+ ```
299
+
300
+ ### Usage Metrics
301
+
302
+ All execution results include token usage metrics. Provider-specific token fields are mapped to a unified format:
303
+
304
+ ```typescript
305
+ const result = await client.runAgent('code-validator', './src');
306
+ const { metrics } = result;
307
+
308
+ console.log(`Input: ${metrics.inputTokens}, Output: ${metrics.outputTokens}`);
309
+ console.log(`Cache: ${metrics.cacheCreationTokens ?? 0} created, ${metrics.cacheReadTokens ?? 0} read`);
310
+
311
+ // Google Gemini 2.5+ models report thinking tokens separately from output tokens.
312
+ // thinking_tokens are included in totalEffectiveTokens (unlike OpenAI reasoning_tokens
313
+ // which are already counted within outputTokens).
314
+ if (metrics.thinkingTokens) {
315
+ console.log(`Thinking: ${metrics.thinkingTokens}`);
316
+ }
317
+
318
+ console.log(`Effective total: ${metrics.totalEffectiveTokens}`);
319
+ ```
320
+
321
+ ## Architecture
322
+
323
+ ```
324
+ UluOpsClient (facade)
325
+ |
326
+ +-- AgentExecutor (single-agent LLM execution)
327
+ | +-- AIProvider (AI SDK v6 wrapper, tool loop via maxSteps)
328
+ | +-- ToolHandler (sandboxed filesystem tools)
329
+ | +-- ToolAdapter (converts tools to AI SDK format)
330
+ | +-- OutputExtractor (3-strategy JSON parsing)
331
+ |
332
+ +-- CommandExecutor (single/multi-agent aggregation)
333
+ | +-- AgentExecutor
334
+ | +-- preflight (prerequisite checks)
335
+ |
336
+ +-- WorkflowExecutor (multi-phase orchestration with gates)
337
+ | +-- CommandExecutor
338
+ |
339
+ +-- PipelineExecutor (multi-stage async pipelines)
340
+ | +-- WorkflowExecutor
341
+ | +-- CommandExecutor
342
+ |
343
+ +-- RegistryClient (definition resolution + hash verification)
344
+ +-- ValidationClient (result submission + history)
345
+ +-- ModelCatalog (registry-backed model alias resolution)
346
+ ```
347
+
348
+ ## Execution Hierarchy
349
+
350
+ | Level | Definition | Description |
351
+ |-------|-----------|-------------|
352
+ | Agent | ADL | Atomic unit: single LLM with filesystem tools |
353
+ | Command | CDL | Wraps 1+ agents with preflight checks and aggregation |
354
+ | Workflow | WDL | Sequences commands into phases with gates |
355
+ | Pipeline | PDL | Orchestrates workflows/commands across stages |
356
+
357
+ ## Configuration
358
+
359
+ ```typescript
360
+ const client = new UluOpsClient({
361
+ // Required
362
+ apiKey: 'your-api-key', // or ULUOPS_API_KEY env var
363
+
364
+ // AI Configuration
365
+ ai: {
366
+ providers: { // Provider API keys (env var fallback)
367
+ anthropic: { apiKey: '...' },
368
+ },
369
+ defaultProvider: 'anthropic', // Default AI provider
370
+ modelOverride: 'sonnet', // Override model for all executions
371
+ },
372
+
373
+ // Service URLs
374
+ registryUrl: 'https://...', // Registry API (or ULUOPS_REGISTRY_URL)
375
+ validationUrl: 'https://...', // Validation API (or ULUOPS_VALIDATION_URL)
376
+
377
+ // Behavior
378
+ trackingEnabled: true, // Auto-submit results to validation service
379
+ timeout: 300000, // Request timeout in ms
380
+ defaultProject: 'my-project', // Default project for result submission
381
+ debug: false, // Detailed execution logging (or ULUOPS_DEBUG)
382
+ defaultThinkingBudget: 10000, // Extended thinking budget (Anthropic + Google models)
383
+ contextBudget: 200000, // Context window budget — forces wrap-up at 80%
384
+ dashboardUrl: 'https://app.uluops.ai', // Dashboard link prefix for run URLs
385
+
386
+ // Local Development
387
+ localDefinitions: './definitions', // Load YAML definitions from local dir
388
+ });
389
+ ```
390
+
391
+ ### Environment Variables
392
+
393
+ | Variable | Description | Default |
394
+ |----------|-------------|---------|
395
+ | `ULUOPS_API_KEY` | Platform API key | (required) |
396
+ | `ANTHROPIC_API_KEY` | Anthropic provider key | - |
397
+ | `OPENAI_API_KEY` | OpenAI provider key | - |
398
+ | `GOOGLE_API_KEY` | Google/Gemini provider key | - |
399
+ | `GOOGLE_GENERATIVE_AI_API_KEY` | Google provider key (alternative) | - |
400
+ | `ULUOPS_REGISTRY_URL` | Registry API URL | `https://api.uluops.ai/api/v1/registry` |
401
+ | `ULUOPS_VALIDATION_URL` | Validation API URL | `https://api.uluops.ai/api/v1/ops` |
402
+ | `ULUOPS_TRACKING_ENABLED` | Auto-submit results | `true` |
403
+ | `ULUOPS_PROJECT` | Default project name | - |
404
+ | `ULUOPS_LOCAL_DEFINITIONS` | Local definitions path | - |
405
+ | `ULUOPS_DASHBOARD_URL` | Dashboard base URL for run links | `https://app.uluops.ai` |
406
+ | `ULUOPS_DEBUG` | Enable detailed execution logging | `false` |
407
+
408
+ ## TypeScript Support
409
+
410
+ Full TypeScript support with exported types for all parameters and results:
411
+
412
+ ```typescript
413
+ import {
414
+ UluOpsClient,
415
+ // Executor types
416
+ type AgentResult,
417
+ type CommandResult,
418
+ type WorkflowResult,
419
+ type PipelineResult,
420
+ // Definition types
421
+ type AgentDefinition,
422
+ type CommandDefinition,
423
+ type WorkflowDefinition,
424
+ type PipelineDefinition,
425
+ // Config types
426
+ type UluOpsConfig,
427
+ type ExecutionInput,
428
+ type ExecutionOptions,
429
+ // Usage metrics
430
+ type UsageMetrics,
431
+ // Error classes
432
+ ExecutionError,
433
+ ConfigurationError,
434
+ ModelNotFoundError,
435
+ // Error code narrowing
436
+ ValidationErrorCodes,
437
+ } from '@uluops/core';
438
+ ```
439
+
440
+ ### Subpath Exports
441
+
442
+ For tree-shaking or importing just types/errors without pulling in the full client:
443
+
444
+ ```typescript
445
+ // Import only types (zero runtime cost)
446
+ import type { AgentResult, ExecutionInput } from '@uluops/core/types';
447
+
448
+ // Import only error classes
449
+ import { ExecutionError, ConfigurationError } from '@uluops/core/errors';
450
+ ```
451
+
452
+ ## Error Handling
453
+
454
+ The SDK provides a structured error hierarchy:
455
+
456
+ ### Core SDK Errors
457
+
458
+ | Error | Description |
459
+ |-------|-------------|
460
+ | `UluOpsError` | Base error class for all SDK errors |
461
+ | `ExecutionError` | Agent/command execution failures |
462
+ | `PreflightError` | Preflight check failures |
463
+ | `ConfigurationError` | Invalid configuration |
464
+ | `ModelNotFoundError` | Model alias not found in registry |
465
+ | `CapabilityError` | Model lacks required capabilities |
466
+ | `ValidationError` | Output validation failures. Use `ValidationErrorCodes` to narrow by code. |
467
+ | `WorkflowError` | Workflow phase gate failures |
468
+ | `PipelineError` | Pipeline stage failures |
469
+ | `ParseError` | Output extraction failures |
470
+
471
+ ```typescript
472
+ import { ConfigurationError, ModelNotFoundError, ExecutionError } from '@uluops/core';
473
+
474
+ try {
475
+ const result = await client.runAgent('code-validator', './src');
476
+ } catch (error) {
477
+ if (error instanceof ConfigurationError) {
478
+ console.error('Check your config:', error.message);
479
+ } else if (error instanceof ModelNotFoundError) {
480
+ console.error('Unknown model alias:', error.message);
481
+ } else if (error instanceof ExecutionError) {
482
+ console.error('Execution failed:', error.message);
483
+ console.log('Partial result:', error.partialResult);
484
+ }
485
+ }
486
+ ```
487
+
488
+ ### Re-exported from @uluops/sdk-core
489
+
490
+ | Error | Description |
491
+ |-------|-------------|
492
+ | `SdkApiError` | Base API error |
493
+ | `RateLimitError` | 429 rate limit exceeded |
494
+ | `UnauthorizedError` | 401 authentication failure |
495
+ | `ForbiddenError` | 403 access denied |
496
+ | `NotFoundError` | 404 resource not found |
497
+ | `ServiceUnavailableError` | 503 service unavailable |
498
+ | `NetworkError` | Connection failures |
499
+ | `TimeoutError` | Request timeout |
500
+
501
+ ## Dependencies
502
+
503
+ | Package | Purpose |
504
+ |---------|---------|
505
+ | `@uluops/sdk-core` | Shared HTTP infrastructure (HttpClient, errors, auth) |
506
+ | `@uluops/registry-sdk` | Registry API client for definitions and models |
507
+ | `@uluops/ops-sdk` | Validation tracking API client |
508
+ | `ai` | Vercel AI SDK v6 - LLM communication and tool loops |
509
+ | `@ai-sdk/anthropic` | Anthropic provider for AI SDK |
510
+ | `@ai-sdk/openai` | OpenAI provider for AI SDK |
511
+ | `@ai-sdk/google` | Google/Gemini provider for AI SDK |
512
+ | `yaml` | YAML parsing for local definitions |
513
+ | `glob` | File globbing for ToolHandler |
514
+ | `zod` | Schema validation for AI SDK tools |
515
+
516
+ ## Development
517
+
518
+ ```bash
519
+ # Install dependencies
520
+ npm install
521
+
522
+ # Type check
523
+ npm run typecheck
524
+
525
+ # Run tests
526
+ npm test
527
+
528
+ # Run tests in watch mode
529
+ npm run test:watch
530
+
531
+ # Run tests with coverage
532
+ npm run test:coverage
533
+
534
+ # Lint
535
+ npm run lint
536
+
537
+ # Build
538
+ npm run build
539
+ ```
540
+
541
+ ## License
542
+
543
+ MIT
@@ -0,0 +1,134 @@
1
+ agent:
2
+ interface:
3
+ name: code-validator
4
+ version: "0.1.0"
5
+ displayName: "Code Validator (Starter)"
6
+ description: >-
7
+ Lightweight code quality checker for local development. Validates function
8
+ design, style compliance, test existence, and basic security hygiene.
9
+ Upgrade to premium for auto-fail rules, calibration, and deep domain knowledge.
10
+ agentType: validator
11
+ domain: software
12
+ tools: [Read, Grep, Glob]
13
+
14
+ defaults:
15
+ model: haiku
16
+ timeout: 120000
17
+
18
+ mission:
19
+ opener: >-
20
+ You are a code quality checker reviewing an implementation phase for
21
+ basic correctness, style compliance, and test presence. Read the target
22
+ directory and evaluate the codebase against the scoring criteria below.
23
+ outcome_framing: >-
24
+ Provide a PASS or FAIL decision on whether this code meets minimum
25
+ quality standards for merging.
26
+
27
+ scoring:
28
+ maxScore: 100
29
+ categories:
30
+ - id: code_quality
31
+ name: Code Quality
32
+ weight: 30
33
+ description: Function design, naming clarity, and error handling.
34
+ criteria:
35
+ - id: function_design
36
+ name: Function Design
37
+ points: 10
38
+ description: Functions are focused, small, and have clear inputs/outputs.
39
+ - id: naming_clarity
40
+ name: Naming Clarity
41
+ points: 10
42
+ description: Variables, functions, and files use descriptive, consistent names.
43
+ - id: error_handling
44
+ name: Error Handling
45
+ points: 10
46
+ description: Errors are caught, logged, or propagated appropriately.
47
+
48
+ - id: standards_compliance
49
+ name: Standards Compliance
50
+ weight: 25
51
+ description: Style consistency, unused code, and formatting.
52
+ criteria:
53
+ - id: style_consistency
54
+ name: Style Consistency
55
+ points: 10
56
+ description: Code follows a consistent style throughout the project.
57
+ - id: no_unused_code
58
+ name: No Unused Code
59
+ points: 8
60
+ description: No unused imports, variables, or dead code paths.
61
+ - id: formatting
62
+ name: Formatting
63
+ points: 7
64
+ description: Consistent indentation, spacing, and line length.
65
+
66
+ - id: testing
67
+ name: Testing
68
+ weight: 25
69
+ description: Test existence, passing status, and edge case coverage.
70
+ criteria:
71
+ - id: tests_exist
72
+ name: Tests Exist
73
+ points: 10
74
+ description: Modified or new code has corresponding test files.
75
+ - id: tests_pass
76
+ name: Tests Pass
77
+ points: 8
78
+ description: Existing tests are not broken by the changes.
79
+ - id: edge_cases_covered
80
+ name: Edge Cases Covered
81
+ points: 7
82
+ description: Tests cover boundary conditions and error scenarios.
83
+
84
+ - id: best_practices
85
+ name: Best Practices
86
+ weight: 20
87
+ description: Security hygiene, DRY, and separation of concerns.
88
+ criteria:
89
+ - id: no_hardcoded_secrets
90
+ name: No Hardcoded Secrets
91
+ points: 8
92
+ description: No API keys, passwords, or tokens in source code.
93
+ - id: no_duplication
94
+ name: No Duplication
95
+ points: 6
96
+ description: No copy-pasted logic that should be extracted.
97
+ - id: separation_of_concerns
98
+ name: Separation of Concerns
99
+ points: 6
100
+ description: Business logic, I/O, and presentation are separated.
101
+
102
+ decisions:
103
+ vocabulary:
104
+ positive: PASS
105
+ negative: FAIL
106
+ preset: quality_gate
107
+
108
+ process:
109
+ phases:
110
+ - id: discovery
111
+ name: Discovery
112
+ description: Identify source files in the target directory using Glob and Read.
113
+ - id: analysis
114
+ name: Analysis
115
+ description: >-
116
+ For each file, evaluate function design, naming, error handling,
117
+ style consistency, and check for corresponding test files.
118
+ - id: scoring
119
+ name: Scoring
120
+ description: >-
121
+ Score each category based on evidence found. Determine PASS (>=70)
122
+ or FAIL (<70) and list specific issues as recommendations.
123
+
124
+ output:
125
+ format: markdown
126
+ sections:
127
+ - id: header
128
+ template: "# Code Validator (Starter) - {{decision}}"
129
+ - id: score_summary
130
+ template: "**Score: {{score}}/{{maxScore}}**"
131
+ - id: categories
132
+ template: "## Categories\n{{#each categories}}\n- {{name}}: {{score}}/{{maxScore}}\n{{/each}}"
133
+ - id: issues
134
+ template: "## Issues\n{{#each recommendations}}\n- [{{priority}}] {{title}}\n{{/each}}"