@rosthq/cli 0.7.139 → 0.7.141

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/README.md CHANGED
@@ -119,11 +119,16 @@ rost onboard source-ingest \
119
119
  The JSON output contains the opaque `source_upload_id` and the exact
120
120
  `source_ref` object to place in the setup plan's `sources[]`.
121
121
 
122
- Transport note: the command body is capped server-side at 1 MiB, and base64
123
- expands content by 4/3 so the largest source file reachable through this
124
- command today is about 780 KB, not the protocol's documented 5,000,000-byte
125
- bound. The CLI checks this before sending and names the exact fitting size;
126
- split or trim a larger export.
122
+ Transport note: two ceilings apply, and the smaller one wins. The application
123
+ caps the command body at 1 MiB for most commands, but `onboarding.source_ingest`
124
+ gets a selectively raised cap (≈ 6.7 MB) sized for its base64 expansion (×4/3).
125
+ The hosting platform enforces a lower request-body ceiling in front of that —
126
+ measured at **at least 4 MiB**, the largest body proven to reach the function —
127
+ and rejects a larger body at the edge before the application sees it. Base64
128
+ expansion therefore puts the largest source file this command can carry at
129
+ roughly **3.1 MB**, not the protocol's documented 5,000,000-byte bound. The CLI
130
+ derives its pre-check from the platform ceiling and names the exact fitting size
131
+ before sending; split or trim a larger export.
127
132
 
128
133
  Stage the one-approval composite setup with the complete declarative plan
129
134
  (`--input '<json>'` inline, or `--input-file <path>` for a large plan):
@@ -7,6 +7,26 @@ export type OnboardingDeps = {
7
7
  makeClient(): Promise<CommandClient>;
8
8
  readFile?: (path: string) => Promise<Buffer>;
9
9
  };
10
+ /**
11
+ * The largest source file this invocation can actually send: the smallest of the
12
+ * three real limits, derived ONCE so the byte count the CLI PRINTS is the byte
13
+ * count it ENFORCES.
14
+ *
15
+ * Exported and parameterised on `bodyCapBytes` for one reason: the
16
+ * `ONBOARDING_SOURCE_MAX_BYTES` clamp is **not the binding term today** — the
17
+ * platform ceiling puts the transport-derived term at ~3.14 MB, well under the
18
+ * 5,000,000-byte protocol bound — so no fixture built from the shipped constants
19
+ * can exercise it, and an untestable clamp is indistinguishable from a clamp that
20
+ * does not work. It becomes binding the moment the effective body cap rises above
21
+ * `ceil(ONBOARDING_SOURCE_MAX_BYTES / 3) * 4 + margins`, which is exactly what
22
+ * happens when the platform ceiling is raised (DER-2927). Passing the cap in lets
23
+ * a test pin that future without waiting for it.
24
+ *
25
+ * `overheadBytes` is the invocation's own serialized size measured with an EMPTY
26
+ * `content_base64`; base64 is ASCII, so its character length equals its UTF-8 byte
27
+ * length and the remaining budget converts at 4 base64 chars per 3 source bytes.
28
+ */
29
+ export declare function maxSendableSourceFileBytes(overheadBytes: number, bodyCapBytes?: number): number;
10
30
  export type OnboardingInvocation = {
11
31
  commandId: "onboarding.status" | "onboarding.resume" | "onboarding.rehearse" | "onboarding.activate" | "onboarding.source_ingest" | "onboarding.setup";
12
32
  body: Record<string, unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"onboarding.d.ts","sourceRoot":"","sources":["../../src/commands/onboarding.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAsB,MAAM,sBAAsB,CAAC;AAMzE,KAAK,KAAK,GAAG;IACX,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC1C,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAI3B,UAAU,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IAGrC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAC9C,CAAC;AAmDF,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,EACL,mBAAmB,GACnB,mBAAmB,GACnB,qBAAqB,GACrB,qBAAqB,GACrB,0BAA0B,GAC1B,kBAAkB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,eAAe,GAAG,OAAO,GAAG,cAAc,CAAC;IAInG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,OAAO,EAAE,MAAM;CAI5B;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAepG;AAED;;;;;;;GAOG;AACH,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,oBAAoB,EAChC,EAAE,EAAE,KAAK,EACT,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,MAAM,CAAC,CAAC;AACnB,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,oBAAoB,EAChC,EAAE,EAAE,KAAK,EACT,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE;IAAE,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,SAAS,GAAG,OAAO,CAAA;CAAE,GAC5D,OAAO,CAAC,MAAM,GAAG,cAAc,CAAC,CAAC;AAoCpC;;;;;GAKG;AACH,wBAAsB,gCAAgC,CACpD,UAAU,EAAE,oBAAoB,EAChC,YAAY,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAY,GACzD,OAAO,CAAC,IAAI,CAAC,CA8Cf;AAgDD,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,oBAAoB,CA+G9E;AA2FD,wBAAgB,eAAe,IAAI,MAAM,CAUxC;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,oBAAoB,CAAC,QAAQ,CAAC,EACtC,MAAM,EAAE,OAAO,GACd,MAAM,CAoBR"}
1
+ {"version":3,"file":"onboarding.d.ts","sourceRoot":"","sources":["../../src/commands/onboarding.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,aAAa,EAAsB,MAAM,sBAAsB,CAAC;AAMzE,KAAK,KAAK,GAAG;IACX,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC1C,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAI3B,UAAU,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IAGrC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAC9C,CAAC;AAkDF;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,0BAA0B,CACxC,aAAa,EAAE,MAAM,EACrB,YAAY,GAAE,MAAsC,GACnD,MAAM,CAMR;AAqBD,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,EACL,mBAAmB,GACnB,mBAAmB,GACnB,qBAAqB,GACrB,qBAAqB,GACrB,0BAA0B,GAC1B,kBAAkB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,eAAe,GAAG,OAAO,GAAG,cAAc,CAAC;IAInG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,OAAO,EAAE,MAAM;CAI5B;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAepG;AAED;;;;;;;GAOG;AACH,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,oBAAoB,EAChC,EAAE,EAAE,KAAK,EACT,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,MAAM,CAAC,CAAC;AACnB,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,oBAAoB,EAChC,EAAE,EAAE,KAAK,EACT,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE;IAAE,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,SAAS,GAAG,OAAO,CAAA;CAAE,GAC5D,OAAO,CAAC,MAAM,GAAG,cAAc,CAAC,CAAC;AAoCpC;;;;;GAKG;AACH,wBAAsB,gCAAgC,CACpD,UAAU,EAAE,oBAAoB,EAChC,YAAY,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAY,GACzD,OAAO,CAAC,IAAI,CAAC,CAqEf;AAgDD,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,oBAAoB,CA+G9E;AA2FD,wBAAgB,eAAe,IAAI,MAAM,CAUxC;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,oBAAoB,CAAC,QAAQ,CAAC,EACtC,MAAM,EAAE,OAAO,GACd,MAAM,CAoBR"}
package/dist/index.js CHANGED
@@ -36074,6 +36074,9 @@ var canonicalReadingDecimalSchema = external_exports.string().trim().min(1).max(
36074
36074
  var managedInferenceHardCapSchema = external_exports.string().trim().max(11).regex(/^(?:0|[1-9]\d{0,7})\.\d{2}$/);
36075
36075
  var ONBOARDING_SETUP_PLAN_MAX_BYTES = 1048576;
36076
36076
  var ONBOARDING_SOURCE_MAX_BYTES = 5e6;
36077
+ var ONBOARDING_SOURCE_INGEST_BODY_MARGIN_BYTES = 8192;
36078
+ var ONBOARDING_SOURCE_INGEST_BODY_CAP_BYTES = Math.ceil(ONBOARDING_SOURCE_MAX_BYTES / 3) * 4 + ONBOARDING_SOURCE_INGEST_BODY_MARGIN_BYTES;
36079
+ var COMMAND_TRANSPORT_PLATFORM_BODY_CEILING_BYTES = 4194304;
36077
36080
  var onboardingSourceKindSchema = external_exports.enum([
36078
36081
  "org_chart",
36079
36082
  "signal_export",
@@ -52427,7 +52430,7 @@ var referenceDocuments = [
52427
52430
  order: 10,
52428
52431
  title: "{{brand}} implementation method",
52429
52432
  summary: "The staged operating-system setup path used by humans, CLI sessions, MCP clients, and in-app agents.",
52430
- version: "2026-07-30.2",
52433
+ version: "2026-07-30.3",
52431
52434
  public: true,
52432
52435
  audiences: ["human", "cli", "mcp", "in_app_agent"],
52433
52436
  stages: ["company_setup", "graph_design", "charter_design", "staffing", "operating_rhythm"],
@@ -52560,6 +52563,8 @@ The Compass is drafted, then activated by a human through supersession.
52560
52563
 
52561
52564
  \`onboarding.setup\`, \`onboarding.finish\`, \`compass.approve_version\`, \`compass.reject_draft\`, and \`compass.set\` are \`human_required\`. \`onboarding.source_ingest\` is a bootstrap-safe \`none\` prerequisite that retains bounded source bytes encrypted under the exact tenant/run, computes its digest and canonical parser manifest server-side, and remains permanently outside Trusted and Full Operator. \`onboarding.setup\` is the one-approval composite apply: it freezes the complete plan and live proof at staging, then rechecks them and applies Compass, cycle, Responsibility Graph, Charters, staffing, goals, Signals/readings, Frictions, tasks, and Sync scope in one transaction. A failure rolls back the entire application and leaves the confirmation pending.
52562
52565
 
52566
+ Both commands fail closed on a missing server capability (for example unconfigured document-source storage) with a named, owner-facing remediation string that says what to do next \u2014 never a bare error code or a raw configuration value. \`onboarding.source_ingest\` checks this before decoding the uploaded source; \`onboarding.setup\` checks it before any plan-shape or Responsibility Graph foundation validation runs, so the block happens as early as the command can report it. The web onboarding entry screen surfaces the same deployment-wide readiness state before an owner invests in the flow.
52567
+
52563
52568
  The whole composite flow has first-class CLI verbs: \`{{cli}} onboard source-ingest --file <path> ...\` for each allowed local source, \`{{cli}} onboard setup --input-file <plan.json>\` to stage the one owner approval (it prints the confirmation id and exact approval URL), \`{{cli}} onboard setup-status --input-file <plan.json>\` to discover the applied receipt by idempotent re-submission of the identical plan, then \`{{cli}} onboard rehearse\` and \`{{cli}} onboard activate\`. Each authenticates with the implementation-bootstrap credential first and falls back to the user session; the generic \`{{cli}} command <id> --json\` path and the generated MCP tools expose the same schemas.
52564
52569
 
52565
52570
  After setup succeeds, call \`onboarding.rehearse\` with the exact setup application, expected setup digest/revision, and a caller idempotency key. This is the implementation principal's one bounded \`execute\` exception: it is ungated because it can run only the setup receipt's exact agents in the sandbox, with no schedule arming, go-live transition, credential access, source mutation, or external communication. It rechecks the current Charter manifest, pinned published Skill versions and content hashes, schedule, execution lane, and canonical configuration digest under the same tenant/run boundary. A complete batch returns an immutable terminal batch receipt plus one immutable per-agent receipt with nonzero checked counts, runtime run ids, bounded tool previews/manifest holds/errors, and \`passed\` or \`failed\` status. Same-key/same-configuration retry returns that terminal evidence; a changed configuration conflicts instead of silently reusing it. The rehearsal never returns an approval URL and never stages activation. The later, separate \`onboarding.activate\` command consumes that exact terminal batch and the unique run/configuration evidence for the setup receipt's complete agent set. It stages one owner approval whose durable card shows every agent, Seat, Charter/configuration digest, rehearsal run, effective lane/model, permissions, schedule, warnings, and the onboarding-completion effect. Approval rechecks the full projection, records one composite human decision, makes every agent live, arms eligible schedules, and completes onboarding atomically. Any stale or failed member rolls the transaction back; same-key retry returns the committed receipt without duplicating effects.
@@ -53706,7 +53711,7 @@ External connectors are being rolled out provider by provider, conservatively (r
53706
53711
  order: 48,
53707
53712
  title: "CLI and MCP installation guide",
53708
53713
  summary: "Install the public CLI, register remote token-backed MCP clients, and find the full command and tool catalog.",
53709
- version: "2026-07-31.1",
53714
+ version: "2026-07-31.2",
53710
53715
  public: true,
53711
53716
  audiences: ["human", "cli", "mcp", "in_app_agent"],
53712
53717
  stages: ["company_setup", "staffing"],
@@ -54240,7 +54245,7 @@ These are the security posture rules for operating after install \u2014 a checkl
54240
54245
  {{cli}} onboard rehearse|activate --setup-application-id <uuid> ... [--json]
54241
54246
  \`\`\`
54242
54247
 
54243
- Every tenant-scoped \`onboard\` verb (\`status\`, \`resume\`, \`source-ingest\`, \`setup\`, \`setup-status\`, \`rehearse\`, \`activate\` \u2014 \`onboard run\` is an offline public print) authenticates with an existing implementation-bootstrap credential first and falls back to the user session, so the agent-led composite flow works without a personal login. \`onboard source-ingest\` reads one local business file client-side, base64-encodes it, and calls \`onboarding.source_ingest\`; the server computes the digest and family manifest and returns the opaque \`source_ref\` to reference from the setup plan's \`sources[]\` (paths and client digests are rejected). The server's 1 MiB command-body cap is authoritative, and base64 expands content by 4/3, so the largest file reachable through this command today is about 780 KB \u2014 the CLI pre-checks and names the exact fitting size; split a larger export. \`onboard setup\` submits the complete declarative plan to \`onboarding.setup\`: staging succeeds with exit code 0 and prints the pending confirmation id plus the exact approval URL (with \`--json\`, the full pending-confirmation object). \`onboard setup-status\` re-submits the identical plan to discover state through the command's idempotent contract: after approval it returns the immutable applied receipt (application id, receipt revision, input digest) without staging anything; while approval is still pending it returns the current approval card \u2014 an identical still-valid card is reused with the same confirmation id and URL, and only a changed server-derived projection supersedes the stale card and mints a fresh one. After application, a same-key re-submission with a different plan digest is a typed conflict.
54248
+ Every tenant-scoped \`onboard\` verb (\`status\`, \`resume\`, \`source-ingest\`, \`setup\`, \`setup-status\`, \`rehearse\`, \`activate\` \u2014 \`onboard run\` is an offline public print) authenticates with an existing implementation-bootstrap credential first and falls back to the user session, so the agent-led composite flow works without a personal login. \`onboard source-ingest\` reads one local business file client-side, base64-encodes it, and calls \`onboarding.source_ingest\`; the server computes the digest and family manifest and returns the opaque \`source_ref\` to reference from the setup plan's \`sources[]\` (paths and client digests are rejected). Two size ceilings apply to this upload and the smaller one wins. The application's command-body cap is 1 MiB for most commands, but \`onboarding.source_ingest\` gets a selectively raised cap (\u2248 6.7 MB, on both the REST and MCP command transports) sized for base64 expansion (\xD74/3). In front of that, the hosting platform enforces a lower request-body ceiling \u2014 measured at at least 4 MiB, the largest body proven to reach the function \u2014 and rejects a larger body at the edge before {{brand}} sees it, so no {{brand}} error can describe that failure. **The platform ceiling is what sets the maximum size.** The raised 6.7 MB application cap sits above it and so never rejects a body the platform would have delivered. The 5,000,000-byte protocol bound is still enforced \u2014 a larger file is refused on that ground first \u2014 but it too sits above the reachable size, so it never decides how large a source can actually be. Only the platform ceiling does, which is why raising the 6.7 MB cap on its own would not make a bigger source uploadable. After base64 expansion the largest source file this command can carry is therefore about **3.1 MB**, short of the protocol's documented 5,000,000-byte source range; reaching that full range needs the platform ceiling raised, which is a separate change. The CLI derives its pre-check from the platform ceiling and names the exact fitting size before sending \u2014 split a larger export. \`onboard setup\` submits the complete declarative plan to \`onboarding.setup\`: staging succeeds with exit code 0 and prints the pending confirmation id plus the exact approval URL (with \`--json\`, the full pending-confirmation object). \`onboard setup-status\` re-submits the identical plan to discover state through the command's idempotent contract: after approval it returns the immutable applied receipt (application id, receipt revision, input digest) without staging anything; while approval is still pending it returns the current approval card \u2014 an identical still-valid card is reused with the same confirmation id and URL, and only a changed server-derived projection supersedes the stale card and mints a fresh one. After application, a same-key re-submission with a different plan digest is a typed conflict.
54244
54249
 
54245
54250
  | Command | Purpose | Scope | Safe example |
54246
54251
  |---|---|---|---|
@@ -59056,8 +59061,18 @@ function formatStagedConfirmation(commandId, details, overrides = {}) {
59056
59061
  var REHEARSE_USAGE = `${cliBrand.binName} onboard rehearse --setup-application-id <uuid> --expected-input-digest <sha256:digest> --expected-receipt-revision <integer> --idempotency-key <key> [--json]`;
59057
59062
  var ACTIVATE_USAGE = `${cliBrand.binName} onboard activate --setup-application-id <uuid> --expected-input-digest <sha256:digest> --expected-receipt-revision <integer> --terminal-rehearsal-batch-receipt-id <uuid> --rehearsal-runs '<json-array>' --configuration-digests '<json-array>' --idempotency-key <key> [--json]`;
59058
59063
  var SOURCE_INGEST_USAGE = `${cliBrand.binName} onboard source-ingest --file <path> --source-key <key> --kind <kind> --title <title> [--json]`;
59059
- var SERVER_COMMAND_BODY_CAP_BYTES = 1048576;
59064
+ var SERVER_COMMAND_BODY_CAP_BYTES = Math.min(
59065
+ ONBOARDING_SOURCE_INGEST_BODY_CAP_BYTES,
59066
+ COMMAND_TRANSPORT_PLATFORM_BODY_CEILING_BYTES
59067
+ );
59060
59068
  var COMMAND_BODY_SAFETY_MARGIN_BYTES = 4096;
59069
+ function maxSendableSourceFileBytes(overheadBytes, bodyCapBytes = SERVER_COMMAND_BODY_CAP_BYTES) {
59070
+ const preflightCap = bodyCapBytes - COMMAND_BODY_SAFETY_MARGIN_BYTES;
59071
+ return Math.min(
59072
+ Math.floor((preflightCap - overheadBytes) / 4) * 3,
59073
+ ONBOARDING_SOURCE_MAX_BYTES
59074
+ );
59075
+ }
59061
59076
  var SETUP_USAGE = `${cliBrand.binName} onboard setup --input '<json-plan>' | --input-file <path> [--json]`;
59062
59077
  var SETUP_STATUS_USAGE = `${cliBrand.binName} onboard setup-status --input '<json-plan>' | --input-file <path> [--json]`;
59063
59078
  function sourceIngestKinds() {
@@ -59124,15 +59139,23 @@ async function resolveOnboardingInvocationFiles(invocation, readFileImpl = readF
59124
59139
  if (bytes.length === 0) {
59125
59140
  throw new OnboardingUsageError(`--file ${invocation.sourceFile} is empty.`);
59126
59141
  }
59142
+ const overheadBytes = Buffer.byteLength(
59143
+ JSON.stringify({ ...invocation.body, content_base64: "" }),
59144
+ "utf8"
59145
+ );
59146
+ const preflightCap = SERVER_COMMAND_BODY_CAP_BYTES - COMMAND_BODY_SAFETY_MARGIN_BYTES;
59147
+ const maxSendableFileBytes = maxSendableSourceFileBytes(overheadBytes);
59148
+ if (bytes.length > ONBOARDING_SOURCE_MAX_BYTES) {
59149
+ throw new OnboardingUsageError(
59150
+ `--file ${invocation.sourceFile} is ${bytes.length} bytes, over the onboarding.source_ingest protocol's documented ${ONBOARDING_SOURCE_MAX_BYTES}-byte source range. The largest file this invocation can actually send is about ${maxSendableFileBytes} bytes. Split the export or trim rows/columns to fit.`
59151
+ );
59152
+ }
59127
59153
  const contentBase64 = bytes.toString("base64");
59128
59154
  invocation.body.content_base64 = contentBase64;
59129
59155
  const bodyBytes = Buffer.byteLength(JSON.stringify(invocation.body), "utf8");
59130
- const preflightCap = SERVER_COMMAND_BODY_CAP_BYTES - COMMAND_BODY_SAFETY_MARGIN_BYTES;
59131
59156
  if (bodyBytes > preflightCap) {
59132
- const overheadBytes = bodyBytes - contentBase64.length;
59133
- const effectiveMaxFileBytes = Math.floor((preflightCap - overheadBytes) / 4) * 3;
59134
59157
  throw new OnboardingUsageError(
59135
- `--file ${invocation.sourceFile} is ${bytes.length} bytes; base64-encoded it makes a ${bodyBytes}-byte command body, over the server's authoritative ${SERVER_COMMAND_BODY_CAP_BYTES}-byte command-transport cap (this check stops ${COMMAND_BODY_SAFETY_MARGIN_BYTES} bytes early on purpose). The largest file this invocation can send is about ${effectiveMaxFileBytes} bytes. The onboarding.source_ingest protocol documents sources up to 5,000,000 bytes; reaching that range needs the server-side transport follow-up. Split the export or trim rows/columns to fit.`
59158
+ `--file ${invocation.sourceFile} is ${bytes.length} bytes; base64-encoded it makes a ${bodyBytes}-byte command body, over the ${preflightCap}-byte preflight budget for this command (the ${SERVER_COMMAND_BODY_CAP_BYTES}-byte request-body ceiling it has to get through, minus a deliberate ${COMMAND_BODY_SAFETY_MARGIN_BYTES}-byte margin). The largest file this invocation can send is about ${maxSendableFileBytes} bytes. Split the export or trim rows/columns to fit.`
59136
59159
  );
59137
59160
  }
59138
59161
  delete invocation.sourceFile;