@aihq/harness 0.4.1 → 0.6.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/cli.js CHANGED
@@ -1,3 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import{ja as s}from"./chunk-Z2VMMIMJ.js";s().parseAsync(process.argv).catch(r=>{process.stderr.write(`fatal: ${r instanceof Error?r.message:String(r)}
2
+ import{qa as s,ra as e,sa as n}from"./chunk-PHJ6DL2Y.js";e(process.argv)?s().parse(process.argv):n().then(({program:r,warnings:o})=>{for(let i of o)process.stderr.write(`aih: plugin: ${i}
3
+ `);return r.parseAsync(process.argv)}).catch(r=>{process.stderr.write(`fatal: ${r instanceof Error?r.message:String(r)}
3
4
  `),process.exitCode=1});
package/dist/index.d.ts CHANGED
@@ -186,7 +186,7 @@ type Verdict = "pass" | "fail" | "skip";
186
186
  * sealed: a new failure mode means a new member here PLUS the `code` set at the
187
187
  * emitter; never derive a code by matching `detail`.
188
188
  */
189
- type CheckCode = "env.node-runtime" | "env.git-missing" | "env.dev-tool-missing" | "env.tool-install-blocked" | "cert.ca-missing" | "tls.verify-failed" | "npm.runtime-broken" | "path.missing" | "mcp.blocked" | "mcp.uv-missing" | "mcp.config-missing" | "mcp.unvendored-offline" | "mcp.policy-denied" | "mcp.hardcoded-secret" | "mcp.allowlist-drift" | "cli.not-detected" | "cli.config-only" | "cli.bootloader-missing" | "cli.bootloader-drift" | "cli.wont-load" | "canon.router-missing" | "canon.context-dir-missing" | "canon.lint-failed" | "canon.adoptable" | "canon.cli-native-unmigrated" | "secrets.plaintext-detected" | "guardrails.gitleaks-missing" | "usage.no-data" | "scale.code-review-graph-missing" | "contract.path-unportable" | "contract.stale" | "org-policy.drift" | "report.context-over-budget" | "report.low-adoption" | "report.contract-untrue" | "ready.blocked" | "trust.fetch-blocked" | "trust.detector-unavailable" | "trust.hidden-unicode" | "trust.prompt-injection" | "trust.source-changed" | "trust.auto-exec-hook" | "trust.dependency-confusion" | "trust.typosquat" | "trust.malicious-code" | "trust.source-drift" | "trust.unpinned-dependency" | "trust.untrusted-publisher" | "trust.unsigned-source" | "trust.license-missing" | "trust.unapproved-skill";
189
+ type CheckCode = "env.node-runtime" | "env.git-missing" | "env.dev-tool-missing" | "env.tool-install-blocked" | "cert.ca-missing" | "tls.verify-failed" | "npm.runtime-broken" | "path.missing" | "mcp.blocked" | "mcp.uv-missing" | "mcp.config-missing" | "mcp.unvendored-offline" | "mcp.policy-denied" | "mcp.hardcoded-secret" | "mcp.allowlist-drift" | "cli.not-detected" | "cli.config-only" | "cli.bootloader-missing" | "cli.bootloader-drift" | "cli.wont-load" | "canon.router-missing" | "canon.context-dir-missing" | "canon.lint-failed" | "canon.adoptable" | "canon.cli-native-unmigrated" | "secrets.plaintext-detected" | "guardrails.gitleaks-missing" | "usage.no-data" | "scale.code-review-graph-missing" | "contract.path-unportable" | "contract.stale" | "org-policy.drift" | "org-policy.invalid" | "org-policy.bundle-invalid" | "report.context-over-budget" | "report.low-adoption" | "report.contract-untrue" | "ready.blocked" | "trust.fetch-blocked" | "trust.detector-unavailable" | "trust.hidden-unicode" | "trust.prompt-injection" | "trust.source-changed" | "trust.auto-exec-hook" | "trust.dependency-confusion" | "trust.typosquat" | "trust.malicious-code" | "trust.source-drift" | "trust.unpinned-dependency" | "trust.untrusted-publisher" | "trust.unsigned-source" | "trust.license-missing" | "trust.unapproved-skill" | "pack.duplicate-name" | "pack.pin-mismatch" | "pack.missing-approval" | "pack.unknown-manifest" | "marketplace.manifest-parse" | "marketplace.path-traversal" | "marketplace.missing-file" | "marketplace.checksum-mismatch" | "marketplace.sums-coverage" | "marketplace.unapproved-verdict" | "marketplace.signature";
190
190
  interface Check {
191
191
  name: string;
192
192
  verdict: Verdict;
@@ -311,6 +311,16 @@ interface ExecAction {
311
311
  blockProbesOnFailure?: boolean;
312
312
  /** Continue the plan even if the command exits non-zero. */
313
313
  allowFailure?: boolean;
314
+ /**
315
+ * Apply-time content pin: refuse to run (abort the apply) unless the file's
316
+ * bytes still hash to `sha256` — pins an apply-time exec to the plan-time
317
+ * preflighted content, so nothing swapped in between plan and apply can ever
318
+ * be consumed by the command (the validate-then-use TOCTOU).
319
+ */
320
+ expect?: {
321
+ path: string;
322
+ sha256: string;
323
+ };
314
324
  }
315
325
  /**
316
326
  * Upsert an aih-managed env block (one `scope`) into a shell profile. Unlike a
@@ -480,6 +490,7 @@ declare function exec(describe: string, argv: string[], opts?: {
480
490
  timeoutMs?: number;
481
491
  failureCheck?: ExecAction["failureCheck"];
482
492
  blockProbesOnFailure?: boolean;
493
+ expect?: ExecAction["expect"];
483
494
  }): ExecAction;
484
495
  declare function envBlock(path: string, scope: string, shell: EnvShell, vars: EnvVar[], describe: string): EnvBlockAction;
485
496
  declare function remove(path: string, describe: string, opts?: {
@@ -493,7 +504,29 @@ declare const CAPABILITIES: CommandSpec[];
493
504
  /** Read-only commands (always safe). */
494
505
  declare const READONLY: CommandSpec[];
495
506
  declare const ALL_COMMANDS: CommandSpec[];
496
- declare function registerCommands(program: Command): void;
507
+ /**
508
+ * Every top-level name the core CLI claims: ALL_COMMANDS plus the parent group
509
+ * names (`workspace` is both a CommandSpec and a group — the Set folds it)
510
+ * plus commander's own reserved `help`/`version`. The plugin registry refuses
511
+ * any external spec colliding with one of these, so a plugin can never shadow
512
+ * `doctor`, capture the `marketplace` group, or impersonate `help`.
513
+ */
514
+ declare function builtinCommandNames(): ReadonlySet<string>;
515
+ /**
516
+ * Register every command on the program. `extra` carries EXTERNAL plugin specs
517
+ * (see src/plugins/registry.ts, already gated + collision-free): they flow
518
+ * through the IDENTICAL registerSpec path as the built-ins — same shared
519
+ * flags, same optional `[root]` positional, same runCapability action (posture
520
+ * resolution, dirty-worktree gate, run ledger). TOP-LEVEL specs only: a plugin
521
+ * cannot contribute subcommands to a parent group (trust/skill/pack/…) in v1.
522
+ *
523
+ * Containment: built-ins register OUTSIDE any try/catch — a throw there is a
524
+ * core bug that must crash loudly. Each plugin spec registers inside its own
525
+ * try/catch: a Commander throw (e.g. a flag conflict the structural gate
526
+ * cannot predict) drops THAT spec with a warning pushed to the `warnings`
527
+ * sink, and every other command stays live.
528
+ */
529
+ declare function registerCommands(program: Command, extra?: CommandSpec[], warnings?: string[]): void;
497
530
 
498
531
  /** Resolved runtime settings (env defaults overlaid with CLI flags). */
499
532
  interface Settings {
@@ -699,6 +732,20 @@ declare class FsTransaction {
699
732
  }
700
733
  /** Read a file's text, or `undefined` if it does not exist. */
701
734
  declare function readIfExists(path: string): string | undefined;
735
+ /**
736
+ * Open-then-read on ONE file descriptor: the regular-file check (`fstat` on the
737
+ * open fd, never a second path lookup) and the read cannot be raced apart, and
738
+ * a symlink swapped in after directory enumeration is refused at open where
739
+ * `O_NOFOLLOW` exists rather than silently followed. Returns undefined for
740
+ * anything that is not a readable regular file.
741
+ *
742
+ * Use this — not {@link readIfExists} — for any path DISCOVERED by a directory
743
+ * scan: a plain exists-then-read pair on a scanned path is a swap window where
744
+ * a symlink planted between enumeration and read gets silently followed and its
745
+ * target's bytes laundered into an artifact (marketplace build, evidence
746
+ * bundle, fleet bundle all package what they read).
747
+ */
748
+ declare function readRegularFile(abs: string): Buffer | undefined;
702
749
 
703
750
  /**
704
751
  * Parse JSON or JSONC text (tolerant of comments + trailing commas). Returns
@@ -778,8 +825,141 @@ declare function parseCertLines(stdout: string): CertEntry[];
778
825
  */
779
826
  declare function parsePemBlocks(stdout: string, subject?: string): CertEntry[];
780
827
 
781
- declare const VERSION = "0.4.1";
782
- /** Build the configured commander program. Imported by both the CLI entry and tests. */
783
- declare function buildProgram(): Command;
828
+ /**
829
+ * The pluggable command registry aih's ONE extension seam (OPA/Semgrep-style
830
+ * open core). The public harness is complete and fully local on its own; on
831
+ * startup the CLI probes for a single optional peer package,
832
+ * {@link PLUGIN_PACKAGE}, and when it is installed and valid, the `aihCommands`
833
+ * CommandSpecs it exports merge into the registry and appear as NATIVE
834
+ * subcommands — flowing through the identical registration path as the
835
+ * built-ins (shared flags, posture resolution, dirty-worktree gate, run
836
+ * ledger), so the private package bolts on without forking the core. An
837
+ * unenrolled machine sees zero output and zero behavior change.
838
+ *
839
+ * Rules the seam is built on:
840
+ * - LITERAL package name only. The probe always imports {@link PLUGIN_PACKAGE}
841
+ * verbatim — never an env var, flag, or config value — so nothing
842
+ * user-controlled can point the import at other code. (The `importer` and
843
+ * `resolver` options are purely test seams; production uses the platform
844
+ * dynamic import and `import.meta.resolve`.)
845
+ * - SAME INSTALL TREE only. Before importing, the probe resolves where the
846
+ * import WOULD load from and refuses anything outside the harness's own
847
+ * install tree, so a global or `npx`-run aih pointed at a hostile repo can
848
+ * never import that repo's planted `node_modules/@aihq/enterprise`. Honesty
849
+ * note (also in the README): when aih itself is installed INSIDE the target
850
+ * repo, the repo already controls the binary — the check draws the boundary
851
+ * at "the tree aih runs from", nothing stronger.
852
+ * - STARTUP BUDGET. The import races a timeout (default
853
+ * {@link DEFAULT_IMPORT_TIMEOUT_MS} ms); a slow or wedged plugin degrades to
854
+ * local-only with a warning instead of stalling every invocation. (`aih
855
+ * --version` skips the probe entirely — see src/cli.ts.)
856
+ * - Kill switch: `AIH_NO_PLUGINS=1` (read from the injectable `env`) skips the
857
+ * probe without touching the importer at all.
858
+ * - Fail open to LOCAL. A missing package is the normal unenrolled case
859
+ * (silent — zero noise); anything else (the package present but failing to
860
+ * resolve or load, a malformed export, an invalid or colliding spec)
861
+ * degrades to local-only behavior with a one-line warning. A broken plugin
862
+ * must never break the CLI.
863
+ * - Built-ins always win: a plugin spec whose name collides with a built-in
864
+ * command, a parent group, or commander's own `help`/`version` is refused
865
+ * ("refusing to shadow").
866
+ * - Shared + reserved flags are off-limits: a plugin option may not claim any
867
+ * token from {@link SHARED_FLAG_TOKENS} (the addSharedFlags surface) or
868
+ * commander's reserved `--help`/`-h`/`--version`/`-V`.
869
+ * - `skipWorktreeGate` is never honored for plugin commands — the field is
870
+ * stripped from the registered copy (see {@link stripWorktreeGateField}).
871
+ * - Warnings render hostile input: every plugin-influenced string that lands
872
+ * in a warning routes through {@link sanitizeLabel} first.
873
+ *
874
+ * Trust boundary note: the boundary is package INSTALLATION — by the time this
875
+ * module inspects the export, `import()` has already run the plugin's module
876
+ * code, exactly like any other installed dependency. The structural gate below
877
+ * is about REGISTRY INTEGRITY (only well-formed, non-colliding specs register),
878
+ * not sandboxing: a gated spec may use any {@link CommandSpec} field, including
879
+ * `readOnly` (`skipWorktreeGate` being the one carve-out).
880
+ */
881
+ /** The one probed plugin package. Literal by design — see the module jsdoc. */
882
+ declare const PLUGIN_PACKAGE = "@aihq/enterprise";
883
+ interface PluginLoadResult {
884
+ commands: CommandSpec[];
885
+ warnings: string[];
886
+ }
887
+ /** Import seam so tests can simulate any module shape without installing anything. */
888
+ type PluginImporter = (specifier: string) => Promise<unknown>;
889
+ /**
890
+ * Resolver seam for the install-tree boundary: maps the package specifier to
891
+ * the FILE PATH the import would load from. Production uses
892
+ * `import.meta.resolve`; tests inject paths inside/outside the allowed roots.
893
+ */
894
+ type PluginResolver = (specifier: string) => string;
895
+ interface PluginLoadOptions {
896
+ /** Test seam replacing the platform dynamic import. */
897
+ importer?: PluginImporter;
898
+ /** Test seam replacing `import.meta.resolve` for the install-tree check. */
899
+ resolver?: PluginResolver;
900
+ /** Environment for the kill switch — matches runCapability's deps.env convention. */
901
+ env?: NodeJS.ProcessEnv;
902
+ /** Import budget in milliseconds (default {@link DEFAULT_IMPORT_TIMEOUT_MS}). */
903
+ timeoutMs?: number;
904
+ }
905
+ /**
906
+ * Long flag tokens `addSharedFlags` (src/commands/index.ts) puts on every
907
+ * capability subcommand. Mirrored as a constant because the registry must stay
908
+ * a leaf module — importing the command tree from here would create an import
909
+ * cycle (commands/index.ts imports {@link sanitizeLabel} back from this file).
910
+ * The mirror is pinned against the real addSharedFlags registration by
911
+ * tests/plugins/registry.test.ts, so any drift fails CI.
912
+ */
913
+ declare const SHARED_FLAG_TOKENS: ReadonlySet<string>;
914
+ /**
915
+ * Make a plugin-influenced string safe to echo in a one-line warning: collapse
916
+ * newlines to spaces, strip C0/C1 control characters (including ESC, so
917
+ * ANSI/OSC sequences lose their teeth) plus DEL, and truncate to `max` with an
918
+ * ellipsis. Exported so the plugin-registration containment in
919
+ * src/commands/index.ts routes through the SAME sanitizer — one
920
+ * implementation, no drift.
921
+ */
922
+ declare function sanitizeLabel(value: string, max?: number): string;
923
+ /**
924
+ * Every root the plugin is allowed to resolve under: each `node_modules`
925
+ * directory on the ancestor chain of THIS module's own file (after bundling,
926
+ * that file IS the CLI binary in `dist/`), plus `<package root>/node_modules`
927
+ * where the package root is the first ancestor directory carrying a
928
+ * package.json — that second clause covers running from the dev tree, where no
929
+ * ancestor is itself a node_modules. Everything is realpath'd; candidates that
930
+ * do not exist are dropped (a missing directory cannot contain the plugin).
931
+ * Exported as a test seam so tests can build paths inside a real root.
932
+ */
933
+ declare function allowedPluginRoots(): string[];
934
+ /**
935
+ * Probe for {@link PLUGIN_PACKAGE} and return its registrable CommandSpecs.
936
+ * Never throws: every failure mode degrades to `{ commands: [] }` plus at most
937
+ * one-line warnings, so the CLI stays fully local no matter how broken the
938
+ * plugin is. `AIH_NO_PLUGINS=1` (from `opts.env ?? process.env`) skips the
939
+ * probe entirely. See {@link PluginLoadOptions} for the test seams.
940
+ */
941
+ declare function loadExternalCommands(builtinNames: ReadonlySet<string>, opts?: PluginLoadOptions): Promise<PluginLoadResult>;
942
+
943
+ declare const VERSION = "0.6.0";
944
+ /**
945
+ * Build the configured commander program. Imported by both the CLI entry and
946
+ * tests. Stays SYNC: `extra` lets callers merge pre-loaded plugin specs — the
947
+ * async plugin probe lives in {@link buildProgramWithPlugins}. `warnings` is an
948
+ * optional sink for per-spec registration containment: a plugin spec Commander
949
+ * refuses at registration time is dropped with a warning instead of taking the
950
+ * CLI down (see registerCommands in src/commands/index.ts).
951
+ */
952
+ declare function buildProgram(extra?: CommandSpec[], warnings?: string[]): Command;
953
+ /**
954
+ * The CLI entry's builder: probe for the optional `@aihq/enterprise` peer
955
+ * (fail-open to local — see src/plugins/registry.ts) and build with whatever
956
+ * validly loaded. `warnings` (probe + registration containment, in that order)
957
+ * is printed to stderr by the entry BEFORE parse; an unenrolled machine gets
958
+ * zero warnings and the exact buildProgram surface.
959
+ */
960
+ declare function buildProgramWithPlugins(): Promise<{
961
+ program: Command;
962
+ warnings: string[];
963
+ }>;
784
964
 
785
- export { ALL_COMMANDS, type AccelBackend, type Action, type ActionKind, type AdapterFactory, AihError, CAPABILITIES, type CertEntry, type Check, type CheckCode, type CommandOption, type CommandSpec, ContextDir, type DigestAction, DirtyWorktreeError, type DocAction, type EnvBlockAction, type EnvShell, type EnvVar, type ExecAction, FsTransaction, FsTxnError, type FsTxnResult, type GpuInfo, type GpuVendor, type HostAdapter, type HostAdapterOptions, MergeError, NotImplementedError, PathContainmentError, type Plan, type PlanContext, type PlanFn, type PlanResult, type Platform, PlatformError, type ProbeAction, READONLY, type RemoveAction, type RemoveSummary, type RunOptions, type RunResult, type Runner, type Settings, SettingsError, VERSION, type VdiInfo, type Verdict, VerificationError, VerificationReport, type WriteAction, type WriteSummary, beginMarker, buildProgram, deepMerge, defaultRunner, derBase64ToPem, digest, doc, dynamicDigest, endMarker, ensureTrailingNewline, envBlock, exec, executePlan, fakeRunner, formatExport, frontmatter, indent, isPlainObject, jsonFile, lines, loadSettings, makeHostAdapter, managedBlock, missingToolRunner, parseCertLines, parseFirstInt, parseJsoncText, parseNvidiaSmi, parsePemBlocks, plan, probe, probeMany, readIfExists, registerCommands, remove, removeManagedBlock, resolveContents, resolvePlatform, retryTransient, safeCaPattern, stripTrailingNewlines, summarizeResult, upsertManagedBlock, upsertTextBlock, vdiFromEnv, writeArtifact, writeJson, writeText };
965
+ export { ALL_COMMANDS, type AccelBackend, type Action, type ActionKind, type AdapterFactory, AihError, CAPABILITIES, type CertEntry, type Check, type CheckCode, type CommandOption, type CommandSpec, ContextDir, type DigestAction, DirtyWorktreeError, type DocAction, type EnvBlockAction, type EnvShell, type EnvVar, type ExecAction, FsTransaction, FsTxnError, type FsTxnResult, type GpuInfo, type GpuVendor, type HostAdapter, type HostAdapterOptions, MergeError, NotImplementedError, PLUGIN_PACKAGE, PathContainmentError, type Plan, type PlanContext, type PlanFn, type PlanResult, type Platform, PlatformError, type PluginImporter, type PluginLoadOptions, type PluginLoadResult, type PluginResolver, type ProbeAction, READONLY, type RemoveAction, type RemoveSummary, type RunOptions, type RunResult, type Runner, SHARED_FLAG_TOKENS, type Settings, SettingsError, VERSION, type VdiInfo, type Verdict, VerificationError, VerificationReport, type WriteAction, type WriteSummary, allowedPluginRoots, beginMarker, buildProgram, buildProgramWithPlugins, builtinCommandNames, deepMerge, defaultRunner, derBase64ToPem, digest, doc, dynamicDigest, endMarker, ensureTrailingNewline, envBlock, exec, executePlan, fakeRunner, formatExport, frontmatter, indent, isPlainObject, jsonFile, lines, loadExternalCommands, loadSettings, makeHostAdapter, managedBlock, missingToolRunner, parseCertLines, parseFirstInt, parseJsoncText, parseNvidiaSmi, parsePemBlocks, plan, probe, probeMany, readIfExists, readRegularFile, registerCommands, remove, removeManagedBlock, resolveContents, resolvePlatform, retryTransient, safeCaPattern, sanitizeLabel, stripTrailingNewlines, summarizeResult, upsertManagedBlock, upsertTextBlock, vdiFromEnv, writeArtifact, writeJson, writeText };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{$ as fr,A as Y,B as _,C as c,D as h,E as j,F as k,G as q,H as v,I as w,J as y,K as z,L as F,M as G,N as H,O as J,P as K,Q,R as U,S as W,T as X,U as Z,V as $,W as rr,X as or,Y as mr,Z as er,_ as tr,a as p,aa as pr,b as x,ba as xr,c as A,ca as Ar,d as I,da as Ir,e as L,ea as r,f as C,fa as o,g as E,ga as m,h as N,ha as e,i as O,ia as t,j as S,ja as f,k as a,l as d,m as g,n as i,o as s,p as D,q as M,r as P,s as R,t as b,u as l,v as n,w as u,x as B,y as T,z as V}from"./chunk-Z2VMMIMJ.js";export{m as ALL_COMMANDS,p as AihError,r as CAPABILITIES,g as ContextDir,O as DirtyWorktreeError,a as FsTransaction,I as FsTxnError,E as MergeError,C as NotImplementedError,N as PathContainmentError,A as PlatformError,o as READONLY,x as SettingsError,t as VERSION,L as VerificationError,K as VerificationReport,k as beginMarker,f as buildProgram,J as deepMerge,Z as defaultRunner,or as derBase64ToPem,P as digest,M as doc,R as dynamicDigest,q as endMarker,j as ensureTrailingNewline,u as envBlock,n as exec,W as executePlan,$ as fakeRunner,w as formatExport,c as frontmatter,_ as indent,H as isPlainObject,h as jsonFile,Y as lines,i as loadSettings,Ir as makeHostAdapter,v as managedBlock,rr as missingToolRunner,pr as parseCertLines,tr as parseFirstInt,G as parseJsoncText,fr as parseNvidiaSmi,xr as parsePemBlocks,T as plan,b as probe,l as probeMany,d as readIfExists,e as registerCommands,B as remove,F as removeManagedBlock,U as resolveContents,Ar as resolvePlatform,S as retryTransient,mr as safeCaPattern,V as stripTrailingNewlines,X as summarizeResult,y as upsertManagedBlock,z as upsertTextBlock,er as vdiFromEnv,Q as writeArtifact,D as writeJson,s as writeText};
1
+ import{$ as xr,A as Y,B as _,C as c,D as j,E as k,F as q,G as v,H as w,I as y,J as z,K as F,L as G,M as H,N as J,O as K,P as Q,Q as U,R as X,S as Z,T as $,U as rr,V as or,W as mr,X as er,Y as tr,Z as fr,_ as pr,a as i,aa as ir,b as a,ba as ar,c as A,ca as Ar,d,da as dr,e as g,ea as gr,f as l,fa as lr,g as n,ga as nr,h as s,ha as sr,i as u,ia as ur,j as C,ja as Cr,k as I,ka as r,l as L,la as o,m as N,ma as m,n as P,na as e,o as b,oa as t,p as E,pa as f,q as O,qa as p,r as S,s as D,sa as x,t as M,u as R,v as h,w as B,x as T,y as V,z as W}from"./chunk-PHJ6DL2Y.js";export{m as ALL_COMMANDS,i as AihError,r as CAPABILITIES,P as ContextDir,u as DirtyWorktreeError,I as FsTransaction,d as FsTxnError,n as MergeError,l as NotImplementedError,lr as PLUGIN_PACKAGE,s as PathContainmentError,A as PlatformError,o as READONLY,nr as SHARED_FLAG_TOKENS,a as SettingsError,f as VERSION,g as VerificationError,U as VerificationReport,ur as allowedPluginRoots,v as beginMarker,p as buildProgram,x as buildProgramWithPlugins,e as builtinCommandNames,Q as deepMerge,or as defaultRunner,tr as derBase64ToPem,D as digest,S as doc,M as dynamicDigest,w as endMarker,q as ensureTrailingNewline,T as envBlock,B as exec,$ as executePlan,mr as fakeRunner,z as formatExport,j as frontmatter,c as indent,K as isPlainObject,k as jsonFile,_ as lines,Cr as loadExternalCommands,b as loadSettings,gr as makeHostAdapter,y as managedBlock,er as missingToolRunner,ar as parseCertLines,xr as parseFirstInt,J as parseJsoncText,ir as parseNvidiaSmi,Ar as parsePemBlocks,W as plan,R as probe,h as probeMany,L as readIfExists,N as readRegularFile,t as registerCommands,V as remove,H as removeManagedBlock,Z as resolveContents,dr as resolvePlatform,C as retryTransient,fr as safeCaPattern,sr as sanitizeLabel,Y as stripTrailingNewlines,rr as summarizeResult,F as upsertManagedBlock,G as upsertTextBlock,pr as vdiFromEnv,X as writeArtifact,O as writeJson,E as writeText};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aihq/harness",
3
- "version": "0.4.1",
3
+ "version": "0.6.0",
4
4
  "description": "Enterprise AI Bootstrapping Harness — bootstraps governed, proxy-safe AI coding into workstations and repos",
5
5
  "repository": {
6
6
  "type": "git",