Skip to content

chore(repo): adopt project-template conventions - #87

Merged
PerfectPan merged 10 commits into
mainfrom
chore/adopt-project-template
Oct 5, 2026
Merged

PerfectPan merged 10 commits into
mainfrom
chore/adopt-project-template

Conversation

@PerfectPan

@PerfectPan PerfectPan commented Oct 5, 2026 •

Copy link
Copy Markdown
Owner

Summary

Bring agent-presence in line with project-template and agent-task-loop. One commit per change; the commit messages carry the details.

  • docs(workflow): replace rfcs/ with docs/specs/ + docs/plans/; implemented RFC content moves into docs/architecture.md, the unfinished midnight usage reset becomes Spec/Plan 0001 (Plan blocked on an open decision); drop CLAUDE.md; restructure AGENTS.md and CONTRIBUTING.md.
  • chore(repo): template review files (Review workflow, repo-checks.conf, pre-commit hook, PR/MR/issue templates, .editorconfig); neutral fixture paths so gh repo-checks repository passes.
  • build(deps): pnpm 12.8.1 with allowBuilds, pmOnFail back to its default so Vercel's own pnpm 12 downloads the pinned one, .node-version = 24 read by pnpm/setup@v3 in every workflow (CI caches the store), actions at latest major tags; remove the stray site/pnpm-workspace.yaml and site/pnpm-lock.yaml that broke pnpm -C site run docs:build.
  • build(deps): every npm dependency to latest (TypeScript 7, Vitest 5, Changesets 3 + changelog-github, Astro 7, @clack/prompts 1.8.1); @types/node stays on 24.
  • build(engines): engines.node >=22, engines.pnpm removed, with a changeset.
  • refactor(site) + build(lint) + style: @perfectpan/lint-config v0.3.2 (type-aware oxlint, oxfmt, shared node tsconfig), lint findings fixed without disabling rules (CI runs astro sync first so lint can type-check the site), then a separate mechanical reformat.
  • ci(release): changesets/action@v2, release PR chore(release): version packages, OIDC publish through pnpm release; the file stays publish.yml.

Validation

  • gh repo-checks repository: ok; gh repo-checks pr-title / pr-body on this title and body: ok.
  • pnpm install --frozen-lockfile (pnpm 12.8.1, Node 24): ok; lockfile has no mirror URLs.
  • pnpm format:check, pnpm lint, pnpm run typecheck: clean.
  • pnpm test: 40 files, 328 tests passed.
  • pnpm run build: ok. Emitted JS matches origin/main except the lint rewrites listed in the build(lint) commit; the style commit minifies to the same output.
  • pnpm -C site run docs:build: 21 pages. The rendered text matches origin/main except Starlight's new mobile "Menu" label, the Node.js 22 note, the neutral example path and the line layout of two oxfmt-formatted JSON examples.
  • npm pack --dry-run: same 268-file list as origin/main.
  • node dist/src/cli.js --help: prints usage.
  • CI (ubuntu, macOS), Review checks and the Vercel preview pass on the head commit; the preview serves the updated install guide.
  • Codex hook fed {"session_id":"smoke-session-1",...} under HOME="$(mktemp -d)": prints {}, exits 0, writes a running session to the temp ~/.agent-presence/state.json; the real home is untouched.

Risks

  • Node.js 20 users can no longer install the next release (minor changeset).
  • The release PR and the weekly pricing PR are opened with GITHUB_TOKEN, so CI needs a close/reopen before merge (documented in CONTRIBUTING).
  • The Task issue template's task label does not exist on GitHub yet; this PR does not create it.

PerfectPan and others added 2 commits October 5, 2026 19:17
Adopt the project-template Spec/Plan workflow and retire rfcs/.

- Add docs/specs/ and docs/plans/ with their README and template copied
  verbatim from project-template, and a docs/README.md map for this
  repository.
- Move the implemented behavior, invariants and limits that only the
  RFCs held into docs/architecture.md: provider id resolution (the
  default is magic-builder, which the Configuration section still
  called feishu-signature), the source table's handler contract and
  trust limits, registry-spec-only `source add`, usage windows,
  scanner rules and badge staleness, the Linux watcher decision and
  when to revisit it, and the log retention limits.
- Carry the one unfinished item, the Token Usage Statistics RFC's
  follow-up to reset the signature's usage tail at midnight while the
  machine is idle, into Spec 0001 and a Plan blocked on where the
  validity deadline travels.
- Remove CLAUDE.md; Claude Code reads AGENTS.md when it is absent.
- Restructure AGENTS.md and CONTRIBUTING.md after the template, keeping
  the repository's commands, hook and source model, release flow and
  the pricing snapshot update, and add the temporary-HOME rule for the
  installer scripts. Changesets, not hand edits, write CHANGELOG.md.
- Repoint the code comments that cited rfcs/ to docs/architecture.md.
- List docs/architecture.md and docs/assets in package.json `files`
  instead of all of docs/, so the Specs and Plans stay out of the npm
  package and the packed file list is unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Adopt the shared project-template review setup. The Review workflow and
the pre-commit hook run the PR title, PR description and repository
checks from PerfectPan/gh-repo-checks (the v1 action in CI, the gh
extension locally) instead of copied scripts.

- Copy review.yml, .github/repo-checks.conf, .githooks/pre-commit,
  scripts/install-git-hooks.sh, .editorconfig and the bug, feature and
  task issue templates verbatim. Issue titles start with [Bug]: ,
  [Feature]:  or [Task]: .
- Replace the PR template with the template's Summary, Validation and
  optional Risks, listing this repository's gates, and add the matching
  GitLab MR template; the repository check keeps the two in sync.
- Replace the personal-looking home paths in test fixtures and the
  source-plugin example in the docs site with neutral paths, so the
  repository check passes.
- Add the review evidence, PR expectations, license, repository
  checks, local hooks and repository setup sections to AGENTS.md and
  CONTRIBUTING.md. The setup section notes that the `task` label the
  Task template applies does not exist on GitHub yet.

SECURITY.md already carries the template text plus this repository's
credential and supply-chain notes, so it stays as is.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
agent-presence Ready Ready Preview Oct 5, 2026 12:23pm UTC

PerfectPan and others added 7 commits October 5, 2026 19:53
Pin pnpm 12.8.1 in packageManager and reinstall with it. Resolved
package versions are unchanged; the lockfile gains pnpm's own pin.

pnpm 10 to 12 changes handled:

- pnpm 11 removed onlyBuiltDependencies. pnpm 12 still accepts the key
  without error but ignores it, so a fresh install failed with
  ERR_PNPM_IGNORED_BUILDS for esbuild and sharp. pnpm-workspace.yaml
  now uses allowBuilds: esbuild is allowed (its postinstall verifies
  the binary Vite and Astro run) and sharp is denied (its prebuilt
  @img/sharp-* binaries make the source-build script unnecessary).
- The other policy keys (minimumReleaseAge 1440 and its strictness
  settings, blockExoticSubdeps, strictDepBuilds, engineStrict,
  verifyDepsBeforeRun) are current pnpm 12 settings, checked against
  pnpm 12's ERR_PNPM_UNRECOGNIZED_WORKSPACE_SETTINGS, which rejects
  unknown keys in a pinned project. They stay explicit; the comment on
  minimumReleaseAge says to pick an older version instead of lowering it.
- pmOnFail: error goes back to pnpm's default, download. With it, any
  pnpm other than exactly 12.8.1 fails with ERR_PNPM_BAD_PM_VERSION
  (reproduced with pnpm 12.1.0), which is what the Vercel build image
  runs into: it picks its own pnpm 12 from packageManager. With the
  default, that pnpm downloads and runs 12.8.1, so the pinned version
  still does every install.
- Remove site/pnpm-workspace.yaml and site/pnpm-lock.yaml, leftovers
  from an install inside site/. site is a project of the root workspace
  and the root lockfile has its importer, but the nested
  pnpm-workspace.yaml made `pnpm -C site run docs:build` treat site/ as
  its own workspace, run an install there and fail with
  ERR_PNPM_IGNORED_BUILDS. The site build now runs against the root
  install. vercel.json is unchanged.

.node-version holds the Node.js Active LTS major, 24. CI, the release
job and the pricing workflow install pnpm and that Node.js through
pnpm/setup@v3 (CI also caches the pnpm store), replacing
pnpm/action-setup and setup-node; the release job needs no
registry-url, because pnpm publishes to publishConfig.registry.
Actions move to their latest major tags: actions/checkout@v7 and
peter-evans/create-pull-request@v8. checkout v7 only refuses fork PR
checkouts under pull_request_target and workflow_run, which no
workflow uses; create-pull-request v8 only moves to the Node 24
runtime.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Upgrade every npm dependency in the root package and site/ to its newest
release that pnpm's one-day minimumReleaseAge allows, majors included.

- @clack/prompts 1.3.0 -> 1.8.1, the one runtime dependency, still
  pinned exactly. Its engines field asks for Node.js >=20.12.
- TypeScript 6 -> 7.0.2, the version agent-task-loop uses. The emitted
  JavaScript is byte-identical to the TypeScript 6 build apart from the
  two comments the previous commit changed; only source maps and
  declaration formatting differ.
- Vitest 4 -> 5.0.3. All 328 tests pass unchanged.
- @changesets/cli 2 -> 3.0.3 with @changesets/changelog-github, and
  .changeset/config.json shaped like agent-task-loop's: schema 4.0.0,
  changelog-github for PerfectPan/agent-presence, and private packages
  (the docs site) neither versioned nor tagged, which is also the v3
  default.
- Astro 6 -> 7.3.5, Starlight 0.40 -> 0.42.5, sharp 0.35.5. The site
  builds the same 21 pages; their rendered text matches the Astro 6
  build except for the mobile "Menu" label newer Starlight adds.

Held back: @types/node stays on 24 (24.19.1), the Node.js line in
.node-version that CI runs, instead of 26.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Node.js 20 is end of life, so engines.node moves from >=20 to >=22,
the lowest maintained LTS line. Nothing requires a higher floor:

- The runtime dependency, @clack/prompts 1.8.1, declares node >=20.12.
- A scan of src/ and scripts/ finds no API newer than Node.js 22
  (fetch, dynamic import and the usual fs/url builtins).
- node:sqlite, the one newer builtin, stays a guarded dynamic import:
  Node.js 22.0-22.12 expose it only behind --experimental-sqlite. Its
  code comment and docs/architecture.md now say that instead of the
  old >=20 reasoning.

The dev toolchain (Vitest 5, Changesets 3, Astro 7) needs Node.js
22.12 or newer, which the .node-version major 24 satisfies.

engines.pnpm goes away: it only describes developing this repository,
which packageManager already pins, and agent-task-loop's published
packages do not declare it either. The changeset records both for users
as a minor release, and the README and install guide state the
Node.js 22 requirement.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@perfectpan/lint-config requires kebab-case file names, and oxlint
checks the script part of .astro files. Rename the six components and
the landing layout with git mv and update every import, the two
Starlight component overrides in astro.config.mjs and the paths
DESIGN.md mentions. Astro takes a component's name from its import, not
its file, so the pages build to the same text.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Add @perfectpan/lint-config v0.3.2 (git dependency) with oxlint,
oxlint-tsgolint and oxfmt, the same way agent-task-loop did.

- .oxlintrc.json extends the shared config: type-aware rules and type
  check, warnings fail, curly: all, kebab-case file names, at most 1000
  lines per non-test file. It ignores only build output (dist/,
  site/dist/, site/.astro/); no rule is turned off.
- oxfmt.config.ts spreads the shared options and keeps single quotes.
  It skips the files copied verbatim from the project template and two
  generated files, CHANGELOG.md (Changesets) and
  src/usage/litellm-pricing.json (`pnpm run update-pricing`), so the
  weekly pricing PR cannot fail the format check.
- tsconfig.json extends the shared node tsconfig and keeps only types,
  the output settings and include. noUncheckedIndexedAccess,
  noUnusedLocals/Parameters and verbatimModuleSyntax stay on.
- Scripts lint, format and format:check; CI runs format:check after
  install and lint after typecheck. Lint also type-checks the docs
  site, whose modules import `astro:content`, so CI first runs the new
  site script docs:sync (`astro sync`) to generate those types.

Fix what the new checks report, behaviour-preserving (the emitted
JavaScript differs only in the rewritten lines below):

- noUncheckedIndexedAccess: uninstall-codex-hook iterates
  Object.entries instead of re-indexing; collectWindowUsage summarises
  each source where its scan resolves instead of indexing a parallel
  array; resolvePricing and the usage table guard lookups whose keys
  come from the same object; tests use optional chaining or `!`.
- Empty spread fallbacks (`...(x ?? {})`) become `...x`.
- billableSources binds scanUsage from the resolved plugin without
  holding the method unbound; registry tests check capabilities with
  `typeof`.
- scan-gemini imports Dirent with `import type`, so
  verbatimModuleSyntax does not leave an empty `import {} from
  'node:fs'` in the output.
- Tests: every vi.fn() mock gets the type of the function it replaces;
  fetch mocks are Mock<typeof fetch>; fs rejections assert ENOENT; the
  platform-conditional integration tests use it.skipIf instead of an
  aliased `test`.
- Site: astro.config.mjs types its head entries as Starlight's head
  config (they were inferred as plain strings under @ts-check), and
  dev-grab.js marks its fire-and-forget copy() with void.

curly findings are left to the next commit, which only runs
`oxlint --fix` and oxfmt.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Output of `oxlint --fix` for `curly: all`, then `oxfmt`, plus two
layout-only edits the tools need:

- oxfmt does not format .astro files, so the braces `oxlint --fix`
  inserted on one line in the inline scripts of language-select,
  theme-select and live-terminal are expanded by hand.
- oxfmt collapses a fenced code block that sits directly inside a JSX
  tag in MDX into inline code. The install guides' <TabItem> blocks
  get a blank line around each fence, which MDX renders the same, so
  oxfmt keeps them as code blocks.

The emitted JavaScript minifies to the same output as the previous
commit's build, and every docs-site page renders the same text.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Move publish.yml to changesets/action@v2, the line that supports
Changesets v3, and to the release conventions agent-task-loop uses:

- The release PR and its commit are titled `chore(release): version
  packages`, the title the repository conventions name for release
  PRs, instead of `chore: release package`.
- The version step runs `pnpm version-packages`. The script was named
  `version`, which npm and pnpm also run as a lifecycle hook during
  `pnpm version`.
- `pnpm release` (`changeset publish`) still runs inside the action, so
  the action keeps pushing the tag and creating the GitHub Release as
  before; pnpm publishes through npm trusted publishing (OIDC) with
  provenance and needs no token or .npmrc. Release commits and tags go
  through the GitHub API (v2's default, v1's github-api commit mode).
- fetch-depth: 0 lets changelog-github find the commit that added each
  changeset.

The workflow file stays publish.yml, which npm's trusted-publisher
setting is bound to. CONTRIBUTING.md and .changeset/README.md describe
the new PR title, the close/reopen needed before CI runs on bot PRs
(release and pricing snapshot), and the publish step.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Follow-ups from the review of this PR:

- The @clack/prompts changeset says that since clack 1.6 note() no
  longer dims its content, so the boxed hints (login QR code, setup's
  signature URL and Magic-Builder token help, the source add trust
  notice) render at full brightness.
- README.md, README.zh-CN.md and the shipped skill install from a
  checkout with `pnpm install --frozen-lockfile`, matching AGENTS.md,
  CONTRIBUTING.md and CI now that the allowBuilds allowlist decides
  which dependency build scripts run. docs/architecture.md names that
  allowlist and minimumReleaseAge, not --ignore-scripts, as the
  install-time controls a source handler's runtime import() bypasses.
- The opencode scanner comment and docs/architecture.md give the exact
  node:sqlite history: absent on Node.js 22.0-22.4, behind
  --experimental-sqlite on 22.5-22.12, unflagged from 22.13. No code
  change.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@PerfectPan
PerfectPan merged commit fdfee49 into main Oct 5, 2026
7 checks passed
@PerfectPan
PerfectPan deleted the chore/adopt-project-template branch October 5, 2026 12:27

This branch was successfully deployed

1 active deployment
Preview — f955469d Deployed Oct 5, 2026 by vercel[bot]
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.

1 participant