@formigio/fazemos-cli 0.10.42 → 0.10.43

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 CHANGED
@@ -9152,11 +9152,61 @@ Types: question | task | signal | response | flag | decision | direction`)
9152
9152
  `Run from inside a Fazemos-aware workspace.`);
9153
9153
  }
9154
9154
  // Resolve recipient
9155
+ // rul_dispatch_cli_fallthrough_on_local_unresolved
9155
9156
  const resolved = resolveRole(to, localRegistry);
9156
9157
  if (!resolved) {
9157
- throw new Error(`Role "${to}" not found in local registry or any cross-workspace ref. ` +
9158
- `Check .fazemos/roles.json.`);
9158
+ // Registry-less path: recipient not found in local workspace registry
9159
+ // (e.g. cross-workspace human role like `founder` in a peer workspace).
9160
+ // Fall through to server-side DB resolution via POST /api/dispatches.
9161
+ // The server resolves the recipient via role_registrations (workspace-agnostic).
9162
+ // rul_dispatch_cli_fallthrough_on_local_unresolved
9163
+ const unresolvedDepth = computeChildDispatchDepth(process.env.FAZEMOS_ORIGINATING_DISPATCH_DEPTH);
9164
+ const unresolvedReqBody = {
9165
+ to,
9166
+ from: opts.from,
9167
+ type,
9168
+ priority: opts.priority ?? 'normal',
9169
+ body,
9170
+ thread_id: opts.thread ?? null,
9171
+ re: opts.re ? [opts.re] : null,
9172
+ expires_at: opts.expiresAt ?? null,
9173
+ source: 'cli',
9174
+ runbook_ref: opts.runbookRef ?? null,
9175
+ params: runbookParams ?? null,
9176
+ dispatch_depth: unresolvedDepth,
9177
+ };
9178
+ let unresolvedResp;
9179
+ try {
9180
+ unresolvedResp = await api('POST', '/api/dispatches', unresolvedReqBody);
9181
+ }
9182
+ catch (err) {
9183
+ // rul_dispatch_4xx_still_hard_fails (BUG53 semantics preserved)
9184
+ // Deliberate 4xx (FROM_ROLE_FORBIDDEN, depth ceiling, validation) hard-fails
9185
+ // in the registry-less path too. No local file fallback — no role.inbox
9186
+ // available (no resolved role entry). Preserves the BUG53 loud-failure contract.
9187
+ // rul_dispatch_local_file_best_effort_cross_workspace
9188
+ const status = err instanceof ApiError ? err.status : undefined;
9189
+ if (!shouldFallBackToFile(status)) {
9190
+ const code = err instanceof ApiError && err.code ? ` ${err.code}` : '';
9191
+ console.error(chalk.red(`✗ Dispatch refused (${status}${code}): ${err instanceof Error ? err.message : String(err)}`));
9192
+ console.error(chalk.gray(' Not falling back to file-only — a deliberate refusal must not be bypassed.'));
9193
+ process.exitCode = 1;
9194
+ return;
9195
+ }
9196
+ // Transient failure (network / 5xx) — no local file fallback in registry-less path.
9197
+ // rul_dispatch_local_file_best_effort_cross_workspace
9198
+ throw err;
9199
+ }
9200
+ // 2xx — server resolved the recipient. Print UX §4.4 stdout copy verbatim.
9201
+ // rul_dispatch_local_file_best_effort_cross_workspace
9202
+ console.log(chalk.green(`✓ Dispatched to ${to} (server-resolved) — id: ${unresolvedResp.id}`));
9203
+ console.log(` Local inbox mirror skipped: '${to}' is not in this workspace's registry;`);
9204
+ console.log(` the durable artifact is the DB row + Slack notification.`);
9205
+ // SKIP local inbox-file write (no role.inbox) — rul_dispatch_local_file_best_effort_cross_workspace
9206
+ // SKIP agent-mode commit+push (no relPath) — rul_dispatch_local_file_best_effort_cross_workspace
9207
+ return;
9159
9208
  }
9209
+ // ── Resolved path: existing behavior unchanged ──────────────────────────
9160
9210
  const { role, registry } = resolved;
9161
9211
  const input = {
9162
9212
  to,