Skip to content

ci: switch to pnpm; deps to npm registry; clear lint debt#5

Merged
brandon-fryslie merged 4 commits into
mainfrom
bf/ci-pnpm-and-deps
May 16, 2026
Merged

ci: switch to pnpm; deps to npm registry; clear lint debt#5
brandon-fryslie merged 4 commits into
mainfrom
bf/ci-pnpm-and-deps

Conversation

@brandon-fryslie

Copy link
Copy Markdown
Contributor

Summary

CI on main has been red since at least 2026-04-26. Three layered issues:

  1. npm ci fails — workflow uses npm but the canonical lockfile is pnpm-lock.yaml. package-lock.json had been stale since May 11 (every dep update since then went only into the pnpm lockfile).
  2. file:../sibling depspackage.json pointed @promptctl/go-template-js and rich-js at sibling directories that only exist on the maintainer's laptop, so even a pnpm install can't resolve them on CI.
  3. Lint never ran clean — 64 pre-existing lint errors hid behind the install failure.

[LAW:one-source-of-truth] is the structural diagnosis: two lockfiles, two package-name aliases for the same package, two sources of optionalDependencies truth.

Changes (three commits)

  • ci: Switch workflow to pnpm/action-setup@v4 + pnpm install --frozen-lockfile + pnpm run ... in both test and release jobs. Delete package-lock.json. Replace file:../ deps with registry versions (@promptctl/go-template-js@^0.3.0, @promptctl/rich-js@^0.2.0). Drop placeholder optionalDependencies from source — scripts/release.mjs already injects them with the real version at publish time.
  • refactor: Rename rich-js@promptctl/rich-js across imports/types/jest config. Adapt to @promptctl/go-template-js@0.3.0: set missingKey: "error" in createCcCandybarEngine (0.3.0 changed the default policy to return "<no value>" instead of throwing MissingFieldError). Fix oklch.ts:40 to use the JS-representable literal.
  • chore(lint): Add Node globals to eslint config; preserve PrunedRaw/UsageCounts as type aliases (load-bearing for structural assignability at extractModelId); replace inline import() type with top-level import type; prettier autoformat sweep.

Test plan

Local verification on bf/ci-pnpm-and-deps:

  • pnpm install --frozen-lockfile succeeds
  • pnpm run lint → 0 errors (1 warning, pre-existing, in loader.ts:425)
  • pnpm run typecheck → clean
  • pnpm test → 30/30 suites, 653/653 tests pass
  • pnpm run build → clean
  • pnpm run check:protocolPROTOCOL_VERSION=2 (TS and Rust agree)
  • CI green on this PR (watch gh pr checks)
  • After merge, rebase bf/single-daemon-flock and confirm PR fix(daemon): enforce single-daemon invariant via atomic bind() (kz8.1) #4 goes green

Follow-up

  • bf/single-daemon-flock (PR fix(daemon): enforce single-daemon invariant via atomic bind() (kz8.1) #4) is parked pending this fix; rebase will pick up CI parity automatically.
  • The PrunedRaw / extractModelId structural-typing escape is a [LAW:types-are-the-program] exception that should be untangled in a follow-up — tighten extractModelId to take PrunedRaw and drop the dead entry.model_id branch.

[LAW:one-source-of-truth] pnpm is the canonical package manager
(pnpm-lock.yaml). package-lock.json was a duplicate, stale lockfile
breaking every CI run since at least 2026-04-26.

Changes:
- release.yml: actions/setup-node@v4 + pnpm/action-setup@v4; install
  with `pnpm install --frozen-lockfile`; replace `npm run`/`npm ci`
  with pnpm equivalents in both `test` and `release` jobs.
- package.json: replace file:../go-template-js with ^0.3.0 and
  file:../rich-js with @promptctl/rich-js@^0.2.0 (both now published).
  Drop placeholder optionalDependencies — scripts/release.mjs already
  injects them with the real version at publish time, so keeping
  PLACEHOLDER entries in source was a duplicate source of truth.
- pnpm-lock.yaml: regenerated. package-lock.json: deleted.
Import-only rename to match the registry-published package name.
Replaces the local `rich-js` alias (pointing at `file:../rich-js`)
with the canonical scope. Also threads through:

- jest.config.js moduleNameMapper + transformIgnorePatterns
- src/themes/rich-js-theme-data.d.ts ambient module declaration

Adapts to @promptctl/go-template-js@0.3.0:

- Set `missingKey: "error"` in createCcCandybarEngine. 0.3.0's default
  policy returns the literal string "<no value>" for missing scope
  fields; callers (SourceRegistry, segments) depend on the prior
  MissingFieldError contract to drive varDefault/defaultEmptyValue.
  [LAW:no-defensive-null-guards] enforces the throw at the boundary.

- src/themes/oklch.ts: write the JS-representable value
  (1.0000000095444297, not 1.0000000095444298) so no-loss-of-precision
  lint stops firing.
Bring lint to zero errors so CI's lint step passes.

- eslint.config.mjs: add missing Node globals (NodeJS, BufferEncoding,
  setTimeout/clearTimeout/setInterval/clearInterval) to the manual
  allowlist. These have been firing as `no-undef` errors across daemon
  and segments code for weeks.

- src/utils/claude.ts: PrunedRaw and UsageCounts intentionally stay as
  `type` aliases (not `interface`) so they remain structurally
  assignable to `Record<string, unknown>` at the extractModelId
  boundary in segments/pricing.ts. The
  @typescript-eslint/consistent-type-definitions rule is disabled
  per-declaration with a comment explaining the load-bearing reason.

- src/segments/pricing.ts: replace inline `import("...").PrunedRaw`
  with a top-level `import type { PrunedRaw }` now that the type-alias
  is preserved upstream.

- Prettier autoformat sweep across dsl-loader, daemon/server,
  template-engine/index, schema-validator (pre-existing drift).
Copilot AI review requested due to automatic review settings May 16, 2026 06:45

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Restores green CI by switching the workflow to pnpm (matching the canonical pnpm-lock.yaml), replacing file:../sibling deps with published @promptctl/* versions, and clearing the lint debt that was hidden behind the install failure. The refactor renames the rich-js import specifier to @promptctl/rich-js everywhere and adapts to the new go-template-js 0.3.0 default by setting missingKey: "error" so existing MissingFieldError-driven flows keep working.

Changes:

  • CI: workflow uses pnpm/action-setup@v4 + pnpm install --frozen-lockfile; package-lock.json removed; sibling file:.. deps replaced with @promptctl/go-template-js@^0.3.0 and @promptctl/rich-js@^0.2.0; placeholder optionalDependencies dropped (re-injected by scripts/release.mjs).
  • Refactor: all rich-js imports/types/jest mappings renamed to @promptctl/rich-js; createCcCandybarEngine pins missingKey: "error" to preserve throw-on-missing behavior; oklch.ts literal adjusted to a JS-representable value.
  • Lint: eslint globals extended with BufferEncoding/NodeJS/timer functions; PrunedRaw/UsageCounts kept as type aliases with explanatory comment and rule-disable; inline import() type replaced with top-level import type; prettier autoformat sweep.

Reviewed changes

Copilot reviewed 23 out of 27 changed files in this pull request and generated no comments.

Show a summary per file
File Description
.github/workflows/release.yml Adds pnpm setup, switches install/lint/build/test/protocol-check commands to pnpm in both jobs.
package.json Replaces sibling file:.. deps with registry versions; removes placeholder optionalDependencies.
pnpm-lock.yaml Updated entries for @promptctl/go-template-js@0.3.0 and @promptctl/rich-js@0.2.0.
jest.config.js Rewrites moduleNameMapper and transformIgnorePatterns to the scoped package path.
eslint.config.mjs Registers Node-typing/timer globals to silence pre-existing no-undef errors.
src/template-engine/engine.ts Splits imports; sets missingKey: "error" to retain throw-on-missing semantics under go-template-js 0.3.0.
src/template-engine/{layout,colors,cells,index}.ts Renamed imports + prettier reformat.
src/themes/{palette-registry,cascade,oklch,rich-js-theme-data.d.ts} Renamed module specifiers; oklch.ts literal trimmed to a JS-exact value.
src/render/strip.ts, src/demo/app.ts, src/var-system/sources.ts Renamed imports plus minor formatting.
src/segments/pricing.ts, src/utils/claude.ts Replaces inline import() type with top-level import type; documents the type-vs-interface requirement with an eslint-disable.
src/utils/schema-validator.ts, src/daemon/server.ts, src/config/dsl-loader.ts Prettier reformatting; NodeInfo switched to interface.
test/{colors,segment-cells,segment-colors,segment-layout}.test.ts Updated import specifiers to @promptctl/rich-js.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

GitHub-hosted macOS runners (especially x86_64 macos-13) have been
queueing for hours and blocking PR checks. All four targets — darwin-{x64,arm64}
and linux-{x64,arm64} — now build on ubuntu-latest using cargo-zigbuild,
which uses zig as the cross-linker and supplies the macOS SDK stubs
needed for libc+libSystem-only binaries like this one.

The rust-client crate has no macOS framework deps (Cargo.toml: serde,
serde_json, libc); cargo-zigbuild handles it cleanly.

No more macOS runners in this workflow.
@brandon-fryslie brandon-fryslie merged commit 2dd1398 into main May 16, 2026
6 checks passed
brandon-fryslie added a commit that referenced this pull request Jun 10, 2026
…y by type (cje) (#100)

Sheriff finding #5 [LAW:no-silent-failure]: a time var declaring
cache: watch_file / depends_on / key / never passed the loader, then
renderDsl silently coerced it to the default 1s TTL — the config's
stated meaning replaced with no diagnostic.

TimeVarDecl.cache narrows to TtlCacheDecl, so the illegal form is
unrepresentable past the load boundary [LAW:types-are-the-program].
The loader's TIME_FIELDS uses a ttl-only OneOfPresentSchema sharing
CACHE_SCHEMA's own ttl arm — one declaration source feeding both the
validator and the emitted JSON schema (regenerated). The render-time
'ttl' in guard and the orphaned follow-up-ticket comment delete; the
TTL mapping is total.

Closes brandon-config-validation-cje.

Co-authored-by: elton-prawn <264370887+elton-prawn@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants