* fix(auth): keep a retired auth JSON from stranding a migrated store Runtime failed closed with AUTH_PROFILE_MIGRATION_REQUIRED whenever a retired credential file was present, even when the canonical SQLite store already held the agent's profiles. One leftover auth.json therefore made a fully migrated install unusable, and the gateway lifecycle preflight refused start/restart on top of it, so every channel and provider stayed offline until Doctor ran. A legacy file is now only fatal when the canonical store cannot serve credentials. Doctor's importer never overwrites a usable stored credential, so a file sitting beside a populated store is unarchived bytes, not pending migration: runtime logs a one-time warning and keeps serving. An empty store with a credential file still fails closed and never falls through to environment auth. Startup degrades that owner to configured-unavailable instead of refusing to boot, which lets the lifecycle preflight go away. * refactor(secrets): retire the auth-profiles.json vocabulary Auth profiles moved to SQLite, but operator-facing surfaces still named the retired JSON file. The duplicate-agentDir error told operators to copy auth-profiles.json to share credentials, which does nothing and lands the second agent in a migration-required state; `openclaw migrate plan codex` reported a target file that is never created; and the secrets picker labelled candidates with a filename that no longer exists. Renames the SecretTargetConfigFile discriminator to "auth-profile-store" and corrects the operator-facing text, the migrate plan target, and the docs that described the file as a live target. Genuine legacy-filename uses in doctor, the security fixer, and migration fixtures are unchanged. Also deletes resolveSecretPlanTargetByPath and ResolvedSecretPlanTarget from the plugin SDK. They have no callers in core, plugins, or tests, and the symbols are absent from the latest stable tag, so they carry no compatibility obligation and are removed rather than deprecated. Their inline parameter type was the only thing putting the retired filename on the public SDK surface. * improve(wizard): warn about device-code phishing The device-code prompt only warned against sharing the code, and only when an expiry was known. Device-code phishing works the other way around: the attacker starts the login and gets the victim to enter the attacker's code. Codes delivered over a chat channel are the risky case and carry no expiry hint, so the warning is now unconditional and covers received codes, matching the Codex CLI prompt. Also documents the Codex auth handoff: a subscription profile is installed as in-memory external auth rather than persisted, and token refresh is inverted so the refresh token stays in OpenClaw's store. * fix(test): make transcript read-failure injection order-independent server.sessions.compaction-read-errors.test.ts injected its failures with mockRejectedValueOnce, which fails the NEXT call to loadTranscriptEvents globally. Under --isolate=false a shard shares one worker, so any sibling transcript read could consume the one-shot rejection before the compaction RPC issued its own; compaction then ran against the real reader and returned ok, failing three assertions. This shard was already red on main; a prior repair fixed the mock's initialization order but left the call-order dependency. Key the injection on the seeded sessionId instead, so unrelated readers cannot consume it and the re-read case counts only its own session's reads. Also updates two expectations invalidated by this branch: the duplicate-agentDir remediation text, and the plugin SDK export ratchet, shrunk by the two retired secret-plan exports.
summary, read_when, title
| summary | read_when | title | |||
|---|---|---|---|---|---|
| Repository script entry points and compatibility notes |
|
Scripts Directory |
Scripts Directory
The scripts/ directory contains repository tooling used by local development,
CI, docs publishing, releases, Docker proof, and maintainer operations. Prefer
the package-script entry points in package.json when one exists, then read the
underlying script before running it directly.
Compatibility
Many scripts are stable paths referenced by package.json, GitHub Actions,
docs, and maintainer runbooks. Do not move, rename, or regroup scripts only to
improve taxonomy. A directory migration needs an explicit maintainer-approved
compatibility plan for package scripts, workflows, docs snippets, and any raw
script paths users may have copied.
This index is a discovery aid for the current flat layout. It does not define a new directory taxonomy.
Common Entry Points
| Area | Prefer | Notes |
|---|---|---|
| Build | pnpm build |
Runs scripts/build-all.mts; use specific build scripts only when debugging a build stage. |
| Changed checks | pnpm changed:lanes --json, pnpm check:changed |
Lane classification lives in scripts/changed-lanes.mjs; changed-file checks live in scripts/check-changed.mjs. |
| Docs | pnpm docs:list, pnpm docs:check-mdx, pnpm docs:check-links |
Backed by scripts/docs-list.js, scripts/check-docs-mdx.mjs, and scripts/docs-link-audit.mjs. |
| Formatting docs | pnpm format:docs:check |
Uses scripts/format-docs.mts; use write mode only when intentionally formatting docs. |
| Lint | pnpm lint, pnpm lint:core, pnpm lint:all |
Wrapper scripts keep oxlint behavior aligned with repo config. |
| Targeted tests | pnpm test <path-or-filter> or node scripts/run-vitest.mjs <path-or-filter> |
Avoid bare vitest; it can start watch mode. |
| Changed tests | pnpm test:changed |
Uses the repo's changed-test resolver instead of a broad Vitest run. |
| Docker proof | pnpm test:docker:all, pnpm test:docker:rerun, pnpm test:docker:timings |
Use the planner/rerun helpers before launching broad Docker work. |
| Live proof | pnpm test:live |
Live checks require the matching environment and credentials. |
| Release checks | pnpm release:check, pnpm release:beta, pnpm release:candidate |
Release scripts are maintainer workflows; read release docs before use. |
| GitHub reads | scripts/gh-read |
Uses a GitHub App read token when configured, leaving normal gh login for writes. |
| Commits | git add <files...> then git commit -m "<message>" |
Stage only the intended files for each commit. |
| Remote proof | node scripts/crabbox-wrapper.mjs ... |
Use when the current host lacks the required isolation, OS, device, or capacity; sync each run and reuse the lease. |
Script Families
check-*.mts/check-*.ts/ retainedcheck-*.mjs: guardrails for architecture, docs, package contents, boundaries, workflows, and generated artifacts.run-*.mjs/run-*.mts: stable wrappers and typed implementations for Node, Vitest, oxlint, tsgo, and environment setup.test-*.mts/ retainedtest-*.mjs/test-*.sh/test-*.ts: test planners, Docker lanes, live checks, and focused validation helpers.docs-*andcheck-docs-*: docs listing, link auditing, MDX checks, spellcheck, sync, and i18n glossary checks.release-*,openclaw-npm-*, andplugin-*-release-*: release preparation, package verification, and publishing helpers.docker-*,test-docker-*, andtest-live-*-docker.sh: Docker E2E planning, rerun, timing, and live/package lane helpers.gh-read*,label-*,sync-labels.ts, and PR helpers: GitHub read, labeling, and maintainer workflow support.generate-*,write-*,copy-*, andsync-*: generated docs, metadata, package surfaces, and build artifact support.lib/: shared helpers imported by script entry points.
Maintenance Rules
- Read
scripts/AGENTS.mdbefore changing scripts. - Keep package scripts, generators, generated-artifact checks, docs references, and workflow references aligned when touching a script path.
- Prefer existing wrappers instead of introducing a raw tool invocation.
- Add or update focused tests under
test/scripts/when changing script behavior.
See also Scripts for public-facing script guidance.