diff --git a/README.md b/README.md index 81bb347..fa528e8 100644 --- a/README.md +++ b/README.md @@ -43,9 +43,9 @@ real interface and feature state Pin Direct as a development dependency: ```sh -bun add --dev @hraness/direct@0.7.16 +bun add --dev @hraness/direct@0.7.17 # or -npm install --save-dev @hraness/direct@0.7.16 +npm install --save-dev @hraness/direct@0.7.17 ``` Keep Direct in `devDependencies`. A production entry must not import Direct, @@ -58,7 +58,7 @@ composition. It requires Git and Bun 1.3.14, then downloads the source and its development dependencies: ```sh -git clone --branch v0.7.16 --depth 1 https://github.com/hraness/direct.git +git clone --branch v0.7.17 --depth 1 https://github.com/hraness/direct.git cd direct bun install --frozen-lockfile --ignore-scripts bun run example:direct @@ -132,9 +132,9 @@ claim separate as `direct` evidence. Install Direct's single bundled skill from the public repository: ```sh -npx skills add hraness/direct#v0.7.16 +npx skills add hraness/direct#v0.7.17 # or -bunx skills add hraness/direct#v0.7.16 +bunx skills add hraness/direct#v0.7.17 ``` The skill is invoked as `$direct`. It routes installation, adoption, and @@ -148,7 +148,7 @@ Copy this prompt into Codex, Claude Code, or another coding agent: ```text Use $direct to install hraness/direct from -the npm registry at the exact 0.7.16 version. Follow the repository README, add +the npm registry at the exact 0.7.17 version. Follow the repository README, add `@hraness/direct` to devDependencies only, and verify that the production dependency graph excludes Direct. Do not add a fixture composition until I ask. @@ -164,7 +164,7 @@ Pin the public npm package to an exact immutable version: ```json { "devDependencies": { - "@hraness/direct": "0.7.16" + "@hraness/direct": "0.7.17" } } ``` @@ -186,8 +186,8 @@ quiescence, coverage claims, cleanup, and emitted production boundaries. The package smoke test keeps that future packaged copy byte-identical to the repository skill. -Prefer `npx skills add hraness/direct#v0.7.16` or -`bunx skills add hraness/direct#v0.7.16` for runner discovery. You can also copy +Prefer `npx skills add hraness/direct#v0.7.17` or +`bunx skills add hraness/direct#v0.7.17` for runner discovery. You can also copy or link that one skill directory into a runner's configured location, then invoke `$direct`. Package installation leaves the skill inert: it does not run a `postinstall` hook or edit repository or user configuration. diff --git a/dist/tooling/bombadil.js b/dist/tooling/bombadil.js index 079bd53..bec85ba 100644 --- a/dist/tooling/bombadil.js +++ b/dist/tooling/bombadil.js @@ -1469,8 +1469,8 @@ class LiveChromeDownloadRenameRetry extends Error { completion; constructor(completion) { super("Chrome download renamed during live artifact inspection"); - this.completion = completion; this.name = "LiveChromeDownloadRenameRetry"; + this.completion = completion; } } diff --git a/docs/adoption.md b/docs/adoption.md index edb0a81..7cf9dd0 100644 --- a/docs/adoption.md +++ b/docs/adoption.md @@ -3,8 +3,8 @@ Add Direct after identifying the product behavior and external boundary under review. Do not begin by designing fixtures around a provider SDK. The repository carries one `$direct` Agent Skill under `skills/direct`. -Install it with `npx skills add hraness/direct#v0.7.16` or -`bunx skills add hraness/direct#v0.7.16`, or copy that directory into the runner's +Install it with `npx skills add hraness/direct#v0.7.17` or +`bunx skills add hraness/direct#v0.7.17`, or copy that directory into the runner's discovery location. Invoke `$direct` for installation, adoption, and verification work. Skill installation is independent from library package installation and does not activate Direct in a product. diff --git a/docs/publishing.md b/docs/publishing.md index 015d362..4929d7f 100644 --- a/docs/publishing.md +++ b/docs/publishing.md @@ -62,8 +62,8 @@ cookie, one-time password, recovery code, or write token to GitHub. `v`. ```sh - git tag v0.7.16 - git push origin refs/tags/v0.7.16 + git tag v0.7.17 + git push origin refs/tags/v0.7.17 ``` 3. Wait for **Release**. The workflow runs these boundaries in order: @@ -123,7 +123,7 @@ Merge the fix to `main`, then dispatch **Release** from current `main` with the exact existing stable tag: ```sh -gh workflow run release.yml --ref main -f tag=v0.7.16 +gh workflow run release.yml --ref main -f tag=v0.7.17 ``` The recovery path skips npm publication. It accepts only the newest stable diff --git a/docs/verification.md b/docs/verification.md index 77bce6a..664eef7 100644 --- a/docs/verification.md +++ b/docs/verification.md @@ -10,8 +10,8 @@ definition with `parseDefinitionCoverageSnapshot` so a valid but stale catalog cannot be mistaken for the catalog under review. The repository carries one `$direct` Agent Skill under `skills/direct`. -Install it with `npx skills add hraness/direct#v0.7.16` or -`bunx skills add hraness/direct#v0.7.16`, or copy that directory into the runner's +Install it with `npx skills add hraness/direct#v0.7.17` or +`bunx skills add hraness/direct#v0.7.17`, or copy that directory into the runner's discovery location. Invoke `$direct` for the workflow below. The skill is independent from library package installation and structures the audit; it does not turn deterministic evidence into proof of a substituted live system. diff --git a/package.json b/package.json index 580ab31..b760ac1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@hraness/direct", - "version": "0.7.16", + "version": "0.7.17", "description": "A TypeScript harness for deterministic frontend testing and development with repeatable scenarios, local fixtures, and browser verification for coding agents.", "license": "MIT", "type": "module", diff --git a/scripts/npm-publish-workflow.test.ts b/scripts/npm-publish-workflow.test.ts index e3e3c55..db96df6 100644 --- a/scripts/npm-publish-workflow.test.ts +++ b/scripts/npm-publish-workflow.test.ts @@ -341,7 +341,7 @@ import { isUtf8ByteLengthAtMost } from "./utf8-byte-boundary.js"; readonly version?: unknown; }; expect(manifest).toEqual(expect.objectContaining({ - version: "0.7.16", + version: "0.7.17", description: "A TypeScript harness for deterministic frontend testing and development with repeatable scenarios, local fixtures, and browser verification for coding agents.", keywords: [ "frontend-development", @@ -567,7 +567,7 @@ import { isUtf8ByteLengthAtMost } from "./utf8-byte-boundary.js"; const binaryDirectory = join(directory, "bin"); const commandLog = join(directory, "commands.log"); const publishMarker = join(directory, "published.txt"); - const tarball = join(directory, "hraness-direct-0.7.16.tgz"); + const tarball = join(directory, "hraness-direct-0.7.17.tgz"); const metadata = join(directory, "npm-pack.json"); const digest = join(directory, "npm-package.sha256"); const sourceSha = "b".repeat(40); @@ -585,7 +585,7 @@ import { isUtf8ByteLengthAtMost } from "./utf8-byte-boundary.js"; writeFile(metadata, "reviewed metadata fixture\n", "utf8"), writeFile(digest, "reviewed digest fixture\n", "utf8"), ]); - await writeFile(gitStub, `#!/bin/bash\nset -euo pipefail\nprintf 'git %s\\n' "$*" >> "$COMMAND_LOG"\ncase "$*" in\n *"rev-parse refs/heads/main"*) printf '%s\\n' "$DEFAULT_SHA" ;;\n *"rev-parse refs/tags/v0.7.16^{commit}"*) printf '%s\\n' "$TAG_SHA" ;;\n *"merge-base --is-ancestor"*) [[ "$ANCESTRY_STATE" == ancestor ]] ;;\n *"tag --list v*"*) printf '%s\\n' "$REMOTE_TAGS" ;;\nesac\n`, "utf8"); + await writeFile(gitStub, `#!/bin/bash\nset -euo pipefail\nprintf 'git %s\\n' "$*" >> "$COMMAND_LOG"\ncase "$*" in\n *"rev-parse refs/heads/main"*) printf '%s\\n' "$DEFAULT_SHA" ;;\n *"rev-parse refs/tags/v0.7.17^{commit}"*) printf '%s\\n' "$TAG_SHA" ;;\n *"merge-base --is-ancestor"*) [[ "$ANCESTRY_STATE" == ancestor ]] ;;\n *"tag --list v*"*) printf '%s\\n' "$REMOTE_TAGS" ;;\nesac\n`, "utf8"); await writeFile(sha256Stub, `#!/bin/bash\nset -euo pipefail\nprintf 'sha256sum %s\\n' "$*" >> "$COMMAND_LOG"\ncase "$1" in\n "$TARBALL") value="$EXPECTED_ARCHIVE_SHA256" ;;\n "$METADATA") value="$EXPECTED_METADATA_SHA256" ;;\n "$DIGEST") value="$EXPECTED_DIGEST_SHA256" ;;\n *) echo "unexpected hash target: $1" >&2; exit 1 ;;\nesac\nprintf '%s %s\\n' "$value" "$1"\n`, "utf8"); await writeFile(npmStub, `#!/bin/bash\nset -euo pipefail\nprintf 'npm %s\\n' "$*" >> "$COMMAND_LOG"\nif [[ "\${1-}" == view ]]; then\n printf '%s\\n' "$PUBLISHED_VERSIONS_JSON"\n exit 0\nfi\nprintf 'published\\n' > "$PUBLISH_MARKER"\n`, "utf8"); await Promise.all([chmod(gitStub, 0o755), chmod(npmStub, 0o755), chmod(sha256Stub, 0o755)]); @@ -601,15 +601,15 @@ import { isUtf8ByteLengthAtMost } from "./utf8-byte-boundary.js"; EXPECTED_DIGEST_SHA256: digestSha256, EXPECTED_METADATA_SHA256: metadataSha256, EXPECTED_SOURCE_SHA: sourceSha, - EXPECTED_VERSION: "0.7.16", - GITHUB_REF: "refs/tags/v0.7.16", + EXPECTED_VERSION: "0.7.17", + GITHUB_REF: "refs/tags/v0.7.17", GITHUB_REPOSITORY: "hraness/direct", GITHUB_SHA: sourceSha, METADATA: metadata, PATH: `${binaryDirectory}:${process.env.PATH ?? ""}`, - PUBLISHED_VERSIONS_JSON: '["0.7.4","0.7.5","0.7.6","0.7.7","0.7.8","0.7.9","0.7.10","0.7.11","0.7.12","0.7.13","0.7.14","0.7.15"]', + PUBLISHED_VERSIONS_JSON: '["0.7.4","0.7.5","0.7.6","0.7.7","0.7.8","0.7.9","0.7.10","0.7.11","0.7.12","0.7.13","0.7.14","0.7.15","0.7.16"]', PUBLISH_MARKER: publishMarker, - REMOTE_TAGS: "v0.7.4\nv0.7.5\nv0.7.6\nv0.7.7\nv0.7.8\nv0.7.9\nv0.7.10\nv0.7.11\nv0.7.12\nv0.7.13\nv0.7.14\nv0.7.15\nv0.7.16", + REMOTE_TAGS: "v0.7.4\nv0.7.5\nv0.7.6\nv0.7.7\nv0.7.8\nv0.7.9\nv0.7.10\nv0.7.11\nv0.7.12\nv0.7.13\nv0.7.14\nv0.7.15\nv0.7.16\nv0.7.17", RUNNER_TEMP: directory, TAG_SHA: sourceSha, TARBALL: tarball, @@ -640,7 +640,7 @@ import { isUtf8ByteLengthAtMost } from "./utf8-byte-boundary.js"; }); expect(moved.exitCode).not.toBe(0); expect(`${moved.stdout}${moved.stderr}`).toContain( - "Tag v0.7.16 changed after artifact verification", + "Tag v0.7.17 changed after artifact verification", ); expect(await Bun.file(publishMarker).exists()).toBe(false); @@ -651,18 +651,18 @@ import { isUtf8ByteLengthAtMost } from "./utf8-byte-boundary.js"; }); expect(detached.exitCode).not.toBe(0); expect(`${detached.stdout}${detached.stderr}`).toContain( - "Tag v0.7.16 is no longer reachable from main", + "Tag v0.7.17 is no longer reachable from main", ); expect(await Bun.file(publishMarker).exists()).toBe(false); await rm(commandLog, { force: true }); const superseded = await runWorkflowScript(script, { ...baseEnvironment, - REMOTE_TAGS: "v0.7.4\nv0.7.5\nv0.7.6\nv0.7.7\nv0.7.8\nv0.7.9\nv0.7.10\nv0.7.11\nv0.7.12\nv0.7.13\nv0.7.14\nv0.7.15\nv0.7.16\nv0.7.17", + REMOTE_TAGS: "v0.7.4\nv0.7.5\nv0.7.6\nv0.7.7\nv0.7.8\nv0.7.9\nv0.7.10\nv0.7.11\nv0.7.12\nv0.7.13\nv0.7.14\nv0.7.15\nv0.7.16\nv0.7.17\nv0.7.18", }); expect(superseded.exitCode).not.toBe(0); expect(`${superseded.stdout}${superseded.stderr}`).toContain( - "Tag v0.7.16 is not the newest stable tag v0.7.17", + "Tag v0.7.17 is not the newest stable tag v0.7.18", ); expect(await readFile(commandLog, "utf8")).not.toContain("npm publish"); expect(await Bun.file(publishMarker).exists()).toBe(false); @@ -670,11 +670,11 @@ import { isUtf8ByteLengthAtMost } from "./utf8-byte-boundary.js"; await rm(commandLog, { force: true }); const staleVersion = await runWorkflowScript(script, { ...baseEnvironment, - PUBLISHED_VERSIONS_JSON: '["0.7.4","0.7.17"]', + PUBLISHED_VERSIONS_JSON: '["0.7.4","0.7.18"]', }); expect(staleVersion.exitCode).not.toBe(0); expect(`${staleVersion.stdout}${staleVersion.stderr}`).toContain( - "@hraness/direct@0.7.16 is not newer than published stable 0.7.17", + "@hraness/direct@0.7.17 is not newer than published stable 0.7.18", ); expect(await Bun.file(publishMarker).exists()).toBe(false); diff --git a/skills/direct/references/install.md b/skills/direct/references/install.md index afa0eb7..9715aa5 100644 --- a/skills/direct/references/install.md +++ b/skills/direct/references/install.md @@ -21,9 +21,9 @@ global `direct` CLI. For a new installation, pin the reviewed public release: ```sh -bun add --dev @hraness/direct@0.7.16 +bun add --dev @hraness/direct@0.7.17 # or, in an npm project -npm install --save-dev @hraness/direct@0.7.16 +npm install --save-dev @hraness/direct@0.7.17 ``` The equivalent manifest entry is: @@ -31,7 +31,7 @@ The equivalent manifest entry is: ```json { "devDependencies": { - "@hraness/direct": "0.7.16" + "@hraness/direct": "0.7.17" } } ``` @@ -43,8 +43,8 @@ If the task starts with skill installation rather than a loaded skill, install the single repository skill with either command: ```sh -npx skills add hraness/direct#v0.7.16 -bunx skills add hraness/direct#v0.7.16 +npx skills add hraness/direct#v0.7.17 +bunx skills add hraness/direct#v0.7.17 ``` Restart or reload the agent runner if it does not discover newly installed diff --git a/src/tooling/bombadil-runner.ts b/src/tooling/bombadil-runner.ts index 09aa070..c3549cd 100644 --- a/src/tooling/bombadil-runner.ts +++ b/src/tooling/bombadil-runner.ts @@ -813,17 +813,18 @@ class BombadilArtifactPolicyError extends Error { } class LiveChromeDownloadRenameRetry extends Error { - public constructor( - public readonly completion: Readonly<{ - device: bigint; - inode: bigint; - runId: string; - size: number; - unobserved: boolean; - }>, - ) { + public readonly completion: Readonly<{ + device: bigint; + inode: bigint; + runId: string; + size: number; + unobserved: boolean; + }>; + + public constructor(completion: LiveChromeDownloadRenameRetry["completion"]) { super("Chrome download renamed during live artifact inspection"); this.name = "LiveChromeDownloadRenameRetry"; + this.completion = completion; } } diff --git a/tsconfig.json b/tsconfig.json index e518373..fd72317 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -51,6 +51,7 @@ "noUnusedParameters": true, "useUnknownInCatchVariables": true, "allowImportingTsExtensions": true, + "erasableSyntaxOnly": true, "isolatedModules": true, "skipLibCheck": true, "noEmit": true,