@harness-engineering/orchestrator 0.8.4 → 0.9.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.
- package/dist/index.d.mts +650 -5
- package/dist/index.d.ts +650 -5
- package/dist/index.js +787 -216
- package/dist/index.mjs +823 -267
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as _harness_engineering_types from '@harness-engineering/types';
|
|
2
|
-
import { Issue, AgentEvent, WorkflowConfig, TokenUsage, ConcernSignal, ScopeTier, EscalationConfig, IssueRoutingDecision, Result, WorkflowDefinition, BackendDef, RoutingConfig, WorkspaceConfig, HooksConfig, AgentBackend, SessionStartParams, AgentSession, AgentError, TurnParams, TurnResult, CheckScriptDefinition, OutputRetentionConfig, RoutingDecision, RoutingUseCase, ContainerConfig, SecretConfig, AgentConfig, LocalModelStatus, CustomTaskDefinition, TokenScope, AuthToken, AuthTokenPublic, IndexedFileKind, SessionSearchResult, ReindexStats, SessionSummarizationConfig, SessionSummary, SessionSummaryMeta, SessionsConfig, GatewayEvent, NotificationEnvelope, NotificationDeliveryResult, NotificationSinkConfig, NotificationsConfig } from '@harness-engineering/types';
|
|
3
|
-
import { IssueTrackerClient, Issue as Issue$1, TrackerConfig, CacheMetricsRecorder, ArchiveHooks, SkillProposal, ProposalGateFinding } from '@harness-engineering/core';
|
|
2
|
+
import { Issue, AgentEvent, WorkflowConfig, TokenUsage, ConcernSignal, ScopeTier, EscalationConfig, IssueRoutingDecision, Result, WorkflowDefinition, BackendDef, RoutingConfig, WorkspaceConfig, HooksConfig, AgentBackend, SessionStartParams, AgentSession, AgentError, TurnParams, TurnResult, CheckScriptDefinition, OutputRetentionConfig, RoutingDecision, RoutingUseCase, ContainerConfig, SecretConfig, AgentConfig, LocalModelStatus, CustomTaskDefinition, MaintenanceConfig, TokenScope, AuthToken, AuthTokenPublic, IndexedFileKind, SessionSearchResult, ReindexStats, SessionSummarizationConfig, SessionSummary, SessionSummaryMeta, SessionsConfig, GatewayEvent, NotificationEnvelope, NotificationDeliveryResult, NotificationSinkConfig, NotificationsConfig } from '@harness-engineering/types';
|
|
3
|
+
import { IssueTrackerClient, Issue as Issue$1, TrackerConfig, eventSourcing, CacheMetricsRecorder, ArchiveHooks, SkillProposal, ProposalGateFinding } from '@harness-engineering/core';
|
|
4
4
|
import { EnrichedSpec, ComplexityScore, SimulationResult, IntelligencePipeline, WeightedRecommendation, AnalysisProvider } from '@harness-engineering/intelligence';
|
|
5
5
|
import { GraphStore } from '@harness-engineering/graph';
|
|
6
6
|
import { execFile } from 'node:child_process';
|
|
@@ -1044,6 +1044,15 @@ declare class RoadmapTrackerAdapter implements IssueTrackerClient {
|
|
|
1044
1044
|
* state and clearing the assignee field.
|
|
1045
1045
|
*/
|
|
1046
1046
|
releaseIssue(issueId: string): Promise<Result<void, Error>>;
|
|
1047
|
+
/**
|
|
1048
|
+
* Resolve the roadmap store anchored on the configured aggregate file path.
|
|
1049
|
+
* The shard backend is chosen when a sibling `roadmap.d/` exists next to the
|
|
1050
|
+
* file; otherwise the monolith file is read/written whole. Callers guard
|
|
1051
|
+
* `this.config.filePath` before invoking.
|
|
1052
|
+
*/
|
|
1053
|
+
private resolveStore;
|
|
1054
|
+
/** Load the roadmap via the store (sharded or monolith), returning a Result. */
|
|
1055
|
+
private loadRoadmap;
|
|
1047
1056
|
private findFeatureById;
|
|
1048
1057
|
/**
|
|
1049
1058
|
* Fetches full issue details for a list of identifiers.
|
|
@@ -1062,12 +1071,47 @@ declare class RoadmapTrackerAdapter implements IssueTrackerClient {
|
|
|
1062
1071
|
}
|
|
1063
1072
|
|
|
1064
1073
|
/**
|
|
1065
|
-
* Interface for Linear GraphQL tool extension
|
|
1066
|
-
*
|
|
1074
|
+
* Interface for a Linear GraphQL tool extension — a thin authenticated client
|
|
1075
|
+
* over Linear's GraphQL API (https://linear.app/developers/graphql).
|
|
1067
1076
|
*/
|
|
1068
1077
|
interface LinearGraphQLExtension {
|
|
1078
|
+
/**
|
|
1079
|
+
* Execute a GraphQL operation. Resolves to `Ok(data)` (the `data` object of
|
|
1080
|
+
* the GraphQL envelope) on success, or `Err` on a transport failure, a non-2xx
|
|
1081
|
+
* HTTP status, or a GraphQL `errors` array.
|
|
1082
|
+
*/
|
|
1083
|
+
query(query: string, variables?: Record<string, unknown>): Promise<Result<unknown, Error>>;
|
|
1084
|
+
}
|
|
1085
|
+
interface LinearGraphQLClientOptions {
|
|
1086
|
+
/**
|
|
1087
|
+
* Linear authentication token. A personal API key is sent verbatim in the
|
|
1088
|
+
* `Authorization` header; an OAuth access token must be passed already prefixed
|
|
1089
|
+
* with `Bearer ` (Linear's two supported schemes).
|
|
1090
|
+
*/
|
|
1091
|
+
apiKey: string;
|
|
1092
|
+
/** Override the GraphQL endpoint (e.g. a proxy). Defaults to Linear's API. */
|
|
1093
|
+
endpoint?: string;
|
|
1094
|
+
/** Injectable fetch for tests; defaults to the global `fetch`. */
|
|
1095
|
+
fetchFn?: typeof fetch;
|
|
1096
|
+
}
|
|
1097
|
+
/**
|
|
1098
|
+
* Real Linear GraphQL client. Replaces {@link LinearGraphQLStub}, which only
|
|
1099
|
+
* logged the query and returned an empty object. POSTs the operation to Linear's
|
|
1100
|
+
* GraphQL endpoint with the API key, and normalizes the three failure modes
|
|
1101
|
+
* (transport throw, non-2xx HTTP, GraphQL `errors`) into a single `Err`.
|
|
1102
|
+
*/
|
|
1103
|
+
declare class LinearGraphQLClient implements LinearGraphQLExtension {
|
|
1104
|
+
private readonly apiKey;
|
|
1105
|
+
private readonly endpoint;
|
|
1106
|
+
private readonly fetchFn;
|
|
1107
|
+
constructor(opts: LinearGraphQLClientOptions);
|
|
1069
1108
|
query(query: string, variables?: Record<string, unknown>): Promise<Result<unknown, Error>>;
|
|
1070
1109
|
}
|
|
1110
|
+
/**
|
|
1111
|
+
* @deprecated Phase-4 placeholder retained for backward compatibility. It logs
|
|
1112
|
+
* the query and returns an empty object; use {@link LinearGraphQLClient} for a
|
|
1113
|
+
* real authenticated client.
|
|
1114
|
+
*/
|
|
1071
1115
|
declare class LinearGraphQLStub implements LinearGraphQLExtension {
|
|
1072
1116
|
query(query: string, _variables?: Record<string, unknown>): Promise<Result<unknown, Error>>;
|
|
1073
1117
|
}
|
|
@@ -1264,6 +1308,15 @@ type RunOrigin = 'cron' | 'cli' | {
|
|
|
1264
1308
|
kind: 'chain';
|
|
1265
1309
|
upstreamTaskId: string;
|
|
1266
1310
|
};
|
|
1311
|
+
/**
|
|
1312
|
+
* Run mode for a maintenance task (on-demand pipeline, D4).
|
|
1313
|
+
*
|
|
1314
|
+
* - 'fix' — current cron behavior: mechanical-ai dispatches on findings,
|
|
1315
|
+
* pure-ai always dispatches, PRs may be opened. Default.
|
|
1316
|
+
* - 'report' — read-only sweep: run the check step, record findings, and take
|
|
1317
|
+
* the no-dispatch branch — never dispatch a fix agent or open a PR.
|
|
1318
|
+
*/
|
|
1319
|
+
type RunMode = 'report' | 'fix';
|
|
1267
1320
|
/**
|
|
1268
1321
|
* Per-task cost ceiling (Hermes Phase 5).
|
|
1269
1322
|
*
|
|
@@ -1325,6 +1378,15 @@ interface TaskDefinition {
|
|
|
1325
1378
|
outputRetention?: OutputRetentionConfig;
|
|
1326
1379
|
/** Hermes Phase 2 — Marks tasks originating from `customTasks` config. */
|
|
1327
1380
|
isCustom?: boolean;
|
|
1381
|
+
/**
|
|
1382
|
+
* On-demand maintenance pipeline (D5). When `true`, the task is excluded
|
|
1383
|
+
* from the human "overdue" sweep computed by `selectTasks` — used for
|
|
1384
|
+
* git-mutating housekeeping (`main-sync`, `perf-baselines`,
|
|
1385
|
+
* `session-cleanup`) and one-shot backfills (`proposal-provenance-backfill`)
|
|
1386
|
+
* that are infra hygiene, not developer-facing health signals.
|
|
1387
|
+
* `undefined` (default) → sweep-eligible.
|
|
1388
|
+
*/
|
|
1389
|
+
excludeFromHumanSweep?: boolean;
|
|
1328
1390
|
}
|
|
1329
1391
|
/**
|
|
1330
1392
|
* Result of a single maintenance task run.
|
|
@@ -1533,6 +1595,13 @@ declare class BackendRouter {
|
|
|
1533
1595
|
private validateReferences;
|
|
1534
1596
|
}
|
|
1535
1597
|
|
|
1598
|
+
/**
|
|
1599
|
+
* The lanes projection shape, re-exported so the orchestrator can hold a
|
|
1600
|
+
* read-back snapshot without importing the core `eventSourcing` namespace
|
|
1601
|
+
* directly — keeping this module the single orchestrator<->core lane coupling.
|
|
1602
|
+
*/
|
|
1603
|
+
type PersistedLanes = eventSourcing.LanesProjection;
|
|
1604
|
+
|
|
1536
1605
|
/**
|
|
1537
1606
|
* Derives the worktree seed paths from a workflow config when
|
|
1538
1607
|
* {@link WorkspaceConfig.seedPaths} is not set explicitly.
|
|
@@ -1545,6 +1614,20 @@ declare class BackendRouter {
|
|
|
1545
1614
|
* otherwise miss it.
|
|
1546
1615
|
*/
|
|
1547
1616
|
declare function deriveSeedPaths(config: WorkflowConfig): string[];
|
|
1617
|
+
/**
|
|
1618
|
+
* Resolve a maintenance `checkCommand` (or housekeeping command) into a runnable
|
|
1619
|
+
* argv. Built-in maintenance task definitions store the command as harness
|
|
1620
|
+
* SUBCOMMAND argv (e.g. `['check-arch']`, `['graph','scan']`); `main-sync`
|
|
1621
|
+
* carries an explicit leading `'harness'` literal. Either way the command must
|
|
1622
|
+
* be executed through the `harness` binary, so:
|
|
1623
|
+
* - `['check-arch']` → `['harness', 'check-arch']`
|
|
1624
|
+
* - `['harness','sync-main']` → `['harness', 'sync-main']` (no double-prefix)
|
|
1625
|
+
* - `[]` → `[]`
|
|
1626
|
+
*
|
|
1627
|
+
* The cron daemon resolves `harness` from PATH (the pre-existing assumption that
|
|
1628
|
+
* `main-sync` already relied on).
|
|
1629
|
+
*/
|
|
1630
|
+
declare function normalizeHarnessCommand(command: string[]): string[];
|
|
1548
1631
|
/**
|
|
1549
1632
|
* The central orchestrator that manages the lifecycle of coding agents.
|
|
1550
1633
|
*
|
|
@@ -1656,6 +1739,11 @@ declare class Orchestrator extends EventEmitter {
|
|
|
1656
1739
|
private abortControllers;
|
|
1657
1740
|
/** Guards against overlapping ticks when a tick takes longer than the polling interval */
|
|
1658
1741
|
private tickInProgress;
|
|
1742
|
+
/** Phase 4 (DLane-5): lanes read back from the durable log on first tick, for
|
|
1743
|
+
* observability only — NOT fed into reconciliation. Empty until the first tick. */
|
|
1744
|
+
private persistedLanes;
|
|
1745
|
+
/** Ensures the lane read-back diagnostic runs at most once (first tick). */
|
|
1746
|
+
private laneReadbackDone;
|
|
1659
1747
|
/** Timestamp of the last stale branch sweep (at most once per hour) */
|
|
1660
1748
|
private lastBranchSweepMs;
|
|
1661
1749
|
/** Current tick-phase activity visible to the dashboard */
|
|
@@ -1698,6 +1786,25 @@ declare class Orchestrator extends EventEmitter {
|
|
|
1698
1786
|
* @param effect - The effect to handle
|
|
1699
1787
|
*/
|
|
1700
1788
|
private handleEffect;
|
|
1789
|
+
/**
|
|
1790
|
+
* Phase 4 (DLane-5): persist an orchestrator lane transition to the durable
|
|
1791
|
+
* core event log at the effect boundary. NEVER throws — `persistLane` returns
|
|
1792
|
+
* an `Err` Result on failure, which is logged and swallowed here so a
|
|
1793
|
+
* lane-persistence failure can never break orchestrator dispatch.
|
|
1794
|
+
*/
|
|
1795
|
+
private persistLaneSafe;
|
|
1796
|
+
/**
|
|
1797
|
+
* Phase 4 (DLane-5): read persisted task lanes back from the durable log and
|
|
1798
|
+
* log a one-line summary. Stores the projection on `this.persistedLanes` for
|
|
1799
|
+
* observability. Read-only — never feeds reconciliation, never throws.
|
|
1800
|
+
*/
|
|
1801
|
+
private readBackPersistedLanes;
|
|
1802
|
+
/**
|
|
1803
|
+
* Phase 4 (DLane-5): the task lanes most recently read back from the durable
|
|
1804
|
+
* log on startup, exposed for external observability. Read-only — a fresh
|
|
1805
|
+
* `{ tasks: {} }` until the first tick's read-back has run.
|
|
1806
|
+
*/
|
|
1807
|
+
getPersistedLanes(): PersistedLanes;
|
|
1701
1808
|
/**
|
|
1702
1809
|
* Guards workspace cleanup by checking whether the agent pushed a branch
|
|
1703
1810
|
* that does not yet have a pull request. If so, the worktree is preserved
|
|
@@ -1980,6 +2087,30 @@ interface CreateBackendOptions {
|
|
|
1980
2087
|
*/
|
|
1981
2088
|
declare function createBackend(def: BackendDef, options?: CreateBackendOptions): AgentBackend;
|
|
1982
2089
|
|
|
2090
|
+
/**
|
|
2091
|
+
* Maintenance backend resolver: map a configured backend NAME to a live
|
|
2092
|
+
* {@link AgentBackend}, or `null` when the name is absent from the loaded
|
|
2093
|
+
* `agent.backends` map. `null` lets the real agent dispatcher no-op honestly
|
|
2094
|
+
* (graceful degradation on a plain checkout) instead of throwing.
|
|
2095
|
+
*/
|
|
2096
|
+
type BackendResolver = (backendName: string) => AgentBackend | null;
|
|
2097
|
+
/**
|
|
2098
|
+
* Build a {@link BackendResolver} from a synthesized `agent.backends` map.
|
|
2099
|
+
*
|
|
2100
|
+
* This is the ONE shared implementation of "resolve a backend name against a
|
|
2101
|
+
* backends map via `createBackend`, else null". It is consumed by BOTH:
|
|
2102
|
+
* - the cron orchestrator (`createMaintenanceTaskRunner`), passing
|
|
2103
|
+
* `this.getBackends()`, and
|
|
2104
|
+
* - the on-demand CLI (`harness maintenance run --fix` →
|
|
2105
|
+
* `makeResolveBackend`), passing the config it loaded from
|
|
2106
|
+
* `harness.orchestrator.md`.
|
|
2107
|
+
*
|
|
2108
|
+
* Keeping it in the orchestrator package (next to `createBackend`) avoids the
|
|
2109
|
+
* two call sites drifting. A `null`/`undefined`/empty map yields a resolver
|
|
2110
|
+
* that always returns `null` — the nothing-configured degradation case.
|
|
2111
|
+
*/
|
|
2112
|
+
declare function makeBackendResolver(backends: Record<string, BackendDef> | null | undefined): BackendResolver;
|
|
2113
|
+
|
|
1983
2114
|
/**
|
|
1984
2115
|
* Zod schema for `BackendDef` (Spec 2 — multi-backend routing).
|
|
1985
2116
|
*
|
|
@@ -2426,6 +2557,520 @@ interface CustomTaskValidatorDeps {
|
|
|
2426
2557
|
*/
|
|
2427
2558
|
declare function validateCustomTasks(customTasks: Record<string, CustomTaskDefinition> | undefined, builtIns: readonly TaskDefinition[], deps?: CustomTaskValidatorDeps): Result<void, CustomTaskValidationError[]>;
|
|
2428
2559
|
|
|
2560
|
+
/** Selection filter for `selectTasks`. `now` is injected for determinism. */
|
|
2561
|
+
interface TaskSelectionFilter {
|
|
2562
|
+
mode: 'overdue' | 'all' | 'ids';
|
|
2563
|
+
/** Required when `mode === 'ids'`; ignored otherwise. */
|
|
2564
|
+
ids?: string[];
|
|
2565
|
+
/** Reference instant — never read from the wall clock internally. */
|
|
2566
|
+
now: Date;
|
|
2567
|
+
}
|
|
2568
|
+
/**
|
|
2569
|
+
* Select the maintenance tasks to run for an on-demand sweep (D3/D5).
|
|
2570
|
+
* Operates only on sweep-eligible tasks (`excludeFromHumanSweep !== true`)
|
|
2571
|
+
* in every mode. Deterministic under the injected `filter.now`.
|
|
2572
|
+
*
|
|
2573
|
+
* - `overdue`: eligible tasks with no satisfying run since their previous fire.
|
|
2574
|
+
* - `all`: every eligible task.
|
|
2575
|
+
* - `ids`: the eligible subset named in `filter.ids` (a named excluded id
|
|
2576
|
+
* is dropped, honoring "excluded tasks never run in either path").
|
|
2577
|
+
* `filter.ids` is treated as a SET membership test, not an ordered
|
|
2578
|
+
* request list: results preserve the input `tasks` array order, not
|
|
2579
|
+
* the order ids appear in `filter.ids`. Duplicate ids are collapsed
|
|
2580
|
+
* and a task is returned at most once. Callers that need request
|
|
2581
|
+
* order must reorder the result themselves.
|
|
2582
|
+
*/
|
|
2583
|
+
declare function selectTasks(tasks: TaskDefinition[], history: RunResult[], filter: TaskSelectionFilter): TaskDefinition[];
|
|
2584
|
+
|
|
2585
|
+
/**
|
|
2586
|
+
* Hermes Phase 2 — Result of running an arbitrary check script.
|
|
2587
|
+
*
|
|
2588
|
+
* Structurally compatible with `CheckCommandResult` (`task-runner.ts`) so
|
|
2589
|
+
* `TaskRunner` can consume it through the same interface, plus a parsed
|
|
2590
|
+
* structured envelope and the captured stderr stream. `structured` is
|
|
2591
|
+
* `null` when no JSON status line was found on stdout. The shape is
|
|
2592
|
+
* declared locally (not imported from `task-runner.ts`) to keep the
|
|
2593
|
+
* module dependency one-way: `task-runner.ts` depends on
|
|
2594
|
+
* `check-script-runner.ts`, never the reverse.
|
|
2595
|
+
*/
|
|
2596
|
+
interface CheckScriptResult {
|
|
2597
|
+
passed: boolean;
|
|
2598
|
+
findings: number;
|
|
2599
|
+
/** Raw stdout. Field name matches `CheckCommandResult.output` for compatibility. */
|
|
2600
|
+
output: string;
|
|
2601
|
+
stderr: string;
|
|
2602
|
+
structured: CheckScriptStatusEnvelope | null;
|
|
2603
|
+
}
|
|
2604
|
+
interface CheckScriptStatusEnvelope {
|
|
2605
|
+
status: 'ok' | 'findings' | 'skip' | 'error';
|
|
2606
|
+
findings?: number;
|
|
2607
|
+
wakeAgent?: boolean;
|
|
2608
|
+
message?: string;
|
|
2609
|
+
outputs?: Record<string, unknown>;
|
|
2610
|
+
}
|
|
2611
|
+
/**
|
|
2612
|
+
* Spawns an arbitrary executable for the mechanical/report/housekeeping
|
|
2613
|
+
* check step. Honors the structured JSON status envelope (last non-empty
|
|
2614
|
+
* stdout line) per Hermes Phase 2 D6. Falls back to the legacy heuristic
|
|
2615
|
+
* regex when no JSON envelope is present.
|
|
2616
|
+
*
|
|
2617
|
+
* The runner is intentionally simple and shells out via `execFile` (no
|
|
2618
|
+
* shell, no `sh -c`) — `args` are passed verbatim to avoid argument
|
|
2619
|
+
* injection from operator-supplied config.
|
|
2620
|
+
*/
|
|
2621
|
+
declare class CheckScriptRunner {
|
|
2622
|
+
private cwd;
|
|
2623
|
+
constructor(cwd: string);
|
|
2624
|
+
run(spec: CheckScriptDefinition, cwd?: string): Promise<CheckScriptResult>;
|
|
2625
|
+
}
|
|
2626
|
+
|
|
2627
|
+
/**
|
|
2628
|
+
* Hermes Phase 2 — Reads an inline-skill body by name. Wraps the host's
|
|
2629
|
+
* skill registry; absent skills resolve to `null` so the resolver can
|
|
2630
|
+
* warn-and-skip instead of throwing.
|
|
2631
|
+
*/
|
|
2632
|
+
interface InlineSkillReader {
|
|
2633
|
+
read(skillName: string): Promise<string | null>;
|
|
2634
|
+
}
|
|
2635
|
+
interface ContextResolverOptions {
|
|
2636
|
+
outputStore: TaskOutputStore;
|
|
2637
|
+
skillReader?: InlineSkillReader;
|
|
2638
|
+
logger?: MaintenanceLogger;
|
|
2639
|
+
/** Per-upstream truncation bound. Default: 2000 chars. */
|
|
2640
|
+
perUpstreamMaxChars?: number;
|
|
2641
|
+
}
|
|
2642
|
+
/**
|
|
2643
|
+
* Resolves Hermes Phase 2 prompt-context inputs for a maintenance task:
|
|
2644
|
+
*
|
|
2645
|
+
* - `resolveContextFrom(taskIds, opts)`: pulls each upstream's latest
|
|
2646
|
+
* output from the store, applies stale/missing markers, and emits a
|
|
2647
|
+
* `## Upstream context` markdown block.
|
|
2648
|
+
*
|
|
2649
|
+
* - `resolveInlineSkills(skillNames, budgetTokens)`: pulls each skill's
|
|
2650
|
+
* markdown body via the registry, applies a per-skill char-count
|
|
2651
|
+
* budget (4 chars ≈ 1 token), warns-then-truncates on overflow, and
|
|
2652
|
+
* emits a `## Reference skills` markdown block.
|
|
2653
|
+
*
|
|
2654
|
+
* Both methods return an empty string when their inputs are absent so
|
|
2655
|
+
* callers can `prompt = skills + upstream + base` without conditional
|
|
2656
|
+
* scaffolding.
|
|
2657
|
+
*/
|
|
2658
|
+
declare class ContextResolver {
|
|
2659
|
+
private outputStore;
|
|
2660
|
+
private skillReader;
|
|
2661
|
+
private logger;
|
|
2662
|
+
private perUpstreamMaxChars;
|
|
2663
|
+
constructor(options: ContextResolverOptions);
|
|
2664
|
+
resolveContextFrom(upstreamTaskIds: string[] | undefined, options?: {
|
|
2665
|
+
maxAgeMinutes?: number;
|
|
2666
|
+
}): Promise<string>;
|
|
2667
|
+
resolveInlineSkills(skillNames: string[] | undefined, budgetTokens?: number): Promise<string>;
|
|
2668
|
+
private formatUpstream;
|
|
2669
|
+
}
|
|
2670
|
+
|
|
2671
|
+
/**
|
|
2672
|
+
* Interface for running CLI check commands in-process.
|
|
2673
|
+
* Each method returns a structured result with a findings count.
|
|
2674
|
+
*/
|
|
2675
|
+
interface CheckCommandRunner {
|
|
2676
|
+
/**
|
|
2677
|
+
* Runs a check command and returns its structured output.
|
|
2678
|
+
* @param command - CLI command args (e.g., ['check-arch'])
|
|
2679
|
+
* @param cwd - Working directory
|
|
2680
|
+
* @returns Object with findings count and whether the check passed
|
|
2681
|
+
*/
|
|
2682
|
+
run(command: string[], cwd: string): Promise<CheckCommandResult>;
|
|
2683
|
+
}
|
|
2684
|
+
interface CheckCommandResult {
|
|
2685
|
+
passed: boolean;
|
|
2686
|
+
findings: number;
|
|
2687
|
+
/** Raw output for logging/reporting */
|
|
2688
|
+
output: string;
|
|
2689
|
+
/**
|
|
2690
|
+
* True when the check command could NOT be executed to a usable result —
|
|
2691
|
+
* the process failed to spawn (ENOENT), the subcommand was unknown, or it
|
|
2692
|
+
* crashed with no parseable findings count. This is distinct from a check
|
|
2693
|
+
* that ran fine and legitimately reported findings (`passed: false`,
|
|
2694
|
+
* `findings > 0`). The TaskRunner maps `executionFailed` onto
|
|
2695
|
+
* `status: 'failure'` so an un-runnable check is never masked as a
|
|
2696
|
+
* successful 1-finding run (ADR 0050 — exit-1-on-check-crash). Omitted /
|
|
2697
|
+
* `undefined` is treated as `false` for backward compatibility with runners
|
|
2698
|
+
* that predate this field.
|
|
2699
|
+
*/
|
|
2700
|
+
executionFailed?: boolean;
|
|
2701
|
+
}
|
|
2702
|
+
/**
|
|
2703
|
+
* Interface for dispatching an AI agent to fix issues.
|
|
2704
|
+
* Wraps AgentRunner.runSession() with maintenance-specific parameters.
|
|
2705
|
+
*/
|
|
2706
|
+
interface AgentDispatcher {
|
|
2707
|
+
/**
|
|
2708
|
+
* Dispatch an AI agent to fix issues on a branch.
|
|
2709
|
+
* @param skill - Skill name to dispatch (e.g., 'harness-arch-fix')
|
|
2710
|
+
* @param branch - Branch to work on
|
|
2711
|
+
* @param backendName - Backend name to use (e.g., 'local', 'claude')
|
|
2712
|
+
* @param cwd - Working directory (worktree path)
|
|
2713
|
+
* @param options - Hermes Phase 2: optional `promptContext` prepended to
|
|
2714
|
+
* the agent's system prompt (inlined skills + upstream
|
|
2715
|
+
* outputs). The dispatcher MAY ignore this field on
|
|
2716
|
+
* backends that don't support context injection; the
|
|
2717
|
+
* TaskRunner persists it independently for observability.
|
|
2718
|
+
* @returns Whether the agent produced any commits
|
|
2719
|
+
*/
|
|
2720
|
+
dispatch(skill: string, branch: string, backendName: string, cwd: string, options?: AgentDispatchOptions): Promise<AgentDispatchResult>;
|
|
2721
|
+
}
|
|
2722
|
+
interface AgentDispatchOptions {
|
|
2723
|
+
/** Hermes Phase 2 — prompt context (inlined skills + upstream outputs). */
|
|
2724
|
+
promptContext?: string;
|
|
2725
|
+
}
|
|
2726
|
+
interface AgentDispatchResult {
|
|
2727
|
+
producedCommits: boolean;
|
|
2728
|
+
fixed: number;
|
|
2729
|
+
}
|
|
2730
|
+
/**
|
|
2731
|
+
* Interface for running housekeeping commands directly.
|
|
2732
|
+
*/
|
|
2733
|
+
interface CommandExecutor {
|
|
2734
|
+
/**
|
|
2735
|
+
* Executes a command directly (no AI). Returns captured stdout so
|
|
2736
|
+
* housekeeping tasks emitting a JSON status line (e.g. `sync-main --json`)
|
|
2737
|
+
* can be parsed by the runner.
|
|
2738
|
+
*
|
|
2739
|
+
* @param command - Command args (e.g., ['cleanup-sessions'])
|
|
2740
|
+
* @param cwd - Working directory
|
|
2741
|
+
*/
|
|
2742
|
+
exec(command: string[], cwd: string): Promise<CommandExecResult>;
|
|
2743
|
+
}
|
|
2744
|
+
interface CommandExecResult {
|
|
2745
|
+
/** Captured stdout. May be empty for legacy housekeeping commands. */
|
|
2746
|
+
stdout: string;
|
|
2747
|
+
}
|
|
2748
|
+
/**
|
|
2749
|
+
* Interface for managing branches and PRs for maintenance tasks.
|
|
2750
|
+
* Matches PRManager's public API shape for DI.
|
|
2751
|
+
*/
|
|
2752
|
+
interface PRLifecycleManager {
|
|
2753
|
+
ensureBranch(branchName: string, baseBranch: string): Promise<{
|
|
2754
|
+
created: boolean;
|
|
2755
|
+
recreated: boolean;
|
|
2756
|
+
}>;
|
|
2757
|
+
ensurePR(task: TaskDefinition, runSummary: string): Promise<{
|
|
2758
|
+
prUrl: string;
|
|
2759
|
+
prUpdated: boolean;
|
|
2760
|
+
}>;
|
|
2761
|
+
}
|
|
2762
|
+
interface TaskRunnerOptions {
|
|
2763
|
+
config: MaintenanceConfig;
|
|
2764
|
+
checkRunner: CheckCommandRunner;
|
|
2765
|
+
agentDispatcher: AgentDispatcher;
|
|
2766
|
+
commandExecutor: CommandExecutor;
|
|
2767
|
+
/** Project root directory for running commands */
|
|
2768
|
+
cwd: string;
|
|
2769
|
+
/** Optional PR lifecycle manager for branch/PR operations */
|
|
2770
|
+
prManager?: PRLifecycleManager;
|
|
2771
|
+
/** Base branch for PR operations (defaults to 'main') */
|
|
2772
|
+
baseBranch?: string;
|
|
2773
|
+
/**
|
|
2774
|
+
* Hermes Phase 2 — Optional check-script runner. When a task declares
|
|
2775
|
+
* `checkScript`, the runner consults this instead of `checkRunner`.
|
|
2776
|
+
* Required for any custom task that uses `checkScript`; tests that don't
|
|
2777
|
+
* exercise custom tasks may omit it.
|
|
2778
|
+
*/
|
|
2779
|
+
checkScriptRunner?: CheckScriptRunner;
|
|
2780
|
+
/**
|
|
2781
|
+
* Hermes Phase 2 — Optional context resolver providing `contextFrom`
|
|
2782
|
+
* upstream injection and `inlineSkills` payload assembly.
|
|
2783
|
+
*/
|
|
2784
|
+
contextResolver?: ContextResolver;
|
|
2785
|
+
/**
|
|
2786
|
+
* Hermes Phase 2 — Persists per-task outputs (stdout / structured /
|
|
2787
|
+
* resolved context) at the end of each run.
|
|
2788
|
+
*/
|
|
2789
|
+
outputStore?: TaskOutputStore;
|
|
2790
|
+
}
|
|
2791
|
+
/**
|
|
2792
|
+
* TaskRunner executes a single maintenance task based on its type.
|
|
2793
|
+
*
|
|
2794
|
+
* Execution paths:
|
|
2795
|
+
* - mechanical-ai: run check -> if findings, dispatch AI agent
|
|
2796
|
+
* - pure-ai: always dispatch AI agent
|
|
2797
|
+
* - report-only: run check, record findings, no AI
|
|
2798
|
+
* - housekeeping: run command directly, no AI
|
|
2799
|
+
*/
|
|
2800
|
+
declare class TaskRunner {
|
|
2801
|
+
private config;
|
|
2802
|
+
private checkRunner;
|
|
2803
|
+
private agentDispatcher;
|
|
2804
|
+
private commandExecutor;
|
|
2805
|
+
private cwd;
|
|
2806
|
+
private prManager;
|
|
2807
|
+
private baseBranch;
|
|
2808
|
+
private checkScriptRunner;
|
|
2809
|
+
private contextResolver;
|
|
2810
|
+
private outputStore;
|
|
2811
|
+
constructor(options: TaskRunnerOptions);
|
|
2812
|
+
/**
|
|
2813
|
+
* Run a maintenance task and return the result.
|
|
2814
|
+
* Dispatches to the appropriate execution path based on task type.
|
|
2815
|
+
* Never throws -- errors are captured in the RunResult.
|
|
2816
|
+
*
|
|
2817
|
+
* @param task - Resolved task definition.
|
|
2818
|
+
* @param origin - Hermes Phase 2 trigger-source tag; defaults to `'cron'`
|
|
2819
|
+
* when called from the scheduler path.
|
|
2820
|
+
*/
|
|
2821
|
+
run(task: TaskDefinition, origin?: RunOrigin, mode?: RunMode): Promise<RunResult>;
|
|
2822
|
+
private persistOutput;
|
|
2823
|
+
/**
|
|
2824
|
+
* Run the check step using whichever runner the task asks for. Custom
|
|
2825
|
+
* tasks that declare `checkScript` go through the Hermes Phase 2
|
|
2826
|
+
* `CheckScriptRunner`; built-ins (and customs that use the legacy
|
|
2827
|
+
* `checkCommand` shape) go through the original heuristic runner.
|
|
2828
|
+
*/
|
|
2829
|
+
private runCheckStep;
|
|
2830
|
+
/**
|
|
2831
|
+
* Hermes Phase 2 — Compose the agent prompt-context block from inlined
|
|
2832
|
+
* skills + upstream task outputs. Returns an empty string when nothing
|
|
2833
|
+
* is configured (or when the resolver is absent), which is the safe
|
|
2834
|
+
* no-op default.
|
|
2835
|
+
*/
|
|
2836
|
+
private composePromptContext;
|
|
2837
|
+
/**
|
|
2838
|
+
* Mechanical-AI: run check (legacy or Phase 2 script), dispatch AI agent
|
|
2839
|
+
* only if fixable findings exist; persist captured stdout/stderr/context
|
|
2840
|
+
* via the output store on the way out.
|
|
2841
|
+
*/
|
|
2842
|
+
private runMechanicalAI;
|
|
2843
|
+
/**
|
|
2844
|
+
* Pure-AI: always dispatch agent with configured skill.
|
|
2845
|
+
*/
|
|
2846
|
+
private runPureAI;
|
|
2847
|
+
/**
|
|
2848
|
+
* Report-only: run check (legacy or Phase 2 script), record metrics, no AI dispatch.
|
|
2849
|
+
*
|
|
2850
|
+
* Honors the JSON status contract emitted by Phase 4/5 CLIs (`harness pulse run`
|
|
2851
|
+
* and `harness compound scan-candidates` in `--non-interactive` mode):
|
|
2852
|
+
* {"status":"success"|"skipped"|"failure"|"no-issues",
|
|
2853
|
+
* "candidatesFound"?: number, "error"?: string, "reason"?: string}
|
|
2854
|
+
*
|
|
2855
|
+
* Legacy report-only tasks emit free-form output and fall through to 'success'.
|
|
2856
|
+
*/
|
|
2857
|
+
private runReportOnly;
|
|
2858
|
+
/**
|
|
2859
|
+
* Housekeeping: run command directly, no AI, no PR.
|
|
2860
|
+
*
|
|
2861
|
+
* Captures stdout and parses a trailing JSON status line if present.
|
|
2862
|
+
* Recognized contracts:
|
|
2863
|
+
* - Phase 4/5 status contract (e.g., harness pulse run): success/skipped/failure/no-issues
|
|
2864
|
+
* - sync-main contract: updated/no-op/skipped/error → mapped onto the run-result status
|
|
2865
|
+
* Legacy housekeeping commands that emit no JSON keep the prior behavior:
|
|
2866
|
+
* status: 'success', findings: 0.
|
|
2867
|
+
*
|
|
2868
|
+
* Hermes Phase 2: a `checkScript` may replace `checkCommand` for housekeeping
|
|
2869
|
+
* tasks; the runner falls through to the same JSON-status parsing path.
|
|
2870
|
+
*/
|
|
2871
|
+
private runHousekeeping;
|
|
2872
|
+
/**
|
|
2873
|
+
* Resolve which AI backend name to use for a given task.
|
|
2874
|
+
* Priority: per-task override > global config > 'local' default.
|
|
2875
|
+
*/
|
|
2876
|
+
private resolveBackend;
|
|
2877
|
+
private failureResult;
|
|
2878
|
+
/**
|
|
2879
|
+
* A precondition-gated check (e.g. `predict` with <3 snapshots, or a
|
|
2880
|
+
* graph-backed check before `harness scan`). The command is correctly
|
|
2881
|
+
* configured; the repo just lacks the state it needs. Reported as `skipped`
|
|
2882
|
+
* — distinct from a hard `failure` — carrying the refusal line as the reason
|
|
2883
|
+
* (surfaced in the run-report summary column). ADR 0050.
|
|
2884
|
+
*/
|
|
2885
|
+
private skippedResult;
|
|
2886
|
+
}
|
|
2887
|
+
/**
|
|
2888
|
+
* Classification of a check that a `CheckCommandRunner` flagged
|
|
2889
|
+
* `executionFailed` (non-zero exit / spawn error with no parseable finding
|
|
2890
|
+
* count). The runners cannot tell these three cases apart with a single
|
|
2891
|
+
* boolean, so the TaskRunner re-classifies the captured output here — keeping
|
|
2892
|
+
* the logic in ONE shared place consumed by BOTH the cron orchestrator and the
|
|
2893
|
+
* on-demand CLI (they each own a thin `CheckCommandRunner` but share this
|
|
2894
|
+
* `TaskRunner`). See ADR 0050 (report-first / execution-honesty).
|
|
2895
|
+
*
|
|
2896
|
+
* - `unrunnable` → the subcommand could not execute at all (unknown command,
|
|
2897
|
+
* ENOENT, missing module, empty output). Maps to `failure`.
|
|
2898
|
+
* - `precondition`→ the subcommand ran but refused because required state is
|
|
2899
|
+
* absent in this repo (e.g. `predict` needs ≥3 snapshots;
|
|
2900
|
+
* graph-backed checks need `harness scan` first). This is NOT
|
|
2901
|
+
* a misconfiguration or a breakage — maps to `skipped` with a
|
|
2902
|
+
* reason so dashboards/cron don't cry wolf.
|
|
2903
|
+
* - `ran-no-count`→ the subcommand ran and exited non-zero to SIGNAL drift but
|
|
2904
|
+
* emitted no machine-parseable count (e.g. `cleanup`,
|
|
2905
|
+
* `check-docs`). A check that ran and flagged work is not an
|
|
2906
|
+
* execution failure — maps to a real (recovered or assumed)
|
|
2907
|
+
* finding count, never `failure`.
|
|
2908
|
+
*/
|
|
2909
|
+
type CheckFailureKind = 'unrunnable' | 'precondition' | 'ran-no-count';
|
|
2910
|
+
interface CheckFailureClassification {
|
|
2911
|
+
kind: CheckFailureKind;
|
|
2912
|
+
/** Human-readable reason, populated for `precondition` (the refusal line). */
|
|
2913
|
+
reason?: string;
|
|
2914
|
+
}
|
|
2915
|
+
/**
|
|
2916
|
+
* Parse an EXPLICIT finding count from output the primary `N keyword` parser in
|
|
2917
|
+
* the `CheckCommandRunner` missed — it only matches "45 issues", not the
|
|
2918
|
+
* "Entropy issues: 32264" (count-after-keyword) shape. Returns `null` when no
|
|
2919
|
+
* explicit count is present (vs `recoverFindingsCount`, which defaults to 1).
|
|
2920
|
+
*
|
|
2921
|
+
* A recoverable explicit count is the strongest possible signal that a check
|
|
2922
|
+
* actually RAN and produced findings, so the classifier trusts it over any
|
|
2923
|
+
* scary-looking words ("ENOENT", "not found") buried in the findings body.
|
|
2924
|
+
*/
|
|
2925
|
+
declare function explicitFindingsCount(output: string): number | null;
|
|
2926
|
+
/**
|
|
2927
|
+
* Recover a finding count from a `ran-no-count` output, falling back to 1 — the
|
|
2928
|
+
* check ran and flagged something, exact count unknown.
|
|
2929
|
+
*/
|
|
2930
|
+
declare function recoverFindingsCount(output: string): number;
|
|
2931
|
+
declare function classifyCheckExecutionFailure(output: string): CheckFailureClassification;
|
|
2932
|
+
|
|
2933
|
+
/**
|
|
2934
|
+
* Dependencies for {@link createAgentDispatcher}. All side-effecting collaborators
|
|
2935
|
+
* are injected so the dispatcher is unit-testable with a MockBackend and a fake
|
|
2936
|
+
* git seam (no real agent process, no real repository).
|
|
2937
|
+
*/
|
|
2938
|
+
interface AgentDispatcherDeps {
|
|
2939
|
+
/**
|
|
2940
|
+
* Resolve a configured backend by name (e.g. `'local'`, `'claude'`). Returns
|
|
2941
|
+
* `null` when the name is unknown/unconfigured — the dispatcher then no-ops
|
|
2942
|
+
* rather than throwing, so a misconfigured maintenance task degrades to
|
|
2943
|
+
* "produced nothing" instead of crashing the scheduler.
|
|
2944
|
+
*/
|
|
2945
|
+
resolveBackend: (backendName: string) => AgentBackend | null;
|
|
2946
|
+
/** Run `git <args>` in `cwd`, returning trimmed stdout (throws on failure). */
|
|
2947
|
+
git: (args: string[], cwd: string) => string;
|
|
2948
|
+
/** Max agent turns per dispatch. Defaults to 10. */
|
|
2949
|
+
maxTurns?: number;
|
|
2950
|
+
logger: {
|
|
2951
|
+
info: (message: string, meta?: Record<string, unknown>) => void;
|
|
2952
|
+
warn: (message: string, meta?: Record<string, unknown>) => void;
|
|
2953
|
+
};
|
|
2954
|
+
}
|
|
2955
|
+
/**
|
|
2956
|
+
* Wire the maintenance {@link AgentDispatcher} to a real agent session.
|
|
2957
|
+
*
|
|
2958
|
+
* Replaces the previous stub (which only logged and returned `producedCommits:
|
|
2959
|
+
* false`). Resolves the named backend, drives a multi-turn {@link AgentRunner}
|
|
2960
|
+
* session over the skill prompt in the worktree, then measures whether the agent
|
|
2961
|
+
* actually committed anything by diffing `HEAD` before/after. Commit count — not
|
|
2962
|
+
* the agent's self-report — is the source of truth for `fixed`.
|
|
2963
|
+
*/
|
|
2964
|
+
declare function createAgentDispatcher(deps: AgentDispatcherDeps): AgentDispatcher;
|
|
2965
|
+
|
|
2966
|
+
/**
|
|
2967
|
+
* Options for the MaintenanceReporter.
|
|
2968
|
+
*/
|
|
2969
|
+
interface MaintenanceReporterOptions {
|
|
2970
|
+
/** Directory where history.json is persisted (default: '.harness/maintenance/') */
|
|
2971
|
+
persistDir?: string;
|
|
2972
|
+
/** Logger for structured error/info output. Falls back to console if not provided. */
|
|
2973
|
+
logger?: MaintenanceLogger;
|
|
2974
|
+
}
|
|
2975
|
+
declare class MaintenanceReporter {
|
|
2976
|
+
private persistDir;
|
|
2977
|
+
private logger;
|
|
2978
|
+
private history;
|
|
2979
|
+
constructor(options?: MaintenanceReporterOptions);
|
|
2980
|
+
/**
|
|
2981
|
+
* Load history from disk. Creates the persist directory if it does not exist.
|
|
2982
|
+
* Errors in persistence are logged to stderr, not thrown.
|
|
2983
|
+
*/
|
|
2984
|
+
load(): Promise<void>;
|
|
2985
|
+
/**
|
|
2986
|
+
* Record a run result. Appends to in-memory history (most recent first),
|
|
2987
|
+
* caps at MAX_HISTORY, and writes to disk asynchronously.
|
|
2988
|
+
*/
|
|
2989
|
+
record(result: RunResult): Promise<void>;
|
|
2990
|
+
/**
|
|
2991
|
+
* Returns a paginated slice of the run history (most recent first).
|
|
2992
|
+
*/
|
|
2993
|
+
getHistory(limit: number, offset: number): RunResult[];
|
|
2994
|
+
/**
|
|
2995
|
+
* Write history to disk. Errors are logged, not thrown.
|
|
2996
|
+
*/
|
|
2997
|
+
private persist;
|
|
2998
|
+
}
|
|
2999
|
+
|
|
3000
|
+
/**
|
|
3001
|
+
* Generous stdout/stderr capture ceiling for spawned maintenance checks. The
|
|
3002
|
+
* Node `execFile` default (1 MB) is far too small for verbose checks — e.g.
|
|
3003
|
+
* `harness cleanup` on a large repo emits ~8 MB — and an exceeded buffer
|
|
3004
|
+
* rejects with EMPTY stdout/stderr, which the runner would misread as a check
|
|
3005
|
+
* that produced no output (a false execution failure). 64 MB leaves ample
|
|
3006
|
+
* headroom while still bounding memory.
|
|
3007
|
+
*/
|
|
3008
|
+
declare const MAINTENANCE_CHECK_MAX_BUFFER: number;
|
|
3009
|
+
/**
|
|
3010
|
+
* Per-check wall-clock budget. Raised from the original 120 s because heavy
|
|
3011
|
+
* whole-repo checks legitimately need longer on large monorepos — `harness
|
|
3012
|
+
* cleanup` (all entropy types) takes ~165 s here — and a too-tight timeout
|
|
3013
|
+
* SIGTERMs the child, yielding empty output that the runner can only read as a
|
|
3014
|
+
* (false) execution failure. 300 s keeps a bound while letting real checks
|
|
3015
|
+
* finish.
|
|
3016
|
+
*/
|
|
3017
|
+
declare const MAINTENANCE_CHECK_TIMEOUT_MS = 300000;
|
|
3018
|
+
/** A resolved child-process invocation: the file to spawn and its argv. The two
|
|
3019
|
+
* callers build this differently (CLI: `process.execPath` + the CLI's own entry
|
|
3020
|
+
* script; cron: the `harness` binary on PATH) but the spawn/parse core is one. */
|
|
3021
|
+
interface HarnessSpawn {
|
|
3022
|
+
file: string;
|
|
3023
|
+
args: string[];
|
|
3024
|
+
}
|
|
3025
|
+
/** The shape of an `execFile` rejection the timeout/classification logic reads. */
|
|
3026
|
+
interface ExecFileError {
|
|
3027
|
+
stdout?: string | Buffer;
|
|
3028
|
+
stderr?: string | Buffer;
|
|
3029
|
+
killed?: boolean;
|
|
3030
|
+
signal?: string | null;
|
|
3031
|
+
code?: string | number | null;
|
|
3032
|
+
}
|
|
3033
|
+
/** Injectable `execFile` (promisified) so tests can drive the spawn-error,
|
|
3034
|
+
* clean-run, findings, and timeout branches without real subprocesses. */
|
|
3035
|
+
type ExecFileAsyncFn = (file: string, args: string[], options: {
|
|
3036
|
+
cwd: string;
|
|
3037
|
+
timeout: number;
|
|
3038
|
+
maxBuffer: number;
|
|
3039
|
+
}) => Promise<{
|
|
3040
|
+
stdout: string | Buffer;
|
|
3041
|
+
stderr?: string | Buffer;
|
|
3042
|
+
}>;
|
|
3043
|
+
interface RunHarnessCheckOptions {
|
|
3044
|
+
/** Injected for tests; defaults to the real promisified `execFile`. */
|
|
3045
|
+
execFileAsync?: ExecFileAsyncFn;
|
|
3046
|
+
/** Per-check wall-clock budget (default {@link MAINTENANCE_CHECK_TIMEOUT_MS}). */
|
|
3047
|
+
timeoutMs?: number;
|
|
3048
|
+
/** stdout/stderr capture ceiling (default {@link MAINTENANCE_CHECK_MAX_BUFFER}). */
|
|
3049
|
+
maxBuffer?: number;
|
|
3050
|
+
}
|
|
3051
|
+
/** Best-effort detection of a child killed by the `execFile` timeout (SIGTERM /
|
|
3052
|
+
* ETIMEDOUT / killed flag). */
|
|
3053
|
+
declare function isCheckTimeoutError(e: ExecFileError): boolean;
|
|
3054
|
+
/**
|
|
3055
|
+
* Spawn a resolved harness check invocation and classify its result into a
|
|
3056
|
+
* {@link CheckCommandResult}. Behavior (shared by cron + CLI):
|
|
3057
|
+
*
|
|
3058
|
+
* - clean exit, parseable count → `{ findings: N }` (or 0 on a parse-miss; a
|
|
3059
|
+
* check that ran and said nothing is clean, not "1 finding").
|
|
3060
|
+
* - non-zero exit WITH a parseable count → real findings (`executionFailed:
|
|
3061
|
+
* false`) — e.g. `check-arch` exits 1 with "45 issues".
|
|
3062
|
+
* - non-zero exit / spawn error with NO parseable count → `executionFailed:
|
|
3063
|
+
* true`, findings 0 (a broken check is not "1 finding"; ADR 0050).
|
|
3064
|
+
* - TIMEOUT (SIGTERM/ETIMEDOUT) → `executionFailed: true`, findings 0, with a
|
|
3065
|
+
* distinct "check timed out after Nms" marker APPENDED to whatever the child
|
|
3066
|
+
* flushed. A timed-out check did not complete: even partial parseable output
|
|
3067
|
+
* ("5 issues") it flushed before SIGTERM is truncated and untrustworthy, so
|
|
3068
|
+
* the timeout is classified ahead of any finding count — never a "ran-no-
|
|
3069
|
+
* count" success. {@link import('./task-runner').classifyCheckExecutionFailure}
|
|
3070
|
+
* matches this marker before `explicitFindingsCount`.
|
|
3071
|
+
*/
|
|
3072
|
+
declare function runHarnessCheck(spawn: HarnessSpawn, cwd: string, opts?: RunHarnessCheckOptions): Promise<CheckCommandResult>;
|
|
3073
|
+
|
|
2429
3074
|
interface CreateTokenInput {
|
|
2430
3075
|
name: string;
|
|
2431
3076
|
scopes: TokenScope[];
|
|
@@ -2875,4 +3520,4 @@ declare function emitProposalCreated(bus: EventEmitter, proposal: SkillProposal)
|
|
|
2875
3520
|
declare function emitProposalApproved(bus: EventEmitter, proposal: SkillProposal): void;
|
|
2876
3521
|
declare function emitProposalRejected(bus: EventEmitter, proposal: SkillProposal): void;
|
|
2877
3522
|
|
|
2878
|
-
export { type AgentUpdateEvent, AnalysisArchive, type AnalysisRecord, type ApplyEventResult, type ArtifactPresence, type AttemptStats, BUILT_IN_TASKS, BackendDefSchema, BackendRouter, type BackendRouterOptions, type BaseRefFallbackEvent, type BuildArchiveHooksOptions, ClaimManager, type ClaimManagerConfig, type CleanWorkspaceEffect, type CreateTokenInput, type CreateTokenResult, type CustomTaskValidationError, type DispatchEffect, type EmitLogEffect, type EscalateEffect, type ExecFileFn$1 as ExecFileFn, type FromConfigOptions, GateNotReadyError, type GateResult, GateRunError, type Highlight, type HighlightsInfo, type IndexedDoc, InteractionQueue, type LinearGraphQLExtension, LinearGraphQLStub, type LiveSession, LocalModelResolver, type LocalModelResolverOptions, MAX_ATTEMPTS, type MigrationResult, MockBackend, type NotificationSink, type NotificationSinkDeliverInput, ORCHESTRATOR_IDENTITY_FILE, Orchestrator, OrchestratorBackendFactory, type OrchestratorBackendFactoryOptions, type OrchestratorContext, type OrchestratorEvent, type OrchestratorState, PRDetector, type PRDetectorLogger, type PendingInteraction, type PersistedOutputEntry, PromotionError, type PromotionResult, PromptRenderer, type ProposalApprovedData, type ProposalCreatedData, type ProposalRejectedData, type PublishedIndex, type QueueInsertInput, type QueueRow, type QueueStats, RETRY_DELAYS_MS, type RateLimitSnapshot as RateLimitComputeSnapshot, type RateLimitConfig, type RateLimitSnapshot$1 as RateLimitSnapshot, type RegistryEntry, type ReleaseClaimEffect, type ResolverLogger, type RetryEntry, type RetryFiredEvent, RoadmapTrackerAdapter, RoutingConfigSchema, RoutingValueSchema, type RunAttemptPhase, type RunOrigin, type RunningEntry, type ScheduleRetryEffect, type SearchOptions, type SideEffect, SinkConfigError, SinkRegistry, type SkillCatalogEntry, SlackSink, type SlackSinkOptions, SqliteSearchIndex, type StallDetectedEvent, type StopEffect, type StreamManifest, StreamRecorder, type SummarizeContext, type SummarizeResult, type SyncMainOptions, type SyncMainResult, type SyncSkipReason, type TaskDefinition, TaskOutputStore, type TaskType, type TickEvent, TokenStore, type TokenTotals, type TriageConfig, type TriageDecision, type TriageSignals, type TriageSkill, type UpdateTokensEffect, type ValidateWorkflowConfigOptions, type ValidatedWorkflowConfig, WebhookQueue, type WorkerExitEvent, WorkflowLoader, WorkspaceHooks, WorkspaceManager, type WorkspaceManagerOptions, applyEvent, artifactPresenceFromIssue, buildArchiveHooks, calculateRetryDelay, canDispatch, computeRateLimitDelay, createBackend, createEmptyState, crossFieldRoutingIssues, defaultFetchModels, deriveSeedPaths, detectScopeTier, discoverSkillCatalog, discoverSkillCatalogNames, emitProposalApproved, emitProposalCreated, emitProposalRejected, extractHighlights, extractTitlePrefix, getAvailableSlots, getDefaultConfig, getPerStateCount, indexSessionDirectory, isEligible, isSummaryEnabled, launchTUI, loadPublishedIndex, migrateAgentConfig, normalizeFts5Query, normalizeLocalModel, openSearchIndex, promote, reconcile, reindexFromArchive, renderAnalysisComment, renderLlmSummaryMarkdown, renderPRComment, resolveEscalationConfig, resolveOrchestratorId, routeIssue, routingWarnings, runGate, savePublishedIndex, searchIndexPath, selectCandidates, sortCandidates, summarizeArchivedSession, syncMain, triageIssue, truncateForBudget, validateCustomTasks, validateWorkflowConfig, wireNotificationSinks, wrapAsEnvelope };
|
|
3523
|
+
export { type AgentDispatchResult, type AgentDispatcher, type AgentDispatcherDeps, type AgentUpdateEvent, AnalysisArchive, type AnalysisRecord, type ApplyEventResult, type ArtifactPresence, type AttemptStats, BUILT_IN_TASKS, BackendDefSchema, type BackendResolver, BackendRouter, type BackendRouterOptions, type BaseRefFallbackEvent, type BuildArchiveHooksOptions, type CheckCommandResult, type CheckCommandRunner, type CheckFailureClassification, type CheckFailureKind, CheckScriptRunner, ClaimManager, type ClaimManagerConfig, type CleanWorkspaceEffect, type CommandExecResult, type CommandExecutor, type CreateTokenInput, type CreateTokenResult, type CustomTaskValidationError, type DispatchEffect, type EmitLogEffect, type EscalateEffect, type ExecFileAsyncFn, type ExecFileError, type ExecFileFn$1 as ExecFileFn, type FromConfigOptions, GateNotReadyError, type GateResult, GateRunError, type HarnessSpawn, type Highlight, type HighlightsInfo, type IndexedDoc, InteractionQueue, LinearGraphQLClient, type LinearGraphQLClientOptions, type LinearGraphQLExtension, LinearGraphQLStub, type LiveSession, LocalModelResolver, type LocalModelResolverOptions, MAINTENANCE_CHECK_MAX_BUFFER, MAINTENANCE_CHECK_TIMEOUT_MS, MAX_ATTEMPTS, MaintenanceReporter, type MaintenanceReporterOptions, type MigrationResult, MockBackend, type NotificationSink, type NotificationSinkDeliverInput, ORCHESTRATOR_IDENTITY_FILE, Orchestrator, OrchestratorBackendFactory, type OrchestratorBackendFactoryOptions, type OrchestratorContext, type OrchestratorEvent, type OrchestratorState, PRDetector, type PRDetectorLogger, type PRLifecycleManager, type PendingInteraction, type PersistedOutputEntry, PromotionError, type PromotionResult, PromptRenderer, type ProposalApprovedData, type ProposalCreatedData, type ProposalRejectedData, type PublishedIndex, type QueueInsertInput, type QueueRow, type QueueStats, RETRY_DELAYS_MS, type RateLimitSnapshot as RateLimitComputeSnapshot, type RateLimitConfig, type RateLimitSnapshot$1 as RateLimitSnapshot, type RegistryEntry, type ReleaseClaimEffect, type ResolverLogger, type RetryEntry, type RetryFiredEvent, RoadmapTrackerAdapter, RoutingConfigSchema, RoutingValueSchema, type RunAttemptPhase, type RunHarnessCheckOptions, type RunMode, type RunOrigin, type RunResult, type RunningEntry, type ScheduleRetryEffect, type SearchOptions, type SideEffect, SinkConfigError, SinkRegistry, type SkillCatalogEntry, SlackSink, type SlackSinkOptions, SqliteSearchIndex, type StallDetectedEvent, type StopEffect, type StreamManifest, StreamRecorder, type SummarizeContext, type SummarizeResult, type SyncMainOptions, type SyncMainResult, type SyncSkipReason, type TaskDefinition, TaskOutputStore, TaskRunner, type TaskRunnerOptions, type TaskSelectionFilter, type TaskType, type TickEvent, TokenStore, type TokenTotals, type TriageConfig, type TriageDecision, type TriageSignals, type TriageSkill, type UpdateTokensEffect, type ValidateWorkflowConfigOptions, type ValidatedWorkflowConfig, WebhookQueue, type WorkerExitEvent, WorkflowLoader, WorkspaceHooks, WorkspaceManager, type WorkspaceManagerOptions, applyEvent, artifactPresenceFromIssue, buildArchiveHooks, calculateRetryDelay, canDispatch, classifyCheckExecutionFailure, computeRateLimitDelay, createAgentDispatcher, createBackend, createEmptyState, crossFieldRoutingIssues, defaultFetchModels, deriveSeedPaths, detectScopeTier, discoverSkillCatalog, discoverSkillCatalogNames, emitProposalApproved, emitProposalCreated, emitProposalRejected, explicitFindingsCount, extractHighlights, extractTitlePrefix, getAvailableSlots, getDefaultConfig, getPerStateCount, indexSessionDirectory, isCheckTimeoutError, isEligible, isSummaryEnabled, launchTUI, loadPublishedIndex, makeBackendResolver, migrateAgentConfig, normalizeFts5Query, normalizeHarnessCommand, normalizeLocalModel, openSearchIndex, promote, reconcile, recoverFindingsCount, reindexFromArchive, renderAnalysisComment, renderLlmSummaryMarkdown, renderPRComment, resolveEscalationConfig, resolveOrchestratorId, routeIssue, routingWarnings, runGate, runHarnessCheck, savePublishedIndex, searchIndexPath, selectCandidates, selectTasks, sortCandidates, summarizeArchivedSession, syncMain, triageIssue, truncateForBudget, validateCustomTasks, validateWorkflowConfig, wireNotificationSinks, wrapAsEnvelope };
|