Thanks for your interest in Basou! Basou is in a pre-1.0 stage — the
scoped @basou/* packages are published to npm and dogfood-ready, the
public APIs are still stabilizing, and we're collecting feedback from a
small set of trial users before opening contributions broadly. This
document describes how to set up the project, the change conventions we
follow, and the easiest way to report problems while we're in this state.
The fastest path right now is to open an issue on github.com/basou-dev/basou/issues using one of the templates:
- Bug report — when the CLI errors out, prints something
surprising, or
pnpm testfails on a fresh checkout. Please run through the Quickstart sanity-check checklist first — if any of those four lines fails, mention which one in the issue title. - Feature request / UX friction — when something works but is
unintuitive (e.g.
basou statusprinted a confusing label, a spec section is missing, a command spelling surprised you).
Security-sensitive issues should not go through the public tracker — see Security policy below.
git clone https://github.com/basou-dev/basou.git
cd basou
pnpm install
pnpm -r build
pnpm test # all green at HEAD; baseline noted in CHANGELOG.mdPrerequisites:
- Node.js >= 20.10.0 (
engines.nodein the rootpackage.json) - pnpm >= 8.15.0
- Git
After the first build, pnpm --filter @basou/cli link --global
exposes a basou binary on your $PATH. The
quickstart walks through the rest
end-to-end.
- TypeScript with
strict: true. We useunknown+ type guards rather thanany;enumis avoided in favour of union literals;interfaceis avoided in favour oftypefor consistency. - ESM throughout. Relative imports end in
.js(per the TypeScript ESM contract); external packages are imported without an extension. - Named exports only (the CLI entry point is the only default-export exception).
pnpm lint(= biome) is the source of truth for formatting and lint;pnpm typecheckfor types. Both must pass on every pull request.pnpm test(= vitest) runs each package's suite; new features land with tests in the same commit. CI runspnpm test:coverage, which additionally enforces a per-package coverage ratchet floor (packages/{core,cli,sdk}/vitest.config.ts): a PR that drops coverage below the floor fails. When your tests raise coverage, raise the floor in the same PR — floors only ever move up. The shared measurement policy lives invitest.coverage.ts.- Error messages stay pathless on the CLI surface. basou maintains a "no absolute paths in stderr" contract, and a workspace-write-time path sanitizer follows the same principle. See docs/spec/ for the full rules.
- English-only convention: Commit messages (subject + body), pull
request titles and descriptions, issue text, GitHub Discussions, and
the bundled
.github/issue / PR templates are all written in English. This follows the project's OSS global accessibility stance — English as a lingua franca for global contributors and users — and is not exclusion of any specific language. The same convention applies to comments inside.github/workflows/*. The one exception is theAGENTS.mdsymlink at the repository root: its target lives in the internal planning repository, is git-ignored from this repository, so it follows that repository's language conventions (Japanese) rather than this one. - Commit prefix:
basou:for source / behaviour changes,docs:for documentation. Body explains the why, not just the what. - One commit, one topic. Avoid bundling unrelated fixes.
- CHANGELOG.md entries live in the
## Unreleasedsection; promote to a versioned section as part of the release commit. CI refuses a pull request that edits anything from the first released-version heading down — two PRs appending at the same position once merged CLEAN and silently left one entry inside an already-published section. - Pull request titles should be a single declarative sentence
("Fix Lock-is-held message wording" rather than "WIP"). The PR
body uses the template that auto-populates from
.github/PULL_REQUEST_TEMPLATE.md. - We do not sign commits in this repo today. AGENTS.md tooling may attach a Co-Authored-By trailer; that's expected and stays.
mainis the only long-lived branch.- Topic branches use
<area>/<short-slug>(e.g.cli/session-start-label,docs/quickstart-sanitize-note). - Force-push is allowed on your own topic branch before review;
never on
main.
- CLI subcommands: add an integration test in
packages/cli/src/commands/<name>.test.tsthat exercises the happy path plus at least one failure mode. - Core APIs: unit-test in
packages/core/src/.../*.test.tsnext to the implementation. The storage layer in particular has a per-file test fixture pattern we ask new code to follow. - Schema changes: round-trip the new shape through its
*.schema.test.tsfile with a positive and a strict-mode rejection case.
If you're unsure what tests to write, open a draft PR — we'd rather discuss the test plan than have you guess.
-
Land all
## Unreleaseditems onmain. -
Promote the section header (
## Unreleased→## X.Y.Z — YYYY-MM-DD). -
Bump
versionin all four package manifests in lockstep:packages/core/package.json,packages/cli/package.json,packages/sdk/package.json, andpackages/basou/package.json(thebasouinstaller tracks the same version even though it is not yet auto-published — see docs/release-checklist.md). -
pnpm install(refreshespnpm-lock.yaml), thenpnpm -r build && pnpm typecheck && pnpm test && pnpm lint. -
Commit as
basou: Release vX.Y.Z (<headline>). -
git tag -a vX.Y.Z -m "..."with a short summary. -
Push the branch and land the bump on
main(through a PR, like any other change). -
Smoke-test the release workflow while the dry-run window is open — once, from
main, before the tag is pushed:gh workflow run release.yml --ref main -f dry_run=true
This runs
verify, packs each tarball, and completes the npm OIDC handshake without publishing anything. It only passes inside that window:pnpm publish --dry-runstill asks the registry, so as soon asmain's version exists on npm the run fails withYou cannot publish over the previously published versions: X.Y.Z. That is how the 2026-09-04 attempt failed — it ran against amainstill at the already-published0.38.0, and every step before the registry check had passed. There is no way to smoke-test the workflow outside the window, so run it here or not at all. -
Push the tag.
-
(Once npm publish is enabled:)
pnpm -r publish --access public. See docs/release-checklist.md for the dry-run + tarball verification step that should run before this. -
Merge the docs-site bump PR the release workflow opened, and read the version back off the live site. The workflow opens that PR on its own but nobody merges it on its own, and an unmerged one is invisible: the release looks complete from every angle except the site. That happened with
0.36.0-- the PR sat open and basou.dev served the previous version for two days, and it was only noticed because the NEXT release's PR happened to overwrite the same files. A release is not done until the published version, the GitHub release, and the site all say the same thing.That job can also fail on a registry propagation race: it retries the install four times over about a minute, and npm's CDN sometimes takes longer than that to serve the version just published.
0.39.0failed this way withERR_PNPM_NO_MATCHING_VERSION ... The latest release of @basou/cli is "0.38.0"while the publish jobs beside it had all succeeded. Publishing is already done at that point, so the remedy is to re-run the failed job once the registry answers -- never to re-tag:npm view @basou/cli@X.Y.Z version # wait until this answers gh run rerun <run-id> --failed
If you find an issue that allows leaking machine-private paths,
secrets, or local-file contents into .basou/ — or any other
class of issue that has security implications — please do not
open a public issue. Instead, report it privately via GitHub
Security Advisories
(https://github.com/basou-dev/basou/security/advisories/new) or
by mailing hello@basou.dev. Acknowledgement within 3 business
days is the goal.
This project adopts the Contributor Covenant 2.1. By participating you agree to abide by its terms.
By contributing you agree that your contributions will be licensed under the Apache 2.0 license that covers this project.