@bridge_gpt/mcp-server 0.2.14 → 0.2.16

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.
@@ -27,7 +27,19 @@ const OCAPI_SETTINGS_READ_ONLY = (ocapiVersion) => JSON.stringify({
27
27
  },
28
28
  {
29
29
  resource_id: "/system_object_definitions/**",
30
- methods: ["get"],
30
+ methods: ["get", "post"],
31
+ read_attributes: "(**)",
32
+ write_attributes: "(**)",
33
+ },
34
+ {
35
+ resource_id: "/site_preferences/**",
36
+ methods: ["get", "post"],
37
+ read_attributes: "(**)",
38
+ write_attributes: "(**)",
39
+ },
40
+ {
41
+ resource_id: "/custom_object_definitions/**",
42
+ methods: ["get", "post"],
31
43
  read_attributes: "(**)",
32
44
  write_attributes: "(**)",
33
45
  },
@@ -2,18 +2,23 @@
2
2
  * SFCC custom-object-definition introspection read tools (BAPI-402, T4–T5).
3
3
  *
4
4
  * Implements:
5
- * custom_object_definition_list — GET /custom_object_definitions
6
- * custom_object_definition_get GET /custom_object_definitions/{type}
5
+ * custom_object_definition_attributes_get — GET /custom_object_definitions/{type}/attribute_definitions
6
+ * custom_object_definition_attribute_search POST /custom_object_definitions/{type}/attribute_definition_search
7
7
  *
8
8
  * Both tools are read-only, run behind the T1 call-time gate, and route
9
9
  * oversized payloads through the sfcc/output.ts truncate-and-save seam.
10
10
  *
11
+ * OCAPI's CustomObjectDefinitions resource only exposes operations scoped to
12
+ * a known object_type — there is no top-level list and no bare get-by-type
13
+ * (unlike SystemObjectDefinitions). A caller-supplied object_type is always
14
+ * required; OCAPI cannot enumerate custom object types.
15
+ *
11
16
  * Note: custom object TYPE creation/update is NOT available via OCAPI REST.
12
17
  * It is a v2 metadata-import capability (metadata XML → WebDAV → import job).
13
18
  */
14
19
  import path from "path";
15
20
  import { z } from "zod";
16
- import { ocapiGet } from "./client.js";
21
+ import { ocapiGet, ocapiPost } from "./client.js";
17
22
  import { withSfccGate } from "./tool-wrapper.js";
18
23
  import { normalizeOcapiBody } from "./ocapi-shape.js";
19
24
  import { truncateAndSaveIfNeeded } from "./output.js";
@@ -29,14 +34,22 @@ const READ_ANNOTATIONS = {
29
34
  // ---------------------------------------------------------------------------
30
35
  // Input schemas
31
36
  // ---------------------------------------------------------------------------
32
- const customObjectListInput = z.object({
33
- count: z.number().optional().describe("Maximum number of custom object types to return."),
34
- start: z.number().optional().describe("Zero-based offset for paging."),
37
+ const customObjectAttributesGetInput = z.object({
38
+ object_type: z
39
+ .string()
40
+ .describe('Known custom object type identifier, e.g. a custom type id starting with "c_". ' +
41
+ "OCAPI cannot enumerate custom object types — the type must already be known."),
35
42
  });
36
- const customObjectGetInput = z.object({
43
+ const customObjectAttributeSearchInput = z.object({
37
44
  object_type: z
38
45
  .string()
39
- .describe('Custom object type identifier, e.g. "GiftCertificate" or a custom type id starting with "c_".'),
46
+ .describe('Known custom object type to search within, e.g. a custom type id starting with "c_". ' +
47
+ "OCAPI cannot enumerate custom object types — the type must already be known."),
48
+ query: z.union([z.string(), z.record(z.string(), z.any())]).describe("Search query. Pass a plain string for a text search across id and display_name, " +
49
+ "or a structured OCAPI query object (term_query, filtered_query, etc.)."),
50
+ start: z.number().optional().describe("Zero-based offset for paging."),
51
+ count: z.number().optional().describe("Maximum number of results to return."),
52
+ sorts: z.array(z.any()).optional().describe("Array of OCAPI sort descriptors."),
40
53
  });
41
54
  // ---------------------------------------------------------------------------
42
55
  // Helpers
@@ -57,39 +70,43 @@ async function saveAndReturn(text, dir, filename) {
57
70
  // ---------------------------------------------------------------------------
58
71
  // Handlers
59
72
  // ---------------------------------------------------------------------------
60
- function buildCustomObjectListHandler(gateDeps, getDocsDir) {
73
+ function buildCustomObjectAttributesGetHandler(gateDeps, getDocsDir) {
61
74
  return withSfccGate(gateDeps, async (args, credentials) => {
62
- const { count, start } = customObjectListInput.parse(args);
63
- const queryParams = {};
64
- if (count !== undefined)
65
- queryParams.count = String(count);
66
- if (start !== undefined)
67
- queryParams.start = String(start);
68
- const queryStr = Object.keys(queryParams).length > 0
69
- ? "?" + new URLSearchParams(queryParams).toString()
70
- : "";
71
- const result = await ocapiGet(`/custom_object_definitions${queryStr}`, credentials);
75
+ const { object_type } = customObjectAttributesGetInput.parse(args);
76
+ const encodedType = encodeURIComponent(object_type);
77
+ const result = await ocapiGet(`/custom_object_definitions/${encodedType}/attribute_definitions`, credentials);
72
78
  if (!result.ok) {
73
79
  return textResult(JSON.stringify({ error: "OCAPI error", status: result.status, body: result.body }, null, 2));
74
80
  }
75
81
  const normalized = normalizeOcapiBody(result.body);
76
82
  const text = JSON.stringify(normalized, null, 2);
77
83
  const dir = path.join(await getDocsDir(), "sfcc");
78
- return saveAndReturn(text, dir, `custom-object-def-list-${safeTimestamp()}.json`);
84
+ return saveAndReturn(text, dir, `custom-object-def-attributes-${safeType(object_type)}-${safeTimestamp()}.json`);
79
85
  });
80
86
  }
81
- function buildCustomObjectGetHandler(gateDeps, getDocsDir) {
87
+ function buildCustomObjectAttributeSearchHandler(gateDeps, getDocsDir) {
82
88
  return withSfccGate(gateDeps, async (args, credentials) => {
83
- const { object_type } = customObjectGetInput.parse(args);
89
+ const { object_type, query, start, count, sorts } = customObjectAttributeSearchInput.parse(args);
84
90
  const encodedType = encodeURIComponent(object_type);
85
- const result = await ocapiGet(`/custom_object_definitions/${encodedType}`, credentials);
91
+ // Coerce plain string queries into OCAPI text_query shape
92
+ const resolvedQuery = typeof query === "string"
93
+ ? { text_query: { fields: ["id", "display_name"], search_phrase: query } }
94
+ : query;
95
+ const postBody = { query: resolvedQuery };
96
+ if (start !== undefined)
97
+ postBody.start = start;
98
+ if (count !== undefined)
99
+ postBody.count = count;
100
+ if (sorts !== undefined)
101
+ postBody.sorts = sorts;
102
+ const result = await ocapiPost(`/custom_object_definitions/${encodedType}/attribute_definition_search`, postBody, credentials);
86
103
  if (!result.ok) {
87
104
  return textResult(JSON.stringify({ error: "OCAPI error", status: result.status, body: result.body }, null, 2));
88
105
  }
89
106
  const normalized = normalizeOcapiBody(result.body);
90
107
  const text = JSON.stringify(normalized, null, 2);
91
108
  const dir = path.join(await getDocsDir(), "sfcc");
92
- return saveAndReturn(text, dir, `custom-object-def-${safeType(object_type)}-${safeTimestamp()}.json`);
109
+ return saveAndReturn(text, dir, `custom-object-def-search-${safeType(object_type)}-${safeTimestamp()}.json`);
93
110
  });
94
111
  }
95
112
  /**
@@ -99,21 +116,21 @@ function buildCustomObjectGetHandler(gateDeps, getDocsDir) {
99
116
  */
100
117
  export function registerSfccCustomObjectDefReadTools(registerTool, deps) {
101
118
  const { gateDeps, getDocsDir } = deps;
102
- registerTool("custom_object_definition_list", {
103
- description: "List all custom object type definitions from the developer sandbox via " +
104
- "GET /custom_object_definitions. Read-only introspection; type definitions cannot be created " +
105
- "or updated via OCAPI (v2 metadata-import only). " +
106
- "Optional `count` and `start` for paging. Oversized outputs auto-saved locally.",
107
- inputSchema: customObjectListInput,
119
+ registerTool("custom_object_definition_attributes_get", {
120
+ description: "Retrieve attribute definitions for a KNOWN custom object type via " +
121
+ "GET /custom_object_definitions/{type}/attribute_definitions. " +
122
+ "OCAPI cannot enumerate types object_type is required. " +
123
+ "Type creation is v2 metadata-import only, not OCAPI. Oversized payloads auto-saved locally.",
124
+ inputSchema: customObjectAttributesGetInput,
108
125
  annotations: READ_ANNOTATIONS,
109
- }, buildCustomObjectListHandler(gateDeps, getDocsDir));
110
- registerTool("custom_object_definition_get", {
111
- description: "Retrieve an EXISTING custom object type from the developer sandbox via " +
112
- "GET /custom_object_definitions/{type}. " +
113
- "Returns the type with key_definition and attribute_definitions/attribute_groups. " +
114
- "Read-only introspection; type definitions cannot be created or updated via OCAPI " +
115
- "(v2 metadata-import only). Oversized payloads auto-saved locally.",
116
- inputSchema: customObjectGetInput,
126
+ }, buildCustomObjectAttributesGetHandler(gateDeps, getDocsDir));
127
+ registerTool("custom_object_definition_attribute_search", {
128
+ description: "Search attribute definitions within a KNOWN custom object type via " +
129
+ "POST /custom_object_definitions/{type}/attribute_definition_search. " +
130
+ "OCAPI cannot enumerate types object_type is required. " +
131
+ "Pass a string or structured OCAPI query. Type creation is v2 metadata-import only. " +
132
+ "Oversized results auto-saved locally.",
133
+ inputSchema: customObjectAttributeSearchInput,
117
134
  annotations: READ_ANNOTATIONS,
118
- }, buildCustomObjectGetHandler(gateDeps, getDocsDir));
135
+ }, buildCustomObjectAttributeSearchHandler(gateDeps, getDocsDir));
119
136
  }
@@ -59,7 +59,7 @@ export function registerSfccTools(registerTool, deps) {
59
59
  gateDeps,
60
60
  getDocsDir: deps.getDocsDir,
61
61
  });
62
- // custom_object_definition_list, custom_object_definition_get (BAPI-402 T4–T5)
62
+ // custom_object_definition_attributes_get, custom_object_definition_attribute_search (BAPI-402 T4–T5)
63
63
  registerSfccCustomObjectDefReadTools(registerTool, {
64
64
  gateDeps,
65
65
  getDocsDir: deps.getDocsDir,
@@ -58,7 +58,11 @@ export function withSfccGate(deps, handler) {
58
58
  `Update the version field in your Bridge API project settings.`);
59
59
  }
60
60
  // (c) Resolve credentials from dw.json
61
- const explicitHostname = typeof args.instance === "string" ? args.instance : undefined;
61
+ // A hostname always contains a dot; the OCAPI instance-context enum
62
+ // (e.g. "sandbox") never does — only treat args.instance as an explicit
63
+ // hostname override when it looks like one.
64
+ const rawInstance = typeof args.instance === "string" ? args.instance : undefined;
65
+ const explicitHostname = rawInstance && rawInstance.includes(".") ? rawInstance : undefined;
62
66
  const credResult = await resolveSfccCredentials(explicitHostname);
63
67
  if (!credResult.ok) {
64
68
  return notConfigured("missing-dw-json", `SFCC credential resolution failed: ${credResult.error} ` +
@@ -253,6 +253,46 @@ function agentDescriptor(agent) {
253
253
  function uvDescriptor() {
254
254
  return commandDescriptor("uv", "uv", UV_INSTALL_HINTS);
255
255
  }
256
+ // ---------------------------------------------------------------------------
257
+ // regression-check (BAPI-460) doctor-only tool descriptors. These probe the
258
+ // deterministic tooling regression-check relies on (ast-grep, ripgrep,
259
+ // lizard). They are doctor-diagnosable but NOT preflight blockers: a missing
260
+ // tool degrades the regression-check report rather than failing the command,
261
+ // so these stay in getDoctorOnlyPrereqDescriptors, not getPreflightPrereqDescriptors.
262
+ // ---------------------------------------------------------------------------
263
+ const AST_GREP_INSTALL_HINTS = {
264
+ darwin: "uv tool install ast-grep-cli",
265
+ linux: "uv tool install ast-grep-cli",
266
+ win32: "uv tool install ast-grep-cli",
267
+ };
268
+ const LIZARD_INSTALL_HINTS = {
269
+ darwin: "uv tool install lizard",
270
+ linux: "uv tool install lizard",
271
+ win32: "uv tool install lizard",
272
+ };
273
+ const RIPGREP_INSTALL_HINTS = {
274
+ darwin: "brew install ripgrep",
275
+ linux: "Install ripgrep with your distro package manager, e.g. apt install ripgrep",
276
+ win32: "winget install BurntSushi.ripgrep.MSVC",
277
+ };
278
+ /** ast-grep ships two equivalent binary names (`ast-grep` and `sg`); either satisfies the probe. */
279
+ function astGrepDescriptor() {
280
+ return {
281
+ id: "ast-grep",
282
+ label: "ast-grep (or sg)",
283
+ installHint: AST_GREP_INSTALL_HINTS,
284
+ probe: async (deps) => {
285
+ const found = await resolveFirstCommandOnPath(deps, ["ast-grep", "sg"]);
286
+ return found ? { found: true, detail: `found on PATH (${found})` } : { found: false };
287
+ },
288
+ };
289
+ }
290
+ function lizardDescriptor() {
291
+ return commandDescriptor("lizard", "lizard", LIZARD_INSTALL_HINTS);
292
+ }
293
+ function ripgrepDescriptor() {
294
+ return commandDescriptor("rg", "ripgrep (rg)", RIPGREP_INSTALL_HINTS);
295
+ }
256
296
  /** Secret-free remediation hint shared by the credential-resolution descriptor. */
257
297
  const CREDENTIAL_RESOLUTION_HINT = "Rerun /install-bridge to persist the routing credential, set BAPI_API_KEY in the " +
258
298
  'environment, or add it under "bapi:<repo_name>" in ~/.config/bridge/credentials.json. ' +
@@ -384,6 +424,9 @@ export function getDoctorOnlyPrereqDescriptors(_platform, _env, agent) {
384
424
  agentDescriptor(agent),
385
425
  credentialResolutionDescriptor(),
386
426
  worktreeMcpReachabilityDescriptor(),
427
+ astGrepDescriptor(),
428
+ lizardDescriptor(),
429
+ ripgrepDescriptor(),
387
430
  ];
388
431
  }
389
432
  /**
@@ -1,2 +1,2 @@
1
1
  // AUTO-GENERATED — do not edit manually. Regenerate with: npm run build
2
- export const VERSION = "0.2.14";
2
+ export const VERSION = "0.2.16";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bridge_gpt/mcp-server",
3
- "version": "0.2.14",
3
+ "version": "0.2.16",
4
4
  "description": "Bridge API MCP server — exposes Jira endpoints as MCP tools for Claude Code agents",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -27,7 +27,7 @@
27
27
  "check:version-generated": "node scripts/bundle-version.js && node scripts/check-version-generated.js",
28
28
  "postbuild": "node scripts/prepend-shebang.cjs",
29
29
  "start": "node build/index.js",
30
- "test": "node --test build/pipeline-utils.test.js build/update-check.test.js build/cli-upgrade.test.js build/decision-page-schema.test.js build/decision-page-template.test.js build/bundle-pipelines.test.js build/instructions-contract.test.js build/pipeline-orchestrator-persistence.test.js build/pipeline-orchestrator-execution.test.js build/pipeline-orchestrator-integration.test.js build/index-static.test.js build/index-resolvers.test.js build/index-project-root.test.js build/index-pipelines.test.js build/index.test.js build/bridge-config.test.js build/credential-store.test.js build/agent-config-credential-migration.test.js build/mcp-invoke.test.js build/mcp-provisioning.test.js build/third-party-mcp-targets.test.js build/git-ignore-utils.test.js build/credential-materialization.test.js build/mcp-registration-doctor.test.js build/secret-safety.test.js build/start-tickets.test.js build/review-tickets.test.js build/start-tickets-base-branch.test.js build/agent-registry.test.js build/agent-registry.model-routing.test.js build/start-tickets.shell-model-routing.test.js build/start-tickets.bridge-api-model-routing.test.js build/start-tickets.tier-fetch-model-routing.test.js build/start-tickets.resolve-model-routing.test.js build/start-tickets.orchestrate-model-routing.test.js build/start-tickets.routing-diagnostics.test.js build/start-tickets-repo.test.js build/start-tickets-credential-invariants.static.test.js build/credentials-cli.test.js build/start-tickets-prereqs.test.js build/doctor.test.js build/install-bridge.test.js build/init.test.js build/resolveUploadAttachment.test.js build/package-static.test.js build/chain-utils.test.js build/chain-orchestrator.test.js build/scheduler-backends/types.test.js build/scheduler-backends/escaping.test.js build/scheduler-backends/launchd.test.js build/scheduler-backends/task-scheduler.test.js build/scheduler-backends/systemd-user.test.js build/scheduler-backends/at-fallback.test.js build/scheduler-backends/index.test.js build/command-catalog.test.js build/scheduled-prompt.test.js build/agent-launchers/claude.test.js build/agent-launchers/cursor.test.js build/agent-launchers/index.test.js build/schedule-store.test.js build/schedule-run.test.js build/agent-capabilities/cli.test.js build/agent-capabilities/runner.test.js build/agent-capabilities/probes.test.js build/agent-capabilities/reporter.test.js build/conductor/taxonomy-and-errors.test.js build/conductor/redaction-normalization.test.js build/conductor/claude-hook.test.js build/conductor/git-ci-types.test.js build/conductor/done-gate.test.js build/conductor/git-ci-taxonomy-payload.test.js build/conductor/bridge-api-client.test.js build/conductor/plan.test.js build/conductor/producer-ledger.test.js build/conductor/spec-review-producer.test.js build/conductor/git-producer.test.js build/conductor/git-hooks.test.js build/conductor/store-migration.test.js build/conductor/pr-discovery.test.js build/conductor/pr-ci-producer.test.js build/conductor/pr-review-producer.test.js build/conductor/doctor.test.js build/conductor/index-poll-ci-producer.test.js build/start-tickets-conductor.test.js build/start-tickets-conductor.spawn.test.js build/conductor/supervisor-config.test.js build/conductor/supervisor-ledger.test.js build/conductor/supervisor-state-reducer.test.js build/conductor/supervisor-housekeeping-projection.test.js build/conductor/supervisor-escalation.test.js build/conductor/supervisor-judgment.test.js build/conductor/supervisor-judgment-python-adapter.test.js build/conductor/supervisor-runtime.test.js build/conductor/supervisor-store-projection.test.js build/conductor/supervisor-cli.test.js build/conductor/supervisor-start-tickets.test.js build/conductor/supervisor-message-relay.test.js build/conductor/supervisor-state-message-events.test.js build/conductor/store-message-relay.test.js build/start-tickets-message-relay.test.js build/conductor/merge-ledger.test.js build/conductor/local-merge.test.js build/conductor/supervisor-merge.test.js build/conductor/bridge-api-merge-client.test.js build/conductor/bridge-api-epic-client.test.js build/conductor/supervisor-merge-runtime-state.test.js build/conductor/epic-state.test.js build/conductor/epic-reconcile.test.js build/conductor/epic-runtime.test.js build/conductor/epic-tick-sequence.test.js build/conductor/epic-runtime-post-action.test.js build/mcp-profile.test.js build/mcp-profile-registration.test.js build/tools-budget.test.js build/integration/measure-tools.test.js build/sfcc/config.test.js build/sfcc/ocapi-shape.test.js build/sfcc/output.test.js build/sfcc/credentials.test.js && node --experimental-test-module-mocks --test build/index-heavy-read-truncation.test.js build/index-artifacts.test.js build/index-brainstorm-filenames.test.js build/index-output-path.test.js build/index-generate-decision-page.test.js build/index-generate-decision-page.integration.test.js build/conductor/paths.test.js build/conductor/store-lifecycle.test.js build/conductor/store-queries.test.js build/conductor/tools.test.js build/conductor/cli.test.js build/conductor/security-regressions.test.js build/conductor/git-inspection.test.js build/conductor/tools-done-gate.test.js build/conductor/cli-git-hooks.test.js build/sfcc/client.test.js build/sfcc/tool-wrapper.test.js build/sfcc/setup-status.test.js build/sfcc/permissions.test.js build/sfcc/register.test.js build/sfcc/reads-system-object.test.js build/sfcc/reads-custom-object-def.test.js build/sfcc/reads-site-preference.test.js",
30
+ "test": "node --test build/pipeline-utils.test.js build/update-check.test.js build/cli-upgrade.test.js build/decision-page-schema.test.js build/decision-page-template.test.js build/bundle-pipelines.test.js build/instructions-contract.test.js build/pipeline-orchestrator-persistence.test.js build/pipeline-orchestrator-execution.test.js build/pipeline-orchestrator-integration.test.js build/index-static.test.js build/index-resolvers.test.js build/index-project-root.test.js build/index-pipelines.test.js build/index.test.js build/bridge-config.test.js build/credential-store.test.js build/agent-config-credential-migration.test.js build/mcp-invoke.test.js build/mcp-provisioning.test.js build/third-party-mcp-targets.test.js build/git-ignore-utils.test.js build/credential-materialization.test.js build/mcp-registration-doctor.test.js build/secret-safety.test.js build/start-tickets.test.js build/review-tickets.test.js build/start-tickets-base-branch.test.js build/agent-registry.test.js build/agent-registry.model-routing.test.js build/start-tickets.shell-model-routing.test.js build/start-tickets.bridge-api-model-routing.test.js build/start-tickets.tier-fetch-model-routing.test.js build/start-tickets.resolve-model-routing.test.js build/start-tickets.orchestrate-model-routing.test.js build/start-tickets.routing-diagnostics.test.js build/start-tickets-repo.test.js build/start-tickets-credential-invariants.static.test.js build/credentials-cli.test.js build/start-tickets-prereqs.test.js build/regression-check.test.js build/doctor.test.js build/install-bridge.test.js build/init.test.js build/resolveUploadAttachment.test.js build/package-static.test.js build/chain-utils.test.js build/chain-orchestrator.test.js build/scheduler-backends/types.test.js build/scheduler-backends/escaping.test.js build/scheduler-backends/launchd.test.js build/scheduler-backends/task-scheduler.test.js build/scheduler-backends/systemd-user.test.js build/scheduler-backends/at-fallback.test.js build/scheduler-backends/index.test.js build/command-catalog.test.js build/scheduled-prompt.test.js build/agent-launchers/claude.test.js build/agent-launchers/cursor.test.js build/agent-launchers/index.test.js build/schedule-store.test.js build/schedule-run.test.js build/agent-capabilities/cli.test.js build/agent-capabilities/runner.test.js build/agent-capabilities/probes.test.js build/agent-capabilities/reporter.test.js build/conductor/taxonomy-and-errors.test.js build/conductor/redaction-normalization.test.js build/conductor/claude-hook.test.js build/conductor/git-ci-types.test.js build/conductor/done-gate.test.js build/conductor/git-ci-taxonomy-payload.test.js build/conductor/bridge-api-client.test.js build/conductor/plan.test.js build/conductor/producer-ledger.test.js build/conductor/spec-review-producer.test.js build/conductor/git-producer.test.js build/conductor/git-hooks.test.js build/conductor/store-migration.test.js build/conductor/pr-discovery.test.js build/conductor/pr-ci-producer.test.js build/conductor/pr-review-producer.test.js build/conductor/doctor.test.js build/conductor/index-poll-ci-producer.test.js build/start-tickets-conductor.test.js build/start-tickets-conductor.spawn.test.js build/conductor/supervisor-config.test.js build/conductor/supervisor-ledger.test.js build/conductor/supervisor-state-reducer.test.js build/conductor/supervisor-housekeeping-projection.test.js build/conductor/supervisor-escalation.test.js build/conductor/supervisor-judgment.test.js build/conductor/supervisor-judgment-python-adapter.test.js build/conductor/supervisor-runtime.test.js build/conductor/supervisor-store-projection.test.js build/conductor/supervisor-cli.test.js build/conductor/supervisor-start-tickets.test.js build/conductor/supervisor-message-relay.test.js build/conductor/supervisor-state-message-events.test.js build/conductor/store-message-relay.test.js build/start-tickets-message-relay.test.js build/conductor/merge-ledger.test.js build/conductor/local-merge.test.js build/conductor/supervisor-merge.test.js build/conductor/bridge-api-merge-client.test.js build/conductor/bridge-api-epic-client.test.js build/conductor/supervisor-merge-runtime-state.test.js build/conductor/epic-state.test.js build/conductor/epic-reconcile.test.js build/conductor/epic-runtime.test.js build/conductor/epic-tick-sequence.test.js build/conductor/epic-runtime-post-action.test.js build/mcp-profile.test.js build/mcp-profile-registration.test.js build/tools-budget.test.js build/integration/measure-tools.test.js build/sfcc/config.test.js build/sfcc/ocapi-shape.test.js build/sfcc/output.test.js build/sfcc/credentials.test.js && node --experimental-test-module-mocks --test build/index-heavy-read-truncation.test.js build/index-artifacts.test.js build/index-brainstorm-filenames.test.js build/index-output-path.test.js build/index-generate-decision-page.test.js build/index-generate-decision-page.integration.test.js build/conductor/paths.test.js build/conductor/store-lifecycle.test.js build/conductor/store-queries.test.js build/conductor/tools.test.js build/conductor/cli.test.js build/conductor/security-regressions.test.js build/conductor/git-inspection.test.js build/conductor/tools-done-gate.test.js build/conductor/cli-git-hooks.test.js build/sfcc/client.test.js build/sfcc/tool-wrapper.test.js build/sfcc/setup-status.test.js build/sfcc/permissions.test.js build/sfcc/register.test.js build/sfcc/reads-system-object.test.js build/sfcc/reads-custom-object-def.test.js build/sfcc/reads-site-preference.test.js",
31
31
  "test:integration": "node --test build/integration/refresh-main.integration.test.js build/integration/start-tickets.integration.test.js build/integration/doctor.integration.test.js build/integration/agent-capabilities.integration.test.js build/integration/conductor-producer.integration.test.js build/integration/conductor-message-relay.integration.test.js",
32
32
  "test:smoke": "node --test build/integration/packaged-cli-smoke.test.js",
33
33
  "prepublishOnly": "node scripts/bundle-assets.js && npm run build && node scripts/verify-shebang.cjs"