bitfab-cli 0.2.385 → 0.2.387
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.
- package/dist/index.js +109 -14
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -23747,9 +23747,54 @@ function toolConfig(contract) {
|
|
|
23747
23747
|
return {
|
|
23748
23748
|
title: contract.title,
|
|
23749
23749
|
description: contract.description,
|
|
23750
|
-
inputSchema: contract.inputSchema
|
|
23750
|
+
inputSchema: external_exports.strictObject(contract.inputSchema)
|
|
23751
23751
|
};
|
|
23752
23752
|
}
|
|
23753
|
+
function isRecord(value) {
|
|
23754
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23755
|
+
}
|
|
23756
|
+
function appendToolParameterWarning(result, warning) {
|
|
23757
|
+
if (!isRecord(result) || !Array.isArray(result.content)) {
|
|
23758
|
+
return result;
|
|
23759
|
+
}
|
|
23760
|
+
return {
|
|
23761
|
+
...result,
|
|
23762
|
+
content: [...result.content, { type: "text", text: warning }]
|
|
23763
|
+
};
|
|
23764
|
+
}
|
|
23765
|
+
function installToolParameterWarnings(protocolServer, contracts, receiver) {
|
|
23766
|
+
const method = "tools/call";
|
|
23767
|
+
const originalHandler = protocolServer._requestHandlers.get(method);
|
|
23768
|
+
if (!originalHandler) {
|
|
23769
|
+
throw new Error("Cannot install tool parameter warnings before tools register");
|
|
23770
|
+
}
|
|
23771
|
+
const contractsByName = new Map(contracts.map((toolContract) => [toolContract.name, toolContract]));
|
|
23772
|
+
protocolServer._requestHandlers.set(method, async (request, extra) => {
|
|
23773
|
+
if (!isRecord(request) || !isRecord(request.params)) {
|
|
23774
|
+
return originalHandler(request, extra);
|
|
23775
|
+
}
|
|
23776
|
+
const { name, arguments: args } = request.params;
|
|
23777
|
+
if (typeof name !== "string" || !isRecord(args)) {
|
|
23778
|
+
return originalHandler(request, extra);
|
|
23779
|
+
}
|
|
23780
|
+
const toolContract = contractsByName.get(name);
|
|
23781
|
+
if (!toolContract) {
|
|
23782
|
+
return originalHandler(request, extra);
|
|
23783
|
+
}
|
|
23784
|
+
const supportedNames = new Set(Object.keys(toolContract.inputSchema));
|
|
23785
|
+
const unsupportedNames = Object.keys(args).filter((key) => !supportedNames.has(key));
|
|
23786
|
+
if (unsupportedNames.length === 0) {
|
|
23787
|
+
return originalHandler(request, extra);
|
|
23788
|
+
}
|
|
23789
|
+
const supportedArgs = Object.fromEntries(Object.entries(args).filter(([key]) => supportedNames.has(key)));
|
|
23790
|
+
const result = await originalHandler({
|
|
23791
|
+
...request,
|
|
23792
|
+
params: { ...request.params, arguments: supportedArgs }
|
|
23793
|
+
}, extra);
|
|
23794
|
+
const parameterLabel = unsupportedNames.length === 1 ? "parameter" : "parameters";
|
|
23795
|
+
return appendToolParameterWarning(result, `Warning: ${receiver} ignored unsupported ${parameterLabel} for ${name}: ${unsupportedNames.join(", ")}. Update Bitfab if you expected ${unsupportedNames.length === 1 ? "it" : "them"} to take effect.`);
|
|
23796
|
+
});
|
|
23797
|
+
}
|
|
23753
23798
|
var getBitfabApiKey = {
|
|
23754
23799
|
name: "get_bitfab_api_key",
|
|
23755
23800
|
title: "Get Bitfab API Key",
|
|
@@ -24917,10 +24962,10 @@ var semver3 = __toESM(require_semver2(), 1);
|
|
|
24917
24962
|
|
|
24918
24963
|
// ../bitfab-plugin-lib/dist/bakedSdkVersions.js
|
|
24919
24964
|
var BAKED_SDK_VERSIONS = {
|
|
24920
|
-
typescript: "0.
|
|
24921
|
-
python: "0.
|
|
24922
|
-
ruby: "0.
|
|
24923
|
-
go: "0.
|
|
24965
|
+
typescript: "0.61.0",
|
|
24966
|
+
python: "0.61.0",
|
|
24967
|
+
ruby: "0.61.0",
|
|
24968
|
+
go: "0.61.0"
|
|
24924
24969
|
};
|
|
24925
24970
|
|
|
24926
24971
|
// ../bitfab-plugin-lib/dist/installedSdk.js
|
|
@@ -31404,10 +31449,10 @@ var setupFlow = Flow.parse({
|
|
|
31404
31449
|
id: "setup",
|
|
31405
31450
|
title: "Bitfab Setup",
|
|
31406
31451
|
frontmatter: {
|
|
31407
|
-
description: "Set up and maintain Bitfab tracing
|
|
31452
|
+
description: "Set up and maintain Bitfab tracing, replay registries, and cloud replay. Use for instrumenting AI/LLM code, adding observability or evaluation, tracing another workflow, changing captured inputs/outputs, re-instrumenting a function, moving side effects across trace boundaries, inspecting missing traces, explaining Bitfab, login, organization switching, session-log consent, database snapshots, templates, or read-only repo instrumentation recommendations (analyze-repo). Also use for 'setup cloud', 'set up cloud replay', or 'replay on GitHub'. Re-enter this skill for each additional function to instrument, even after earlier setup. Do not use for improving output quality, pass rates, labeling, or experiments (use bitfab:assistant), or upgrading SDK/plugin versions (use bitfab:update)",
|
|
31408
31453
|
argumentHint: {
|
|
31409
31454
|
deriveFromModes: true,
|
|
31410
|
-
suffix: "[
|
|
31455
|
+
suffix: "[what to do]"
|
|
31411
31456
|
}
|
|
31412
31457
|
},
|
|
31413
31458
|
commands: BITFAB_PLUGIN_COMMANDS.defineCommands({
|
|
@@ -31475,9 +31520,9 @@ var setupFlow = Flow.parse({
|
|
|
31475
31520
|
- Keep prose between tool calls to one line or none. Save fuller explanation for decision points and the workflow summaries the user acts on.
|
|
31476
31521
|
- Surfacing a risk, ambiguity, or unexpected finding is never the narration to suppress: raise it immediately, even mid-probe (e.g. unserializable inputs, a shim with lazy init, an ambiguous project root).
|
|
31477
31522
|
|
|
31478
|
-
This skill has
|
|
31523
|
+
This skill has twelve phases: **explain**, **login**, **session-logs**, **instrument**, **modify**, **inspect**, **switch-org**, **replay**, **db-snapshot**, **templates**, **analyze-repo**, and **cloud**. The \`cloud\` mode configures direct GitHub Actions replay without Bitfab login or a repository connection. Run individually or through setup (\`wizard\` runs login \u2192 instrument; \`explain\` is a standalone read-only overview that requires no login; \`session-logs\` is standalone and does not require login; \`modify\` is only invoked explicitly or as a branch from Instrument's existing-SDK-usage menu; \`inspect\` is a standalone diagnostic (with optional one-shot fixes) invoked explicitly; \`switch-org\` is a standalone account action (requires auth) invoked explicitly; \`db-snapshot\` is only invoked explicitly; \`templates\` is only invoked explicitly; \`analyze-repo\` is a standalone, **non-interactive** batch action (requires auth) invoked explicitly: it scans, picks the top few candidates, and reports source locations and replay dependencies, asking nothing and editing no code).
|
|
31479
31524
|
|
|
31480
|
-
**Natural-language aliases:** "explain Bitfab" \u2192 \`explain\`; "trace a new workflow" / "instrument another function" \u2192 \`instrument\`; "adjust what is captured" / "re-instrument" \u2192 \`modify\`; "why are my traces missing" \u2192 \`inspect\`; "switch org" \u2192 \`switch-org\`; "set up database snapshots" \u2192 \`db-snapshot\`; "analyze the repo" \u2192 \`analyze-repo\` (read-only source recommendations).
|
|
31525
|
+
**Natural-language aliases:** "set up cloud replay" / "replay on GitHub" \u2192 \`cloud\`; "explain Bitfab" \u2192 \`explain\`; "trace a new workflow" / "instrument another function" \u2192 \`instrument\`; "adjust what is captured" / "re-instrument" \u2192 \`modify\`; "why are my traces missing" \u2192 \`inspect\`; "switch org" \u2192 \`switch-org\`; "set up database snapshots" \u2192 \`db-snapshot\`; "analyze the repo" \u2192 \`analyze-repo\` (read-only source recommendations).
|
|
31481
31526
|
|
|
31482
31527
|
When instrumenting a workflow, **its instrumentation and replay pipeline are written together in the same cycle** after the workflow is selected (see Instrument's write-instrumentation step). The standalone \`replay\` mode remains available for coverage-verification and backfill.
|
|
31483
31528
|
|
|
@@ -31510,6 +31555,7 @@ If the block prints \`ERROR: Bitfab plugin not installed\`, the user hasn't inst
|
|
|
31510
31555
|
inspect: "inspect/status-check",
|
|
31511
31556
|
"switch-org": "switch-org/status-check",
|
|
31512
31557
|
replay: "replay/gather-keys",
|
|
31558
|
+
cloud: "cloud/inspect",
|
|
31513
31559
|
"db-snapshot": "db-snapshot/preflight",
|
|
31514
31560
|
templates: "templates/pick-function",
|
|
31515
31561
|
"analyze-repo": "analyze-repo/preflight"
|
|
@@ -31525,6 +31571,7 @@ If the block prints \`ERROR: Bitfab plugin not installed\`, the user hasn't inst
|
|
|
31525
31571
|
inspect: "Diagnose (and offer to fix) your tracing setup: auth, what's instrumented, plugin/SDK freshness, replay coverage, trace arrival.",
|
|
31526
31572
|
"switch-org": "Switch which Bitfab org the plugin reads and writes (replaces the local API key).",
|
|
31527
31573
|
replay: "Create or update replay registry modules for instrumented workflows.",
|
|
31574
|
+
cloud: "Set up replay in your own GitHub Actions using local gh authentication. No Bitfab repository connection required.",
|
|
31528
31575
|
"db-snapshot": "Set up per-trace database snapshots so replay runs against the DB state at trace time (TypeScript, Python, Ruby).",
|
|
31529
31576
|
templates: "Iterate on the span-rendering templates for one trace function.",
|
|
31530
31577
|
"analyze-repo": "Read-only discovery: scan source, rank the top workflows to instrument, and report recommendations without creating artifacts or changing code."
|
|
@@ -31577,6 +31624,50 @@ Never modify existing code on a refactor path without completing this three-step
|
|
|
31577
31624
|
}
|
|
31578
31625
|
],
|
|
31579
31626
|
phases: [
|
|
31627
|
+
{
|
|
31628
|
+
id: "cloud",
|
|
31629
|
+
title: "Cloud replay",
|
|
31630
|
+
stepStyle: "list",
|
|
31631
|
+
intro: "Run replay in the customer's GitHub Actions. Use this standalone mode for 'setup cloud', 'set up cloud replay', or 'replay on GitHub'. Do not enter login or connect a repository to Bitfab. Normal replay still uses a Bitfab API key on the runner.",
|
|
31632
|
+
steps: [
|
|
31633
|
+
{
|
|
31634
|
+
id: "inspect",
|
|
31635
|
+
kind: "action",
|
|
31636
|
+
title: "Inspect the replay environment",
|
|
31637
|
+
toolCalls: ["bash", "read", "glob", "grep", "ask"],
|
|
31638
|
+
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.
|
|
31639
|
+
|
|
31640
|
+
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.
|
|
31641
|
+
|
|
31642
|
+
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.`,
|
|
31643
|
+
next: "cloud/install"
|
|
31644
|
+
},
|
|
31645
|
+
{
|
|
31646
|
+
id: "install",
|
|
31647
|
+
kind: "action",
|
|
31648
|
+
title: "Install the repository-owned runner",
|
|
31649
|
+
toolCalls: ["bash", "read", "write", "edit"],
|
|
31650
|
+
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 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.
|
|
31651
|
+
|
|
31652
|
+
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.
|
|
31653
|
+
|
|
31654
|
+
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.`,
|
|
31655
|
+
next: "cloud/verify"
|
|
31656
|
+
},
|
|
31657
|
+
{
|
|
31658
|
+
id: "verify",
|
|
31659
|
+
kind: "action",
|
|
31660
|
+
title: "Verify and hand off",
|
|
31661
|
+
toolCalls: ["bash", "read", "ask"],
|
|
31662
|
+
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.
|
|
31663
|
+
|
|
31664
|
+
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.
|
|
31665
|
+
|
|
31666
|
+
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.`,
|
|
31667
|
+
next: "cleanup/finish"
|
|
31668
|
+
}
|
|
31669
|
+
]
|
|
31670
|
+
},
|
|
31580
31671
|
{
|
|
31581
31672
|
id: "login",
|
|
31582
31673
|
title: "Login",
|
|
@@ -31673,6 +31764,7 @@ Save the answer (replace \`CONSENT\` with \`true\` or \`false\`):
|
|
|
31673
31764
|
inspect: "cleanup/finish",
|
|
31674
31765
|
"switch-org": "cleanup/finish",
|
|
31675
31766
|
replay: "cleanup/finish",
|
|
31767
|
+
cloud: "cleanup/finish",
|
|
31676
31768
|
"db-snapshot": "cleanup/finish",
|
|
31677
31769
|
templates: "cleanup/finish",
|
|
31678
31770
|
"analyze-repo": "cleanup/finish"
|
|
@@ -31741,6 +31833,7 @@ then close with one line: to start tracing, run \`{{cmd}}setup\`; to debug an ex
|
|
|
31741
31833
|
next: {
|
|
31742
31834
|
byMode: {
|
|
31743
31835
|
wizard: "approach/choose-driver",
|
|
31836
|
+
cloud: "cleanup/finish",
|
|
31744
31837
|
explain: "cleanup/finish",
|
|
31745
31838
|
login: "cleanup/finish",
|
|
31746
31839
|
"session-logs": "cleanup/finish",
|
|
@@ -31940,6 +32033,7 @@ Confirm the change to the user.`,
|
|
|
31940
32033
|
inspect: "cleanup/finish",
|
|
31941
32034
|
"switch-org": "cleanup/finish",
|
|
31942
32035
|
replay: "cleanup/finish",
|
|
32036
|
+
cloud: "cleanup/finish",
|
|
31943
32037
|
"db-snapshot": "cleanup/finish",
|
|
31944
32038
|
templates: "cleanup/finish",
|
|
31945
32039
|
"analyze-repo": "cleanup/finish"
|
|
@@ -43230,6 +43324,7 @@ function createMcpServer(platform2, getConfig2, pluginVersion) {
|
|
|
43230
43324
|
for (const { contract, handle } of handlers) {
|
|
43231
43325
|
server.registerTool(contract.name, toolConfig(contract), async (args) => handle(args));
|
|
43232
43326
|
}
|
|
43327
|
+
installToolParameterWarnings(server.server, handlers.map(({ contract }) => contract), `Bitfab plugin ${pluginVersion}`);
|
|
43233
43328
|
return { server, proxy };
|
|
43234
43329
|
}
|
|
43235
43330
|
async function startMcpServer(platform2, getConfig2, pluginVersion) {
|
|
@@ -46049,7 +46144,7 @@ var AUTO_APPROVED_TOOLS = /* @__PURE__ */ new Set([
|
|
|
46049
46144
|
).map((tool) => `mcp__Bitfab__${tool.name}`)
|
|
46050
46145
|
]);
|
|
46051
46146
|
var OTHER_VALUE = "__bitfab_other__";
|
|
46052
|
-
function
|
|
46147
|
+
function isRecord2(value) {
|
|
46053
46148
|
return typeof value === "object" && value !== null;
|
|
46054
46149
|
}
|
|
46055
46150
|
function parseQuestions(input) {
|
|
@@ -46057,11 +46152,11 @@ function parseQuestions(input) {
|
|
|
46057
46152
|
return [];
|
|
46058
46153
|
}
|
|
46059
46154
|
return input.questions.flatMap((candidate) => {
|
|
46060
|
-
if (!
|
|
46155
|
+
if (!isRecord2(candidate) || typeof candidate.question !== "string" || !Array.isArray(candidate.options)) {
|
|
46061
46156
|
return [];
|
|
46062
46157
|
}
|
|
46063
46158
|
const options = candidate.options.flatMap((option) => {
|
|
46064
|
-
if (!
|
|
46159
|
+
if (!isRecord2(option) || typeof option.label !== "string") {
|
|
46065
46160
|
return [];
|
|
46066
46161
|
}
|
|
46067
46162
|
return [
|
|
@@ -46253,7 +46348,7 @@ function createPreToolUseHook() {
|
|
|
46253
46348
|
if (input.hook_event_name !== "PreToolUse") {
|
|
46254
46349
|
return { continue: true };
|
|
46255
46350
|
}
|
|
46256
|
-
const toolInput =
|
|
46351
|
+
const toolInput = isRecord2(input.tool_input) ? input.tool_input : {};
|
|
46257
46352
|
if (input.tool_name === "AskUserQuestion") {
|
|
46258
46353
|
return { continue: true };
|
|
46259
46354
|
}
|
|
@@ -46284,7 +46379,7 @@ function createPostToolUseHook(verification) {
|
|
|
46284
46379
|
}
|
|
46285
46380
|
verification.recordToolSuccess(
|
|
46286
46381
|
input.tool_name,
|
|
46287
|
-
|
|
46382
|
+
isRecord2(input.tool_input) ? input.tool_input : {},
|
|
46288
46383
|
input.tool_response
|
|
46289
46384
|
);
|
|
46290
46385
|
return { continue: true };
|
package/package.json
CHANGED