bitfab-cli 0.2.397 → 0.2.399

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.
Files changed (2) hide show
  1. package/dist/index.js +34 -12
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -24679,10 +24679,10 @@ var semver3 = __toESM(require_semver2(), 1);
24679
24679
 
24680
24680
  // ../bitfab-plugin-lib/dist/bakedSdkVersions.js
24681
24681
  var BAKED_SDK_VERSIONS = {
24682
- typescript: "0.62.1",
24682
+ typescript: "0.62.2",
24683
24683
  python: "0.62.1",
24684
- ruby: "0.62.0",
24685
- go: "0.62.0"
24684
+ ruby: "0.62.1",
24685
+ go: "0.62.1"
24686
24686
  };
24687
24687
 
24688
24688
  // ../bitfab-plugin-lib/dist/installedSdk.js
@@ -26805,6 +26805,9 @@ var Flow = external_exports.object({
26805
26805
  * `split-chain` (a dispatch edge back to an earlier sub-skill renders
26806
26806
  * like any other), which the sequential `split` orchestrator cannot
26807
26807
  * express.
26808
+ * Codex writes non-inline phases to ordinary `references/<phase>.md`
26809
+ * files and routes by reading them, keeping phase names out of skill
26810
+ * discovery. Other targets emit phase sub-skills.
26808
26811
  *
26809
26812
  * `mode` is per-target (the standard default-plus-override form), so split
26810
26813
  * can roll out one target at a time: `{ default: "monolith", claude:
@@ -27526,9 +27529,25 @@ function escapeMermaidLabel(s2) {
27526
27529
  function s(value, target, label) {
27527
27530
  return resolveTargetableString(value, target, label);
27528
27531
  }
27532
+ function usesPhaseReferences(flow, target) {
27533
+ return target.name === "codex" && resolvePerTarget(flow.compile.mode, target.name) === "split-chain";
27534
+ }
27529
27535
  function dispatchSkillRef(target, skillName) {
27530
27536
  return target.dispatchRef?.(skillName) ?? `\`${skillName}\``;
27531
27537
  }
27538
+ function phaseDestination(flow, target, phaseId, unitPhases) {
27539
+ if (!usesPhaseReferences(flow, target)) {
27540
+ return `the ${dispatchSkillRef(target, `${flow.id}-${phaseId}`)} skill`;
27541
+ }
27542
+ const phase = flow.phases.find((candidate) => candidate.id === phaseId);
27543
+ if (phase === void 0) {
27544
+ throw new Error(`Unknown phase "${phaseId}" in flow "${flow.id}"`);
27545
+ }
27546
+ const fromReference = [...unitPhases].some((id) => !flow.compile.inlinePhases.includes(id));
27547
+ const prefix = fromReference ? "./" : "references/";
27548
+ const title = s(phase.title, target.name, `phase[${phaseId}].title`);
27549
+ return `the [${title}](${prefix}${phaseId}.md) reference`;
27550
+ }
27532
27551
  function resolveArgumentHint(flow, target) {
27533
27552
  const argumentHint = flow.frontmatter.argumentHint;
27534
27553
  if (argumentHint === void 0) {
@@ -27632,7 +27651,7 @@ function applyFlowPlaceholders(text2, flow, target, unitPhases) {
27632
27651
  const title = s(phase.title, target.name, `phase[${phaseId}].title`);
27633
27652
  return `the *${title}* section`;
27634
27653
  }
27635
- return `the ${dispatchSkillRef(target, `${flow.id}-${phaseId}`)} skill`;
27654
+ return phaseDestination(flow, target, phaseId, unitPhases);
27636
27655
  });
27637
27656
  result = result.replace(/\{\{dispatch-ref:([a-z0-9-]+)\}\}/g, (_match, phaseId) => {
27638
27657
  const phase = flow.phases.find((p9) => p9.id === phaseId);
@@ -27644,8 +27663,8 @@ function applyFlowPlaceholders(text2, flow, target, unitPhases) {
27644
27663
  const title = s(phase.title, target.name, `phase[${phaseId}].title`);
27645
27664
  return `the *${title}* section`;
27646
27665
  }
27647
- const skill = dispatchSkillRef(target, `${flow.id}-${phaseId}`);
27648
- return `the ${skill} skill with the current mode, forwarding \`${target.argsToken}\` minus the leading mode keyword (if the user typed one)`;
27666
+ const destination = phaseDestination(flow, target, phaseId, unitPhases);
27667
+ return `${destination} with the current mode, forwarding \`${target.argsToken}\` minus the leading mode keyword (if the user typed one)`;
27649
27668
  });
27650
27669
  const stepNumbers = computeStepNumbers(flow, target.name, unitPhases === void 0 && flow.compile.continuousStepNumbers === true);
27651
27670
  result = result.replace(/\{\{step:([a-z0-9-]+\/[a-z0-9-]+)\}\}/g, (_match, ref) => {
@@ -27827,6 +27846,9 @@ function destinationRenderer(flow, target, unitPhases) {
27827
27846
  }
27828
27847
  const phaseId = ref.split("/")[0];
27829
27848
  if (unitPhases !== void 0 && !unitPhases.has(phaseId)) {
27849
+ if (usesPhaseReferences(flow, target)) {
27850
+ return phaseDestination(flow, target, phaseId, unitPhases);
27851
+ }
27830
27852
  return `the \`${flow.id}-${phaseId}\` skill`;
27831
27853
  }
27832
27854
  if (phaseId === sourcePhaseId) {
@@ -31358,9 +31380,9 @@ Never modify existing code on a refactor path without completing this three-step
31358
31380
  kind: "action",
31359
31381
  title: "Inspect the replay environment",
31360
31382
  toolCalls: ["bash", "read", "glob", "grep", "ask"],
31361
- body: `Read the existing GitHub Actions, runtime manifests, lockfiles, replay registry, gitignore, and environment-variable NAMES. Never read or print secret values. Check git origin, Python 3.10+, and gh authentication. Local dispatch supports macOS/Linux and github.com. Inspect all push-triggered workflows and deployment integrations. Temporary branches use bitfab-replay/** and can trigger those systems. Ask before changing existing CI or deployment behavior. Do not set pushTriggersReviewed until these triggers have been reviewed with the user.
31383
+ body: `Read the existing GitHub Actions, runtime manifests, lockfiles, replay registry, gitignore, and environment-variable NAMES. Never read or print secret values. Check git origin, Python 3.10+, and gh authentication. Local dispatch supports macOS/Linux and github.com. Inspect all push-triggered workflows and deployment integrations. Temporary branches use bitfab-replay/** and can trigger those systems. Offer the usual fixes: a push workflow can add bitfab-replay/** to branches-ignore, and a Vercel project can skip those branches with git.deploymentEnabled {"bitfab-replay/**": false} in its vercel.json or an Ignored Build Step in the dashboard. Ask before changing existing CI or deployment behavior. Do not set pushTriggersReviewed until these triggers have been reviewed with the user.
31362
31384
 
31363
- Choose one existing replay pipeline and reproduce its runtime, dependency installation, build steps, working directory, caches, and required services from CI. Use the installed SDK's cloud-capable CLI. TypeScript/Python/Ruby registry imports happen on the runner only. Go must dispatch cloud flags before building its registry or initializing the application. A private database needs runner network access or a replay-safe service fixture. Do not silently give replay production side effects. Submodules/gitlinks and credential-like tracked files are rejected by the snapshot helper. Surface blockers instead of claiming the environment is ready.
31385
+ Choose one existing replay registry and reproduce its runtime, dependency installation, build steps, working directory, caches, and required services from CI. Cover what every pipeline in that registry needs, since cloud replay allows all of them by default. Use the installed SDK's cloud-capable CLI: run its bitfab-replay --cloud --help now. If it does not print the cloud options, the project's SDK predates cloud replay, so upgrade it through bitfab:update before continuing. Never give the user .bitfab/cloudReplay.py as the command to run; the SDK command starts it. TypeScript/Python/Ruby registry imports happen on the runner only. Go must dispatch cloud flags before building its registry or initializing the application. For database reads, prefer database branching. When the Bitfab organization has a database connected, each replay item gets a branch at its trace's captured instant, and the runner needs no database secret. That works only when every registry entry that reads the database sets dbBranch, and the application takes its connection per call from the replay branch URL (getCurrentReplayBranch().databaseUrl, or the Python, Ruby, or Go equivalent), falling back to its normal URL. A pool or engine created once at import from DATABASE_URL never sees the branch, and the SDK does not change DATABASE_URL, so check how the application builds its database client. When either piece is missing, offer to run db-snapshot mode first. Without branching, a private database needs runner network access or a replay-safe service fixture. Do not silently give replay production side effects. Submodules/gitlinks and credential-like tracked files are rejected by the snapshot helper. A gitlink with no .gitmodules entry is usually a nested repository committed by accident: offer to untrack it with git rm --cached and ignore its folder. Surface blockers instead of claiming the environment is ready.
31364
31386
 
31365
31387
  Present the proposed workflow, fixed replay command, required secret/variable names, and any required CI trigger exclusions. Ask only about unresolved project choices. Never ask for secret values in chat.`,
31366
31388
  next: "cloud/install"
@@ -31370,15 +31392,15 @@ Present the proposed workflow, fixed replay command, required secret/variable na
31370
31392
  kind: "action",
31371
31393
  title: "Install the repository-owned runner",
31372
31394
  toolCalls: ["bash", "read", "write", "edit"],
31373
- body: `Create a reviewed JSON setup specification containing version: 1, provider: "github", workflow: "bitfab-replay.yml", workingDirectory (repository-relative), registry (repository-relative path or null for Go), pipeline, command (a JSON argv array without the pipeline argument or cloud flags), pushTriggersReviewed: true, setupSteps (GitHub Actions step objects), secrets (names including BITFAB_API_KEY), and variables (names only). Optional secretPrefix (uppercase, ending in an underscore) names the GitHub secret each one is read from without changing the environment variable the replay sees; it defaults to BITFAB_CLOUD_, and only an explicit empty string turns prefixing off. Optional runsOn, services, and environment match the existing CI. Prefer a GitHub Environment with required reviewers when replay code receives sensitive credentials. Pin third-party actions to reviewed commit SHAs. Ensure Python 3.10+ exists on the runner. Commands run in workingDirectory. Registry in the command must be relative to that directory. Set step working-directory explicitly where needed. Do not copy deployment steps, local env values, or API keys into the specification.
31395
+ body: `Create a reviewed JSON setup specification containing version: 1, provider: "github", workflow: "bitfab-replay.yml", workingDirectory (repository-relative), registry (repository-relative path or null for Go), pipeline (null allows every pipeline in the registry and is the default; a name restricts replay to that one pipeline, for when the others need credentials or services the runner should not have), command (a JSON argv array without the pipeline argument or cloud flags), pushTriggersReviewed: true, setupSteps (GitHub Actions step objects), secrets (names including BITFAB_API_KEY), and variables (names only). The runner always provides BITFAB_API_KEY. Find the variable the registry's Bitfab client actually reads its key from, and when it is another name, map it in the command, for example ["sh", "-c", "APP_KEY_NAME=\\"$BITFAB_API_KEY\\" exec <command> \\"$@\\"", "sh"]. Optional secretPrefix (uppercase, ending in an underscore) names the GitHub secret each one is read from without changing the environment variable the replay sees; it defaults to BITFAB_CLOUD_, and only an explicit empty string turns prefixing off. Optional runsOn, services, and environment match the existing CI. Prefer a GitHub Environment with required reviewers when replay code receives sensitive credentials. Pin third-party actions to reviewed commit SHAs. Ensure Python 3.10+ exists on the runner. Commands run in workingDirectory. Registry in the command must be relative to that directory. Set step working-directory explicitly where needed. Do not copy deployment steps, local env values, or API keys into the specification.
31374
31396
 
31375
31397
  Run python3 "{{pluginRoot}}/scripts/cloudReplay.py" init --config <specification-path>. This creates .bitfab/cloud.json, .bitfab/cloudReplay.py, and .github/workflows/bitfab-replay.yml. The generated workflow is JSON, which is valid YAML. Existing files are never overwritten. For an existing setup, review the diff and edit project configuration deliberately. Remove only your temporary specification after successful installation. If .bitfab is ignored, propose a narrow gitignore exception for these two files. Never force-add secrets or arbitrary ignored files.
31376
31398
 
31377
- Tell the user which repository or Environment secrets to create in GitHub Settings \u2192 Secrets and variables \u2192 Actions. BITFAB_API_KEY belongs to their intended Bitfab organization. Other names come from their application, such as OPENAI_API_KEY. BITFAB_SERVICE_URL is optional. Do not override the SDK's default with an empty GitHub variable. Runtime secrets belong on the replay step. Any install-time credentials need explicit references on the relevant setup step. Local gh authentication is separate from these runner secrets. Do not create a Bitfab cloud target, install a GitHub App, or request a repository connection.
31399
+ Tell the user which repository or Environment secrets to create in GitHub Settings \u2192 Secrets and variables \u2192 Actions. BITFAB_API_KEY belongs to the Bitfab organization that holds the registry's traces; confirm that with the user, because a key from another organization finds none of them. Other names come from their application, such as OPENAI_API_KEY. BITFAB_SERVICE_URL is optional. Do not override the SDK's default with an empty GitHub variable. Runtime secrets belong on the replay step. Any install-time credentials need explicit references on the relevant setup step. Local gh authentication is separate from these runner secrets. Do not create a Bitfab cloud target, install a GitHub App, or request a repository connection.
31378
31400
 
31379
31401
  Init records the secret names and the resolved prefix in .bitfab/cloud.json, so later lifecycle commands reuse them without being told again. Runner secrets are prefixed BITFAB_CLOUD_ unless the user asks otherwise, so the runner reads BITFAB_CLOUD_OPENAI_API_KEY and exposes it to the replay as OPENAI_API_KEY. Replay credentials then never collide with secrets the repository already uses, and can carry narrower scopes or a different Bitfab organization than production. Pass a different prefix, or an empty string to reuse the repository's existing bare-named secrets, only when the user wants that. Report the prefixed names from requiredSecrets as the ones to create.
31380
31402
 
31381
- When the project keeps local environment files, list the NAMES each required secret could come from and ask whether to copy those local values into GitHub. Never read, print, or compare the values, and ask once for the whole set rather than per secret. On a yes, run python3 .bitfab/cloudReplay.py secrets --env-file <file> [--env-file <file>] [--environment <name>], which reads the recorded names and prefix, parses quoted, multi-line, and JSON values correctly, and pipes each value to gh on standard input so it never appears in arguments, process listings, or shell history. Never hand-extract a value with grep, cut, or a shell variable, and never pass one through gh secret set --body. Use --dry-run first to report which names the files define. The command reports set, missing, and empty names only; create the missing ones by hand. A name your files define as blank is skipped rather than uploaded, because an empty secret replaces a working default with nothing. Warn before copying a value whose own configuration points somewhere a runner cannot reach, such as a localhost service URL, or that grants more than the replay needs, and let the user decide. Setting secrets requires the same explicit authorization as any other remote write, and a wrong value only surfaces when the first real replay runs, since the dry run never calls the application.`,
31403
+ When the project keeps local environment files, list the NAMES each required secret could come from and ask whether to copy those local values into GitHub. Never read, print, or compare the values, and ask once for the whole set rather than per secret. On a yes, run python3 .bitfab/cloudReplay.py secrets --env-file <file> [--env-file <file>] [--environment <name>], which reads the recorded names and prefix, parses quoted, multi-line, and JSON values correctly, and pipes each value to gh on standard input so it never appears in arguments, process listings, or shell history. Never hand-extract a value with grep, cut, or a shell variable, and never pass one through gh secret set --body. Use --dry-run first to report which names the files define. The command reports set, missing, and empty names only; create the missing ones by hand. A name your files define as blank is skipped rather than uploaded, because an empty secret replaces a working default with nothing. Warn before copying a value whose own configuration points somewhere a runner cannot reach, such as a localhost service URL, or that grants more than the replay needs, and let the user decide. When the value for BITFAB_API_KEY lives locally under the client's other name, or only a development key sits under BITFAB_API_KEY, leave it out of the copy and have the user set it. Environment secrets need the Environment to exist: check with gh api repos/<owner>/<repo>/environments, and when it is missing, ask before creating it with gh api -X PUT repos/<owner>/<repo>/environments/<name>, offering the user as a required reviewer. Setting secrets requires the same explicit authorization as any other remote write, and a wrong value only surfaces when the first real replay runs, since the dry run never calls the application.`,
31382
31404
  next: "cloud/verify"
31383
31405
  },
31384
31406
  {
@@ -31388,7 +31410,7 @@ When the project keeps local environment files, list the NAMES each required sec
31388
31410
  toolCalls: ["bash", "read", "ask"],
31389
31411
  body: `Validate workflow syntax (actionlint when available) and run the installed SDK CLI with --cloud --help. The workflow must land on the default branch once before workflow_dispatch can run it on temporary branches. Explain the required commit/merge. Do not push, merge, change repository permissions, or set secrets without authorization.
31390
31412
 
31391
- After the setup files are tracked, run bitfab-replay --cloud <pipeline> --trace-ids <real-trace-uuid> --cloud-dry-run using the selected SDK command. It reports changed tracked files and omitted new files. Include new source files explicitly with repeated --cloud-include <repository-relative-file>. Review the entire snapshot for credentials. Filename screening is not a secret scanner. Then, only when remote replay is authorized, run without --cloud-dry-run. The helper creates a commit through an isolated index, pushes bitfab-replay/<UUID>, dispatches that branch, waits, retrieves the test-run identity, and deletes the branch with an exact-SHA lease. HEAD, staged changes, and working files stay untouched. Never reset or undo the user's work.
31413
+ After the setup files are tracked (until then, pass each one with --cloud-include; the helper names any that are missing), run bitfab-replay --cloud <pipeline> --trace-ids <real-trace-uuid> --cloud-dry-run using the selected SDK command. It reports changed tracked files and omitted new files. Include new source files explicitly with repeated --cloud-include <repository-relative-file>. Review the entire snapshot for credentials. Filename screening is not a secret scanner. Then, only when remote replay is authorized, run without --cloud-dry-run. The helper creates a commit through an isolated index, pushes bitfab-replay/<UUID>, dispatches that branch, waits, retrieves the test-run identity, and deletes the branch with an exact-SHA lease. HEAD, staged changes, and working files stay untouched. Never reset or undo the user's work.
31392
31414
 
31393
31415
  Use --cloud-detach to return immediately. Explain --cloud-status, --cloud-watch, --cloud-cancel, and --cloud-cleanup with the printed execution UUID. Records live under this worktree's Git directory. Interrupted/lost-response submissions must be recovered, not blindly dispatched again. Cancel requests do not imply the job stopped. Watch/status confirms completion before deleting the branch. Detached jobs do not automatically clean themselves without a later local lifecycle command. Report separately whether files are generated, secrets configured, workflow merged, dry-run verified, and an actual remote replay completed. Never call a mock smoke run a real replay.`,
31394
31416
  next: "cleanup/finish"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bitfab-cli",
3
- "version": "0.2.397",
3
+ "version": "0.2.399",
4
4
  "description": "Install and configure the Bitfab plugin in Claude Code, Codex, or Cursor, or the Bitfab skill pack in Amp (Alpha).",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",