@biffo/cli 0.109.1 → 0.109.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,9 +8,9 @@ name: CI
8
8
 
9
9
  on:
10
10
  push:
11
- branches: [main]
11
+ branches: [dev]
12
12
  pull_request:
13
- branches: [main]
13
+ branches: [dev]
14
14
 
15
15
  concurrency:
16
16
  group: ${{ github.workflow }}-${{ github.ref }}
@@ -0,0 +1,71 @@
1
+ # Rules of Engagement for AI Agents
2
+
3
+ These rules are **binding for every automated coding agent** working in this
4
+ repository — Claude Code, Codex, Cursor, or any other. They are tool-agnostic:
5
+ express everything as plain `git` / `gh` / `pnpm` / `uv` commands. Tool-specific
6
+ guidance belongs in that tool's own file (e.g. `CLAUDE.md`), which imports this
7
+ one rather than restating it.
8
+
9
+ This is a **Biffo satellite repo** (a plugin or sibling app), separate from the
10
+ core project it extends. It follows the same engagement rules as every Biffo
11
+ repo; only its product differs.
12
+
13
+ ## 1. One integration branch: `dev`
14
+
15
+ - **`dev` is the integration branch** — you branch from it and open every PR back
16
+ into it. There is one environment and no production, so there is one branch.
17
+ `gh repo view --json defaultBranchRef` confirms it; if it reports anything other
18
+ than `dev`, flag it rather than working around it.
19
+ - **All changes land via PR.** No direct commits to `dev`, no force-pushes to it.
20
+ Branch protection stays on.
21
+ - Never leave the primary checkout parked on a feature branch or let it fall
22
+ behind — keep it on `dev`, no more than a `git fetch` behind, and do the work
23
+ in worktrees (§2).
24
+
25
+ ## 2. Work in an isolated worktree
26
+
27
+ - **Always start from a freshly-fetched `dev`:** `git fetch origin`, then
28
+ `git worktree add .worktrees/<name> -b <type>/<slug> origin/dev`. Never branch
29
+ from a stale local ref.
30
+ - **Install dependencies in the new worktree before working** — `uv sync` and/or
31
+ `pnpm install`, so the local gates (pre-push checks, lint-staged) run against
32
+ fresh deps, not a stale `.venv`/`node_modules`.
33
+ - **One worktree per unit of work**, under the git-ignored `.worktrees/`.
34
+ - **Clean up when the PR merges:** `git worktree remove .worktrees/<name>`, then
35
+ let the branch be deleted. Keep `git worktree list` short and every entry live.
36
+
37
+ ## 3. Commits
38
+
39
+ - **Conventional Commits** (`feat`, `fix`, `chore`, `docs`, `test`, `infra`,
40
+ `security`, `refactor`, `perf`, `ci`), enforced by commitlint.
41
+ - Tag your commits with your agent's own `Co-Authored-By:` trailer.
42
+ - Keep commits and PRs **scoped to one concern**.
43
+
44
+ ## 4. Pull requests
45
+
46
+ - Link the issue the PR resolves (`Closes #N`) and describe what changed and why.
47
+ - Mark a PR **ready** (not draft) when it is meant to merge.
48
+ - Behavior changes ship **with tests**. Don't reduce coverage to make CI pass.
49
+
50
+ ## 5. Merging — never merge red
51
+
52
+ - Get CI green and confirm it: `gh pr checks <N>`. A green local run is not
53
+ sufficient — verify the actual PR checks.
54
+ - **Squash-merge, delete the branch, remove the worktree:**
55
+ `gh pr merge <N> --squash --delete-branch`.
56
+
57
+ ## 6. Push honestly, and verify the remote has your commit
58
+
59
+ - **Push with the exit status visible:** `git push origin HEAD; echo $?`. A pipe
60
+ (`git push | tail`) reports the pipe's status, not git's — a rejected push then
61
+ reads as success and the commit is silently lost. Never trust a "pushed"
62
+ message printed unconditionally after a pipe.
63
+ - **Confirm the remote actually has the commit before relying on it,** especially
64
+ before merge: `git log origin/<branch> -1`. A green PR page is not proof your
65
+ latest local commit reached it.
66
+
67
+ ## 7. Security
68
+
69
+ - **Never commit secrets** (keys, tokens, credentials, `.env` values).
70
+ - **Never silently disable a security gate.** If one must be loosened, do it in
71
+ the open and raise a tracking issue to restore it.
@@ -0,0 +1,15 @@
1
+ # AI Assistant Context
2
+
3
+ The tool-agnostic rules of engagement for **all** automated agents (integration
4
+ branch, worktrees, commits, PRs, merging, honest pushes, security) live in
5
+ [`AGENTS.md`](AGENTS.md) and are imported below. They are binding for any change
6
+ in this repo; `AGENTS.md` is the single source of truth.
7
+
8
+ @AGENTS.md
9
+
10
+ ## What this repo is
11
+
12
+ A **Biffo plugin** — code that extends a core Biffo project, distributed and
13
+ mounted by it. See the core project's ADR-0003 (plugin system) and ADR-0021
14
+ (shared plugin hosting) for how a plugin is installed and run. This repo carries
15
+ the plugin's own manifest (`biffo.plugin.json`), source, and tests.
@@ -12,9 +12,9 @@ name: CI
12
12
 
13
13
  on:
14
14
  push:
15
- branches: [main, dev, staging]
15
+ branches: [dev, staging]
16
16
  pull_request:
17
- branches: [main, dev, staging]
17
+ branches: [dev, staging]
18
18
  # Manual re-run, matching the core project's CI. Without this there is no way
19
19
  # to trigger CI on a protected branch without pushing to it — and a sibling
20
20
  # repo has the same branch protection, so the same recovery gap. See #293.
@@ -2,9 +2,9 @@ name: 'CodeQL'
2
2
 
3
3
  on:
4
4
  push:
5
- branches: [main, dev, staging]
5
+ branches: [dev, staging]
6
6
  pull_request:
7
- branches: [main, dev, staging]
7
+ branches: [dev, staging]
8
8
  schedule:
9
9
  # Weekly catch-up scan (Tuesday 05:17 UTC) for issues that land outside
10
10
  # PR review (e.g. direct merges onto a branch).
@@ -10,7 +10,7 @@ name: Deploy
10
10
 
11
11
  on:
12
12
  push:
13
- branches: [dev, staging, main]
13
+ branches: [dev, staging]
14
14
  workflow_dispatch:
15
15
  inputs:
16
16
  environment:
@@ -0,0 +1,71 @@
1
+ # Rules of Engagement for AI Agents
2
+
3
+ These rules are **binding for every automated coding agent** working in this
4
+ repository — Claude Code, Codex, Cursor, or any other. They are tool-agnostic:
5
+ express everything as plain `git` / `gh` / `pnpm` / `uv` commands. Tool-specific
6
+ guidance belongs in that tool's own file (e.g. `CLAUDE.md`), which imports this
7
+ one rather than restating it.
8
+
9
+ This is a **Biffo satellite repo** (a plugin or sibling app), separate from the
10
+ core project it extends. It follows the same engagement rules as every Biffo
11
+ repo; only its product differs.
12
+
13
+ ## 1. One integration branch: `dev`
14
+
15
+ - **`dev` is the integration branch** — you branch from it and open every PR back
16
+ into it. There is one environment and no production, so there is one branch.
17
+ `gh repo view --json defaultBranchRef` confirms it; if it reports anything other
18
+ than `dev`, flag it rather than working around it.
19
+ - **All changes land via PR.** No direct commits to `dev`, no force-pushes to it.
20
+ Branch protection stays on.
21
+ - Never leave the primary checkout parked on a feature branch or let it fall
22
+ behind — keep it on `dev`, no more than a `git fetch` behind, and do the work
23
+ in worktrees (§2).
24
+
25
+ ## 2. Work in an isolated worktree
26
+
27
+ - **Always start from a freshly-fetched `dev`:** `git fetch origin`, then
28
+ `git worktree add .worktrees/<name> -b <type>/<slug> origin/dev`. Never branch
29
+ from a stale local ref.
30
+ - **Install dependencies in the new worktree before working** — `uv sync` and/or
31
+ `pnpm install`, so the local gates (pre-push checks, lint-staged) run against
32
+ fresh deps, not a stale `.venv`/`node_modules`.
33
+ - **One worktree per unit of work**, under the git-ignored `.worktrees/`.
34
+ - **Clean up when the PR merges:** `git worktree remove .worktrees/<name>`, then
35
+ let the branch be deleted. Keep `git worktree list` short and every entry live.
36
+
37
+ ## 3. Commits
38
+
39
+ - **Conventional Commits** (`feat`, `fix`, `chore`, `docs`, `test`, `infra`,
40
+ `security`, `refactor`, `perf`, `ci`), enforced by commitlint.
41
+ - Tag your commits with your agent's own `Co-Authored-By:` trailer.
42
+ - Keep commits and PRs **scoped to one concern**.
43
+
44
+ ## 4. Pull requests
45
+
46
+ - Link the issue the PR resolves (`Closes #N`) and describe what changed and why.
47
+ - Mark a PR **ready** (not draft) when it is meant to merge.
48
+ - Behavior changes ship **with tests**. Don't reduce coverage to make CI pass.
49
+
50
+ ## 5. Merging — never merge red
51
+
52
+ - Get CI green and confirm it: `gh pr checks <N>`. A green local run is not
53
+ sufficient — verify the actual PR checks.
54
+ - **Squash-merge, delete the branch, remove the worktree:**
55
+ `gh pr merge <N> --squash --delete-branch`.
56
+
57
+ ## 6. Push honestly, and verify the remote has your commit
58
+
59
+ - **Push with the exit status visible:** `git push origin HEAD; echo $?`. A pipe
60
+ (`git push | tail`) reports the pipe's status, not git's — a rejected push then
61
+ reads as success and the commit is silently lost. Never trust a "pushed"
62
+ message printed unconditionally after a pipe.
63
+ - **Confirm the remote actually has the commit before relying on it,** especially
64
+ before merge: `git log origin/<branch> -1`. A green PR page is not proof your
65
+ latest local commit reached it.
66
+
67
+ ## 7. Security
68
+
69
+ - **Never commit secrets** (keys, tokens, credentials, `.env` values).
70
+ - **Never silently disable a security gate.** If one must be loosened, do it in
71
+ the open and raise a tracking issue to restore it.
@@ -0,0 +1,16 @@
1
+ # AI Assistant Context
2
+
3
+ The tool-agnostic rules of engagement for **all** automated agents (integration
4
+ branch, worktrees, commits, PRs, merging, honest pushes, security) live in
5
+ [`AGENTS.md`](AGENTS.md) and are imported below. They are binding for any change
6
+ in this repo; `AGENTS.md` is the single source of truth.
7
+
8
+ @AGENTS.md
9
+
10
+ ## What this repo is
11
+
12
+ A **Biffo sibling app** (ADR-0007) — an independently-deployed microservice that
13
+ shares the core project's login and domain (`baseurl.com/<name>`) but has its own
14
+ repo, CI/CD, and AWS resources. It never touches the core database directly — it
15
+ only ever calls the core project's own API. Its own identity lives in
16
+ `biffo.sibling.json`.
package/dist/index.js CHANGED
@@ -515,10 +515,11 @@ var GitAdapter = class {
515
515
  *
516
516
  * Sets the initial branch name explicitly (`-b`) rather than relying on
517
517
  * the running machine's `init.defaultBranch` git config, which isn't
518
- * guaranteed to be "main" (or even consistent between a dev's laptop and
519
- * a CI runner).
518
+ * guaranteed to be "dev" (or even consistent between a dev's laptop and
519
+ * a CI runner). Defaults to `dev`, the single integration branch every Biffo
520
+ * repo uses (#559).
520
521
  */
521
- async init(cwd, initialBranch = "main") {
522
+ async init(cwd, initialBranch = "dev") {
522
523
  await execa("git", ["init", "-b", initialBranch], { cwd });
523
524
  }
524
525
  /** Adds a remote. Fails if a remote with this name already exists. */
@@ -531,7 +532,7 @@ var GitAdapter = class {
531
532
  async commit(cwd, message) {
532
533
  await execa("git", ["commit", "-m", message], { cwd });
533
534
  }
534
- /** The current branch name (e.g. "main"). */
535
+ /** The current branch name (e.g. "dev"). */
535
536
  async currentBranch(cwd) {
536
537
  const { stdout } = await execa("git", ["rev-parse", "--abbrev-ref", "HEAD"], { cwd });
537
538
  return stdout.trim();
@@ -644,7 +645,7 @@ var GitHubAdapter = class {
644
645
  * The repo's default branch — the integration branch a PR should target.
645
646
  *
646
647
  * Asked of GitHub rather than inferred from the local checkout: it differs per
647
- * repo (biffo-template uses `main`, instances use `dev`), and the local
648
+ * repo (every Biffo repo uses `dev` (#559)), and the local
648
649
  * current branch is whatever the caller happens to be on, which under the
649
650
  * worktree-per-change workflow is never it.
650
651
  */
@@ -840,7 +841,7 @@ var GitHubAdapter = class {
840
841
  `Ref "${ref}" not found in ${org}/${repo} after ${timeoutMs / 1e3}s \u2014 GitHub template generation may have stalled. Check the repository and re-run biffo init.`
841
842
  );
842
843
  }
843
- async createBranch(org, repo, branch, from = "main", waitTimeoutMs = 12e4, waitIntervalMs = 3e3) {
844
+ async createBranch(org, repo, branch, from = "dev", waitTimeoutMs = 12e4, waitIntervalMs = 3e3) {
844
845
  try {
845
846
  await this.octokit.repos.getBranch({ owner: org, repo, branch });
846
847
  log.info(`Branch ${branch} already exists \u2014 skipping`);
@@ -1003,7 +1004,7 @@ var GitHubAdapter = class {
1003
1004
  }
1004
1005
  async configureBranchProtection(config, protectionIntervalMs = 3e3, statusChecks = DEFAULT_STATUS_CHECKS) {
1005
1006
  const { org, repo } = config.source_control.config;
1006
- const branches = ["dev", "staging", "main"];
1007
+ const branches = ["dev", "staging"];
1007
1008
  for (const branch of branches) {
1008
1009
  log.info(`Waiting for ${branch} branch to be ready...`);
1009
1010
  await this.waitForBranch(org, repo, branch);
@@ -1043,7 +1044,7 @@ var GitHubAdapter = class {
1043
1044
  }
1044
1045
  }
1045
1046
  }
1046
- log.success("Branch protection configured on dev, staging, and main");
1047
+ log.success("Branch protection configured on dev and staging");
1047
1048
  }
1048
1049
  async createEnvironments(config) {
1049
1050
  const { org, repo } = config.source_control.config;
@@ -1269,7 +1270,7 @@ var GitHubAdapter = class {
1269
1270
  }
1270
1271
  }
1271
1272
  }
1272
- async triggerWorkflow(org, repo, workflowId, inputs = {}, ref = "main", timeoutMs = 6e4, intervalMs = 5e3) {
1273
+ async triggerWorkflow(org, repo, workflowId, inputs = {}, ref = "dev", timeoutMs = 6e4, intervalMs = 5e3) {
1273
1274
  const deadline = Date.now() + timeoutMs;
1274
1275
  while (true) {
1275
1276
  try {
@@ -1288,7 +1289,7 @@ var GitHubAdapter = class {
1288
1289
  }
1289
1290
  }
1290
1291
  }
1291
- async waitForWorkflowRun(org, repo, workflowId, baselineRunId, timeoutMs = 36e5, intervalMs = 3e4, branch = "main") {
1292
+ async waitForWorkflowRun(org, repo, workflowId, baselineRunId, timeoutMs = 36e5, intervalMs = 3e4, branch = "dev") {
1292
1293
  const deadline = Date.now() + timeoutMs;
1293
1294
  while (Date.now() < deadline) {
1294
1295
  const { data } = await this.octokit.actions.listWorkflowRuns({
@@ -1977,7 +1978,7 @@ function breakingChangesBetween(from, to, entries) {
1977
1978
  }
1978
1979
 
1979
1980
  // src/lib/global-workflows.ts
1980
- var GLOBAL_DISPATCH_REF = "main";
1981
+ var GLOBAL_DISPATCH_REF = "dev";
1981
1982
  var GLOBAL_DISPATCH_WORKFLOW_PATHS = [
1982
1983
  ".github/workflows/deploy-global.yml"
1983
1984
  ];
@@ -5300,11 +5301,11 @@ async function pushSkeleton(git, skeletonRoot, cloneUrl, config, coreConfig, git
5300
5301
  // `template_version` field doc on `SiblingMarker` (lib/sibling-teardown.ts).
5301
5302
  templateVersion: getLatestCoreVersion()
5302
5303
  });
5303
- await git.init(workDir, "main");
5304
+ await git.init(workDir, "dev");
5304
5305
  await git.addRemote(workDir, "origin", cloneUrl);
5305
5306
  await git.add(workDir, ["."]);
5306
5307
  await git.commit(workDir, `feat: scaffold ${config.project.name} sibling app (ADR-0007)`);
5307
- await git.push(workDir, "main", { token: githubToken });
5308
+ await git.push(workDir, "dev", { token: githubToken });
5308
5309
  } finally {
5309
5310
  git.cleanup(workDir);
5310
5311
  }
@@ -5345,8 +5346,7 @@ function writeSiblingTemplate(templateRoot, targetDir, config, context) {
5345
5346
  }
5346
5347
  async function configureSiblingGithub(github, config, coreConfig, session, coreIdentity) {
5347
5348
  const { org, repo } = githubRepo(config);
5348
- await github.createBranch(org, repo, "dev", "main");
5349
- await github.createBranch(org, repo, "staging", "main");
5349
+ await github.createBranch(org, repo, "staging", "dev");
5350
5350
  await github.setDefaultBranch(org, repo, "dev");
5351
5351
  await github.configureBranchProtection(config);
5352
5352
  await github.createEnvironments(config);
@@ -5694,9 +5694,8 @@ async function runInit(github, aws, config, session, appSibling) {
5694
5694
  }
5695
5695
  const { org, repo } = config.source_control.config;
5696
5696
  if (!hasCompleted(session, "github_branches")) {
5697
- log.step(5, totalSteps, "Creating dev and staging branches...");
5698
- await github.createBranch(org, repo, "dev", "main");
5699
- await github.createBranch(org, repo, "staging", "main");
5697
+ log.step(5, totalSteps, "Creating the staging branch...");
5698
+ await github.createBranch(org, repo, "staging", "dev");
5700
5699
  markStepComplete(session, "github_branches");
5701
5700
  } else {
5702
5701
  log.step(5, totalSteps, "Branches already created \u2014 skipping");
@@ -5833,8 +5832,8 @@ function appSiblingRegistryFiles(config) {
5833
5832
  }));
5834
5833
  }
5835
5834
  var INSTANCE_CONFIG_FILE = "biffo.config.json";
5836
- var INSTANCE_FILE_BASE_BRANCH = "main";
5837
- var INSTANCE_FILE_FOLLOWER_BRANCHES = ["dev", "staging"];
5835
+ var INSTANCE_FILE_BASE_BRANCH = "dev";
5836
+ var INSTANCE_FILE_FOLLOWER_BRANCHES = ["staging"];
5838
5837
  var INSTANCE_FILE_BRANCHES = [
5839
5838
  INSTANCE_FILE_BASE_BRANCH,
5840
5839
  ...INSTANCE_FILE_FOLLOWER_BRANCHES
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@biffo/cli",
3
- "version": "0.109.1",
3
+ "version": "0.109.2",
4
4
  "description": "Biffo project scaffolding CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",