@harness-engineering/types 0.9.0 → 0.9.2

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.
package/dist/index.d.ts CHANGED
@@ -1,814 +1,945 @@
1
1
  /**
2
- * Represents a ticket created in an external tracking service.
2
+ * Result type for consistent error handling across the toolkit.
3
3
  */
4
- interface ExternalTicket {
5
- /** External identifier, e.g., "github:owner/repo#42" */
6
- externalId: string;
7
- /** URL to the ticket in the external service */
8
- url: string;
9
- }
4
+ type Result<T, E = Error> = {
5
+ ok: true;
6
+ value: T;
7
+ } | {
8
+ ok: false;
9
+ error: E;
10
+ };
10
11
  /**
11
- * Current state of a ticket in the external service.
12
- * Pulled during syncFromExternal.
12
+ * Creates a successful Result.
13
13
  */
14
- interface ExternalTicketState {
15
- /** External identifier */
16
- externalId: string;
17
- /** Ticket title in the external service */
18
- title: string;
19
- /** External status (e.g., "open", "closed") */
20
- status: string;
21
- /** External labels (used for status disambiguation on GitHub) */
22
- labels: string[];
23
- /** Current assignee in the external service, or null */
24
- assignee: string | null;
25
- }
14
+ declare function Ok<T>(value: T): Result<T, never>;
26
15
  /**
27
- * Result of a sync operation. Collects successes and errors per-feature.
16
+ * Creates a failed Result.
28
17
  */
29
- interface SyncResult {
30
- /** Tickets created during this sync */
31
- created: ExternalTicket[];
32
- /** External IDs of tickets that were updated */
33
- updated: string[];
34
- /** Assignment changes detected during pull */
35
- assignmentChanges: Array<{
36
- feature: string;
37
- from: string | null;
38
- to: string | null;
39
- }>;
40
- /** Per-feature errors (sync never throws) */
41
- errors: Array<{
42
- featureOrId: string;
43
- error: Error;
44
- }>;
45
- }
18
+ declare function Err<E>(error: E): Result<never, E>;
46
19
  /**
47
- * Configuration for external tracker sync.
20
+ * Type guard to check if a Result is successful.
48
21
  */
49
- interface TrackerSyncConfig {
50
- /** Adapter kind -- narrowed to GitHub-only for now */
51
- kind: 'github';
52
- /** Repository in "owner/repo" format (for GitHub) */
53
- repo?: string;
54
- /** Labels auto-applied to created tickets for filtering + identification */
55
- labels?: string[];
56
- /** Maps roadmap status -> external status string */
57
- statusMap: Record<FeatureStatus, string>;
58
- /**
59
- * Maps external status (+ optional label) -> roadmap status.
60
- * Compound keys like "open:in-progress" express state + label.
61
- * Optional — when absent, syncFromExternal preserves current roadmap status.
62
- */
63
- reverseStatusMap?: Record<string, FeatureStatus>;
64
- }
65
-
22
+ declare function isOk<T, E>(result: Result<T, E>): result is {
23
+ ok: true;
24
+ value: T;
25
+ };
66
26
  /**
67
- * Token usage statistics for an agent turn or session.
27
+ * Type guard to check if a Result is failed.
68
28
  */
69
- interface TokenUsage {
70
- /** Number of tokens used in the input (prompt) */
71
- inputTokens: number;
72
- /** Number of tokens generated in the output (response) */
73
- outputTokens: number;
74
- /** Combined total tokens used */
75
- totalTokens: number;
76
- }
29
+ declare function isErr<T, E>(result: Result<T, E>): result is {
30
+ ok: false;
31
+ error: E;
32
+ };
33
+
77
34
  /**
78
- * Reference to a blocking issue.
35
+ * A single step in a multi-skill workflow.
79
36
  */
80
- interface BlockerRef {
81
- /** Unique ID of the blocker */
82
- id: string | null;
83
- /** Human-readable identifier (e.g., "CORE-123") */
84
- identifier: string | null;
85
- /** Current state of the blocker */
86
- state: string | null;
37
+ interface WorkflowStep {
38
+ /** The skill to execute (e.g., "detect-doc-drift") */
39
+ skill: string;
40
+ /** Name of the artifact this step produces */
41
+ produces: string;
42
+ /** Name of the artifact this step expects as input */
43
+ expects?: string;
44
+ /** Whether failure of this step stops the workflow */
45
+ gate?: 'pass-required' | 'advisory';
87
46
  }
88
47
  /**
89
- * Representation of a work item (issue/feature) in a tracker.
48
+ * Definition of a sequence of steps to achieve a goal.
90
49
  */
91
- interface Issue {
92
- /** Unique ID in the tracking system */
93
- id: string;
94
- /** Human-readable identifier (e.g., "CORE-123") */
95
- identifier: string;
96
- /** Title or headline of the issue */
97
- title: string;
98
- /** Detailed description, if available */
99
- description: string | null;
100
- /** Numerical priority (lower is typically higher priority) */
101
- priority: number | null;
102
- /** Current lifecycle state */
103
- state: string;
104
- /** Name of the git branch associated with this issue */
105
- branchName: string | null;
106
- /** Direct URL to the issue in the tracker */
107
- url: string | null;
108
- /** List of labels or tags */
109
- labels: string[];
110
- /** References to issues that block this one */
111
- blockedBy: BlockerRef[];
112
- /** ISO timestamp of creation */
113
- createdAt: string | null;
114
- /** ISO timestamp of last update */
115
- updatedAt: string | null;
50
+ interface Workflow {
51
+ /** Descriptive name of the workflow */
52
+ name: string;
53
+ /** Ordered list of steps */
54
+ steps: WorkflowStep[];
116
55
  }
117
56
  /**
118
- * Categories of errors that can occur during agent execution.
57
+ * Possible outcomes for a single workflow step.
119
58
  */
120
- type AgentErrorCategory = 'agent_not_found' | 'invalid_workspace_cwd' | 'response_timeout' | 'turn_timeout' | 'process_exit' | 'response_error' | 'turn_failed' | 'turn_cancelled' | 'turn_input_required';
59
+ type StepOutcome = 'pass' | 'fail' | 'skipped';
121
60
  /**
122
- * Error returned by an agent backend.
61
+ * Detailed result of a workflow step execution.
123
62
  */
124
- interface AgentError {
125
- /** Machine-readable category */
126
- category: AgentErrorCategory;
127
- /** Human-readable message */
128
- message: string;
129
- /** Optional additional context */
130
- details?: unknown;
63
+ interface WorkflowStepResult {
64
+ /** The step that was executed */
65
+ step: WorkflowStep;
66
+ /** The outcome of the execution */
67
+ outcome: StepOutcome;
68
+ /** Path to the produced artifact, if any */
69
+ artifact?: string;
70
+ /** Error message if outcome is 'fail' */
71
+ error?: string;
72
+ /** Execution time in milliseconds */
73
+ durationMs: number;
131
74
  }
132
75
  /**
133
- * Parameters for starting a new agent session.
76
+ * Final result of a complete workflow execution.
134
77
  */
135
- interface SessionStartParams {
136
- /** Absolute path to the workspace directory */
137
- workspacePath: string;
138
- /** Permission level for the agent (e.g., "readonly", "full") */
139
- permissionMode: string;
140
- /** List of tool names the agent is allowed to use */
141
- allowedTools?: string[];
142
- /** Custom system instructions for the agent */
143
- systemPrompt?: string;
78
+ interface WorkflowResult {
79
+ /** The workflow that was executed */
80
+ workflow: Workflow;
81
+ /** Results for each step in the workflow */
82
+ stepResults: WorkflowStepResult[];
83
+ /** Whether the overall workflow passed (all required gates passed) */
84
+ pass: boolean;
85
+ /** Total execution time in milliseconds */
86
+ totalDurationMs: number;
144
87
  }
88
+
145
89
  /**
146
- * Represents an active session with an agent backend.
90
+ * Stability classification for prompt caching.
91
+ *
92
+ * - `static` -- changes only on deploy/update (skills index, tool definitions, SKILL.md)
93
+ * - `session` -- stable within a session, varies between sessions (graph context, project state)
94
+ * - `ephemeral` -- changes per call (tool responses, diff content, file reads)
147
95
  */
148
- interface AgentSession {
149
- /** Unique ID for the session */
150
- sessionId: string;
151
- /** Workspace associated with this session */
152
- workspacePath: string;
153
- /** Name of the backend provider */
154
- backendName: string;
155
- /** ISO timestamp when the session started */
156
- startedAt: string;
157
- }
96
+ type StabilityTier = 'static' | 'session' | 'ephemeral';
158
97
  /**
159
- * Parameters for a single interaction (turn) with an agent.
98
+ * Metadata describing a content block's caching stability.
160
99
  */
161
- interface TurnParams {
162
- /** ID of the active session */
163
- sessionId: string;
164
- /** User or system prompt for this turn */
165
- prompt: string;
166
- /** Whether this is a continuation of a previous turn */
167
- isContinuation: boolean;
100
+ interface StabilityMetadata {
101
+ /** The stability classification of this content */
102
+ stability: StabilityTier;
103
+ /** Advisory TTL hint (e.g., '1h', '5m') -- provider adapters decide actual TTL */
104
+ ttlHint?: string;
168
105
  }
106
+
169
107
  /**
170
- * Event emitted by an agent during a turn.
108
+ * Predefined cognitive modes for skills.
171
109
  */
172
- interface AgentEvent {
173
- /** Event type (e.g., "thought", "tool_call", "output") */
174
- type: string;
175
- /** ISO timestamp */
176
- timestamp: string;
177
- /** Optional subtype for finer-grained classification */
178
- subtype?: string;
179
- /** Token usage snapshot if available */
180
- usage?: TokenUsage;
181
- /** Event payload */
182
- content?: unknown;
183
- /** Session ID if not implicit */
184
- sessionId?: string;
185
- }
110
+ declare const STANDARD_COGNITIVE_MODES: readonly ["adversarial-reviewer", "constructive-architect", "meticulous-implementer", "diagnostic-investigator", "advisory-guide", "meticulous-verifier"];
186
111
  /**
187
- * Result of a completed agent turn.
112
+ * Cognitive mode of a skill, determining its behavior and persona.
188
113
  */
189
- interface TurnResult {
190
- /** Whether the turn completed successfully */
191
- success: boolean;
192
- /** ID of the session */
193
- sessionId: string;
194
- /** Cumulative usage for this turn */
195
- usage: TokenUsage;
196
- /** Error message if success is false */
197
- error?: string;
114
+ type CognitiveMode = (typeof STANDARD_COGNITIVE_MODES)[number] | (string & {});
115
+ /**
116
+ * Static metadata for a skill.
117
+ */
118
+ interface SkillMetadata {
119
+ /** Unique name of the skill */
120
+ name: string;
121
+ /** Semantic version string */
122
+ version: string;
123
+ /** Brief description of what the skill does */
124
+ description: string;
125
+ /** The cognitive mode this skill operates in */
126
+ cognitive_mode?: CognitiveMode;
127
+ /** Caching stability tier -- defaults to inferred from content type if omitted */
128
+ stability?: StabilityTier;
198
129
  }
199
130
  /**
200
- * Interface for agent backend implementations (Claude, Mock, etc.)
131
+ * Contextual information for a skill execution.
201
132
  */
202
- interface AgentBackend {
203
- /** Unique name of the backend */
204
- readonly name: string;
205
- /** Starts a new session */
206
- startSession(params: SessionStartParams): Promise<Result<AgentSession, AgentError>>;
207
- /** Runs a turn and streams events */
208
- runTurn(session: AgentSession, params: TurnParams): AsyncGenerator<AgentEvent, TurnResult, void>;
209
- /** Stops and cleans up a session */
210
- stopSession(session: AgentSession): Promise<Result<void, AgentError>>;
211
- /** Verifies connectivity and health */
212
- healthCheck(): Promise<Result<void, AgentError>>;
133
+ interface SkillContext {
134
+ /** Name of the executing skill */
135
+ skillName: string;
136
+ /** Current pipeline phase */
137
+ phase: string;
138
+ /** Files relevant to the current execution */
139
+ files: string[];
140
+ /** Optional token budget uses a plain record to avoid cross-package deps. */
141
+ tokenBudget?: Record<string, number>;
142
+ /** Additional metadata */
143
+ metadata: Record<string, unknown>;
213
144
  }
214
145
  /**
215
- * Interface for issue tracking systems (Roadmap, Linear, GitHub, etc.)
146
+ * Context for a single turn in a multi-turn skill interaction.
216
147
  */
217
- interface IssueTrackerClient {
218
- /** Fetches issues eligible for agent assignment */
219
- fetchCandidateIssues(): Promise<Result<Issue[], Error>>;
220
- /** Fetches issues in specific lifecycle states */
221
- fetchIssuesByStates(stateNames: string[]): Promise<Result<Issue[], Error>>;
222
- /** Fetches current state for a set of issue IDs */
223
- fetchIssueStatesByIds(issueIds: string[]): Promise<Result<Map<string, Issue>, Error>>;
148
+ interface TurnContext extends SkillContext {
149
+ /** Current turn number (1-indexed) */
150
+ turnNumber: number;
151
+ /** Results from previous turns in the same session */
152
+ previousResults: unknown[];
224
153
  }
225
154
  /**
226
- * Configuration for an issue tracker adapter.
155
+ * Error reported by a skill.
227
156
  */
228
- interface TrackerConfig {
229
- /** Adapter kind (e.g., "roadmap", "linear") */
230
- kind: string;
231
- /** API endpoint if applicable */
232
- endpoint?: string;
233
- /** API key or token */
234
- apiKey?: string;
235
- /** Project slug or identifier */
236
- projectSlug?: string;
237
- /** Local file path for file-based trackers */
238
- filePath?: string;
239
- /** States considered "ready for work" */
240
- activeStates: string[];
241
- /** States considered "finished" */
242
- terminalStates: string[];
243
- }
157
+ type SkillError = {
158
+ /** Machine-readable error code */
159
+ code: string;
160
+ /** Human-readable error message */
161
+ message: string;
162
+ /** Phase in which the error occurred */
163
+ phase: string;
164
+ };
244
165
  /**
245
- * Polling interval configuration.
166
+ * Result of a skill execution.
246
167
  */
247
- interface PollingConfig {
248
- /** Interval in milliseconds */
249
- intervalMs: number;
250
- }
168
+ type SkillResult = {
169
+ /** Whether the skill achieved its goal */
170
+ success: boolean;
171
+ /** List of artifact paths produced */
172
+ artifacts: string[];
173
+ /** One-line summary of the outcome */
174
+ summary: string;
175
+ };
251
176
  /**
252
- * Workspace management configuration.
177
+ * Lifecycle hooks for skills.
253
178
  */
254
- interface WorkspaceConfig {
255
- /** Root directory where agent workspaces are created */
256
- root: string;
179
+ interface SkillLifecycleHooks {
180
+ /** Called before the skill starts execution */
181
+ preExecution?: (context: SkillContext) => SkillContext | null;
182
+ /** Called before each turn in a multi-turn interaction */
183
+ perTurn?: (context: TurnContext) => TurnContext | null;
184
+ /** Called after the skill completes execution */
185
+ postExecution?: (context: SkillContext, result: SkillResult) => void;
257
186
  }
187
+
258
188
  /**
259
- * Lifecycle hooks configuration.
189
+ * Names of standard CI checks.
260
190
  */
261
- interface HooksConfig {
262
- /** Script to run after creating a workspace */
263
- afterCreate: string | null;
264
- /** Script to run before starting an agent */
265
- beforeRun: string | null;
266
- /** Script to run after an agent completes */
267
- afterRun: string | null;
268
- /** Script to run before removing a workspace */
269
- beforeRemove: string | null;
270
- /** Maximum time allowed for hook execution */
271
- timeoutMs: number;
272
- }
191
+ type CICheckName = 'validate' | 'deps' | 'docs' | 'entropy' | 'security' | 'perf' | 'phase-gate' | 'arch' | 'traceability';
273
192
  /**
274
- * Configuration for the agent runner.
193
+ * Status of a CI check.
275
194
  */
276
- interface AgentConfig {
277
- /** Backend type to use */
278
- backend: string;
279
- /** Command to launch the agent if applicable */
280
- command?: string;
281
- /** Model name/identifier */
282
- model?: string;
283
- /** API key for the agent provider */
284
- apiKey?: string;
285
- /** Global limit on concurrent agents */
286
- maxConcurrentAgents: number;
287
- /** Maximum turns allowed per session */
288
- maxTurns: number;
289
- /** Maximum backoff for retries */
290
- maxRetryBackoffMs: number;
291
- /** Concurrency limits partitioned by issue state */
292
- maxConcurrentAgentsByState: Record<string, number>;
293
- /** Policy for approving tool calls */
294
- approvalPolicy?: string;
295
- /** Policy for execution environment isolation */
296
- sandboxPolicy?: string;
297
- /** Timeout for a single turn */
298
- turnTimeoutMs: number;
299
- /** Timeout for reading from the agent */
300
- readTimeoutMs: number;
301
- /** Timeout for agent inactivity */
302
- stallTimeoutMs: number;
303
- }
195
+ type CICheckStatus = 'pass' | 'fail' | 'warn' | 'skip';
304
196
  /**
305
- * Internal server configuration.
197
+ * A specific issue found during a CI check.
306
198
  */
307
- interface ServerConfig {
308
- /** Port to listen on (null to disable) */
309
- port: number | null;
199
+ interface CICheckIssue {
200
+ /** Severity level */
201
+ severity: 'error' | 'warning';
202
+ /** Descriptive message */
203
+ message: string;
204
+ /** Path to the affected file */
205
+ file?: string;
206
+ /** Line number in the affected file */
207
+ line?: number;
310
208
  }
311
209
  /**
312
- * Root workflow configuration object.
210
+ * Result of a single CI check execution.
313
211
  */
314
- interface WorkflowConfig {
315
- /** Issue tracker settings */
316
- tracker: TrackerConfig;
317
- /** Polling loop settings */
318
- polling: PollingConfig;
319
- /** Workspace settings */
320
- workspace: WorkspaceConfig;
321
- /** Lifecycle hook settings */
322
- hooks: HooksConfig;
323
- /** Agent execution settings */
324
- agent: AgentConfig;
325
- /** Server settings */
326
- server: ServerConfig;
212
+ interface CICheckResult {
213
+ /** Name of the check */
214
+ name: CICheckName;
215
+ /** Final status of the check */
216
+ status: CICheckStatus;
217
+ /** List of issues discovered */
218
+ issues: CICheckIssue[];
219
+ /** Execution time in milliseconds */
220
+ durationMs: number;
327
221
  }
328
222
  /**
329
- * Complete workflow definition including config and prompts.
223
+ * Summary counts for a set of CI checks.
330
224
  */
331
- interface WorkflowDefinition {
332
- /** Orchestrator configuration */
333
- config: WorkflowConfig;
334
- /** Template used to generate agent prompts */
335
- promptTemplate: string;
225
+ interface CICheckSummary {
226
+ /** Total number of checks run */
227
+ total: number;
228
+ /** Number of passing checks */
229
+ passed: number;
230
+ /** Number of failing checks */
231
+ failed: number;
232
+ /** Number of checks with warnings */
233
+ warnings: number;
234
+ /** Number of skipped checks */
235
+ skipped: number;
336
236
  }
337
-
338
237
  /**
339
- * Extended entry for cost tracking storage and display.
340
- * Composes TokenUsage — does not extend it.
238
+ * Final report for a CI run.
341
239
  */
342
- interface UsageRecord {
343
- /** Harness session identifier */
344
- sessionId: string;
345
- /** ISO 8601 timestamp of the usage event */
240
+ interface CICheckReport {
241
+ /** Schema version */
242
+ version: 1;
243
+ /** Name of the project */
244
+ project: string;
245
+ /** ISO timestamp of the run */
346
246
  timestamp: string;
347
- /** Token counts for this event */
348
- tokens: TokenUsage;
349
- /** Tokens used to create prompt cache entries */
350
- cacheCreationTokens?: number;
351
- /** Tokens read from prompt cache */
352
- cacheReadTokens?: number;
353
- /** Model identifier (e.g., "claude-sonnet-4-20250514") */
354
- model?: string;
355
- /** Cost in integer microdollars (USD * 1,000,000), calculated at read time */
356
- costMicroUSD?: number;
247
+ /** Detailed results for each check */
248
+ checks: CICheckResult[];
249
+ /** Aggregated summary */
250
+ summary: CICheckSummary;
251
+ /** Process exit code suggested for the CI runner */
252
+ exitCode: 0 | 1 | 2;
357
253
  }
358
254
  /**
359
- * Per-model pricing rates, all in USD per 1 million tokens.
255
+ * Severity level that should trigger a CI failure.
360
256
  */
361
- interface ModelPricing {
362
- /** Input token cost per 1M tokens */
363
- inputPer1M: number;
364
- /** Output token cost per 1M tokens */
365
- outputPer1M: number;
366
- /** Cache read cost per 1M tokens (not all models support caching) */
367
- cacheReadPer1M?: number;
368
- /** Cache write/creation cost per 1M tokens */
369
- cacheWritePer1M?: number;
370
- }
257
+ type CIFailOnSeverity = 'error' | 'warning';
371
258
  /**
372
- * Aggregated usage for a single calendar day.
259
+ * Configuration options for the CI command.
373
260
  */
374
- interface DailyUsage {
375
- /** ISO 8601 date string (YYYY-MM-DD) */
376
- date: string;
377
- /** Number of distinct sessions that had activity on this day */
378
- sessionCount: number;
379
- /** Summed token counts across all sessions */
380
- tokens: TokenUsage;
381
- /** Summed cache creation tokens (omitted if no cache data) */
382
- cacheCreationTokens?: number;
383
- /** Summed cache read tokens (omitted if no cache data) */
384
- cacheReadTokens?: number;
385
- /** Total cost in integer microdollars, null if any session has unknown pricing */
386
- costMicroUSD: number | null;
387
- /** Distinct model identifiers seen on this day */
388
- models: string[];
261
+ interface CICheckOptions {
262
+ /** Checks to skip */
263
+ skip?: CICheckName[];
264
+ /** Severity level that causes failure */
265
+ failOn?: CIFailOnSeverity;
266
+ /** Custom config file path */
267
+ configPath?: string;
389
268
  }
390
269
  /**
391
- * Aggregated usage for a single session across all its turns.
270
+ * Supported CI platforms.
392
271
  */
393
- interface SessionUsage {
394
- /** Harness session identifier */
395
- sessionId: string;
396
- /** ISO 8601 timestamp of the first event in this session */
397
- firstTimestamp: string;
398
- /** ISO 8601 timestamp of the last event in this session */
399
- lastTimestamp: string;
400
- /** Summed token counts across all turns */
401
- tokens: TokenUsage;
402
- /** Summed cache creation tokens (omitted if no cache data) */
403
- cacheCreationTokens?: number;
404
- /** Summed cache read tokens (omitted if no cache data) */
405
- cacheReadTokens?: number;
406
- /** Model identifier (may be populated from CC data) */
407
- model?: string;
408
- /** Total cost in integer microdollars, null if pricing unavailable */
409
- costMicroUSD: number | null;
410
- /** Data source: 'harness', 'claude-code', or 'merged' */
411
- source: 'harness' | 'claude-code' | 'merged';
272
+ type CIPlatform = 'github' | 'gitlab' | 'generic';
273
+ /**
274
+ * Options for initializing CI configuration.
275
+ */
276
+ interface CIInitOptions {
277
+ /** Target CI platform */
278
+ platform?: CIPlatform;
279
+ /** Checks to enable */
280
+ checks?: CICheckName[];
412
281
  }
413
282
 
414
283
  /**
415
- * Session-scoped accumulative state types.
416
- *
417
- * Session memory allows skills to append to shared sections (terminology,
418
- * decisions, constraints, risks, openQuestions, evidence) rather than
419
- * overwriting. Each entry is timestamped and tagged with the authoring skill.
420
- *
421
- * @see docs/changes/ai-foundations-integration/proposal.md
284
+ * Valid statuses for a roadmap feature.
422
285
  */
286
+ type FeatureStatus = 'backlog' | 'planned' | 'in-progress' | 'done' | 'blocked';
423
287
  /**
424
- * Names of accumulative session sections.
425
- * Runtime array used for iteration and validation.
288
+ * Priority override levels for roadmap features.
289
+ * When present, priority replaces positional ordering as the primary sort key.
426
290
  */
427
- declare const SESSION_SECTION_NAMES: readonly ["terminology", "decisions", "constraints", "risks", "openQuestions", "evidence"];
291
+ type Priority = 'P0' | 'P1' | 'P2' | 'P3';
428
292
  /**
429
- * Union type of valid session section names.
293
+ * A feature entry in the project roadmap.
430
294
  */
431
- type SessionSectionName = (typeof SESSION_SECTION_NAMES)[number];
295
+ interface RoadmapFeature {
296
+ /** Feature name (from the H3 heading, without "Feature:" prefix) */
297
+ name: string;
298
+ /** Current status */
299
+ status: FeatureStatus;
300
+ /** Relative path to the spec file, or null if none */
301
+ spec: string | null;
302
+ /** Relative paths to plan files */
303
+ plans: string[];
304
+ /** Names of blocking features (textual references) */
305
+ blockedBy: string[];
306
+ /** One-line summary */
307
+ summary: string;
308
+ /** GitHub username, email, or display name — null if unassigned */
309
+ assignee: string | null;
310
+ /** Optional priority override — null uses positional ordering */
311
+ priority: Priority | null;
312
+ /** External tracker ID (e.g., "github:owner/repo#42") — null if not synced */
313
+ externalId: string | null;
314
+ }
432
315
  /**
433
- * Lifecycle status of a session entry.
434
- * - `active` current and relevant
435
- * - `resolved` — addressed or answered (e.g., an open question that was resolved)
436
- * - `superseded` — replaced by a newer entry
316
+ * A milestone grouping in the roadmap. The special "Backlog" milestone
317
+ * has `isBacklog: true` and appears as `## Backlog` instead of `## Milestone: <name>`.
437
318
  */
438
- type SessionEntryStatus = 'active' | 'resolved' | 'superseded';
319
+ interface RoadmapMilestone {
320
+ /** Milestone name (e.g., "MVP Release") or "Backlog" */
321
+ name: string;
322
+ /** True for the special Backlog section */
323
+ isBacklog: boolean;
324
+ /** Features in this milestone, in document order */
325
+ features: RoadmapFeature[];
326
+ }
439
327
  /**
440
- * A single entry in a session section.
441
- * Entries are append-only; skills mark them as `resolved` or `superseded`
442
- * rather than deleting.
328
+ * A single record in the assignment history log.
329
+ * Reassignment produces two records: 'unassigned' for previous, 'assigned' for new.
443
330
  */
444
- interface SessionEntry {
445
- /** Auto-generated unique identifier */
446
- id: string;
447
- /** ISO 8601 timestamp of when the entry was created */
448
- timestamp: string;
449
- /** Name of the skill that authored this entry */
450
- authorSkill: string;
451
- /** The entry content (free-form text) */
452
- content: string;
453
- /** Lifecycle status of the entry */
454
- status: SessionEntryStatus;
331
+ interface AssignmentRecord {
332
+ /** Feature name */
333
+ feature: string;
334
+ /** Assignee identifier (username, email, or display name) */
335
+ assignee: string;
336
+ /** What happened */
337
+ action: 'assigned' | 'completed' | 'unassigned';
338
+ /** ISO date string (YYYY-MM-DD) */
339
+ date: string;
455
340
  }
456
341
  /**
457
- * Container mapping each section name to its array of entries.
458
- * Used as the shape of session-scoped state in `state.json`.
342
+ * YAML frontmatter of the roadmap file.
459
343
  */
460
- type SessionSections = {
461
- [K in SessionSectionName]: SessionEntry[];
462
- };
344
+ interface RoadmapFrontmatter {
345
+ /** Project name */
346
+ project: string;
347
+ /** Schema version (currently 1) */
348
+ version: number;
349
+ /** ISO date when roadmap was created */
350
+ created?: string;
351
+ /** ISO date when roadmap was last updated */
352
+ updated?: string;
353
+ /** ISO timestamp of last automated sync */
354
+ lastSynced: string;
355
+ /** ISO timestamp of last manual edit */
356
+ lastManualEdit: string;
357
+ }
358
+ /**
359
+ * Parsed roadmap document.
360
+ */
361
+ interface Roadmap {
362
+ /** Parsed frontmatter */
363
+ frontmatter: RoadmapFrontmatter;
364
+ /** Milestones in document order (including Backlog) */
365
+ milestones: RoadmapMilestone[];
366
+ /** Assignment history records, in document order */
367
+ assignmentHistory: AssignmentRecord[];
368
+ }
463
369
 
464
370
  /**
465
- * @harness-engineering/types
466
- *
467
- * Core types and interfaces for Harness Engineering toolkit
371
+ * Represents a ticket created in an external tracking service.
468
372
  */
373
+ interface ExternalTicket {
374
+ /** External identifier, e.g., "github:owner/repo#42" */
375
+ externalId: string;
376
+ /** URL to the ticket in the external service */
377
+ url: string;
378
+ }
469
379
  /**
470
- * Result type for consistent error handling across the toolkit.
380
+ * Current state of a ticket in the external service.
381
+ * Pulled during syncFromExternal.
471
382
  */
472
- type Result<T, E = Error> = {
473
- ok: true;
474
- value: T;
475
- } | {
476
- ok: false;
477
- error: E;
478
- };
383
+ interface ExternalTicketState {
384
+ /** External identifier */
385
+ externalId: string;
386
+ /** Ticket title in the external service */
387
+ title: string;
388
+ /** External status (e.g., "open", "closed") */
389
+ status: string;
390
+ /** External labels (used for status disambiguation on GitHub) */
391
+ labels: string[];
392
+ /** Current assignee in the external service, or null */
393
+ assignee: string | null;
394
+ }
479
395
  /**
480
- * Creates a successful Result.
396
+ * Result of a sync operation. Collects successes and errors per-feature.
481
397
  */
482
- declare function Ok<T>(value: T): Result<T, never>;
398
+ interface SyncResult {
399
+ /** Tickets created during this sync */
400
+ created: ExternalTicket[];
401
+ /** External IDs of tickets that were updated */
402
+ updated: string[];
403
+ /** Assignment changes detected during pull */
404
+ assignmentChanges: Array<{
405
+ feature: string;
406
+ from: string | null;
407
+ to: string | null;
408
+ }>;
409
+ /** Per-feature errors (sync never throws) */
410
+ errors: Array<{
411
+ featureOrId: string;
412
+ error: Error;
413
+ }>;
414
+ }
483
415
  /**
484
- * Creates a failed Result.
416
+ * Configuration for external tracker sync.
485
417
  */
486
- declare function Err<E>(error: E): Result<never, E>;
418
+ interface TrackerSyncConfig {
419
+ /** Adapter kind -- narrowed to GitHub-only for now */
420
+ kind: 'github';
421
+ /** Repository in "owner/repo" format (for GitHub) */
422
+ repo?: string;
423
+ /** Labels auto-applied to created tickets for filtering + identification */
424
+ labels?: string[];
425
+ /** Maps roadmap status -> external status string */
426
+ statusMap: Record<FeatureStatus, string>;
427
+ /**
428
+ * Maps external status (+ optional label) -> roadmap status.
429
+ * Compound keys like "open:in-progress" express state + label.
430
+ * Optional — when absent, syncFromExternal preserves current roadmap status.
431
+ */
432
+ reverseStatusMap?: Record<string, FeatureStatus>;
433
+ }
434
+
487
435
  /**
488
- * Type guard to check if a Result is successful.
436
+ * Token usage statistics for an agent turn or session.
489
437
  */
490
- declare function isOk<T, E>(result: Result<T, E>): result is {
491
- ok: true;
492
- value: T;
493
- };
438
+ interface TokenUsage {
439
+ /** Number of tokens used in the input (prompt) */
440
+ inputTokens: number;
441
+ /** Number of tokens generated in the output (response) */
442
+ outputTokens: number;
443
+ /** Combined total tokens used */
444
+ totalTokens: number;
445
+ /** Tokens used to create a new cache entry (provider-specific) */
446
+ cacheCreationTokens?: number;
447
+ /** Tokens read from an existing cache entry (provider-specific) */
448
+ cacheReadTokens?: number;
449
+ }
494
450
  /**
495
- * Type guard to check if a Result is failed.
451
+ * Reference to a blocking issue.
496
452
  */
497
- declare function isErr<T, E>(result: Result<T, E>): result is {
498
- ok: false;
499
- error: E;
500
- };
453
+ interface BlockerRef {
454
+ /** Unique ID of the blocker */
455
+ id: string | null;
456
+ /** Human-readable identifier (e.g., "CORE-123") */
457
+ identifier: string | null;
458
+ /** Current state of the blocker */
459
+ state: string | null;
460
+ }
501
461
  /**
502
- * A single step in a multi-skill workflow.
462
+ * Representation of a work item (issue/feature) in a tracker.
503
463
  */
504
- interface WorkflowStep {
505
- /** The skill to execute (e.g., "detect-doc-drift") */
506
- skill: string;
507
- /** Name of the artifact this step produces */
508
- produces: string;
509
- /** Name of the artifact this step expects as input */
510
- expects?: string;
511
- /** Whether failure of this step stops the workflow */
512
- gate?: 'pass-required' | 'advisory';
464
+ interface Issue {
465
+ /** Unique ID in the tracking system */
466
+ id: string;
467
+ /** Human-readable identifier (e.g., "CORE-123") */
468
+ identifier: string;
469
+ /** Title or headline of the issue */
470
+ title: string;
471
+ /** Detailed description, if available */
472
+ description: string | null;
473
+ /** Numerical priority (lower is typically higher priority) */
474
+ priority: number | null;
475
+ /** Current lifecycle state */
476
+ state: string;
477
+ /** Name of the git branch associated with this issue */
478
+ branchName: string | null;
479
+ /** Direct URL to the issue in the tracker */
480
+ url: string | null;
481
+ /** List of labels or tags */
482
+ labels: string[];
483
+ /** References to issues that block this one */
484
+ blockedBy: BlockerRef[];
485
+ /** ISO timestamp of creation */
486
+ createdAt: string | null;
487
+ /** ISO timestamp of last update */
488
+ updatedAt: string | null;
489
+ }
490
+ /**
491
+ * Categories of errors that can occur during agent execution.
492
+ */
493
+ type AgentErrorCategory = 'agent_not_found' | 'invalid_workspace_cwd' | 'response_timeout' | 'turn_timeout' | 'process_exit' | 'response_error' | 'turn_failed' | 'turn_cancelled' | 'turn_input_required';
494
+ /**
495
+ * Error returned by an agent backend.
496
+ */
497
+ interface AgentError {
498
+ /** Machine-readable category */
499
+ category: AgentErrorCategory;
500
+ /** Human-readable message */
501
+ message: string;
502
+ /** Optional additional context */
503
+ details?: unknown;
513
504
  }
514
505
  /**
515
- * Definition of a sequence of steps to achieve a goal.
506
+ * Parameters for starting a new agent session.
516
507
  */
517
- interface Workflow {
518
- /** Descriptive name of the workflow */
519
- name: string;
520
- /** Ordered list of steps */
521
- steps: WorkflowStep[];
508
+ interface SessionStartParams {
509
+ /** Absolute path to the workspace directory */
510
+ workspacePath: string;
511
+ /** Permission level for the agent (e.g., "readonly", "full") */
512
+ permissionMode: string;
513
+ /** List of tool names the agent is allowed to use */
514
+ allowedTools?: string[];
515
+ /** Custom system instructions for the agent */
516
+ systemPrompt?: string;
522
517
  }
523
518
  /**
524
- * Possible outcomes for a single workflow step.
519
+ * Represents an active session with an agent backend.
525
520
  */
526
- type StepOutcome = 'pass' | 'fail' | 'skipped';
521
+ interface AgentSession {
522
+ /** Unique ID for the session */
523
+ sessionId: string;
524
+ /** Workspace associated with this session */
525
+ workspacePath: string;
526
+ /** Name of the backend provider */
527
+ backendName: string;
528
+ /** ISO timestamp when the session started */
529
+ startedAt: string;
530
+ }
527
531
  /**
528
- * Detailed result of a workflow step execution.
532
+ * Parameters for a single interaction (turn) with an agent.
529
533
  */
530
- interface WorkflowStepResult {
531
- /** The step that was executed */
532
- step: WorkflowStep;
533
- /** The outcome of the execution */
534
- outcome: StepOutcome;
535
- /** Path to the produced artifact, if any */
536
- artifact?: string;
537
- /** Error message if outcome is 'fail' */
538
- error?: string;
539
- /** Execution time in milliseconds */
540
- durationMs: number;
534
+ interface TurnParams {
535
+ /** ID of the active session */
536
+ sessionId: string;
537
+ /** User or system prompt for this turn */
538
+ prompt: string;
539
+ /** Whether this is a continuation of a previous turn */
540
+ isContinuation: boolean;
541
541
  }
542
542
  /**
543
- * Final result of a complete workflow execution.
543
+ * Event emitted by an agent during a turn.
544
544
  */
545
- interface WorkflowResult {
546
- /** The workflow that was executed */
547
- workflow: Workflow;
548
- /** Results for each step in the workflow */
549
- stepResults: WorkflowStepResult[];
550
- /** Whether the overall workflow passed (all required gates passed) */
551
- pass: boolean;
552
- /** Total execution time in milliseconds */
553
- totalDurationMs: number;
545
+ interface AgentEvent {
546
+ /** Event type (e.g., "thought", "tool_call", "output") */
547
+ type: string;
548
+ /** ISO timestamp */
549
+ timestamp: string;
550
+ /** Optional subtype for finer-grained classification */
551
+ subtype?: string;
552
+ /** Token usage snapshot if available */
553
+ usage?: TokenUsage;
554
+ /** Event payload */
555
+ content?: unknown;
556
+ /** Session ID if not implicit */
557
+ sessionId?: string;
554
558
  }
555
559
  /**
556
- * Predefined cognitive modes for skills.
560
+ * Result of a completed agent turn.
557
561
  */
558
- declare const STANDARD_COGNITIVE_MODES: readonly ["adversarial-reviewer", "constructive-architect", "meticulous-implementer", "diagnostic-investigator", "advisory-guide", "meticulous-verifier"];
562
+ interface TurnResult {
563
+ /** Whether the turn completed successfully */
564
+ success: boolean;
565
+ /** ID of the session */
566
+ sessionId: string;
567
+ /** Cumulative usage for this turn */
568
+ usage: TokenUsage;
569
+ /** Error message if success is false */
570
+ error?: string;
571
+ }
559
572
  /**
560
- * Cognitive mode of a skill, determining its behavior and persona.
573
+ * Interface for agent backend implementations (Claude, Mock, etc.)
561
574
  */
562
- type CognitiveMode = (typeof STANDARD_COGNITIVE_MODES)[number] | (string & {});
575
+ interface AgentBackend {
576
+ /** Unique name of the backend */
577
+ readonly name: string;
578
+ /** Starts a new session */
579
+ startSession(params: SessionStartParams): Promise<Result<AgentSession, AgentError>>;
580
+ /** Runs a turn and streams events */
581
+ runTurn(session: AgentSession, params: TurnParams): AsyncGenerator<AgentEvent, TurnResult, void>;
582
+ /** Stops and cleans up a session */
583
+ stopSession(session: AgentSession): Promise<Result<void, AgentError>>;
584
+ /** Verifies connectivity and health */
585
+ healthCheck(): Promise<Result<void, AgentError>>;
586
+ }
563
587
  /**
564
- * Static metadata for a skill.
588
+ * Interface for issue tracking systems (Roadmap, Linear, GitHub, etc.)
565
589
  */
566
- interface SkillMetadata {
567
- /** Unique name of the skill */
568
- name: string;
569
- /** Semantic version string */
570
- version: string;
571
- /** Brief description of what the skill does */
572
- description: string;
573
- /** The cognitive mode this skill operates in */
574
- cognitive_mode?: CognitiveMode;
590
+ interface IssueTrackerClient {
591
+ /** Fetches issues eligible for agent assignment */
592
+ fetchCandidateIssues(): Promise<Result<Issue[], Error>>;
593
+ /** Fetches issues in specific lifecycle states */
594
+ fetchIssuesByStates(stateNames: string[]): Promise<Result<Issue[], Error>>;
595
+ /** Fetches current state for a set of issue IDs */
596
+ fetchIssueStatesByIds(issueIds: string[]): Promise<Result<Map<string, Issue>, Error>>;
575
597
  }
576
598
  /**
577
- * Contextual information for a skill execution.
599
+ * Configuration for an issue tracker adapter.
578
600
  */
579
- interface SkillContext {
580
- /** Name of the executing skill */
581
- skillName: string;
582
- /** Current pipeline phase */
583
- phase: string;
584
- /** Files relevant to the current execution */
585
- files: string[];
586
- /** Optional token budget uses a plain record to avoid cross-package deps. */
587
- tokenBudget?: Record<string, number>;
588
- /** Additional metadata */
589
- metadata: Record<string, unknown>;
601
+ interface TrackerConfig {
602
+ /** Adapter kind (e.g., "roadmap", "linear") */
603
+ kind: string;
604
+ /** API endpoint if applicable */
605
+ endpoint?: string;
606
+ /** API key or token */
607
+ apiKey?: string;
608
+ /** Project slug or identifier */
609
+ projectSlug?: string;
610
+ /** Local file path for file-based trackers */
611
+ filePath?: string;
612
+ /** States considered "ready for work" */
613
+ activeStates: string[];
614
+ /** States considered "finished" */
615
+ terminalStates: string[];
590
616
  }
591
617
  /**
592
- * Context for a single turn in a multi-turn skill interaction.
618
+ * Polling interval configuration.
593
619
  */
594
- interface TurnContext extends SkillContext {
595
- /** Current turn number (1-indexed) */
596
- turnNumber: number;
597
- /** Results from previous turns in the same session */
598
- previousResults: unknown[];
620
+ interface PollingConfig {
621
+ /** Interval in milliseconds */
622
+ intervalMs: number;
599
623
  }
600
624
  /**
601
- * Error reported by a skill.
625
+ * Workspace management configuration.
602
626
  */
603
- type SkillError = {
604
- /** Machine-readable error code */
605
- code: string;
606
- /** Human-readable error message */
607
- message: string;
608
- /** Phase in which the error occurred */
609
- phase: string;
610
- };
627
+ interface WorkspaceConfig {
628
+ /** Root directory where agent workspaces are created */
629
+ root: string;
630
+ }
611
631
  /**
612
- * Names of standard CI checks.
632
+ * Lifecycle hooks configuration.
613
633
  */
614
- type CICheckName = 'validate' | 'deps' | 'docs' | 'entropy' | 'security' | 'perf' | 'phase-gate' | 'arch' | 'traceability';
634
+ interface HooksConfig {
635
+ /** Script to run after creating a workspace */
636
+ afterCreate: string | null;
637
+ /** Script to run before starting an agent */
638
+ beforeRun: string | null;
639
+ /** Script to run after an agent completes */
640
+ afterRun: string | null;
641
+ /** Script to run before removing a workspace */
642
+ beforeRemove: string | null;
643
+ /** Maximum time allowed for hook execution */
644
+ timeoutMs: number;
645
+ }
615
646
  /**
616
- * Status of a CI check.
647
+ * Configuration for the agent runner.
617
648
  */
618
- type CICheckStatus = 'pass' | 'fail' | 'warn' | 'skip';
649
+ interface AgentConfig {
650
+ /** Backend type to use */
651
+ backend: string;
652
+ /** Command to launch the agent if applicable */
653
+ command?: string;
654
+ /** Model name/identifier */
655
+ model?: string;
656
+ /** API key for the agent provider */
657
+ apiKey?: string;
658
+ /** Global limit on concurrent agents */
659
+ maxConcurrentAgents: number;
660
+ /** Maximum turns allowed per session */
661
+ maxTurns: number;
662
+ /** Maximum backoff for retries */
663
+ maxRetryBackoffMs: number;
664
+ /** Concurrency limits partitioned by issue state */
665
+ maxConcurrentAgentsByState: Record<string, number>;
666
+ /** Policy for approving tool calls */
667
+ approvalPolicy?: string;
668
+ /** Policy for execution environment isolation */
669
+ sandboxPolicy?: string;
670
+ /** Timeout for a single turn */
671
+ turnTimeoutMs: number;
672
+ /** Timeout for reading from the agent */
673
+ readTimeoutMs: number;
674
+ /** Timeout for agent inactivity */
675
+ stallTimeoutMs: number;
676
+ }
619
677
  /**
620
- * A specific issue found during a CI check.
678
+ * Internal server configuration.
621
679
  */
622
- interface CICheckIssue {
623
- /** Severity level */
624
- severity: 'error' | 'warning';
625
- /** Descriptive message */
626
- message: string;
627
- /** Path to the affected file */
628
- file?: string;
629
- /** Line number in the affected file */
630
- line?: number;
680
+ interface ServerConfig {
681
+ /** Port to listen on (null to disable) */
682
+ port: number | null;
631
683
  }
632
684
  /**
633
- * Result of a single CI check execution.
685
+ * Root workflow configuration object.
634
686
  */
635
- interface CICheckResult {
636
- /** Name of the check */
637
- name: CICheckName;
638
- /** Final status of the check */
639
- status: CICheckStatus;
640
- /** List of issues discovered */
641
- issues: CICheckIssue[];
642
- /** Execution time in milliseconds */
643
- durationMs: number;
687
+ interface WorkflowConfig {
688
+ /** Issue tracker settings */
689
+ tracker: TrackerConfig;
690
+ /** Polling loop settings */
691
+ polling: PollingConfig;
692
+ /** Workspace settings */
693
+ workspace: WorkspaceConfig;
694
+ /** Lifecycle hook settings */
695
+ hooks: HooksConfig;
696
+ /** Agent execution settings */
697
+ agent: AgentConfig;
698
+ /** Server settings */
699
+ server: ServerConfig;
644
700
  }
645
701
  /**
646
- * Summary counts for a set of CI checks.
702
+ * Complete workflow definition including config and prompts.
647
703
  */
648
- interface CICheckSummary {
649
- /** Total number of checks run */
650
- total: number;
651
- /** Number of passing checks */
652
- passed: number;
653
- /** Number of failing checks */
654
- failed: number;
655
- /** Number of checks with warnings */
656
- warnings: number;
657
- /** Number of skipped checks */
658
- skipped: number;
704
+ interface WorkflowDefinition {
705
+ /** Orchestrator configuration */
706
+ config: WorkflowConfig;
707
+ /** Template used to generate agent prompts */
708
+ promptTemplate: string;
659
709
  }
710
+
660
711
  /**
661
- * Final report for a CI run.
712
+ * Extended entry for cost tracking storage and display.
713
+ * Composes TokenUsage — does not extend it.
662
714
  */
663
- interface CICheckReport {
664
- /** Schema version */
665
- version: 1;
666
- /** Name of the project */
667
- project: string;
668
- /** ISO timestamp of the run */
715
+ interface UsageRecord {
716
+ /** Harness session identifier */
717
+ sessionId: string;
718
+ /** ISO 8601 timestamp of the usage event */
669
719
  timestamp: string;
670
- /** Detailed results for each check */
671
- checks: CICheckResult[];
672
- /** Aggregated summary */
673
- summary: CICheckSummary;
674
- /** Process exit code suggested for the CI runner */
675
- exitCode: 0 | 1 | 2;
720
+ /** Token counts for this event */
721
+ tokens: TokenUsage;
722
+ /** Tokens used to create prompt cache entries */
723
+ cacheCreationTokens?: number;
724
+ /** Tokens read from prompt cache */
725
+ cacheReadTokens?: number;
726
+ /** Model identifier (e.g., "claude-sonnet-4-20250514") */
727
+ model?: string;
728
+ /** Cost in integer microdollars (USD * 1,000,000), calculated at read time */
729
+ costMicroUSD?: number;
676
730
  }
677
731
  /**
678
- * Severity level that should trigger a CI failure.
732
+ * Per-model pricing rates, all in USD per 1 million tokens.
679
733
  */
680
- type CIFailOnSeverity = 'error' | 'warning';
734
+ interface ModelPricing {
735
+ /** Input token cost per 1M tokens */
736
+ inputPer1M: number;
737
+ /** Output token cost per 1M tokens */
738
+ outputPer1M: number;
739
+ /** Cache read cost per 1M tokens (not all models support caching) */
740
+ cacheReadPer1M?: number;
741
+ /** Cache write/creation cost per 1M tokens */
742
+ cacheWritePer1M?: number;
743
+ }
681
744
  /**
682
- * Configuration options for the CI command.
745
+ * Aggregated usage for a single calendar day.
683
746
  */
684
- interface CICheckOptions {
685
- /** Checks to skip */
686
- skip?: CICheckName[];
687
- /** Severity level that causes failure */
688
- failOn?: CIFailOnSeverity;
689
- /** Custom config file path */
690
- configPath?: string;
747
+ interface DailyUsage {
748
+ /** ISO 8601 date string (YYYY-MM-DD) */
749
+ date: string;
750
+ /** Number of distinct sessions that had activity on this day */
751
+ sessionCount: number;
752
+ /** Summed token counts across all sessions */
753
+ tokens: TokenUsage;
754
+ /** Summed cache creation tokens (omitted if no cache data) */
755
+ cacheCreationTokens?: number;
756
+ /** Summed cache read tokens (omitted if no cache data) */
757
+ cacheReadTokens?: number;
758
+ /** Total cost in integer microdollars, null if any session has unknown pricing */
759
+ costMicroUSD: number | null;
760
+ /** Distinct model identifiers seen on this day */
761
+ models: string[];
691
762
  }
692
763
  /**
693
- * Supported CI platforms.
764
+ * Aggregated usage for a single session across all its turns.
694
765
  */
695
- type CIPlatform = 'github' | 'gitlab' | 'generic';
766
+ interface SessionUsage {
767
+ /** Harness session identifier */
768
+ sessionId: string;
769
+ /** ISO 8601 timestamp of the first event in this session */
770
+ firstTimestamp: string;
771
+ /** ISO 8601 timestamp of the last event in this session */
772
+ lastTimestamp: string;
773
+ /** Summed token counts across all turns */
774
+ tokens: TokenUsage;
775
+ /** Summed cache creation tokens (omitted if no cache data) */
776
+ cacheCreationTokens?: number;
777
+ /** Summed cache read tokens (omitted if no cache data) */
778
+ cacheReadTokens?: number;
779
+ /** Model identifier (may be populated from CC data) */
780
+ model?: string;
781
+ /** Total cost in integer microdollars, null if pricing unavailable */
782
+ costMicroUSD: number | null;
783
+ /** Data source: 'harness', 'claude-code', or 'merged' */
784
+ source: 'harness' | 'claude-code' | 'merged';
785
+ }
786
+
696
787
  /**
697
- * Options for initializing CI configuration.
788
+ * A single skill invocation record stored in adoption.jsonl.
789
+ * One line per invocation, appended by the adoption-tracker hook.
698
790
  */
699
- interface CIInitOptions {
700
- /** Target CI platform */
701
- platform?: CIPlatform;
702
- /** Checks to enable */
703
- checks?: CICheckName[];
791
+ interface SkillInvocationRecord {
792
+ /** Skill name (e.g., "harness-brainstorming") */
793
+ skill: string;
794
+ /** Session identifier */
795
+ session: string;
796
+ /** ISO 8601 timestamp when the skill started */
797
+ startedAt: string;
798
+ /** Duration in milliseconds */
799
+ duration: number;
800
+ /** Invocation outcome */
801
+ outcome: 'completed' | 'failed' | 'abandoned';
802
+ /** Phase names reached during the invocation */
803
+ phasesReached: string[];
804
+ /** Skill tier (1, 2, or 3). Absent when not derivable from events. */
805
+ tier?: number;
806
+ /** How the skill was triggered. Absent when not derivable from events. */
807
+ trigger?: string;
808
+ }
809
+ /**
810
+ * Aggregated summary for a single skill across multiple invocations.
811
+ */
812
+ interface SkillAdoptionSummary {
813
+ /** Skill name */
814
+ skill: string;
815
+ /** Total invocation count */
816
+ invocations: number;
817
+ /** Fraction of invocations with outcome 'completed' (0-1) */
818
+ successRate: number;
819
+ /** Mean duration in milliseconds */
820
+ avgDuration: number;
821
+ /** ISO 8601 timestamp of the most recent invocation */
822
+ lastUsed: string;
823
+ /** Skill tier (absent when unknown) */
824
+ tier?: number;
825
+ }
826
+ /**
827
+ * Point-in-time snapshot of adoption metrics.
828
+ * Used by CLI commands and dashboard API.
829
+ */
830
+ interface AdoptionSnapshot {
831
+ /** Time period: "daily", "weekly", or "all-time" */
832
+ period: string;
833
+ /** Total invocations in the period */
834
+ totalInvocations: number;
835
+ /** Count of distinct skills invoked */
836
+ uniqueSkills: number;
837
+ /** Top skills by invocation count */
838
+ topSkills: SkillAdoptionSummary[];
839
+ /** ISO 8601 timestamp when this snapshot was generated */
840
+ generatedAt: string;
704
841
  }
842
+
705
843
  /**
706
- * Result of a skill execution.
844
+ * Session-scoped accumulative state types.
845
+ *
846
+ * Session memory allows skills to append to shared sections (terminology,
847
+ * decisions, constraints, risks, openQuestions, evidence) rather than
848
+ * overwriting. Each entry is timestamped and tagged with the authoring skill.
849
+ *
850
+ * @see docs/changes/ai-foundations-integration/proposal.md
707
851
  */
708
- type SkillResult = {
709
- /** Whether the skill achieved its goal */
710
- success: boolean;
711
- /** List of artifact paths produced */
712
- artifacts: string[];
713
- /** One-line summary of the outcome */
714
- summary: string;
715
- };
716
852
  /**
717
- * Lifecycle hooks for skills.
853
+ * Names of accumulative session sections.
854
+ * Runtime array used for iteration and validation.
718
855
  */
719
- interface SkillLifecycleHooks {
720
- /** Called before the skill starts execution */
721
- preExecution?: (context: SkillContext) => SkillContext | null;
722
- /** Called before each turn in a multi-turn interaction */
723
- perTurn?: (context: TurnContext) => TurnContext | null;
724
- /** Called after the skill completes execution */
725
- postExecution?: (context: SkillContext, result: SkillResult) => void;
726
- }
856
+ declare const SESSION_SECTION_NAMES: readonly ["terminology", "decisions", "constraints", "risks", "openQuestions", "evidence"];
727
857
  /**
728
- * Valid statuses for a roadmap feature.
858
+ * Union type of valid session section names.
729
859
  */
730
- type FeatureStatus = 'backlog' | 'planned' | 'in-progress' | 'done' | 'blocked';
860
+ type SessionSectionName = (typeof SESSION_SECTION_NAMES)[number];
731
861
  /**
732
- * Priority override levels for roadmap features.
733
- * When present, priority replaces positional ordering as the primary sort key.
862
+ * Lifecycle status of a session entry.
863
+ * - `active` current and relevant
864
+ * - `resolved` — addressed or answered (e.g., an open question that was resolved)
865
+ * - `superseded` — replaced by a newer entry
734
866
  */
735
- type Priority = 'P0' | 'P1' | 'P2' | 'P3';
867
+ type SessionEntryStatus = 'active' | 'resolved' | 'superseded';
736
868
  /**
737
- * A feature entry in the project roadmap.
869
+ * A single entry in a session section.
870
+ * Entries are append-only; skills mark them as `resolved` or `superseded`
871
+ * rather than deleting.
738
872
  */
739
- interface RoadmapFeature {
740
- /** Feature name (from the H3 heading, without "Feature:" prefix) */
741
- name: string;
742
- /** Current status */
743
- status: FeatureStatus;
744
- /** Relative path to the spec file, or null if none */
745
- spec: string | null;
746
- /** Relative paths to plan files */
747
- plans: string[];
748
- /** Names of blocking features (textual references) */
749
- blockedBy: string[];
750
- /** One-line summary */
751
- summary: string;
752
- /** GitHub username, email, or display name — null if unassigned */
753
- assignee: string | null;
754
- /** Optional priority override — null uses positional ordering */
755
- priority: Priority | null;
756
- /** External tracker ID (e.g., "github:owner/repo#42") — null if not synced */
757
- externalId: string | null;
873
+ interface SessionEntry {
874
+ /** Auto-generated unique identifier */
875
+ id: string;
876
+ /** ISO 8601 timestamp of when the entry was created */
877
+ timestamp: string;
878
+ /** Name of the skill that authored this entry */
879
+ authorSkill: string;
880
+ /** The entry content (free-form text) */
881
+ content: string;
882
+ /** Lifecycle status of the entry */
883
+ status: SessionEntryStatus;
758
884
  }
759
885
  /**
760
- * A milestone grouping in the roadmap. The special "Backlog" milestone
761
- * has `isBacklog: true` and appears as `## Backlog` instead of `## Milestone: <name>`.
886
+ * Container mapping each section name to its array of entries.
887
+ * Used as the shape of session-scoped state in `state.json`.
762
888
  */
763
- interface RoadmapMilestone {
764
- /** Milestone name (e.g., "MVP Release") or "Backlog" */
765
- name: string;
766
- /** True for the special Backlog section */
767
- isBacklog: boolean;
768
- /** Features in this milestone, in document order */
769
- features: RoadmapFeature[];
770
- }
889
+ type SessionSections = {
890
+ [K in SessionSectionName]: SessionEntry[];
891
+ };
892
+
771
893
  /**
772
- * A single record in the assignment history log.
773
- * Reassignment produces two records: 'unassigned' for previous, 'assigned' for new.
894
+ * Project-level telemetry configuration stored in harness.config.json.
895
+ * Only the on/off toggle lives here -- identity is in .harness/telemetry.json.
774
896
  */
775
- interface AssignmentRecord {
776
- /** Feature name */
777
- feature: string;
778
- /** Assignee identifier (username, email, or display name) */
779
- assignee: string;
780
- /** What happened */
781
- action: 'assigned' | 'completed' | 'unassigned';
782
- /** ISO date string (YYYY-MM-DD) */
783
- date: string;
897
+ interface TelemetryConfig {
898
+ /** Whether telemetry collection is enabled. Default: true. */
899
+ enabled: boolean;
784
900
  }
785
901
  /**
786
- * YAML frontmatter of the roadmap file.
902
+ * Optional identity fields stored in .harness/telemetry.json (gitignored).
903
+ * Each field is independently opt-in.
787
904
  */
788
- interface RoadmapFrontmatter {
789
- /** Project name */
790
- project: string;
791
- /** Schema version (currently 1) */
792
- version: number;
793
- /** ISO date when roadmap was created */
794
- created?: string;
795
- /** ISO date when roadmap was last updated */
796
- updated?: string;
797
- /** ISO timestamp of last automated sync */
798
- lastSynced: string;
799
- /** ISO timestamp of last manual edit */
800
- lastManualEdit: string;
905
+ interface TelemetryIdentity {
906
+ project?: string;
907
+ team?: string;
908
+ alias?: string;
801
909
  }
802
910
  /**
803
- * Parsed roadmap document.
911
+ * Resolved consent state after merging env vars, config, and identity file.
912
+ * Discriminated union: when allowed is false, no identity or installId fields exist.
804
913
  */
805
- interface Roadmap {
806
- /** Parsed frontmatter */
807
- frontmatter: RoadmapFrontmatter;
808
- /** Milestones in document order (including Backlog) */
809
- milestones: RoadmapMilestone[];
810
- /** Assignment history records, in document order */
811
- assignmentHistory: AssignmentRecord[];
914
+ type ConsentState = {
915
+ allowed: true;
916
+ identity: TelemetryIdentity;
917
+ installId: string;
918
+ } | {
919
+ allowed: false;
920
+ };
921
+ /**
922
+ * A single telemetry event payload for PostHog HTTP batch API.
923
+ */
924
+ interface TelemetryEvent {
925
+ /** Event name, e.g. "skill_invocation", "session_end" */
926
+ event: string;
927
+ /** installId (anonymous) or alias (identified) */
928
+ distinctId: string;
929
+ properties: {
930
+ installId: string;
931
+ os: string;
932
+ nodeVersion: string;
933
+ harnessVersion: string;
934
+ skillName?: string;
935
+ duration?: number;
936
+ outcome?: 'success' | 'failure';
937
+ phasesReached?: string[];
938
+ project?: string;
939
+ team?: string;
940
+ };
941
+ /** ISO 8601 timestamp */
942
+ timestamp: string;
812
943
  }
813
944
 
814
- export { type AgentBackend, type AgentConfig, type AgentError, type AgentErrorCategory, type AgentEvent, type AgentSession, type AssignmentRecord, type BlockerRef, type CICheckIssue, type CICheckName, type CICheckOptions, type CICheckReport, type CICheckResult, type CICheckStatus, type CICheckSummary, type CIFailOnSeverity, type CIInitOptions, type CIPlatform, type CognitiveMode, type DailyUsage, Err, type ExternalTicket, type ExternalTicketState, type FeatureStatus, type HooksConfig, type Issue, type IssueTrackerClient, type ModelPricing, Ok, type PollingConfig, type Priority, type Result, type Roadmap, type RoadmapFeature, type RoadmapFrontmatter, type RoadmapMilestone, SESSION_SECTION_NAMES, STANDARD_COGNITIVE_MODES, type ServerConfig, type SessionEntry, type SessionEntryStatus, type SessionSectionName, type SessionSections, type SessionStartParams, type SessionUsage, type SkillContext, type SkillError, type SkillLifecycleHooks, type SkillMetadata, type SkillResult, type StepOutcome, type SyncResult, type TokenUsage, type TrackerConfig, type TrackerSyncConfig, type TurnContext, type TurnParams, type TurnResult, type UsageRecord, type Workflow, type WorkflowConfig, type WorkflowDefinition, type WorkflowResult, type WorkflowStep, type WorkflowStepResult, type WorkspaceConfig, isErr, isOk };
945
+ export { type AdoptionSnapshot, type AgentBackend, type AgentConfig, type AgentError, type AgentErrorCategory, type AgentEvent, type AgentSession, type AssignmentRecord, type BlockerRef, type CICheckIssue, type CICheckName, type CICheckOptions, type CICheckReport, type CICheckResult, type CICheckStatus, type CICheckSummary, type CIFailOnSeverity, type CIInitOptions, type CIPlatform, type CognitiveMode, type ConsentState, type DailyUsage, Err, type ExternalTicket, type ExternalTicketState, type FeatureStatus, type HooksConfig, type Issue, type IssueTrackerClient, type ModelPricing, Ok, type PollingConfig, type Priority, type Result, type Roadmap, type RoadmapFeature, type RoadmapFrontmatter, type RoadmapMilestone, SESSION_SECTION_NAMES, STANDARD_COGNITIVE_MODES, type ServerConfig, type SessionEntry, type SessionEntryStatus, type SessionSectionName, type SessionSections, type SessionStartParams, type SessionUsage, type SkillAdoptionSummary, type SkillContext, type SkillError, type SkillInvocationRecord, type SkillLifecycleHooks, type SkillMetadata, type SkillResult, type StabilityMetadata, type StabilityTier, type StepOutcome, type SyncResult, type TelemetryConfig, type TelemetryEvent, type TelemetryIdentity, type TokenUsage, type TrackerConfig, type TrackerSyncConfig, type TurnContext, type TurnParams, type TurnResult, type UsageRecord, type Workflow, type WorkflowConfig, type WorkflowDefinition, type WorkflowResult, type WorkflowStep, type WorkflowStepResult, type WorkspaceConfig, isErr, isOk };