@capxul/cli 4.20.0-beta.10 → 4.20.0-beta.11

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/main.mjs CHANGED
@@ -95,8 +95,7 @@ const RESTORING = { phase: "restoring" };
95
95
  const label = (state) => {
96
96
  if (state.phase !== "authenticated") return state.phase;
97
97
  if (state.account.at !== "claimed") return `authenticated:${state.account.at}`;
98
- const org = state.account.org;
99
- return org === null ? "authenticated:claimed" : `authenticated:claimed:${org.at}`;
98
+ return state.account.org === null ? "authenticated:claimed" : "authenticated:claimed:organization";
100
99
  };
101
100
  const EVENT_TAGS = [
102
101
  "RequestOtp",
@@ -114,8 +113,8 @@ const EVENT_TAGS = [
114
113
  "RetryAccount",
115
114
  "CreateOrganization",
116
115
  "AttachOrganization",
117
- "RetryOrganization",
118
- "LeaveOrganization"
116
+ "LeaveOrganization",
117
+ "ObserveOrganization"
119
118
  ];
120
119
  const PRIVATE_EVENT_TAGS = [
121
120
  "OtpSent",
@@ -131,9 +130,8 @@ const PRIVATE_EVENT_TAGS = [
131
130
  "AccountClaiming",
132
131
  "AccountClaimed",
133
132
  "AccountFailed",
134
- "OrgAt",
135
- "OrgReady",
136
- "OrgFailed"
133
+ "OrgSelected",
134
+ "OrgSelectionFailed"
137
135
  ];
138
136
  const IDENTITY_EVENT_TAGS = [...EVENT_TAGS, ...PRIVATE_EVENT_TAGS];
139
137
  /** Valid in every `authenticated:*` position — the pre-S1 auth machine's row. */
@@ -183,18 +181,11 @@ const TRANSITION_TABLE = {
183
181
  "CreateOrganization",
184
182
  "AttachOrganization"
185
183
  ],
186
- "authenticated:claimed:creating": [...SESSION_EVENTS],
187
- "authenticated:claimed:loading": [...SESSION_EVENTS],
188
- "authenticated:claimed:settingUp": [...SESSION_EVENTS],
189
- "authenticated:claimed:ready": [
184
+ "authenticated:claimed:organization": [
190
185
  ...SESSION_EVENTS,
191
186
  "AttachOrganization",
192
- "LeaveOrganization"
193
- ],
194
- "authenticated:claimed:failed": [
195
- ...SESSION_EVENTS,
196
- "RetryOrganization",
197
- "LeaveOrganization"
187
+ "LeaveOrganization",
188
+ "ObserveOrganization"
198
189
  ]
199
190
  };
200
191
  const DEFAULT_CONFIG = {
@@ -274,36 +265,24 @@ const privateTransition = (state, event) => {
274
265
  failure: event.failure,
275
266
  retryable: isRetryable(event.failure)
276
267
  }) } : WRONG;
277
- case "OrgAt": {
278
- const held = claimedOrg(state);
279
- if (held === null || held.claimed.org === null) return WRONG;
280
- const org = held.claimed.org;
281
- return org.at === "creating" || org.at === "loading" || org.at === "settingUp" ? { next: withOrg(held.state, held.claimed, {
282
- at: "settingUp",
283
- orgId: event.orgId,
284
- step: event.step
285
- }) } : WRONG;
286
- }
287
- case "OrgReady": {
268
+ case "OrgSelected": {
288
269
  const held = claimedOrg(state);
289
- if (held === null || held.claimed.org === null) return WRONG;
290
- const org = held.claimed.org;
291
- return org.at === "creating" || org.at === "settingUp" || org.at === "loading" ? { next: withOrg(held.state, held.claimed, {
292
- at: "ready",
293
- orgId: event.orgId
294
- }) } : WRONG;
270
+ if (held === null || held.claimed.org === null || held.claimed.org.orgId !== null) return WRONG;
271
+ return { next: withOrg(held.state, held.claimed, {
272
+ orgId: event.setup.orgId,
273
+ setup: event.setup,
274
+ observation: "connected"
275
+ }) };
295
276
  }
296
- case "OrgFailed": {
277
+ case "OrgSelectionFailed": {
297
278
  const held = claimedOrg(state);
298
- if (held === null || held.claimed.org === null) return WRONG;
299
- const org = held.claimed.org;
300
- return org.at === "creating" || org.at === "loading" || org.at === "settingUp" ? { next: withOrg(held.state, held.claimed, {
301
- at: "failed",
302
- orgId: event.orgId,
303
- step: event.step,
304
- failure: event.failure,
305
- retryable: event.retryable ?? isRetryable(event.failure)
306
- }) } : WRONG;
279
+ if (held === null || held.claimed.org === null || held.claimed.org.orgId !== null) return WRONG;
280
+ return { next: withOrg(held.state, held.claimed, {
281
+ orgId: null,
282
+ setup: null,
283
+ observation: "error",
284
+ failure: event.failure
285
+ }) };
307
286
  }
308
287
  }
309
288
  };
@@ -372,35 +351,43 @@ const transition$1 = (state, event, config = DEFAULT_CONFIG) => {
372
351
  case "CreateOrganization": {
373
352
  const held = claimedOrg(state);
374
353
  if (held === null || held.claimed.org !== null) return WRONG;
375
- const draft = {
376
- name: event.draft.name,
377
- handle: event.draft.handle,
378
- country: event.draft.country
379
- };
380
354
  return { next: withOrg(held.state, held.claimed, {
381
- at: "creating",
382
- draft
355
+ orgId: null,
356
+ setup: null,
357
+ observation: "loading"
383
358
  }) };
384
359
  }
385
360
  case "AttachOrganization": {
386
361
  const held = claimedOrg(state);
387
362
  if (held === null) return WRONG;
388
- if (held.claimed.org?.at === "ready" && held.claimed.org.orgId === event.orgId) return { next: state };
389
- if (held.claimed.org !== null && held.claimed.org.at !== "ready") return WRONG;
363
+ if (held.claimed.org?.orgId === event.orgId) return { next: state };
390
364
  return { next: withOrg(held.state, held.claimed, {
391
- at: "loading",
392
- orgId: event.orgId
365
+ orgId: event.orgId,
366
+ setup: null,
367
+ observation: "loading"
393
368
  }) };
394
369
  }
395
- case "RetryOrganization": {
370
+ case "ObserveOrganization": {
396
371
  const held = claimedOrg(state);
397
- if (held === null || held.claimed.org === null) return WRONG;
398
- const org = held.claimed.org;
399
- if (org.at !== "failed" || !org.retryable || org.orgId === null) return WRONG;
372
+ if (held === null || held.claimed.org?.orgId !== event.orgId) return WRONG;
373
+ const snapshot = event.snapshot;
374
+ if (snapshot.status === "value") {
375
+ if (String(snapshot.value.orgId) !== event.orgId) return { refused: "INVALID_INPUT" };
376
+ return { next: withOrg(held.state, held.claimed, {
377
+ orgId: event.orgId,
378
+ setup: snapshot.value,
379
+ observation: "connected"
380
+ }) };
381
+ }
400
382
  return { next: withOrg(held.state, held.claimed, {
401
- at: "settingUp",
402
- orgId: org.orgId,
403
- step: org.step
383
+ ...held.claimed.org,
384
+ observation: snapshot.status === "loading" ? "loading" : "error",
385
+ ...snapshot.status === "error" ? { failure: {
386
+ code: snapshot.error.code,
387
+ message: snapshot.error.message,
388
+ ...snapshot.error.mode === void 0 ? {} : { mode: snapshot.error.mode },
389
+ error: snapshot.error
390
+ } } : {}
404
391
  }) };
405
392
  }
406
393
  case "LeaveOrganization": {
@@ -2335,6 +2322,38 @@ function validateHandle(raw) {
2335
2322
  return handle;
2336
2323
  }
2337
2324
  //#endregion
2325
+ //#region ../../packages/types/src/organization-setup.ts
2326
+ /** Backend-owned Organization setup states shared by wire and telemetry. */
2327
+ const ORGANIZATION_SETUP_STATUSES = [
2328
+ "awaitingAuthorization",
2329
+ "processing",
2330
+ "needsAttention",
2331
+ "ready",
2332
+ "rechecking",
2333
+ "failed"
2334
+ ];
2335
+ /** Closed reasons for a stored Organization setup issue. */
2336
+ const ORGANIZATION_SETUP_REASONS = [
2337
+ "submission_unknown",
2338
+ "receipt_unresolved",
2339
+ "provider_unavailable",
2340
+ "receipt_reverted",
2341
+ "deterministic_address_mismatch",
2342
+ "receipt_mismatch",
2343
+ "block_identity_changed",
2344
+ "authority_event_mismatch",
2345
+ "allowance_timestamp_mismatch",
2346
+ "receipt_identity_unavailable",
2347
+ "receipt_identity_mismatch",
2348
+ "contract_code_unavailable",
2349
+ "contract_state_mismatch",
2350
+ "permission_projection_mismatch",
2351
+ "bootstrap_reorg",
2352
+ "dependent_authority_unresolved",
2353
+ "historical_evidence_missing",
2354
+ "worker_failed"
2355
+ ];
2356
+ //#endregion
2338
2357
  //#region ../../packages/types/src/index.ts
2339
2358
  const ASSET_ID_RE = /^eip155:([1-9][0-9]*)\/erc20:(0x[0-9a-f]{40})$/;
2340
2359
  const EVM_ADDRESS_RE$1 = /^0x[0-9a-f]{40}$/i;
@@ -4501,9 +4520,6 @@ function deriveCapxulSafeAddressForOwner(input) {
4501
4520
  }).toLowerCase();
4502
4521
  }
4503
4522
  //#endregion
4504
- //#region ../../packages/config/src/role-dsl.ts
4505
- const ADMIN_ROLE_LABEL = "Admin";
4506
- //#endregion
4507
4523
  //#region ../../packages/config/src/capxul-payments-v2.ts
4508
4524
  /** The exact compiled CapxulPaymentsV2 ABI. */
4509
4525
  const CAPXUL_PAYMENTS_V2_ABI = [
@@ -5973,8 +5989,8 @@ const TelemetryEnvelopeProps = {
5973
5989
  * failure came from the chain path. Spread into every failure event and posted
5974
5990
  * on `$exception`, so one PostHog filter finds a cause wherever it was seen.
5975
5991
  */
5976
- const FailureModeSchema = Schema.Literals(FAILURE_MODES$1);
5977
- const ChainUpstreamSchema = Schema.Literals(CHAIN_UPSTREAMS);
5992
+ const FailureModeSchema$1 = Schema.Literals(FAILURE_MODES$1);
5993
+ const ChainUpstreamSchema$1 = Schema.Literals(CHAIN_UPSTREAMS);
5978
5994
  /**
5979
5995
  * The refusing upstream's response headers (#1818): exactly the names in
5980
5996
  * `RESPONSE_HEADER_ALLOWLIST`, each optional, so the catalog itself refuses a
@@ -5992,15 +6008,15 @@ const ResponseHeadersSchema = Schema.Struct({
5992
6008
  });
5993
6009
  /** One upstream tried, flat (#1818): the `chain_attempts` entry on every producer's row. */
5994
6010
  const ChainAttemptSchema = Schema.Struct({
5995
- upstream: ChainUpstreamSchema,
5996
- failure_mode: FailureModeSchema,
6011
+ upstream: ChainUpstreamSchema$1,
6012
+ failure_mode: FailureModeSchema$1,
5997
6013
  http_status: Schema.optional(Schema.Number),
5998
6014
  rpc_code: Schema.optional(Schema.Number),
5999
6015
  duration_ms: Schema.Number
6000
6016
  });
6001
6017
  const ChainCauseTelemetryProps = {
6002
- failure_mode: Schema.optional(FailureModeSchema),
6003
- chain_upstream: Schema.optional(ChainUpstreamSchema),
6018
+ failure_mode: Schema.optional(FailureModeSchema$1),
6019
+ chain_upstream: Schema.optional(ChainUpstreamSchema$1),
6004
6020
  chain_method: OptionalString,
6005
6021
  chain_retryable: Schema.optional(Schema.Boolean),
6006
6022
  chain_http_status: Schema.optional(Schema.Number),
@@ -6199,9 +6215,9 @@ const ChainUpstreamFallbackProps = Schema.Struct({
6199
6215
  ...TelemetryEnvelopeProps,
6200
6216
  service: ChainServiceSchema,
6201
6217
  method: Schema.String,
6202
- from_upstream: ChainUpstreamSchema,
6203
- to_upstream: Schema.optional(ChainUpstreamSchema),
6204
- failure_mode: FailureModeSchema,
6218
+ from_upstream: ChainUpstreamSchema$1,
6219
+ to_upstream: Schema.optional(ChainUpstreamSchema$1),
6220
+ failure_mode: FailureModeSchema$1,
6205
6221
  exhausted: Schema.Boolean,
6206
6222
  http_status: Schema.optional(Schema.Number),
6207
6223
  rpc_code: Schema.optional(Schema.Number),
@@ -6210,8 +6226,8 @@ const ChainUpstreamFallbackProps = Schema.Struct({
6210
6226
  const BundlerErrorProps = Schema.Struct({
6211
6227
  ...TelemetryEnvelopeProps,
6212
6228
  method: Schema.String,
6213
- failure_mode: FailureModeSchema,
6214
- chain_upstream: ChainUpstreamSchema,
6229
+ failure_mode: FailureModeSchema$1,
6230
+ chain_upstream: ChainUpstreamSchema$1,
6215
6231
  chain_retryable: Schema.Boolean,
6216
6232
  http_status: Schema.optional(Schema.Number),
6217
6233
  rpc_code: Schema.optional(Schema.Number),
@@ -6222,13 +6238,13 @@ const ReceiptPendingProps = Schema.Struct({
6222
6238
  ...TelemetryEnvelopeProps,
6223
6239
  service: ChainServiceSchema,
6224
6240
  method: Schema.String,
6225
- chain_upstream: ChainUpstreamSchema,
6241
+ chain_upstream: ChainUpstreamSchema$1,
6226
6242
  reason: Schema.Literals(["zero_block_hash", "no_receipt"])
6227
6243
  });
6228
6244
  const OperationRetriedProps = Schema.Struct({
6229
6245
  ...TelemetryEnvelopeProps,
6230
6246
  operation: Schema.String,
6231
- failure_mode: FailureModeSchema,
6247
+ failure_mode: FailureModeSchema$1,
6232
6248
  reason: Schema.optional(Schema.Literal("connection-lost-in-flight")),
6233
6249
  connection_id: OptionalString,
6234
6250
  connection_count: Schema.optional(Schema.Number),
@@ -6269,14 +6285,16 @@ const OrganizationCreationStartedProps = Schema.Struct({
6269
6285
  ...TelemetryEnvelopeProps,
6270
6286
  $insert_id: Schema.String,
6271
6287
  organization_id: OrgIdTelemetrySchema,
6272
- attempt_number: AttemptNumberSchema
6288
+ attempt_number: AttemptNumberSchema,
6289
+ release: Schema.optional(Schema.String.check(Schema.isPattern(/^[0-9a-f]{40}$/u)))
6273
6290
  });
6274
6291
  const OrganizationCreationReadyProps = Schema.Struct({
6275
6292
  ...TelemetryEnvelopeProps,
6276
6293
  $insert_id: Schema.String,
6277
6294
  organization_id: OrgIdTelemetrySchema,
6278
6295
  attempt_number: AttemptNumberSchema,
6279
- duration_ms: DurationMsSchema$1
6296
+ duration_ms: DurationMsSchema$1,
6297
+ release: Schema.optional(Schema.String.check(Schema.isPattern(/^[0-9a-f]{40}$/u)))
6280
6298
  });
6281
6299
  const OrganizationCreationFailedProps = Schema.Struct({
6282
6300
  ...TelemetryEnvelopeProps,
@@ -6287,20 +6305,13 @@ const OrganizationCreationFailedProps = Schema.Struct({
6287
6305
  stage: OnboardingStageSchema,
6288
6306
  error_code: Schema.String,
6289
6307
  retryable: Schema.Boolean,
6308
+ release: Schema.optional(Schema.String.check(Schema.isPattern(/^[0-9a-f]{40}$/u))),
6290
6309
  /** #1655: the SDK's backoff before this attempt. Absent on the first attempt. */
6291
6310
  backoff_ms: Schema.optional(DurationMsSchema$1),
6292
6311
  failure_reason: Schema.optional(Schema.Literals([
6293
- "deterministic_address_mismatch",
6294
6312
  "receipt_provider_unavailable",
6295
- "receipt_mismatch",
6296
6313
  "block_provider_unavailable",
6297
- "authority_event_mismatch",
6298
- "allowance_timestamp_mismatch",
6299
- "receipt_identity_unavailable",
6300
- "receipt_identity_mismatch",
6301
- "contract_code_unavailable",
6302
- "contract_state_mismatch",
6303
- "permission_projection_mismatch"
6314
+ ...ORGANIZATION_SETUP_REASONS
6304
6315
  ]))
6305
6316
  });
6306
6317
  const OnboardingIntentSchema = Schema.Literals(["personal", "organization"]);
@@ -7057,12 +7068,17 @@ const CliCommandCompletedTelemetryEventSchema = Schema.Struct({
7057
7068
  "cancelled"
7058
7069
  ]),
7059
7070
  duration_ms: Schema.Number,
7071
+ organization_id: Schema.optional(OrgIdTelemetrySchema),
7072
+ setup_status: Schema.optional(Schema.Literals(ORGANIZATION_SETUP_STATUSES)),
7073
+ setup_reason: Schema.optional(Schema.Literals(ORGANIZATION_SETUP_REASONS)),
7074
+ $groups: Schema.optional(Schema.Struct({ organization: OrgIdTelemetrySchema })),
7060
7075
  error_code: Schema.optional(Schema.Literals([
7061
7076
  ...CAPXUL_ERROR_CODES,
7062
7077
  "CLI_USAGE",
7063
7078
  "CLI_CONFIG",
7064
7079
  "CLI_STORAGE",
7065
- "CLI_DEFECT"
7080
+ "CLI_DEFECT",
7081
+ "CLI_DEADLINE"
7066
7082
  ]))
7067
7083
  })
7068
7084
  });
@@ -7968,14 +7984,7 @@ const CAPXUL_FUNCTIONS = {
7968
7984
  setOrgLogo: "media:setOrgLogo",
7969
7985
  setProfileImage: "media:setProfileImage"
7970
7986
  },
7971
- "org/actions": {
7972
- confirmBootstrap: "org/actions:confirmBootstrap",
7973
- prepareBootstrap: "org/actions:prepareBootstrap",
7974
- prepareFounderAccount: "org/actions:prepareFounderAccount",
7975
- readTreasury: "org/actions:readTreasury",
7976
- resumeBootstrapSubmission: "org/actions:resumeBootstrapSubmission",
7977
- submitBootstrap: "org/actions:submitBootstrap"
7978
- },
7987
+ "org/actions": { readTreasury: "org/actions:readTreasury" },
7979
7988
  "payroll/actions": { authorizeRun: "payroll/actions:authorizeRun" },
7980
7989
  "payroll/mutations": {
7981
7990
  removeGroup: "payroll/mutations:removeGroup",
@@ -7992,17 +8001,18 @@ const CAPXUL_FUNCTIONS = {
7992
8001
  authorize: "permission/queries:authorize",
7993
8002
  read: "permission/queries:read"
7994
8003
  },
7995
- "org/lifecycle": {
7996
- getProofReceipt: "org/lifecycle:getProofReceipt",
7997
- load: "org/lifecycle:load",
7998
- recordFailure: "org/lifecycle:recordFailure",
7999
- retry: "org/lifecycle:retry",
8000
- startOrResume: "org/lifecycle:startOrResume"
8004
+ "org/setup": {
8005
+ begin: "org/setup:begin",
8006
+ get: "org/setup:get",
8007
+ getProofReceipt: "org/setup:getProofReceipt",
8008
+ listMine: "org/setup:listMine",
8009
+ prepareAuthorization: "org/setup:prepareAuthorization",
8010
+ resume: "org/setup:resume",
8011
+ submitAuthorization: "org/setup:submitAuthorization"
8001
8012
  },
8002
8013
  "org/mutations": {
8003
8014
  accept: "org/mutations:accept",
8004
8015
  cancel: "org/mutations:cancel",
8005
- createOrg: "org/mutations:createOrg",
8006
8016
  decline: "org/mutations:decline",
8007
8017
  invite: "org/mutations:invite",
8008
8018
  resend: "org/mutations:resend",
@@ -8123,6 +8133,60 @@ const CLIENT_AUTHORIZATION_REFUSALS = [
8123
8133
  "revoke_unconfirmed"
8124
8134
  ];
8125
8135
  //#endregion
8136
+ //#region ../../packages/wire/src/organization-setup.ts
8137
+ const FailureModeSchema = Schema.Literals(FAILURE_MODES$1);
8138
+ const ChainUpstreamSchema = Schema.Literals(CHAIN_UPSTREAMS);
8139
+ const ChainCauseSchema = Schema.Struct({
8140
+ mode: FailureModeSchema,
8141
+ upstream: ChainUpstreamSchema,
8142
+ method: Schema.String,
8143
+ retryable: Schema.Boolean,
8144
+ httpStatus: Schema.optional(Schema.Number),
8145
+ rpcCode: Schema.optional(Schema.Number),
8146
+ revert: Schema.optional(Schema.Struct({
8147
+ name: Schema.NullOr(Schema.String),
8148
+ selector: Schema.String,
8149
+ args: Schema.Record(Schema.String, Schema.String)
8150
+ })),
8151
+ providerMessage: Schema.optional(Schema.String),
8152
+ attempts: Schema.optional(Schema.Array(Schema.Struct({
8153
+ upstream: ChainUpstreamSchema,
8154
+ mode: FailureModeSchema,
8155
+ httpStatus: Schema.optional(Schema.Number),
8156
+ rpcCode: Schema.optional(Schema.Number),
8157
+ durationMs: Schema.Number
8158
+ }))),
8159
+ responseHeaders: Schema.optional(Schema.Record(Schema.String, Schema.String))
8160
+ });
8161
+ const ErrorSchema = Schema.Struct({
8162
+ code: Schema.Literals(CAPXUL_ERROR_CODES),
8163
+ message: Schema.String,
8164
+ details: Schema.optional(Schema.Record(Schema.String, Schema.Unknown)),
8165
+ correlationId: Schema.optional(Schema.String),
8166
+ layer: Schema.optional(Schema.String),
8167
+ mode: Schema.optional(FailureModeSchema),
8168
+ chain: Schema.optional(ChainCauseSchema)
8169
+ });
8170
+ const OrganizationSetupIssueSchema = Schema.Struct({
8171
+ reason: Schema.Literals(ORGANIZATION_SETUP_REASONS),
8172
+ error: Schema.optional(ErrorSchema)
8173
+ });
8174
+ const OrganizationSetupSchema = Schema.Struct({
8175
+ orgId: Schema.String,
8176
+ status: Schema.Literals(ORGANIZATION_SETUP_STATUSES),
8177
+ completedAt: Schema.NullOr(Schema.Number),
8178
+ lastCheckedAt: Schema.NullOr(Schema.Number),
8179
+ nextCheckAt: Schema.NullOr(Schema.Number),
8180
+ issue: Schema.NullOr(OrganizationSetupIssueSchema),
8181
+ lastSendIssue: Schema.NullOr(OrganizationSetupIssueSchema),
8182
+ recovery: Schema.Literals([
8183
+ "authorize",
8184
+ "checkAgain",
8185
+ "none"
8186
+ ]),
8187
+ phase: Schema.optional(Schema.Literals(["resolvingSubmission", "confirmingBootstrap"]))
8188
+ });
8189
+ //#endregion
8126
8190
  //#region ../../packages/wire/src/payment-document.ts
8127
8191
  const UINT256_MAX = 2n ** 256n - 1n;
8128
8192
  const INT256_MIN = -(2n ** 255n);
@@ -10929,7 +10993,7 @@ function signerFailure(source, operation, cause) {
10929
10993
  }
10930
10994
  //#endregion
10931
10995
  //#region ../../packages/sdk/package.json
10932
- var version$2 = "4.20.0-beta.10";
10996
+ var version$2 = "4.20.0-beta.11";
10933
10997
  //#endregion
10934
10998
  //#region ../../packages/sdk/src/telemetry/exception-projection.ts
10935
10999
  /** Fixed fallback for failures that have no safe message. */
@@ -14350,7 +14414,7 @@ function mismatch(field, message) {
14350
14414
  error: Errors.invalidInput(field, message)
14351
14415
  };
14352
14416
  }
14353
- function cancelled(operation) {
14417
+ function cancelled$1(operation) {
14354
14418
  return {
14355
14419
  ok: false,
14356
14420
  error: Errors.cancelled({ operation })
@@ -14382,7 +14446,7 @@ async function abandonPrepared(deps, executionId, reason, result, onPreparedClos
14382
14446
  return result;
14383
14447
  }
14384
14448
  async function executePersonalPayment(deps, payment, signal, requestKey, onPreparedClosed) {
14385
- if (isAborted$2(signal)) return cancelled(CAPXUL_OPERATIONS.payments.pay);
14449
+ if (isAborted$2(signal)) return cancelled$1(CAPXUL_OPERATIONS.payments.pay);
14386
14450
  if (deps.signer === void 0) return mismatch("signer", "payments.pay requires a configured CapxulSigner");
14387
14451
  const session = deps.actor.authSession();
14388
14452
  if (session === null) return {
@@ -14410,10 +14474,10 @@ async function executePersonalPayment(deps, payment, signal, requestKey, onPrepa
14410
14474
  executionId: prepared.value.executionId,
14411
14475
  recipient: prepared.value.recipientObservation
14412
14476
  }, deps.runPromise);
14413
- if (isAborted$2(signal)) return abandonPrepared(deps, prepared.value.executionId, "cancelled", cancelled(CAPXUL_OPERATIONS.payments.pay), onPreparedClosed);
14477
+ if (isAborted$2(signal)) return abandonPrepared(deps, prepared.value.executionId, "cancelled", cancelled$1(CAPXUL_OPERATIONS.payments.pay), onPreparedClosed);
14414
14478
  const signature = await signerCall(deps.signer.source, "signUserOpHash", () => deps.signer.signUserOpHash(prepared.value.digest));
14415
14479
  if (!signature.ok) return abandonPrepared(deps, prepared.value.executionId, "signer_rejected", signature, onPreparedClosed);
14416
- if (isAborted$2(signal)) return abandonPrepared(deps, prepared.value.executionId, "cancelled", cancelled(CAPXUL_OPERATIONS.payments.pay), onPreparedClosed);
14480
+ if (isAborted$2(signal)) return abandonPrepared(deps, prepared.value.executionId, "cancelled", cancelled$1(CAPXUL_OPERATIONS.payments.pay), onPreparedClosed);
14417
14481
  return runIfActive(void 0, CAPXUL_OPERATIONS.payments.submitExecution, () => deps.convexCall.action(deps.functions.submitPaymentExecution, { input: {
14418
14482
  executionId: prepared.value.executionId,
14419
14483
  signature: signature.value
@@ -40685,6 +40749,7 @@ const MINIMAL_LOG_NAMES = /* @__PURE__ */ new Set([
40685
40749
  "convex.action.connection_lost",
40686
40750
  "cli.command.completed",
40687
40751
  "cli.sdk.operation.failed",
40752
+ "cli.signer.wait",
40688
40753
  "cli.wallet.step"
40689
40754
  ]);
40690
40755
  const MINIMAL_ERROR_CODES = /* @__PURE__ */ new Set([
@@ -40692,7 +40757,8 @@ const MINIMAL_ERROR_CODES = /* @__PURE__ */ new Set([
40692
40757
  "CLI_USAGE",
40693
40758
  "CLI_CONFIG",
40694
40759
  "CLI_STORAGE",
40695
- "CLI_DEFECT"
40760
+ "CLI_DEFECT",
40761
+ "CLI_DEADLINE"
40696
40762
  ]);
40697
40763
  const MINIMAL_NUMBERS = /* @__PURE__ */ new Set([
40698
40764
  "schema_version",
@@ -40772,6 +40838,13 @@ const MINIMAL_ENUM_VALUES = /* @__PURE__ */ new Map([
40772
40838
  ["provider", ["better-auth", "oidc"]],
40773
40839
  ["cli_identity_kind", ["anonymous", "identified"]],
40774
40840
  ["output_mode", ["human", "json"]],
40841
+ ["setup_status", ORGANIZATION_SETUP_STATUSES],
40842
+ ["setup_reason", ORGANIZATION_SETUP_REASONS],
40843
+ ["signer_stage", [
40844
+ "address",
40845
+ "readiness",
40846
+ "sign"
40847
+ ]],
40775
40848
  ["unit", [
40776
40849
  "1",
40777
40850
  "s",
@@ -40792,6 +40865,7 @@ const MINIMAL_VERSION_KEYS = /* @__PURE__ */ new Set([
40792
40865
  ]);
40793
40866
  function minimalStringValue(key, text) {
40794
40867
  if (key === "operation") return isCapxulOperation(text);
40868
+ if (key === "organization_id") return /^org_[0-9A-Za-z]+$/u.test(text);
40795
40869
  if (MINIMAL_CODE_KEYS.has(key)) return MINIMAL_ERROR_CODES.has(text);
40796
40870
  if (MINIMAL_VERSION_KEYS.has(key)) return /^[A-Za-z0-9][A-Za-z0-9._+@-]{0,127}$/u.test(text);
40797
40871
  if (key === "trace_id") return traceId(text);
@@ -45357,11 +45431,8 @@ const OBSERVED_CONVEX_ACTIONS = /* @__PURE__ */ new Set([
45357
45431
  "account/actions:readBalance",
45358
45432
  "holdings/actions:current",
45359
45433
  "smartAccount/actions:claim",
45360
- "org/actions:prepareFounderAccount",
45361
- "org/actions:prepareBootstrap",
45362
- "org/actions:submitBootstrap",
45363
- "org/actions:resumeBootstrapSubmission",
45364
- "org/actions:confirmBootstrap",
45434
+ "org/setup:prepareAuthorization",
45435
+ "org/setup:submitAuthorization",
45365
45436
  "org/actions:readTreasury",
45366
45437
  "moneyExecution/actions:preparePermissionExecution",
45367
45438
  "moneyExecution/actions:submitPermissionExecution",
@@ -45397,8 +45468,7 @@ const OBSERVED_CONVEX_QUERIES = /* @__PURE__ */ new Set([
45397
45468
  "permission/queries:read",
45398
45469
  "permission/queries:authorize",
45399
45470
  "identity/queries:loadByAuthUserId",
45400
- "smartAccount/queries:loadByAuthUserId",
45401
- "org/lifecycle:load"
45471
+ "smartAccount/queries:loadByAuthUserId"
45402
45472
  ]);
45403
45473
  const OBSERVED_CONVEX_MUTATIONS = /* @__PURE__ */ new Set([
45404
45474
  "movement/activity:annotate",
@@ -45419,9 +45489,8 @@ const OBSERVED_CONVEX_MUTATIONS = /* @__PURE__ */ new Set([
45419
45489
  "identity/mutations:update",
45420
45490
  "identity/mutations:completeOnboarding",
45421
45491
  "smartAccount/mutations:provision",
45422
- "org/lifecycle:startOrResume",
45423
- "org/lifecycle:recordFailure",
45424
- "org/lifecycle:retry",
45492
+ "org/setup:begin",
45493
+ "org/setup:resume",
45425
45494
  "org/mutations:invite",
45426
45495
  "org/mutations:accept"
45427
45496
  ]);
@@ -45964,6 +46033,43 @@ function orgErrorFromCapxul(operation, error, cause = error) {
45964
46033
  }
45965
46034
  var OrgPortTag = class extends Context.Service()("@capxul/sdk/ports/OrgPort") {};
45966
46035
  //#endregion
46036
+ //#region ../../packages/sdk/src/surface/org-lifecycle.ts
46037
+ function validateOrganizationSetupScope(orgId, setup) {
46038
+ return String(setup.orgId) === String(orgId) ? {
46039
+ ok: true,
46040
+ value: setup
46041
+ } : {
46042
+ ok: false,
46043
+ error: Errors.invalidInput("orgId", "Organization setup scope does not match")
46044
+ };
46045
+ }
46046
+ function rehydrateSetupIssue(item) {
46047
+ return item === null ? null : {
46048
+ reason: item.reason,
46049
+ ...item.error === void 0 ? {} : { error: deserializeCapxulError(item.error) }
46050
+ };
46051
+ }
46052
+ /** Validate the wire projection and restore its structured error causes. */
46053
+ function parseOrganizationSetup(value) {
46054
+ try {
46055
+ const wire = Schema.decodeUnknownSync(OrganizationSetupSchema)(value);
46056
+ return {
46057
+ ok: true,
46058
+ value: {
46059
+ ...wire,
46060
+ orgId: toOrgId(wire.orgId),
46061
+ issue: rehydrateSetupIssue(wire.issue),
46062
+ lastSendIssue: rehydrateSetupIssue(wire.lastSendIssue)
46063
+ }
46064
+ };
46065
+ } catch (cause) {
46066
+ return {
46067
+ ok: false,
46068
+ error: Errors.invalidInput("organizationSetup", String(cause))
46069
+ };
46070
+ }
46071
+ }
46072
+ //#endregion
45967
46073
  //#region ../../packages/sdk/src/adapters/org/parse.ts
45968
46074
  /** Brand the backend access projection without adding authority or profile fields. */
45969
46075
  function brandOrganizationAccess(wire) {
@@ -45976,37 +46082,17 @@ function brandOrganizationAccess(wire) {
45976
46082
  address: toAddress(wire.account.address),
45977
46083
  ready: wire.account.ready
45978
46084
  },
45979
- setup: brandOrgLifecycle(wire.setup),
46085
+ setup: brandOrgSetup(wire.setup),
45980
46086
  member: wire.member === null ? null : brandMemberIdentity(wire.member),
45981
46087
  capabilities: wire.capabilities,
45982
46088
  custody: wire.custody,
45983
46089
  observedAt: wire.observedAt
45984
46090
  };
45985
46091
  }
45986
- function brandOrgLifecycle(wire) {
45987
- const orgId = toOrgId(wire.orgId);
45988
- if (wire.status === "ready") return {
45989
- ...wire,
45990
- orgId
45991
- };
45992
- if (wire.status === "settingUp") {
45993
- if (!isSetupStep$1(wire.step)) throw Errors.invalidInput("lifecycle.step", "Unknown setup step");
45994
- return {
45995
- ...wire,
45996
- orgId,
45997
- step: wire.step
45998
- };
45999
- }
46000
- if (!isSetupStep$1(wire.at)) throw Errors.invalidInput("lifecycle.at", "Unknown setup step");
46001
- return {
46002
- ...wire,
46003
- orgId,
46004
- at: wire.at,
46005
- error: new CapxulError(CAPXUL_ERROR_CODES.find((candidate) => candidate === wire.error.code) ?? "UNKNOWN", wire.error.message)
46006
- };
46007
- }
46008
- function isSetupStep$1(value) {
46009
- return value === "preparingFounderAccount" || value === "awaitingFounderAuthorization" || value === "submittingBootstrap" || value === "confirmingBootstrap";
46092
+ function brandOrgSetup(wire) {
46093
+ const parsed = parseOrganizationSetup(wire);
46094
+ if (!parsed.ok) throw parsed.error;
46095
+ return parsed.value;
46010
46096
  }
46011
46097
  function brandMemberIdentity(wire) {
46012
46098
  return {
@@ -46114,9 +46200,6 @@ var ConvexOrganizationAdapter = class {
46114
46200
  this.#telemetry = input.telemetry;
46115
46201
  this.#rates = input.rates ?? MONEY_READ_RATES;
46116
46202
  }
46117
- createOrg(_input) {
46118
- return Effect.fail(orgErrorFromCapxul("createOrg", Errors.notImplemented("organizationSetup", "use onboarding.completeOrganization")));
46119
- }
46120
46203
  listOrgs(input) {
46121
46204
  return this.#convex.query(this.#fns.listAll, copyInvocationObservation(input, {})).pipe(Effect.mapError((error) => orgErrorFromCapxul("listOrgs", error.publicError, error)), Effect.map((wires) => wires.map(brandOrganizationAccess)), Effect.catchDefect((cause) => Effect.fail(toOrgError("listOrgs", cause))));
46122
46205
  }
@@ -46158,267 +46241,234 @@ function partialOrgTruth(operation, currentState) {
46158
46241
  //#endregion
46159
46242
  //#region ../../packages/sdk/src/adapters/org/ConvexOrganizationSetupAdapter.ts
46160
46243
  const DEFAULT_FUNCTIONS = {
46161
- startOrResume: makeFunctionReference(CAPXUL_FUNCTIONS["org/lifecycle"].startOrResume),
46162
- prepareFounderAccount: makeFunctionReference(CAPXUL_FUNCTIONS["org/actions"].prepareFounderAccount),
46163
- prepareBootstrap: makeFunctionReference(CAPXUL_FUNCTIONS["org/actions"].prepareBootstrap),
46164
- submitBootstrap: makeFunctionReference(CAPXUL_FUNCTIONS["org/actions"].submitBootstrap),
46165
- resumeBootstrapSubmission: makeFunctionReference(CAPXUL_FUNCTIONS["org/actions"].resumeBootstrapSubmission),
46166
- confirmBootstrap: makeFunctionReference(CAPXUL_FUNCTIONS["org/actions"].confirmBootstrap),
46167
- recordFailure: makeFunctionReference(CAPXUL_FUNCTIONS["org/lifecycle"].recordFailure),
46168
- load: makeFunctionReference(CAPXUL_FUNCTIONS["org/lifecycle"].load),
46169
- retry: makeFunctionReference(CAPXUL_FUNCTIONS["org/lifecycle"].retry)
46170
- };
46171
- /** Durable Organization setup capability composed by the standard client. */
46244
+ begin: makeFunctionReference(CAPXUL_FUNCTIONS["org/setup"].begin),
46245
+ get: makeFunctionReference(CAPXUL_FUNCTIONS["org/setup"].get),
46246
+ listMine: makeFunctionReference(CAPXUL_FUNCTIONS["org/setup"].listMine),
46247
+ resume: makeFunctionReference(CAPXUL_FUNCTIONS["org/setup"].resume),
46248
+ prepare: makeFunctionReference(CAPXUL_FUNCTIONS["org/setup"].prepareAuthorization),
46249
+ submit: makeFunctionReference(CAPXUL_FUNCTIONS["org/setup"].submitAuthorization)
46250
+ };
46251
+ /** Convex transport for one backend-owned Organization setup. */
46172
46252
  var ConvexOrganizationSetupAdapter = class {
46173
46253
  #convex;
46174
46254
  #signer;
46175
46255
  #chainId;
46176
- #fns;
46256
+ #functions;
46257
+ #runPromise;
46258
+ #subscriptions = /* @__PURE__ */ new Set();
46259
+ #generation = 0;
46177
46260
  constructor(input) {
46178
46261
  this.#convex = input.convex;
46179
46262
  this.#signer = input.signer ?? null;
46180
46263
  this.#chainId = input.chainId;
46181
- this.#fns = input.functions ?? DEFAULT_FUNCTIONS;
46264
+ this.#functions = input.functions ?? DEFAULT_FUNCTIONS;
46265
+ this.#runPromise = input.runPromise ?? Effect.runPromise;
46182
46266
  }
46183
- async startOrResume(input) {
46184
- if (this.#signer === null) return fail$2(Errors.capabilityUnavailable("signer", "startOrResume"));
46185
- const result = await runCall("startOrResume", this.#convex.mutation(this.#fns.startOrResume, copyInvocationObservation(input, {
46267
+ async begin(input) {
46268
+ const result = await this.#call("begin", this.#convex.mutation(this.#functions.begin, copyInvocationObservation(input, {
46186
46269
  ...input,
46187
46270
  chainId: this.#chainId
46188
46271
  })));
46189
46272
  if (!result.ok) return result;
46190
- const lifecycle = parseLifecycle("startOrResume", result.value.lifecycle);
46191
- if (!lifecycle.ok) return lifecycle;
46192
- const orgId = parseOrgId("startOrResume", result.value.orgId);
46193
- if (!orgId.ok) return orgId;
46194
- if (String(orgId.value) !== String(lifecycle.value.orgId)) return fail$2(Errors.invalidInput("orgId", "Organization lifecycle scope does not match"));
46273
+ const setup = parseOrganizationSetup(result.value.setup);
46274
+ if (!setup.ok) return setup;
46275
+ try {
46276
+ const orgId = toOrgId(result.value.orgId);
46277
+ const scoped = validateOrganizationSetupScope(orgId, setup.value);
46278
+ return scoped.ok ? {
46279
+ ok: true,
46280
+ value: {
46281
+ orgId,
46282
+ setup: scoped.value
46283
+ }
46284
+ } : scoped;
46285
+ } catch (cause) {
46286
+ return fail$1(Errors.invalidInput("orgId", String(cause)));
46287
+ }
46288
+ }
46289
+ async get(orgId, options) {
46290
+ if (options?.signal?.aborted) return cancelled();
46291
+ const result = await this.#call("get", this.#convex.query(this.#functions.get, { orgId }));
46292
+ if (!result.ok) return result;
46293
+ if (result.value === null) return fail$1(Errors.invalidInput("orgId", "Organization setup was not found"));
46294
+ const parsed = parseOrganizationSetup(result.value);
46295
+ return parsed.ok ? validateOrganizationSetupScope(orgId, parsed.value) : parsed;
46296
+ }
46297
+ async listMine(input = {}, options) {
46298
+ if (options?.signal?.aborted) return cancelled();
46299
+ if (input.cursor !== void 0 && typeof input.cursor !== "string" || input.limit !== void 0 && (!Number.isSafeInteger(input.limit) || input.limit < 1 || input.limit > 50)) return fail$1(Errors.invalidInput("organizationSetupPage", "Invalid cursor or limit"));
46300
+ const generation = this.#generation;
46301
+ const result = await abortable(this.#call("listMine", this.#convex.query(this.#functions.listMine, input)), options?.signal);
46302
+ if (generation !== this.#generation || options?.signal?.aborted) return cancelled();
46303
+ if (!result.ok) return result;
46304
+ const value = result.value;
46305
+ if (typeof value !== "object" || value === null || !Array.isArray(value.page) || !(value.cursor === null || typeof value.cursor === "string") || typeof value.isDone !== "boolean") return fail$1(Errors.invalidInput("organizationSetupPage", "Invalid page envelope"));
46306
+ const page = [];
46307
+ for (const item of value.page) {
46308
+ const parsed = parseOrganizationSetup(item);
46309
+ if (!parsed.ok) return parsed;
46310
+ page.push(parsed.value);
46311
+ }
46195
46312
  return {
46196
46313
  ok: true,
46197
46314
  value: {
46198
- orgId: orgId.value,
46199
- lifecycle: lifecycle.value
46315
+ page,
46316
+ cursor: value.cursor,
46317
+ isDone: value.isDone
46200
46318
  }
46201
46319
  };
46202
46320
  }
46203
- prepareFounderAccount(input) {
46204
- return this.#lifecycleAction("prepareFounderAccount", input, () => this.#convex.action(this.#fns.prepareFounderAccount, copyInvocationObservation(input, {
46205
- orgId: input.orgId,
46206
- ...input.observationContext === void 0 ? {} : { observationContext: input.observationContext }
46207
- })));
46208
- }
46209
- async authorizeAndSubmitBootstrap(input) {
46210
- const cancelled = cancellation(input.signal);
46211
- if (cancelled !== void 0) return cancelled;
46321
+ async resume(orgId, options) {
46322
+ if (options?.signal?.aborted) return cancelled();
46323
+ const result = await this.#call("resume", this.#convex.mutation(this.#functions.resume, { orgId }));
46324
+ if (!result.ok) return result;
46325
+ const parsed = parseOrganizationSetup(result.value);
46326
+ return parsed.ok ? validateOrganizationSetupScope(orgId, parsed.value) : parsed;
46327
+ }
46328
+ async authorize(orgId, options) {
46329
+ if (options?.signal?.aborted) return cancelled();
46330
+ const current = await this.get(orgId, options);
46331
+ if (options?.signal?.aborted) return cancelled();
46332
+ if (!current.ok || current.value.status !== "awaitingAuthorization") return current;
46212
46333
  const signer = this.#signer;
46213
- if (signer === null) return fail$2(Errors.capabilityUnavailable("signer", "authorizeAndSubmitBootstrap"));
46214
- const signerAddress = await signerResult(signer.source, "getAddress", () => signer.getAddress());
46215
- if (!signerAddress.ok) return signerAddress;
46216
- const prepared = await runCall("prepareBootstrap", this.#convex.action(this.#fns.prepareBootstrap, copyInvocationObservation(input, {
46217
- orgId: input.orgId,
46218
- signerAddress: signerAddress.value,
46219
- ...input.observationContext === void 0 ? {} : { observationContext: input.observationContext }
46220
- })));
46334
+ if (signer === null) return fail$1(Errors.capabilityUnavailable("signer", "authorize"));
46335
+ const address = await signerResult(signer, "getAddress", () => signer.getAddress());
46336
+ if (!address.ok) return address;
46337
+ const prepared = await this.#call("prepareAuthorization", this.#convex.action(this.#functions.prepare, { orgId }));
46221
46338
  if (!prepared.ok) return prepared;
46222
- const authority = validatePreparedAuthorities(prepared.value, signerAddress.value);
46339
+ const authority = validatePrepared(prepared.value, orgId, address.value);
46223
46340
  if (!authority.ok) return authority;
46224
- const cancelledAfterPrepare = cancellation(input.signal);
46225
- if (cancelledAfterPrepare !== void 0) return cancelledAfterPrepare;
46226
- const signature = await signerResult(signer.source, "signUserOpHash", () => signer.signUserOpHash(prepared.value.digest));
46341
+ if (options?.signal?.aborted) return cancelled();
46342
+ const signature = await signerResult(signer, "signUserOpHash", () => signer.signUserOpHash(prepared.value.digest));
46227
46343
  if (!signature.ok) return signature;
46228
- const cancelledAfterSign = cancellation(input.signal);
46229
- if (cancelledAfterSign !== void 0) return cancelledAfterSign;
46230
- const submitted = await runCall("submitBootstrap", this.#convex.action(this.#fns.submitBootstrap, copyInvocationObservation(input, {
46231
- orgId: input.orgId,
46232
- signerAddress: signerAddress.value,
46233
- signature: signature.value,
46344
+ if (options?.signal?.aborted) return cancelled();
46345
+ const submitted = await this.#call("submitAuthorization", this.#convex.action(this.#functions.submit, {
46346
+ orgId,
46347
+ preparationId: prepared.value.preparationId,
46234
46348
  userOp: prepared.value.userOp,
46235
- ...input.observationContext === void 0 ? {} : { observationContext: input.observationContext }
46236
- })));
46237
- if (!submitted.ok) return submitted;
46238
- return parseLifecycle("submitBootstrap", submitted.value);
46239
- }
46240
- resumeSubmittedBootstrap(input) {
46241
- return this.#lifecycleAction("resumeBootstrapSubmission", input, () => this.#convex.action(this.#fns.resumeBootstrapSubmission, copyInvocationObservation(input, {
46242
- orgId: input.orgId,
46243
- ...input.observationContext === void 0 ? {} : { observationContext: input.observationContext }
46244
- })));
46245
- }
46246
- confirmSubmittedBootstrap(input) {
46247
- return this.#lifecycleAction("confirmBootstrap", input, () => this.#convex.action(this.#fns.confirmBootstrap, copyInvocationObservation(input, {
46248
- orgId: input.orgId,
46249
- ...input.observationContext === void 0 ? {} : { observationContext: input.observationContext },
46250
- ...input.retryDelayMs === void 0 ? {} : { retryDelayMs: input.retryDelayMs }
46251
- })));
46252
- }
46253
- async recordFailure(input) {
46254
- const errorProvider = input.error.details?.provider;
46255
- const errorOperation = input.error.details?.operation;
46256
- const result = await runCall("recordFailure", this.#convex.mutation(this.#fns.recordFailure, copyInvocationObservation(input, {
46257
- orgId: input.orgId,
46258
- errorCode: input.error.code,
46259
- ...typeof errorProvider === "string" && typeof errorOperation === "string" ? {
46260
- errorProvider,
46261
- errorOperation
46262
- } : {},
46263
- retryable: input.retryable,
46264
- ...input.observationContext === void 0 ? {} : { observationContext: input.observationContext }
46265
- })));
46266
- return result.ok ? parseLifecycle("recordFailure", result.value) : result;
46267
- }
46268
- async loadLifecycle(input) {
46269
- const result = await runCall("loadLifecycle", this.#convex.query(this.#fns.load, input));
46270
- if (!result.ok) return result;
46271
- if (result.value === null) return fail$2(Errors.invalidInput("orgId", "Organization lifecycle was not found"));
46272
- return parseLifecycle("loadLifecycle", result.value);
46273
- }
46274
- async retry(input) {
46275
- const cancelled = cancellation(input.signal);
46276
- if (cancelled !== void 0) return cancelled;
46277
- const current = await this.loadLifecycle({
46278
- orgId: input.orgId,
46279
- ...input.observationContext === void 0 ? {} : { observationContext: input.observationContext }
46280
- });
46281
- if (!current.ok) return current;
46282
- if (current.value.status === "failed" && current.value.retryable && current.value.at === "awaitingFounderAuthorization") {
46283
- if (this.#signer === null) return fail$2(Errors.capabilityUnavailable("signer", "retry"));
46284
- const reset = resetSignerSession(this.#signer);
46285
- if (!reset.ok) return reset;
46349
+ signature: signature.value
46350
+ }));
46351
+ if (!submitted.ok) {
46352
+ const acceptedSetup = await this.get(orgId);
46353
+ return acceptedSetup.ok && acceptedSetup.value.status !== "awaitingAuthorization" ? acceptedSetup : submitted;
46354
+ }
46355
+ const parsed = parseOrganizationSetup(submitted.value);
46356
+ return parsed.ok ? validateOrganizationSetupScope(orgId, parsed.value) : parsed;
46357
+ }
46358
+ async subscribe(orgId, listener, options) {
46359
+ if (options?.signal?.aborted) return cancelled();
46360
+ let active = true;
46361
+ let remoteStop;
46362
+ const stop = () => {
46363
+ if (!active) return;
46364
+ active = false;
46365
+ options?.signal?.removeEventListener("abort", stop);
46366
+ this.#subscriptions.delete(stop);
46367
+ remoteStop?.();
46368
+ };
46369
+ const notify = (snapshot) => {
46370
+ try {
46371
+ Promise.resolve(listener(snapshot)).catch(() => void 0);
46372
+ } catch {}
46373
+ };
46374
+ options?.signal?.addEventListener("abort", stop, { once: true });
46375
+ this.#subscriptions.add(stop);
46376
+ const result = await this.#call("subscribe", this.#convex.subscribe(this.#functions.get, { orgId }, (snapshot) => {
46377
+ if (!active) return;
46378
+ if (snapshot.status === "loading") return notify({ status: "loading" });
46379
+ if (snapshot.status === "error") return notify({
46380
+ status: "error",
46381
+ error: snapshot.error
46382
+ });
46383
+ const parsed = snapshot.value === null ? fail$1(Errors.invalidInput("orgId", "Organization setup was not found")) : parseOrganizationSetup(snapshot.value);
46384
+ const scoped = parsed.ok ? validateOrganizationSetupScope(orgId, parsed.value) : parsed;
46385
+ notify(scoped.ok ? {
46386
+ status: "value",
46387
+ value: scoped.value
46388
+ } : {
46389
+ status: "error",
46390
+ error: scoped.error
46391
+ });
46392
+ }));
46393
+ if (!result.ok) {
46394
+ stop();
46395
+ return result;
46396
+ }
46397
+ remoteStop = result.value;
46398
+ if (!active) {
46399
+ remoteStop();
46400
+ return cancelled();
46286
46401
  }
46287
- const result = await runCall("retry", this.#convex.mutation(this.#fns.retry, copyInvocationObservation(input, {
46288
- orgId: input.orgId,
46289
- ...input.observationContext === void 0 ? {} : { observationContext: input.observationContext }
46290
- })));
46291
- if (!result.ok) return result;
46292
- return parseLifecycle("retry", result.value);
46293
- }
46294
- async #lifecycleAction(operation, input, call) {
46295
- const cancelled = cancellation(input.signal);
46296
- if (cancelled !== void 0) return cancelled;
46297
- const result = await runCall(operation, call());
46298
- if (!result.ok) return result;
46299
- const cancelledAfter = cancellation(input.signal);
46300
- if (cancelledAfter !== void 0) return cancelledAfter;
46301
- return parseLifecycle(operation, result.value);
46302
- }
46303
- };
46304
- function resetSignerSession(signer) {
46305
- const resetSession = signer.resetSession;
46306
- if (typeof resetSession !== "function") return {
46307
- ok: true,
46308
- value: void 0
46309
- };
46310
- try {
46311
- resetSession.call(signer);
46312
46402
  return {
46313
46403
  ok: true,
46314
- value: void 0
46404
+ value: stop
46315
46405
  };
46316
- } catch (cause) {
46317
- return fail$2(signerFailure(signer.source, "resetSession", cause));
46318
46406
  }
46319
- }
46320
- async function runCall(operation, effect) {
46321
- try {
46322
- const result = await Effect.runPromise(Effect.result(effect));
46323
- return Result.isSuccess(result) ? {
46324
- ok: true,
46325
- value: result.success
46326
- } : fail$2(publicError(operation, result.failure));
46327
- } catch (cause) {
46328
- return fail$2(publicError(operation, cause));
46329
- }
46330
- }
46331
- function publicError(operation, cause) {
46332
- if (cause instanceof CapxulError) return cause;
46333
- if (typeof cause === "object" && cause !== null) {
46334
- const carried = cause.publicError;
46335
- if (carried instanceof CapxulError) return carried;
46407
+ invalidateSubscriptions() {
46408
+ this.#generation += 1;
46409
+ for (const stop of this.#subscriptions) stop();
46336
46410
  }
46337
- return Errors.providerError("convex-organization", operation, cause);
46338
- }
46339
- async function signerResult(source, operation, run) {
46340
- try {
46341
- return {
46342
- ok: true,
46343
- value: await run()
46344
- };
46345
- } catch (cause) {
46346
- return fail$2(signerFailure(source, operation, cause));
46411
+ async #call(operation, effect) {
46412
+ try {
46413
+ const result = await this.#runPromise(Effect.result(effect));
46414
+ return Result.isSuccess(result) ? {
46415
+ ok: true,
46416
+ value: result.success
46417
+ } : fail$1(publicError(result.failure));
46418
+ } catch (cause) {
46419
+ return fail$1(publicError(cause));
46420
+ }
46347
46421
  }
46348
- }
46349
- function validatePreparedAuthorities(prepared, signerAddress) {
46422
+ };
46423
+ function validatePrepared(prepared, orgId, signerAddress) {
46350
46424
  const signer = signerAddress.toLowerCase();
46351
- const preparedSigner = prepared.signerAddress.toLowerCase();
46425
+ if (prepared.orgId !== orgId || prepared.expectedSigner.toLowerCase() !== signer) return fail$1(Errors.invalidInput("authorization", "Prepared signer or Organization does not match"));
46352
46426
  const founder = prepared.founderPersonalAccount.toLowerCase();
46353
46427
  const organization = prepared.organizationAccountAddress.toLowerCase();
46354
- const sender = prepared.userOp.sender.toLowerCase();
46355
- if (preparedSigner !== signer) return fail$2(Errors.invalidInput("signerAddress", "Prepared signer does not match configured signer"));
46356
- if (founder === signer || organization === signer || organization === founder) return fail$2(Errors.invalidInput("organizationAuthority", "Signer EOA, founder Account, and Organization Account must be distinct"));
46357
- if (sender !== founder) return fail$2(Errors.invalidInput("userOp.sender", "Bootstrap sender must be the founder Account"));
46358
- if (!/^0x[0-9a-fA-F]{64}$/u.test(prepared.digest)) return fail$2(Errors.invalidInput("digest", "Prepared bootstrap digest must be 32-byte hex"));
46428
+ if (founder === signer || organization === signer || organization === founder || prepared.userOp.sender.toLowerCase() !== founder) return fail$1(Errors.invalidInput("organizationAuthority", "Prepared authorities do not match"));
46429
+ if (!/^0x[0-9a-fA-F]{64}$/u.test(prepared.digest)) return fail$1(Errors.invalidInput("digest", "Prepared digest must be 32-byte hex"));
46359
46430
  return {
46360
46431
  ok: true,
46361
46432
  value: void 0
46362
46433
  };
46363
46434
  }
46364
- function parseLifecycle(operation, wire) {
46365
- const orgId = parseOrgId(operation, wire.orgId);
46366
- if (!orgId.ok) return orgId;
46367
- if (wire.status === "loading") return {
46368
- ok: true,
46369
- value: {
46370
- status: "loading",
46371
- orgId: orgId.value
46372
- }
46373
- };
46374
- if (wire.status === "ready") return {
46375
- ok: true,
46376
- value: {
46377
- status: "ready",
46378
- orgId: orgId.value,
46379
- canTransact: true
46380
- }
46381
- };
46382
- if (wire.status === "failed") {
46383
- if (!isSetupStep(wire.at)) return fail$2(Errors.invalidInput("lifecycle.at", "Unknown setup step"));
46384
- return {
46385
- ok: true,
46386
- value: {
46387
- status: "failed",
46388
- orgId: orgId.value,
46389
- at: wire.at,
46390
- error: new CapxulError(wire.error.code, wire.error.message),
46391
- retryable: wire.retryable
46392
- }
46393
- };
46394
- }
46395
- if (!isSetupStep(wire.step)) return fail$2(Errors.invalidInput("lifecycle.step", `Unknown setup step from ${operation}`));
46396
- return {
46397
- ok: true,
46398
- value: {
46399
- status: "settingUp",
46400
- orgId: orgId.value,
46401
- step: wire.step
46402
- }
46403
- };
46404
- }
46405
- function parseOrgId(operation, value) {
46435
+ async function signerResult(signer, operation, run) {
46406
46436
  try {
46407
46437
  return {
46408
46438
  ok: true,
46409
- value: toOrgId(value)
46439
+ value: await run()
46410
46440
  };
46411
46441
  } catch (cause) {
46412
- return fail$2(Errors.providerError("convex-organization", operation, cause));
46442
+ return fail$1(signerFailure(signer.source, operation, cause));
46443
+ }
46444
+ }
46445
+ function publicError(cause) {
46446
+ if (cause instanceof CapxulError) return cause;
46447
+ if (typeof cause === "object" && cause !== null && "publicError" in cause) {
46448
+ const carried = cause.publicError;
46449
+ if (carried instanceof CapxulError) return carried;
46413
46450
  }
46451
+ return Errors.unknown(cause);
46414
46452
  }
46415
- function isSetupStep(value) {
46416
- return value === "preparingFounderAccount" || value === "awaitingFounderAuthorization" || value === "submittingBootstrap" || value === "confirmingBootstrap";
46453
+ function cancelled() {
46454
+ return fail$1(Errors.cancelled({ operation: CAPXUL_OPERATIONS.organization.setup }));
46417
46455
  }
46418
- function cancellation(signal) {
46419
- return signal?.aborted ? fail$2(Errors.cancelled({ operation: CAPXUL_OPERATIONS.organization.setup })) : void 0;
46456
+ async function abortable(pending, signal) {
46457
+ if (signal === void 0) return pending;
46458
+ if (signal.aborted) return cancelled();
46459
+ let onAbort;
46460
+ const interrupted = new Promise((resolve) => {
46461
+ onAbort = () => resolve(cancelled());
46462
+ signal.addEventListener("abort", onAbort, { once: true });
46463
+ if (signal.aborted) onAbort();
46464
+ });
46465
+ try {
46466
+ return await Promise.race([pending, interrupted]);
46467
+ } finally {
46468
+ signal.removeEventListener("abort", onAbort);
46469
+ }
46420
46470
  }
46421
- function fail$2(error) {
46471
+ function fail$1(error) {
46422
46472
  return {
46423
46473
  ok: false,
46424
46474
  error
@@ -46583,22 +46633,27 @@ const IDENTITY_SLOT_BY_EVENT = {
46583
46633
  AccountFailed: IDENTITY_SLOT.account,
46584
46634
  CreateOrganization: IDENTITY_SLOT.org,
46585
46635
  AttachOrganization: IDENTITY_SLOT.org,
46586
- RetryOrganization: IDENTITY_SLOT.org,
46587
46636
  LeaveOrganization: IDENTITY_SLOT.org,
46588
- OrgAt: IDENTITY_SLOT.org,
46589
- OrgReady: IDENTITY_SLOT.org,
46590
- OrgFailed: IDENTITY_SLOT.org
46637
+ ObserveOrganization: IDENTITY_SLOT.org,
46638
+ OrgSelected: IDENTITY_SLOT.org,
46639
+ OrgSelectionFailed: IDENTITY_SLOT.org
46591
46640
  };
46592
46641
  const identitySlot = (event) => IDENTITY_SLOT_BY_EVENT[event._tag];
46593
46642
  const initialIdentityState = () => RESTORING;
46594
- function createIdentityAuthorityTracker(sessionStore) {
46643
+ function createIdentityAuthorityTracker(sessionStore, onGenerationChange = () => void 0) {
46595
46644
  let generation = 0;
46596
46645
  let authUserId = null;
46597
46646
  let stopped = false;
46598
46647
  let readState = initialIdentityState;
46648
+ const advanceGeneration = () => {
46649
+ generation += 1;
46650
+ try {
46651
+ onGenerationChange();
46652
+ } catch {}
46653
+ };
46599
46654
  const revoke = () => {
46600
46655
  if (stopped) return;
46601
- generation += 1;
46656
+ advanceGeneration();
46602
46657
  authUserId = null;
46603
46658
  };
46604
46659
  return {
@@ -46616,13 +46671,13 @@ function createIdentityAuthorityTracker(sessionStore) {
46616
46671
  observe: (state) => {
46617
46672
  if (stopped) return;
46618
46673
  const next = state.phase === "authenticated" ? state.session.authUserId : null;
46619
- if (authUserId !== null && next !== authUserId) generation += 1;
46674
+ if (authUserId !== null && next !== authUserId) advanceGeneration();
46620
46675
  authUserId = next;
46621
46676
  },
46622
46677
  invalidate: () => {
46623
46678
  if (stopped) return;
46624
46679
  stopped = true;
46625
- generation += 1;
46680
+ advanceGeneration();
46626
46681
  authUserId = null;
46627
46682
  },
46628
46683
  matches: (captured, expectedAuthUserId) => {
@@ -46633,29 +46688,6 @@ function createIdentityAuthorityTracker(sessionStore) {
46633
46688
  }
46634
46689
  };
46635
46690
  }
46636
- /** 2 s, 4 s, 8 s, 16 s, 32 s, 60 s, 60 s: about three minutes, then the user decides. */
46637
- const DEFAULT_CONFIRMATION_BACKOFF = {
46638
- initialDelayMs: 2e3,
46639
- maxDelayMs: 6e4,
46640
- maxRetries: 7
46641
- };
46642
- /**
46643
- * A public partial override must not bring the tight loop back: a zero,
46644
- * negative, or non-finite delay, or a non-integer or infinite retry count,
46645
- * falls back to the default for that field. `maxDelayMs` is never below
46646
- * `initialDelayMs`.
46647
- */
46648
- const positiveMs = (value, fallback) => value !== void 0 && Number.isFinite(value) && value > 0 ? value : fallback;
46649
- function normalizeConfirmationBackoff(override) {
46650
- const initialDelayMs = positiveMs(override?.initialDelayMs, DEFAULT_CONFIRMATION_BACKOFF.initialDelayMs);
46651
- const maxDelayMs = Math.max(initialDelayMs, positiveMs(override?.maxDelayMs, DEFAULT_CONFIRMATION_BACKOFF.maxDelayMs));
46652
- const retries = override?.maxRetries;
46653
- return {
46654
- initialDelayMs,
46655
- maxDelayMs,
46656
- maxRetries: retries !== void 0 && Number.isSafeInteger(retries) && retries >= 0 ? retries : DEFAULT_CONFIRMATION_BACKOFF.maxRetries
46657
- };
46658
- }
46659
46691
  const failureOf = (error) => {
46660
46692
  if (error instanceof CapxulError) {
46661
46693
  const mode = error.mode ?? error.details?.failure_mode;
@@ -46779,12 +46811,6 @@ const accountLane = (input, config, session, send, isCurrent) => Effect.gen(func
46779
46811
  address: String(claimed.success.smartAccountAddress)
46780
46812
  });
46781
46813
  });
46782
- const orgStep = (lifecycle) => {
46783
- if (lifecycle.status === "ready") return "ready";
46784
- if (lifecycle.status === "settingUp") return lifecycle.step;
46785
- if (lifecycle.status === "failed") return lifecycle.at;
46786
- return "preparingFounderAccount";
46787
- };
46788
46814
  const orgEngineeringContext = (controls, parent) => {
46789
46815
  const correlationId = safeEngineeringIdentifier(controls.correlation_id);
46790
46816
  const journeyId = safeEngineeringIdentifier(controls.journey_id);
@@ -46795,165 +46821,22 @@ const orgEngineeringContext = (controls, parent) => {
46795
46821
  ...traceparent === void 0 ? {} : { traceparent }
46796
46822
  };
46797
46823
  };
46798
- const runOrgStep = (setup, orgId, step, controls, retryDelayMs) => {
46799
- const [name, invoke] = step === "preparingFounderAccount" ? ["organization-setup.prepare-founder-account", (parent) => setup.prepareFounderAccount({
46800
- orgId,
46801
- observationContext: orgEngineeringContext(controls, parent)
46802
- })] : step === "awaitingFounderAuthorization" ? ["organization-setup.authorize-and-submit-bootstrap", (parent) => setup.authorizeAndSubmitBootstrap({
46803
- orgId,
46824
+ const beginOrganization$1 = (setup, draft, send, controls) => Effect.gen(function* () {
46825
+ const opened = yield* Effect.result(resultEffect("organization-setup.begin", (parent) => setup.begin({
46826
+ ...draft,
46804
46827
  observationContext: orgEngineeringContext(controls, parent)
46805
- })] : step === "submittingBootstrap" ? ["organization-setup.resume-submitted-bootstrap", (parent) => setup.resumeSubmittedBootstrap({
46806
- orgId,
46807
- observationContext: orgEngineeringContext(controls, parent)
46808
- })] : ["organization-setup.confirm-submitted-bootstrap", (parent) => setup.confirmSubmittedBootstrap({
46809
- orgId,
46810
- observationContext: orgEngineeringContext(controls, parent),
46811
- ...retryDelayMs === void 0 ? {} : { retryDelayMs }
46812
- })];
46813
- return resultEffect(name, invoke);
46814
- };
46815
- const orgLane = (setup, start, send, controls, backoff, telemetry) => Effect.gen(function* () {
46816
- let orgId;
46817
- let lifecycle;
46818
- if (start.kind === "create") {
46819
- const opened = yield* Effect.result(resultEffect("organization-setup.start-or-resume", (parent) => setup.startOrResume({
46820
- ...start.draft,
46821
- observationContext: orgEngineeringContext(controls, parent)
46822
- })));
46823
- if (Result.isFailure(opened)) {
46824
- yield* send({
46825
- _tag: "OrgFailed",
46826
- orgId: null,
46827
- step: "preparingFounderAccount",
46828
- failure: opened.failure
46829
- });
46830
- return yield* Effect.fail(opened.failure);
46831
- }
46832
- orgId = String(opened.success.orgId);
46833
- lifecycle = opened.success.lifecycle;
46834
- } else {
46835
- const opened = yield* Effect.result(start.kind === "retry" ? resultEffect("organization-setup.retry", (parent) => setup.retry({
46836
- orgId: start.orgId,
46837
- observationContext: orgEngineeringContext(controls, parent)
46838
- })) : resultEffect("organization-setup.load-lifecycle", (parent) => setup.loadLifecycle({
46839
- orgId: start.orgId,
46840
- observationContext: orgEngineeringContext(controls, parent)
46841
- })));
46842
- if (Result.isFailure(opened)) {
46843
- yield* send({
46844
- _tag: "OrgFailed",
46845
- orgId: start.orgId,
46846
- step: "preparingFounderAccount",
46847
- failure: opened.failure
46848
- });
46849
- return yield* Effect.fail(opened.failure);
46850
- }
46851
- orgId = start.orgId;
46852
- lifecycle = opened.success;
46853
- }
46854
- if (lifecycle.status === "failed") {
46855
- const failure = failureOf(lifecycle.error);
46856
- yield* send({
46857
- _tag: "OrgFailed",
46858
- orgId,
46859
- step: lifecycle.at,
46860
- failure,
46861
- retryable: lifecycle.retryable
46862
- });
46863
- return yield* Effect.fail(failure);
46864
- }
46865
- let step = orgStep(lifecycle);
46866
- if (step === "ready") {
46828
+ })));
46829
+ if (Result.isFailure(opened)) {
46867
46830
  yield* send({
46868
- _tag: "OrgReady",
46869
- orgId
46831
+ _tag: "OrgSelectionFailed",
46832
+ failure: opened.failure
46870
46833
  });
46871
- return;
46834
+ return yield* Effect.fail(opened.failure);
46872
46835
  }
46873
46836
  yield* send({
46874
- _tag: "OrgAt",
46875
- orgId,
46876
- step
46837
+ _tag: "OrgSelected",
46838
+ setup: opened.success.setup
46877
46839
  });
46878
- let retries = 0;
46879
- let retryDelayMs;
46880
- while (step !== "ready") {
46881
- const current = step;
46882
- const advanced = yield* Effect.result(runOrgStep(setup, orgId, current, controls, retryDelayMs));
46883
- retryDelayMs = void 0;
46884
- if (Result.isFailure(advanced)) {
46885
- yield* send({
46886
- _tag: "OrgFailed",
46887
- orgId,
46888
- step: current,
46889
- failure: advanced.failure
46890
- });
46891
- return yield* Effect.fail(advanced.failure);
46892
- }
46893
- lifecycle = advanced.success;
46894
- if (lifecycle.status === "failed") {
46895
- if (lifecycle.at === "confirmingBootstrap" && lifecycle.retryable && retries < backoff.maxRetries) {
46896
- const delayMs = Math.min(backoff.initialDelayMs * 2 ** retries, backoff.maxDelayMs);
46897
- retries += 1;
46898
- if (telemetry !== void 0) yield* telemetry.emit({
46899
- name: "operation_retried",
46900
- props: {
46901
- operation: CAPXUL_OPERATIONS.org.confirmBootstrap,
46902
- failure_mode: failureOf(lifecycle.error).mode ?? "unknown",
46903
- attempt: retries,
46904
- delay_ms: delayMs
46905
- }
46906
- }).pipe(Effect.catchDefect(() => Effect.void));
46907
- yield* Effect.sleep(Duration.millis(delayMs));
46908
- const reset = yield* Effect.result(resultEffect("organization-setup.retry", (parent) => setup.retry({
46909
- orgId,
46910
- observationContext: orgEngineeringContext(controls, parent)
46911
- })));
46912
- if (Result.isFailure(reset)) {
46913
- yield* send({
46914
- _tag: "OrgFailed",
46915
- orgId,
46916
- step: current,
46917
- failure: reset.failure
46918
- });
46919
- return yield* Effect.fail(reset.failure);
46920
- }
46921
- lifecycle = reset.success;
46922
- if (lifecycle.status !== "failed") {
46923
- retryDelayMs = delayMs;
46924
- step = orgStep(lifecycle);
46925
- yield* step === "ready" ? send({
46926
- _tag: "OrgReady",
46927
- orgId
46928
- }) : send({
46929
- _tag: "OrgAt",
46930
- orgId,
46931
- step
46932
- });
46933
- continue;
46934
- }
46935
- }
46936
- const failure = failureOf(lifecycle.error);
46937
- yield* send({
46938
- _tag: "OrgFailed",
46939
- orgId,
46940
- step: lifecycle.at,
46941
- failure,
46942
- retryable: lifecycle.retryable
46943
- });
46944
- return yield* Effect.fail(failure);
46945
- }
46946
- step = orgStep(lifecycle);
46947
- yield* step === "ready" ? send({
46948
- _tag: "OrgReady",
46949
- orgId
46950
- }) : send({
46951
- _tag: "OrgAt",
46952
- orgId,
46953
- step
46954
- });
46955
- if (step === current) yield* Effect.sleep("1 second");
46956
- }
46957
46840
  });
46958
46841
  const recoverIdentityFailure = (state, event, failure) => {
46959
46842
  if (event === "ReadSession") return {
@@ -46984,23 +46867,8 @@ const recoverIdentityFailure = (state, event, failure) => {
46984
46867
  failure
46985
46868
  };
46986
46869
  if (state.account.at !== "claimed" || state.account.org === null) return void 0;
46987
- const org = state.account.org;
46988
- if (org.at === "creating") return {
46989
- _tag: "OrgFailed",
46990
- orgId: null,
46991
- step: "preparingFounderAccount",
46992
- failure
46993
- };
46994
- if (org.at === "loading") return {
46995
- _tag: "OrgFailed",
46996
- orgId: org.orgId,
46997
- step: "preparingFounderAccount",
46998
- failure
46999
- };
47000
- return org.at === "settingUp" ? {
47001
- _tag: "OrgFailed",
47002
- orgId: org.orgId,
47003
- step: org.step,
46870
+ return state.account.org.orgId === null ? {
46871
+ _tag: "OrgSelectionFailed",
47004
46872
  failure
47005
46873
  } : void 0;
47006
46874
  };
@@ -47011,7 +46879,6 @@ const identitySpec = (input, sessionStore, authority) => {
47011
46879
  hasSigner: input.signer !== void 0,
47012
46880
  ...input.otpTtlMs === void 0 ? {} : { otpTtlMs: input.otpTtlMs }
47013
46881
  };
47014
- const backoff = normalizeConfirmationBackoff(input.confirmationBackoff);
47015
46882
  return {
47016
46883
  machine: "identity",
47017
46884
  initial: RESTORING,
@@ -47028,7 +46895,7 @@ const identitySpec = (input, sessionStore, authority) => {
47028
46895
  IDENTITY_SLOT.session,
47029
46896
  IDENTITY_SLOT.account,
47030
46897
  IDENTITY_SLOT.org
47031
- ] : [],
46898
+ ] : event._tag === "LeaveOrganization" || event._tag === "AttachOrganization" ? [IDENTITY_SLOT.org] : [],
47032
46899
  work: ({ state, event }) => {
47033
46900
  const activeSession = state.phase === "authenticated" ? state.session : null;
47034
46901
  const org = state.phase === "authenticated" && state.account.at === "claimed" ? state.account.org : null;
@@ -47122,29 +46989,10 @@ const identitySpec = (input, sessionStore, authority) => {
47122
46989
  }
47123
46990
  };
47124
46991
  }
47125
- case "CreateOrganization": return input.organizationSetup === void 0 || org?.at !== "creating" ? void 0 : {
47126
- slot: IDENTITY_SLOT.org,
47127
- port: "organization-setup",
47128
- run: (send, controls) => orgLane(input.organizationSetup, {
47129
- kind: "create",
47130
- draft: event.draft
47131
- }, send, controls, backoff, input.telemetry)
47132
- };
47133
- case "AttachOrganization": return input.organizationSetup === void 0 || org?.at !== "loading" ? void 0 : {
47134
- slot: IDENTITY_SLOT.org,
47135
- port: "organization-setup",
47136
- run: (send, controls) => orgLane(input.organizationSetup, {
47137
- kind: "attach",
47138
- orgId: org.orgId
47139
- }, send, controls, backoff, input.telemetry)
47140
- };
47141
- case "RetryOrganization": return input.organizationSetup === void 0 || org?.at !== "settingUp" ? void 0 : {
46992
+ case "CreateOrganization": return input.organizationSetup === void 0 || org === null || org.orgId !== null ? void 0 : {
47142
46993
  slot: IDENTITY_SLOT.org,
47143
46994
  port: "organization-setup",
47144
- run: (send, controls) => orgLane(input.organizationSetup, {
47145
- kind: "retry",
47146
- orgId: org.orgId
47147
- }, send, controls, backoff, input.telemetry)
46995
+ run: (send, controls) => beginOrganization$1(input.organizationSetup, event.draft, send, controls)
47148
46996
  };
47149
46997
  default: return;
47150
46998
  }
@@ -47153,10 +47001,69 @@ const identitySpec = (input, sessionStore, authority) => {
47153
47001
  };
47154
47002
  const bootIdentityFlow = (input, options = {}) => Effect.gen(function* () {
47155
47003
  const sessionStore = { current: null };
47156
- const authority = createIdentityAuthorityTracker(sessionStore);
47004
+ let invalidateOrganizationSubscriptions = () => input.organizationSetup?.invalidateSubscriptions?.();
47005
+ const authority = createIdentityAuthorityTracker(sessionStore, () => invalidateOrganizationSubscriptions());
47157
47006
  const actor = yield* boot(identitySpec(input, sessionStore, authority), options);
47158
47007
  authority.bindState(actor.snapshot);
47159
- const unsubscribeAuthority = actor.subscribe(authority.observe);
47008
+ const runPromise = input.runPromise ?? Effect.runPromise;
47009
+ let selectedOrgId = null;
47010
+ let stopRemote = null;
47011
+ let selectionEpoch = 0;
47012
+ invalidateOrganizationSubscriptions = () => {
47013
+ selectionEpoch += 1;
47014
+ const stop = stopRemote;
47015
+ stopRemote = null;
47016
+ try {
47017
+ stop?.();
47018
+ } finally {
47019
+ input.organizationSetup?.invalidateSubscriptions?.();
47020
+ }
47021
+ };
47022
+ const observe = (state) => {
47023
+ authority.observe(state);
47024
+ const nextOrgId = state.phase === "authenticated" && state.account.at === "claimed" ? state.account.org?.orgId ?? null : null;
47025
+ if (nextOrgId === selectedOrgId) return;
47026
+ selectedOrgId = nextOrgId;
47027
+ selectionEpoch += 1;
47028
+ const epoch = selectionEpoch;
47029
+ stopRemote?.();
47030
+ stopRemote = null;
47031
+ if (nextOrgId === null || input.organizationSetup === void 0) return;
47032
+ const capturedLifetime = authority.snapshot();
47033
+ const expectedAuthUserId = state.phase === "authenticated" ? state.session.authUserId : null;
47034
+ const emit = (snapshot) => {
47035
+ if (epoch !== selectionEpoch || !authority.matches(capturedLifetime, expectedAuthUserId)) return;
47036
+ runPromise(actor.tell({
47037
+ _tag: "ObserveOrganization",
47038
+ orgId: nextOrgId,
47039
+ snapshot
47040
+ })).catch(() => void 0);
47041
+ };
47042
+ try {
47043
+ const orgId = toOrgId(nextOrgId);
47044
+ input.organizationSetup.subscribe(orgId, emit).then((result) => {
47045
+ if (epoch !== selectionEpoch) {
47046
+ if (result.ok) result.value();
47047
+ return;
47048
+ }
47049
+ if (result.ok) stopRemote = result.value;
47050
+ else emit({
47051
+ status: "error",
47052
+ error: result.error
47053
+ });
47054
+ }).catch((cause) => emit({
47055
+ status: "error",
47056
+ error: Errors.unknown(cause)
47057
+ }));
47058
+ } catch (cause) {
47059
+ emit({
47060
+ status: "error",
47061
+ error: Errors.unknown(cause)
47062
+ });
47063
+ }
47064
+ };
47065
+ const unsubscribeAuthority = actor.subscribe(observe);
47066
+ observe(actor.snapshot());
47160
47067
  yield* Effect.addFinalizer(() => Effect.sync(() => {
47161
47068
  authority.invalidate();
47162
47069
  unsubscribeAuthority();
@@ -47181,7 +47088,7 @@ const bootIdentityFlow = (input, options = {}) => Effect.gen(function* () {
47181
47088
  });
47182
47089
  //#endregion
47183
47090
  //#region ../../packages/sdk/src/contract/org-lifecycle.ts
47184
- const organizationSetupProofReceiptQuery = makeFunctionReference(CAPXUL_FUNCTIONS["org/lifecycle"].getProofReceipt);
47091
+ const organizationSetupProofReceiptQuery = makeFunctionReference(CAPXUL_FUNCTIONS["org/setup"].getProofReceipt);
47185
47092
  //#endregion
47186
47093
  //#region ../../packages/sdk/src/surface/capxul-deps.ts
47187
47094
  /** The single Context tag the atoms + public methods both resolve. */
@@ -47864,6 +47771,10 @@ function normalizeOrganization(input) {
47864
47771
  ok: false,
47865
47772
  error: Errors.invalidInput("size", "must be text")
47866
47773
  };
47774
+ if (input.logoStorageId !== void 0 && typeof input.logoStorageId !== "string") return {
47775
+ ok: false,
47776
+ error: Errors.invalidInput("logoStorageId", "must be a storage ID")
47777
+ };
47867
47778
  let country;
47868
47779
  try {
47869
47780
  country = toCountryCode(input.country);
@@ -47882,7 +47793,8 @@ function normalizeOrganization(input) {
47882
47793
  handle: handle.value,
47883
47794
  country,
47884
47795
  ...bio.length === 0 ? {} : { bio },
47885
- ...size.length === 0 ? {} : { size }
47796
+ ...size.length === 0 ? {} : { size },
47797
+ ...input.logoStorageId === void 0 ? {} : { logoStorageId: input.logoStorageId }
47886
47798
  }
47887
47799
  };
47888
47800
  }
@@ -47974,93 +47886,137 @@ async function reachClaimedAccount(deps, options) {
47974
47886
  value: state
47975
47887
  } : organizationWrongState(state.phase === "authenticated" ? state.account.at : state.phase, ["claimed"]);
47976
47888
  }
47977
- async function createOrResumeOrganization(deps, state, draft, options) {
47978
- const selected = await selectOrganizationLane(deps, state, options);
47979
- if (!selected.ok) return selected;
47980
- state = selected.value;
47981
- const active = state.account.org;
47982
- if (active?.at === "ready") return {
47983
- ok: true,
47984
- value: { organizationId: active.orgId }
47985
- };
47986
- if (active?.at === "failed" && !active.retryable) return {
47889
+ async function beginOrganization(deps, input, options) {
47890
+ const normalized = normalizeOrganization(input);
47891
+ if (!normalized.ok) return normalized;
47892
+ const setup = deps.organizationSetup;
47893
+ if (setup === void 0) return {
47987
47894
  ok: false,
47988
- error: publicIdentityFailure(active.failure)
47895
+ error: Errors.notImplemented("organizationSetup", "begin")
47989
47896
  };
47990
- if (active?.at === "failed" && active.orgId === null) {
47991
- const cleared = await deps.sendIdentity({ _tag: "LeaveOrganization" }, options);
47992
- if (!cleared.ok) return cleared;
47897
+ const captured = deps.authLifetime();
47898
+ try {
47899
+ const session = await deps.restoreSession(options);
47900
+ if (!session.ok) return session;
47901
+ if (session.value === null) return {
47902
+ ok: false,
47903
+ error: Errors.notAuthenticated()
47904
+ };
47905
+ const authUserId = String(session.value.authUserId);
47906
+ const current = () => deps.matchesAuthLifetime(captured, authUserId) && !requestCancelled(options);
47907
+ if (!current()) return cancelledOrganization();
47908
+ const profile = await deps.loadProfile(options);
47909
+ if (!current()) return cancelledOrganization();
47910
+ if (!profile.ok) return profile;
47911
+ if (profile.value?.displayName === null || profile.value?.handle === null || profile.value === null) return organizationWrongState("profile-incomplete", ["profile-complete"]);
47912
+ const refreshed = await deps.refreshIdentity(options);
47913
+ if (!current()) return cancelledOrganization();
47914
+ if (!refreshed.ok) return refreshed;
47915
+ const claimed = await reachClaimedAccount(deps, options);
47916
+ if (!current()) return cancelledOrganization();
47917
+ if (!claimed.ok) return claimed;
47918
+ const begun = await setup.begin(normalized.value);
47919
+ if (!current()) return cancelledOrganization();
47920
+ if (begun.ok) {
47921
+ await deps.sendIdentity({
47922
+ _tag: "AttachOrganization",
47923
+ orgId: String(begun.value.orgId)
47924
+ }, options);
47925
+ if (!current()) return cancelledOrganization();
47926
+ }
47927
+ return begun;
47928
+ } catch (cause) {
47929
+ return {
47930
+ ok: false,
47931
+ error: Errors.unknown(cause)
47932
+ };
47993
47933
  }
47994
- const event = active?.at === "failed" && active.orgId !== null ? { _tag: "RetryOrganization" } : {
47995
- _tag: "CreateOrganization",
47996
- draft
47997
- };
47998
- const created = await deps.sendIdentity(event, options);
47999
- if (!created.ok) return created;
48000
- const final = created.value;
48001
- const organization = isClaimedIdentityState(final) ? final.account.org : null;
48002
- return organization?.at === "ready" ? {
48003
- ok: true,
48004
- value: { organizationId: organization.orgId }
48005
- } : organizationWrongState(organization?.at ?? "organization-missing", ["ready"], organization !== null && "orgId" in organization ? organization.orgId ?? void 0 : void 0);
48006
47934
  }
48007
- async function selectOrganizationLane(deps, state, options) {
48008
- if (options?.intent !== "create") return {
48009
- ok: true,
48010
- value: state
47935
+ function setupFailure(setup) {
47936
+ const issue = setup.issue;
47937
+ const details = {
47938
+ ...issue?.error?.details,
47939
+ organizationId: String(setup.orgId),
47940
+ ...issue !== null && { setupReason: issue.reason }
48011
47941
  };
48012
- const active = state.account.org;
48013
- if (active?.at === "ready") {
48014
- const left = await deps.sendIdentity({ _tag: "LeaveOrganization" }, options);
48015
- if (!left.ok) return left;
48016
- return isClaimedIdentityState(left.value) ? {
48017
- ok: true,
48018
- value: left.value
48019
- } : organizationWrongState("organization-leave-incomplete", ["claimed"]);
47942
+ if (issue?.error !== void 0) {
47943
+ const error = issue.error;
47944
+ return new CapxulError(error.code, error.message, {
47945
+ details,
47946
+ ...error.mode === void 0 ? {} : { mode: error.mode },
47947
+ ...error.chain === void 0 ? {} : { chain: error.chain },
47948
+ ...error.layer === void 0 ? {} : { layer: error.layer },
47949
+ ...error.correlationId === void 0 ? {} : { correlationId: error.correlationId }
47950
+ });
48020
47951
  }
48021
- if (active === null || active === void 0) return {
48022
- ok: true,
48023
- value: state
48024
- };
48025
- const organizationId = "orgId" in active ? active.orgId ?? void 0 : void 0;
48026
- return organizationWrongState(active.at, ["no-active-organization"], organizationId);
47952
+ const fallback = Errors.wrongState({
47953
+ method: CAPXUL_OPERATIONS.onboarding.completeOrganization,
47954
+ currentState: setup.status,
47955
+ validStates: ["ready"],
47956
+ organizationId: String(setup.orgId)
47957
+ });
47958
+ return new CapxulError(fallback.code, fallback.message, { details: {
47959
+ ...fallback.details,
47960
+ ...details
47961
+ } });
48027
47962
  }
48028
- function projectOrganizationState(state) {
48029
- if (state.phase !== "authenticated" || state.account.at !== "claimed") return {
48030
- organizationId: null,
48031
- lifecycle: null
48032
- };
48033
- const org = state.account.org;
48034
- if (org === null || org.at === "creating") return {
48035
- organizationId: null,
48036
- lifecycle: null
48037
- };
48038
- if (org.at === "failed" && org.orgId === null) return {
48039
- organizationId: null,
48040
- lifecycle: null
48041
- };
48042
- const organizationId = toOrgId(org.orgId);
48043
- return {
48044
- organizationId,
48045
- lifecycle: org.at === "loading" ? {
48046
- status: "loading",
48047
- orgId: organizationId
48048
- } : org.at === "settingUp" ? {
48049
- status: "settingUp",
48050
- orgId: organizationId,
48051
- step: org.step
48052
- } : org.at === "ready" ? {
48053
- status: "ready",
48054
- orgId: organizationId,
48055
- canTransact: true
48056
- } : {
48057
- status: "failed",
48058
- orgId: organizationId,
48059
- at: org.step,
48060
- error: publicIdentityFailure(org.failure),
48061
- retryable: org.retryable
48062
- }
48063
- };
47963
+ const cancelledOrganization = () => ({
47964
+ ok: false,
47965
+ error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.onboarding.completeOrganization })
47966
+ });
47967
+ function awaitReady(deps, orgId, options) {
47968
+ const setup = deps.organizationSetup;
47969
+ if (setup === void 0) return Promise.resolve({
47970
+ ok: false,
47971
+ error: Errors.notImplemented("organizationSetup", "subscribe")
47972
+ });
47973
+ const lifetime = deps.authLifetime();
47974
+ const isCurrent = () => deps.matchesAuthLifetime(lifetime, lifetime.authUserId);
47975
+ return new Promise((resolve) => {
47976
+ let done = false;
47977
+ let stopRemote = null;
47978
+ let stopIdentity = null;
47979
+ const finish = (result) => {
47980
+ if (done) return;
47981
+ done = true;
47982
+ stopRemote?.();
47983
+ stopIdentity?.();
47984
+ options?.signal?.removeEventListener("abort", onAbort);
47985
+ resolve(result);
47986
+ };
47987
+ const onAbort = () => finish(cancelledOrganization());
47988
+ options?.signal?.addEventListener("abort", onAbort, { once: true });
47989
+ const releaseIdentity = deps.subscribeIdentity((state) => {
47990
+ if (state.phase !== "authenticated" || !deps.matchesAuthLifetime(lifetime, state.session.authUserId)) finish(cancelledOrganization());
47991
+ });
47992
+ if (done) releaseIdentity();
47993
+ else stopIdentity = releaseIdentity;
47994
+ if (options?.signal?.aborted || !isCurrent()) return onAbort();
47995
+ setup.subscribe(orgId, (snapshot) => {
47996
+ if (done) return;
47997
+ if (!isCurrent()) return finish(cancelledOrganization());
47998
+ if (snapshot.status === "loading") return;
47999
+ if (snapshot.status === "error") return finish({
48000
+ ok: false,
48001
+ error: snapshot.error
48002
+ });
48003
+ if (snapshot.value.status === "ready") return finish({
48004
+ ok: true,
48005
+ value: { organizationId: orgId }
48006
+ });
48007
+ if (snapshot.value.status === "needsAttention" || snapshot.value.status === "failed") finish({
48008
+ ok: false,
48009
+ error: setupFailure(snapshot.value)
48010
+ });
48011
+ }, options).then((result) => {
48012
+ if (!result.ok) return finish(result);
48013
+ if (done) result.value();
48014
+ else stopRemote = result.value;
48015
+ }).catch((cause) => finish({
48016
+ ok: false,
48017
+ error: Errors.unknown(cause)
48018
+ }));
48019
+ });
48064
48020
  }
48065
48021
  const cancelledPerson = () => ({
48066
48022
  ok: false,
@@ -48114,8 +48070,22 @@ const samePersonInput = (left, right) => {
48114
48070
  function makeOnboardingMethods(deps) {
48115
48071
  let personFlight = null;
48116
48072
  return {
48117
- subscribeOrganization(observer) {
48118
- return deps.subscribeIdentity((state) => observer(projectOrganizationState(state)));
48073
+ async listOrganizationSetups(input, options) {
48074
+ if (requestCancelled(options)) return cancelledOrganization();
48075
+ if (deps.organizationSetup === void 0) return {
48076
+ ok: false,
48077
+ error: Errors.notImplemented("organizationSetup", "listMine")
48078
+ };
48079
+ const lifetime = deps.authLifetime();
48080
+ const session = await deps.restoreSession(options);
48081
+ if (!session.ok) return session;
48082
+ if (session.value === null) return {
48083
+ ok: false,
48084
+ error: Errors.notAuthenticated()
48085
+ };
48086
+ if (!deps.matchesAuthLifetime(lifetime, String(session.value.authUserId)) || requestCancelled(options)) return cancelledOrganization();
48087
+ const listed = await deps.organizationSetup.listMine(input, options);
48088
+ return deps.matchesAuthLifetime(lifetime, String(session.value.authUserId)) && !requestCancelled(options) ? listed : cancelledOrganization();
48119
48089
  },
48120
48090
  async completePerson(input, options) {
48121
48091
  if (options?.signal?.aborted) return cancelledPerson();
@@ -48261,39 +48231,40 @@ function makeOnboardingMethods(deps) {
48261
48231
  if (personFlight?.pending === pending) personFlight = null;
48262
48232
  }
48263
48233
  },
48234
+ beginOrganization(input, options) {
48235
+ return beginOrganization(deps, input, options);
48236
+ },
48264
48237
  async completeOrganization(input, options) {
48265
- const operation = CAPXUL_OPERATIONS.onboarding.completeOrganization;
48266
- const normalized = normalizeOrganization(input);
48267
- if (!normalized.ok) return normalized;
48268
- const session = await deps.restoreSession(options);
48269
- if (!session.ok) return session;
48270
- if (session.value === null) return {
48271
- ok: false,
48272
- error: Errors.notAuthenticated()
48273
- };
48274
- const profile = await deps.loadProfile(options);
48275
- if (!profile.ok) return profile;
48276
- if (profile.value === null || profile.value.displayName === null || profile.value.handle === null) return {
48277
- ok: false,
48278
- error: Errors.wrongState({
48279
- method: operation,
48280
- currentState: "profile-incomplete",
48281
- validStates: ["profile-complete"]
48282
- })
48283
- };
48284
- const refreshed = await deps.refreshIdentity(options);
48285
- if (!refreshed.ok) return refreshed;
48286
- if (requestCancelled(options)) return {
48287
- ok: false,
48288
- error: Errors.cancelled({ operation })
48289
- };
48290
- const claimed = await reachClaimedAccount(deps, options);
48291
- if (!claimed.ok) return claimed;
48292
- if (requestCancelled(options)) return {
48293
- ok: false,
48294
- error: Errors.cancelled({ operation })
48295
- };
48296
- return createOrResumeOrganization(deps, claimed.value, normalized.value, options);
48238
+ try {
48239
+ const begun = await beginOrganization(deps, input, options);
48240
+ if (!begun.ok) return begun;
48241
+ const lifetime = deps.authLifetime();
48242
+ const isCurrent = () => deps.matchesAuthLifetime(lifetime, lifetime.authUserId);
48243
+ if (!isCurrent()) return cancelledOrganization();
48244
+ const { orgId } = begun.value;
48245
+ let setup = begun.value.setup;
48246
+ if (setup.status === "awaitingAuthorization") {
48247
+ const authorized = await deps.organizationSetup.authorize(orgId, options);
48248
+ if (!isCurrent()) return cancelledOrganization();
48249
+ if (!authorized.ok) return authorized;
48250
+ setup = authorized.value;
48251
+ }
48252
+ if (requestCancelled(options) || !isCurrent()) return cancelledOrganization();
48253
+ if (setup.status === "ready") return {
48254
+ ok: true,
48255
+ value: { organizationId: orgId }
48256
+ };
48257
+ if (setup.status === "needsAttention" || setup.status === "failed") return {
48258
+ ok: false,
48259
+ error: setupFailure(setup)
48260
+ };
48261
+ return awaitReady(deps, orgId, options);
48262
+ } catch (cause) {
48263
+ return {
48264
+ ok: false,
48265
+ error: Errors.unknown(cause)
48266
+ };
48267
+ }
48297
48268
  }
48298
48269
  };
48299
48270
  }
@@ -49346,92 +49317,6 @@ function makeUnavailablePayrollMethods() {
49346
49317
  };
49347
49318
  }
49348
49319
  //#endregion
49349
- //#region ../../packages/sdk/src/surface/_shared/org-telemetry.ts
49350
- /** Extract the domain from an email for telemetry (never the local part / PII). */
49351
- function emailDomain$1(email) {
49352
- const at = email.lastIndexOf("@");
49353
- if (at < 0 || at === email.length - 1) return void 0;
49354
- return email.slice(at + 1).toLowerCase();
49355
- }
49356
- /** Fire-and-forget emit through an optional port; never throws. */
49357
- async function emitOrgTelemetry(telemetry, event, runPromise) {
49358
- if (telemetry === void 0) return;
49359
- await Promise.resolve().then(() => runPromise(Effect.suspend(() => telemetry.emit(event)).pipe(Effect.catch((cause) => reportOrgTelemetryFailure("error", event.name, cause)), Effect.catchDefect((cause) => reportOrgTelemetryFailure("defect", event.name, cause))))).catch(() => void 0);
49360
- }
49361
- function emitOrgCreateStarted(telemetry, input, runPromise) {
49362
- const domain = input.email === void 0 ? void 0 : emailDomain$1(input.email);
49363
- return emitOrgTelemetry(telemetry, {
49364
- name: "org_create_started",
49365
- props: {
49366
- template: input.template,
49367
- ...domain === void 0 ? {} : { email_domain: domain }
49368
- }
49369
- }, runPromise);
49370
- }
49371
- /** Spread the `chainId` prop only when known — never emit a misleading `0`. */
49372
- function chainIdProp(chainId) {
49373
- return chainId === void 0 ? {} : { chainId };
49374
- }
49375
- function emitOrgSafeCreated(telemetry, input, runPromise) {
49376
- return emitOrgTelemetry(telemetry, {
49377
- name: "org_safe_created",
49378
- props: {
49379
- org_id: input.orgId,
49380
- safe_address: input.safeAddress,
49381
- ...chainIdProp(input.chainId)
49382
- }
49383
- }, runPromise);
49384
- }
49385
- function emitOrgSafeConfirmed(telemetry, input, runPromise) {
49386
- return emitOrgTelemetry(telemetry, {
49387
- name: "org_safe_confirmed",
49388
- props: {
49389
- org_id: input.orgId,
49390
- safe_address: input.safeAddress,
49391
- ...chainIdProp(input.chainId)
49392
- }
49393
- }, runPromise);
49394
- }
49395
- function emitOrgRolesSeeded(telemetry, input, runPromise) {
49396
- return emitOrgTelemetry(telemetry, {
49397
- name: "org_roles_seeded",
49398
- props: {
49399
- org_id: input.orgId,
49400
- role: input.role
49401
- }
49402
- }, runPromise);
49403
- }
49404
- function emitOrgCreated(telemetry, input, runPromise) {
49405
- return emitOrgTelemetry(telemetry, {
49406
- name: "org_created",
49407
- props: {
49408
- org_id: input.orgId,
49409
- safe_address: input.safeAddress,
49410
- ...chainIdProp(input.chainId)
49411
- }
49412
- }, runPromise);
49413
- }
49414
- function emitOrgCreateFailed(telemetry, error, runPromise) {
49415
- return emitOrgTelemetry(telemetry, {
49416
- name: "org_create_failed",
49417
- props: {
49418
- ...failureDetail(error),
49419
- reason: error.code
49420
- }
49421
- }, runPromise);
49422
- }
49423
- function reportOrgTelemetryFailure(kind, name, cause) {
49424
- if (!isOrgTelemetryDebugEnabled()) return Effect.void;
49425
- return Effect.logWarning("org.telemetry.dropped").pipe(Effect.annotateLogs({
49426
- kind,
49427
- event_name: name,
49428
- ...failureDetail(cause)
49429
- }));
49430
- }
49431
- function isOrgTelemetryDebugEnabled() {
49432
- return globalThis.process?.env?.CAPXUL_DEBUG_TELEMETRY === "1";
49433
- }
49434
- //#endregion
49435
49320
  //#region ../../packages/sdk/src/surface/org-deps.ts
49436
49321
  var OrgDepsTag = class extends Context.Service()("@capxul/sdk/OrgDeps") {};
49437
49322
  function orgDepsLayer(deps) {
@@ -49453,91 +49338,6 @@ function stripPrefix(value) {
49453
49338
  const cleaned = (underscore < 0 ? value : value.slice(underscore + 1)).replace(/[^0-9A-Za-z]/g, "");
49454
49339
  return cleaned.length > 0 ? cleaned : "0";
49455
49340
  }
49456
- /** Map an arbitrary string deterministically into lowercase hex chars. */
49457
- function toHexSeed(value) {
49458
- let out = "";
49459
- for (const ch of value) out += (ch.codePointAt(0) ?? 0).toString(16).padStart(2, "0");
49460
- return out.length > 0 ? out : "0";
49461
- }
49462
- /**
49463
- * Build the hermetic `OrgView` for the no-port L1 path: a deterministic
49464
- * counterfactual-shaped placeholder Org Safe + a `$0` treasury (D3). The live
49465
- * path replaces this with the real deployed address + RPC balance.
49466
- */
49467
- function hermeticOrgView(input) {
49468
- const orgId = toOrgId(`org_${stripPrefix(`x_${input.handle}`)}`);
49469
- const placeholder = `0x${toHexSeed(input.handle).padEnd(40, "0").slice(0, 40)}`;
49470
- return {
49471
- id: orgId,
49472
- name: input.name,
49473
- handle: input.handle,
49474
- safeAddress: toAddress(placeholder),
49475
- role: ADMIN_ROLE_LABEL,
49476
- treasury: zeroTreasury(orgId),
49477
- bio: null,
49478
- size: null,
49479
- logoUrl: null,
49480
- account: {
49481
- id: null,
49482
- address: toAddress(placeholder),
49483
- ready: null
49484
- },
49485
- setup: {
49486
- status: "settingUp",
49487
- orgId,
49488
- step: "preparingFounderAccount"
49489
- },
49490
- member: null,
49491
- capabilities: {
49492
- canManagePeople: false,
49493
- canSpend: false
49494
- },
49495
- custody: { status: "unknown" },
49496
- observedAt: 0
49497
- };
49498
- }
49499
- function createOrgProgram(input) {
49500
- return Effect.gen(function* () {
49501
- const deps = yield* OrgDepsTag;
49502
- const chainId = deps.chainId;
49503
- yield* Effect.promise(() => emitOrgCreateStarted(deps.telemetry, { template: input.template }, deps.runPromise));
49504
- return yield* Effect.gen(function* () {
49505
- if (deps.orgPort !== void 0) {
49506
- const org = yield* deps.orgPort.createOrg({ input }).pipe(Effect.mapError((error) => error.publicError));
49507
- yield* emitCreationFunnelTail(deps.telemetry, org, chainId, deps.runPromise);
49508
- return org;
49509
- }
49510
- const org = hermeticOrgView(input);
49511
- yield* emitCreationFunnelTail(deps.telemetry, org, chainId, deps.runPromise);
49512
- return org;
49513
- }).pipe(Effect.tapError((error) => Effect.promise(() => emitOrgCreateFailed(deps.telemetry, error, deps.runPromise))));
49514
- });
49515
- }
49516
- /** Emit the remaining `org_creation` funnel steps once the org is built. */
49517
- function emitCreationFunnelTail(telemetry, org, chainId, runPromise) {
49518
- return Effect.promise(async () => {
49519
- const chain = chainId === void 0 ? {} : { chainId };
49520
- await emitOrgSafeCreated(telemetry, {
49521
- orgId: org.id,
49522
- safeAddress: org.safeAddress,
49523
- ...chain
49524
- }, runPromise);
49525
- await emitOrgSafeConfirmed(telemetry, {
49526
- orgId: org.id,
49527
- safeAddress: org.safeAddress,
49528
- ...chain
49529
- }, runPromise);
49530
- if (org.role !== null) await emitOrgRolesSeeded(telemetry, {
49531
- orgId: org.id,
49532
- role: org.role
49533
- }, runPromise);
49534
- await emitOrgCreated(telemetry, {
49535
- orgId: org.id,
49536
- safeAddress: org.safeAddress,
49537
- ...chain
49538
- }, runPromise);
49539
- });
49540
- }
49541
49341
  function readTreasuryProgram(orgId) {
49542
49342
  return Effect.gen(function* () {
49543
49343
  const deps = yield* OrgDepsTag;
@@ -49604,90 +49404,6 @@ function listOrgsProgram() {
49604
49404
  });
49605
49405
  }
49606
49406
  //#endregion
49607
- //#region ../../packages/sdk/src/surface/org-lifecycle.ts
49608
- function fail$1(error) {
49609
- return {
49610
- ok: false,
49611
- error
49612
- };
49613
- }
49614
- function validateOrganizationLifecycleScope(orgId, lifecycle) {
49615
- if (String(lifecycle.orgId) !== String(orgId)) return fail$1(Errors.invalidInput("orgId", "Organization lifecycle scope does not match"));
49616
- return {
49617
- ok: true,
49618
- value: lifecycle
49619
- };
49620
- }
49621
- /** Advance only the steps still required by one durable Organization lane. */
49622
- async function advanceOrganizationSetup(setup, orgId, initial, context) {
49623
- const { signal, observationSource } = context ?? {};
49624
- const scopedInitial = validateOrganizationLifecycleScope(orgId, initial);
49625
- if (!scopedInitial.ok) return scopedInitial;
49626
- let lifecycle = scopedInitial.value;
49627
- for (let transition = 0; transition < 3; transition += 1) {
49628
- if (lifecycle.status !== "settingUp") return {
49629
- ok: true,
49630
- value: lifecycle
49631
- };
49632
- const currentStep = lifecycle.step;
49633
- if (signal?.aborted) return recordSetupFailure(setup, orgId, Errors.cancelled({ operation: CAPXUL_OPERATIONS.organization.setup }), true, observationSource);
49634
- const stepInput = copyInvocationObservation(observationSource, {
49635
- orgId,
49636
- ...signal === void 0 ? {} : { signal }
49637
- });
49638
- const next = lifecycle.step === "preparingFounderAccount" ? await setup.prepareFounderAccount(stepInput) : lifecycle.step === "awaitingFounderAuthorization" ? await setup.authorizeAndSubmitBootstrap(stepInput) : lifecycle.step === "submittingBootstrap" ? await setup.resumeSubmittedBootstrap(stepInput) : await setup.confirmSubmittedBootstrap(stepInput);
49639
- if (!next.ok) return recordSetupFailure(setup, orgId, next.error, isRetryableOrganizationSetupFailure(next.error), observationSource);
49640
- const scopedNext = validateOrganizationLifecycleScope(orgId, next.value);
49641
- if (!scopedNext.ok) return recordSetupFailure(setup, orgId, scopedNext.error, false, observationSource);
49642
- lifecycle = scopedNext.value;
49643
- if (currentStep === "confirmingBootstrap") return {
49644
- ok: true,
49645
- value: lifecycle
49646
- };
49647
- }
49648
- if (lifecycle.status !== "settingUp" || lifecycle.step === "confirmingBootstrap") return {
49649
- ok: true,
49650
- value: lifecycle
49651
- };
49652
- return recordSetupFailure(setup, orgId, Errors.wrongState({
49653
- method: CAPXUL_OPERATIONS.organization.setup,
49654
- currentState: lifecycle.step,
49655
- validStates: [
49656
- "confirmingBootstrap",
49657
- "ready",
49658
- "failed"
49659
- ]
49660
- }), false, observationSource);
49661
- }
49662
- async function recordSetupFailure(setup, orgId, error, retryable, observationSource) {
49663
- const recorded = await setup.recordFailure(copyInvocationObservation(observationSource, {
49664
- orgId,
49665
- error,
49666
- retryable
49667
- }));
49668
- if (!recorded.ok) return recorded;
49669
- const scopedRecorded = validateOrganizationLifecycleScope(orgId, recorded.value);
49670
- if (!scopedRecorded.ok) return scopedRecorded;
49671
- return scopedRecorded;
49672
- }
49673
- /**
49674
- * ADR-0023 R7: the layer that saw the chain failure says whether the same
49675
- * request can succeed later; its word wins over the mode table. The table is
49676
- * the one `identity/model.ts` uses, so the two gates read one list
49677
- * (`org.account.get` retried a `transient: false` 403 in 1.5 s, 2026-09-03).
49678
- */
49679
- function isRetryableProviderFailure(error) {
49680
- if (error.chain !== void 0) return error.chain.retryable;
49681
- const mode = error.mode ?? error.details?.failure_mode;
49682
- return !DEFINITIVE_PROVIDER_MODES.has(isFailureMode(mode) ? mode : void 0);
49683
- }
49684
- /** @internal Exported for the retry-gate test; the surface calls it from the setup loop. */
49685
- function isRetryableOrganizationSetupFailure(error) {
49686
- if (error.code === "CANCELLED" || error.code === "SIGNER_REJECTED") return true;
49687
- if (error.code === "PROVIDER_ERROR") return isRetryableProviderFailure(error);
49688
- return error.code === "NETWORK_ERROR" || error.code === "UNKNOWN";
49689
- }
49690
- //#endregion
49691
49407
  //#region ../../packages/sdk/src/surface/org.ts
49692
49408
  /**
49693
49409
  * Org method surface (canon §C2/§C3, D13). The entity-scoped bundle is
@@ -49715,6 +49431,20 @@ function invitationMethodsDeps(deps, convexCall) {
49715
49431
  ...deps.signer === void 0 ? {} : { signer: deps.signer }
49716
49432
  };
49717
49433
  }
49434
+ async function invokeSetup(setup, method, call) {
49435
+ if (setup === void 0) return {
49436
+ ok: false,
49437
+ error: Errors.notImplemented("organizationSetup", method)
49438
+ };
49439
+ try {
49440
+ return await call();
49441
+ } catch (cause) {
49442
+ return {
49443
+ ok: false,
49444
+ error: Errors.unknown(cause)
49445
+ };
49446
+ }
49447
+ }
49718
49448
  function makeOrgMethods(deps) {
49719
49449
  const orgDeps = {
49720
49450
  runPromise: deps.runPromise,
@@ -49740,13 +49470,6 @@ function makeOrgMethods(deps) {
49740
49470
  }))), controls, CAPXUL_OPERATIONS.org.orgs, deps.runPromise);
49741
49471
  };
49742
49472
  return {
49743
- createOrg(input, options) {
49744
- if (options?.signal?.aborted) return Promise.resolve({
49745
- ok: false,
49746
- error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.org.createOrg })
49747
- });
49748
- return toCapxulResult(createOrgProgram(input), layer, deps.runPromise);
49749
- },
49750
49473
  orgs: Object.assign((options) => listOrganizations(deps.invocationControls?.(options) ?? options), { invitations: deps.convexCall === void 0 ? () => Promise.resolve({
49751
49474
  ok: false,
49752
49475
  error: Errors.notImplemented("invitations", "listOwn")
@@ -49767,38 +49490,11 @@ function makeOrgMethods(deps) {
49767
49490
  convexCall,
49768
49491
  ...observedRunnerDeps(deps)
49769
49492
  }, String(orgId)),
49770
- async getLifecycle(options) {
49771
- if (options?.signal?.aborted) return {
49772
- ok: false,
49773
- error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.org.getLifecycle })
49774
- };
49775
- if (deps.organizationSetup === void 0) return {
49776
- ok: false,
49777
- error: Errors.notImplemented("organizationSetup", "getLifecycle")
49778
- };
49779
- const loaded = await deps.organizationSetup.loadLifecycle({ orgId });
49780
- if (!loaded.ok) return loaded;
49781
- return validateOrganizationLifecycleScope(orgId, loaded.value);
49782
- },
49783
- async retrySetup(options) {
49784
- if (options?.signal?.aborted) return {
49785
- ok: false,
49786
- error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.org.retrySetup })
49787
- };
49788
- const setup = deps.organizationSetup;
49789
- if (setup === void 0) return {
49790
- ok: false,
49791
- error: Errors.notImplemented("organizationSetup", "retrySetup")
49792
- };
49793
- const retried = await setup.retry(copyInvocationObservation(options, {
49794
- orgId,
49795
- ...options?.signal === void 0 ? {} : { signal: options.signal }
49796
- }));
49797
- if (!retried.ok) return retried;
49798
- return advanceOrganizationSetup(setup, orgId, retried.value, {
49799
- signal: options?.signal,
49800
- observationSource: options
49801
- });
49493
+ setup: {
49494
+ get: (options) => invokeSetup(deps.organizationSetup, "get", () => deps.organizationSetup.get(orgId, options)),
49495
+ subscribe: (listener, options) => invokeSetup(deps.organizationSetup, "subscribe", () => deps.organizationSetup.subscribe(orgId, listener, options)),
49496
+ resume: (options) => invokeSetup(deps.organizationSetup, "resume", () => deps.organizationSetup.resume(orgId, options)),
49497
+ authorize: (options) => invokeSetup(deps.organizationSetup, "authorize", () => deps.organizationSetup.authorize(orgId, options))
49802
49498
  },
49803
49499
  profile: {
49804
49500
  get(_options) {
@@ -50154,8 +49850,8 @@ const APPLIED_ACTION_BY_EVENT = {
50154
49850
  RetryAccount: "none",
50155
49851
  CreateOrganization: "none",
50156
49852
  AttachOrganization: "none",
50157
- RetryOrganization: "none",
50158
49853
  LeaveOrganization: "none",
49854
+ ObserveOrganization: "none",
50159
49855
  OtpSent: "otp-requested",
50160
49856
  OtpFailed: "failed",
50161
49857
  Verified: "verified",
@@ -50169,9 +49865,8 @@ const APPLIED_ACTION_BY_EVENT = {
50169
49865
  AccountClaiming: "none",
50170
49866
  AccountClaimed: "none",
50171
49867
  AccountFailed: "none",
50172
- OrgAt: "none",
50173
- OrgReady: "none",
50174
- OrgFailed: "none"
49868
+ OrgSelected: "none",
49869
+ OrgSelectionFailed: "none"
50175
49870
  };
50176
49871
  const linkage = (record) => ({
50177
49872
  ...record.correlation_id === void 0 ? {} : { correlation_id: record.correlation_id },
@@ -50234,8 +49929,7 @@ const REFUSAL_EVENTS = /* @__PURE__ */ new Set([
50234
49929
  "ClaimAccount",
50235
49930
  "RetryAccount",
50236
49931
  "CreateOrganization",
50237
- "AttachOrganization",
50238
- "RetryOrganization"
49932
+ "AttachOrganization"
50239
49933
  ]);
50240
49934
  function mapIdentityProductObservation(record, state) {
50241
49935
  if (record.machine !== "identity" || !IDENTITY_EVENT_TAG_SET.has(record.event)) return NONE;
@@ -50414,7 +50108,7 @@ function assembleCapxulClient(input) {
50414
50108
  ...input.signer === void 0 ? {} : { signer: input.signer },
50415
50109
  ...input.organizationSetup === void 0 ? {} : { organizationSetup: input.organizationSetup },
50416
50110
  ...input.otpTtlMs === void 0 ? {} : { otpTtlMs: input.otpTtlMs },
50417
- ...input.ports.telemetry === void 0 ? {} : { telemetry: input.ports.telemetry }
50111
+ runPromise: effectRunner.runPromise
50418
50112
  }), scope)), observation.hostObservationSnapshot);
50419
50113
  const unsubscribeProductTelemetry = actor.subscribeTransitions((record) => {
50420
50114
  effectRunner.runPromise(executeIdentityProductObservation(input.ports.telemetry, record, actor.snapshot())).catch(() => {});
@@ -50442,7 +50136,7 @@ function assembleCapxulClient(input) {
50442
50136
  return stopPromise;
50443
50137
  };
50444
50138
  if (input.signal !== void 0) input.signal.addEventListener("abort", () => void stopActor(), { once: true });
50445
- const selectedOrgPort = input.orgPort ?? input.orgDeploymentPort;
50139
+ const selectedOrgPort = input.orgPort;
50446
50140
  let kickProvisioning;
50447
50141
  const financialOps = makeFinancialOpsMethods({
50448
50142
  runPromise: effectRunner.runPromise,
@@ -50529,7 +50223,8 @@ function assembleCapxulClient(input) {
50529
50223
  getLifecycle: account.getLifecycle,
50530
50224
  snapshotIdentity: actor.snapshot,
50531
50225
  subscribeIdentity: actor.subscribe,
50532
- sendIdentity: (event, options) => runCapxulEffect(askIdentity(actor, event, options), options, CAPXUL_OPERATIONS._internal.identity.send, effectRunner.runPromise)
50226
+ sendIdentity: (event, options) => runCapxulEffect(askIdentity(actor, event, options), options, CAPXUL_OPERATIONS._internal.identity.send, effectRunner.runPromise),
50227
+ ...input.organizationSetup === void 0 ? {} : { organizationSetup: input.organizationSetup }
50533
50228
  });
50534
50229
  const system = makeSystemMethods({
50535
50230
  convexCall: input.ports.convexCall,
@@ -50659,7 +50354,6 @@ function assembleCapxulClient(input) {
50659
50354
  offramp: financialOps.offramp,
50660
50355
  paymentDocuments: financialOps.paymentDocuments,
50661
50356
  media,
50662
- createOrg: orgMethods.createOrg,
50663
50357
  orgs: orgMethods.orgs,
50664
50358
  org: orgMethods.org,
50665
50359
  signer: input.signer?.statusStore ?? UNOBSERVABLE_SIGNER_STATUS,
@@ -51754,7 +51448,8 @@ async function createCapxulClientWithSignerControls(input, controls) {
51754
51448
  organizationSetup: new ConvexOrganizationSetupAdapter({
51755
51449
  convex: adapters.value.ports.convexCall,
51756
51450
  ...signer === void 0 ? {} : { signer },
51757
- chainId: adapters.value.bootstrap.chainId
51451
+ chainId: adapters.value.bootstrap.chainId,
51452
+ runPromise: effectRunner.runPromise
51758
51453
  }),
51759
51454
  ...input.signal === void 0 ? {} : { signal: input.signal },
51760
51455
  ...input.otpTtlMs === void 0 ? {} : { otpTtlMs: input.otpTtlMs },
@@ -52091,8 +51786,8 @@ function captureException(telemetry, error, context) {
52091
51786
  }
52092
51787
  //#endregion
52093
51788
  //#region src/version.ts
52094
- const cliVersion = "4.20.0-beta.10";
52095
- const sdkVersion = "4.20.0-beta.10";
51789
+ const cliVersion = "4.20.0-beta.11";
51790
+ const sdkVersion = "4.20.0-beta.11";
52096
51791
  const ReleaseVersion = Schema.String.check(Schema.isMaxLength(256), Schema.isPattern(/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*)?$/u)).pipe(Schema.brand("CliReleaseVersion"));
52097
51792
  const parts = (version) => {
52098
51793
  const [core = "", ...prerelease] = version.split("+")[0].split("-");
@@ -52850,20 +52545,31 @@ const authInputMessage = (error) => {
52850
52545
  if (PROFILE_FIELDS.has(field)) return PROFILE_INPUT_MESSAGE;
52851
52546
  return INPUT_MESSAGE;
52852
52547
  };
52853
- /**
52854
- * The one allowlist. Only a WRONG_STATE whose SDK details carry an Organization
52855
- * ID the public constructor accepts emits that ID, and it never enters message
52856
- * text or valid states. No other error detail reaches terminal output, and a
52857
- * malformed SDK value is omitted rather than published as an identifier.
52858
- */
52548
+ /** Keep validated identifiers and structured provider causes; omit unknown details. */
52859
52549
  function allowlistedDetails(error) {
52860
- if (error.code !== "WRONG_STATE") return void 0;
52550
+ const safe = {};
52861
52551
  try {
52862
52552
  const organizationId = String(toOrgId(error.details?.organizationId));
52863
- return organizationId.trim().length === 0 ? void 0 : { organizationId };
52864
- } catch {
52865
- return;
52866
- }
52553
+ if (organizationId.trim().length > 0) safe.organizationId = organizationId;
52554
+ } catch {}
52555
+ if (typeof error.details?.setupReason === "string" && ORGANIZATION_SETUP_REASONS.some((reason) => reason === error.details?.setupReason)) safe.setupReason = error.details.setupReason;
52556
+ if (typeof error.details?.retryable === "boolean") safe.retryable = error.details.retryable;
52557
+ if (error.chain !== void 0) {
52558
+ safe.retryable = error.chain.retryable;
52559
+ safe.upstream = error.chain.upstream;
52560
+ safe.method = error.chain.method;
52561
+ if (error.chain.httpStatus !== void 0) safe.httpStatus = error.chain.httpStatus;
52562
+ if (error.chain.rpcCode !== void 0) safe.rpcCode = error.chain.rpcCode;
52563
+ }
52564
+ if (typeof error.details?.httpStatus === "number" && Number.isSafeInteger(error.details.httpStatus)) safe.httpStatus = error.details.httpStatus;
52565
+ if (typeof error.details?.rpcCode === "number" && Number.isSafeInteger(error.details.rpcCode)) safe.rpcCode = error.details.rpcCode;
52566
+ if (typeof error.details?.provider === "string" && [
52567
+ "openfort",
52568
+ "browserBridge",
52569
+ "better-auth",
52570
+ "signer"
52571
+ ].includes(error.details.provider)) safe.provider = error.details.provider;
52572
+ return Object.keys(safe).length === 0 ? void 0 : safe;
52867
52573
  }
52868
52574
  function walletDetails(error) {
52869
52575
  if (!isWalletStage(error.details?.walletStage)) return void 0;
@@ -52934,14 +52640,17 @@ function classifyFailure(cause, command) {
52934
52640
  const wrongState = error.code === "WRONG_STATE";
52935
52641
  const input = error.code === "INVALID_INPUT" || error.code === "OTP_EXPIRED";
52936
52642
  const wallet = walletDetails(error);
52937
- const details = wallet ?? allowlistedDetails(error);
52643
+ const details = {
52644
+ ...allowlistedDetails(error),
52645
+ ...wallet
52646
+ };
52938
52647
  return {
52939
52648
  code: error.code,
52940
52649
  message: applicationMessage(error, command, wallet),
52941
52650
  exitCode: auth ? 3 : denied ? 4 : input || wrongState ? 2 : 5,
52942
52651
  outcome: auth || denied || input || wrongState ? "refused" : "failed",
52943
52652
  ...error.mode === void 0 ? {} : { mode: error.mode },
52944
- ...details === void 0 ? {} : { details }
52653
+ ...Object.keys(details).length === 0 ? {} : { details }
52945
52654
  };
52946
52655
  }
52947
52656
  return {
@@ -53037,7 +52746,8 @@ const codes = [
53037
52746
  "CLI_USAGE",
53038
52747
  "CLI_CONFIG",
53039
52748
  "CLI_STORAGE",
53040
- "CLI_DEFECT"
52749
+ "CLI_DEFECT",
52750
+ "CLI_DEADLINE"
53041
52751
  ];
53042
52752
  const identifier = Schema.String.check(Schema.isPattern(/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u));
53043
52753
  const version = Schema.String.check(Schema.isPattern(/^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/u));
@@ -53049,6 +52759,37 @@ const completionSchema = Schema.Struct({
53049
52759
  wait_duration_ms: Schema.Number,
53050
52760
  retry_count: Schema.Literal(0)
53051
52761
  });
52762
+ const SETUP_COMMANDS = /* @__PURE__ */ new Set([
52763
+ CAPXUL_OPERATIONS.org.create,
52764
+ CAPXUL_OPERATIONS.org.retry,
52765
+ "org.status",
52766
+ "org.wait"
52767
+ ]);
52768
+ /** Project one backend-checked Organization result, never a local pointer. */
52769
+ function organizationCompletion(command, result, failure) {
52770
+ if (!SETUP_COMMANDS.has(command)) return { fields: {} };
52771
+ const schemas = CliCommandCompletedTelemetryEventSchema.fields.props.fields;
52772
+ const data = Exit.isSuccess(result) ? own(result.value, "data") : void 0;
52773
+ const lifecycle = own(data, "lifecycle");
52774
+ const rawOrgId = Exit.isSuccess(result) ? own(data, "organizationId") : failure?.details?.organizationId;
52775
+ const decodedId = Schema.decodeUnknownOption(schemas.organization_id)(rawOrgId);
52776
+ if (Option.isNone(decodedId) || typeof decodedId.value !== "string") return { fields: {} };
52777
+ const organizationId = decodedId.value;
52778
+ const verified = Exit.isSuccess(result) && own(lifecycle, "orgId") === organizationId;
52779
+ if (Exit.isSuccess(result) && !verified) return { fields: {} };
52780
+ const rawStatus = verified ? own(lifecycle, "status") : failure?.details?.lastObservedSetup?.status;
52781
+ const rawReason = verified ? own(own(lifecycle, "issue"), "reason") : failure?.details?.setupReason;
52782
+ const decodedStatus = Schema.decodeUnknownOption(schemas.setup_status)(rawStatus);
52783
+ const decodedReason = Schema.decodeUnknownOption(schemas.setup_reason)(rawReason);
52784
+ return {
52785
+ fields: {
52786
+ organization_id: organizationId,
52787
+ ...Option.isSome(decodedStatus) && decodedStatus.value !== void 0 ? { setup_status: decodedStatus.value } : {},
52788
+ ...Option.isSome(decodedReason) && decodedReason.value !== void 0 ? { setup_reason: decodedReason.value } : {}
52789
+ },
52790
+ ...verified ? { group: { organization: organizationId } } : {}
52791
+ };
52792
+ }
53052
52793
  const CAPTURE_CAPACITY = 32;
53053
52794
  const CAPTURE_BYTES = 8192;
53054
52795
  const textEncoder = new TextEncoder();
@@ -53226,12 +52967,15 @@ function observeInvocation(input, work) {
53226
52967
  const client = { capture: (event, properties) => {
53227
52968
  if (!enabled()) return;
53228
52969
  if (event === "$exception" || event === "capxul_sdk_expected_outcome") {
53229
- const code = safeCode(own(properties, "error_kind"));
52970
+ const code = safeCode(own(properties, "error_kind")) ?? (event === "$exception" ? "UNKNOWN" : void 0);
53230
52971
  const operation = own(properties, "operation");
53231
52972
  if (code !== void 0 && sdkDiagnostics.length < CAPTURE_CAPACITY) sdkDiagnostics.push({
53232
- ...projectSdkProperties(properties),
53233
- error_code: code,
53234
- ...isCapxulOperation(operation) ? { operation } : {}
52973
+ log: {
52974
+ ...projectSdkProperties(properties),
52975
+ error_code: code,
52976
+ ...isCapxulOperation(operation) ? { operation } : {}
52977
+ },
52978
+ ...event === "$exception" ? { exception: projectException(properties, input.command, "SDK_DEFECT") } : {}
53235
52979
  });
53236
52980
  else dropped += 1;
53237
52981
  return;
@@ -53339,6 +53083,7 @@ function observeInvocation(input, work) {
53339
53083
  const errorCode = failure?.code;
53340
53084
  const outcome = failure?.outcome ?? "succeeded";
53341
53085
  const duration = Math.max(0, clock.currentTimeMillisUnsafe() - started);
53086
+ const organization = organizationCompletion(input.command, result, failure);
53342
53087
  const completion = Schema.decodeUnknownSync(completionSchema)({
53343
53088
  ...engineeringEnvelope,
53344
53089
  ...input.anonymousIdentity === void 0 ? {} : { posthogDistinctId: input.anonymousIdentity.id },
@@ -53352,13 +53097,14 @@ function observeInvocation(input, work) {
53352
53097
  wait_duration_ms: waitDuration,
53353
53098
  retry_count: 0,
53354
53099
  output_mode: input.outputMode ?? "human",
53355
- ...errorCode === void 0 ? {} : { error_code: errorCode }
53100
+ ...errorCode === void 0 ? {} : { error_code: errorCode },
53101
+ ...organization.fields
53356
53102
  });
53357
53103
  yield* Effect.annotateCurrentSpan(completion);
53358
53104
  yield* logEngineeringInfo("cli.command.completed", completion);
53359
53105
  for (const diagnostic of sdkDiagnostics) yield* logEngineeringInfo("cli.sdk.operation.failed", {
53360
53106
  ...engineeringEnvelope,
53361
- ...diagnostic
53107
+ ...diagnostic.log
53362
53108
  });
53363
53109
  const metricAttributes = {
53364
53110
  command: input.command,
@@ -53390,7 +53136,9 @@ function observeInvocation(input, work) {
53390
53136
  occurred_at: clock.currentTimeMillisUnsafe(),
53391
53137
  outcome,
53392
53138
  duration_ms: duration,
53393
- ...errorCode === void 0 ? {} : { error_code: errorCode }
53139
+ ...errorCode === void 0 ? {} : { error_code: errorCode },
53140
+ ...organization.fields,
53141
+ ...organization.group === void 0 ? {} : { $groups: organization.group }
53394
53142
  }
53395
53143
  });
53396
53144
  capture("cli_command_completed", { ...terminal.props });
@@ -53419,6 +53167,9 @@ function observeInvocation(input, work) {
53419
53167
  group: () => Effect.void,
53420
53168
  reset: () => Effect.void
53421
53169
  }, error, { capxul_error_code: "UNKNOWN" });
53170
+ } else if (failure?.code === "UNKNOWN") {
53171
+ const sdkDefect = sdkDiagnostics.find((item) => item.exception !== void 0)?.exception;
53172
+ if (sdkDefect !== void 0) capture("$exception", sdkDefect);
53422
53173
  }
53423
53174
  }
53424
53175
  }).pipe(Effect.catchCause(() => Effect.void));
@@ -53473,7 +53224,7 @@ function projectSdkProperties(properties) {
53473
53224
  if (failureMode !== void 0) output.failure_mode = failureMode;
53474
53225
  return output;
53475
53226
  }
53476
- function projectException(properties, command) {
53227
+ function projectException(properties, command, kind = "CLI_DEFECT") {
53477
53228
  const sanitized = sanitizePostHogBrowserEvent({
53478
53229
  event: "$exception",
53479
53230
  properties: { ...properties }
@@ -53494,17 +53245,17 @@ function projectException(properties, command) {
53494
53245
  };
53495
53246
  });
53496
53247
  return {
53497
- $exception_type: "CLI_DEFECT",
53498
- $exception_message: "CLI command failed",
53248
+ $exception_type: kind,
53249
+ $exception_message: kind === "CLI_DEFECT" ? "CLI command failed" : "SDK operation failed",
53499
53250
  $exception_level: "error",
53500
- $exception_fingerprint: `cli.${command}.CLI_DEFECT:${frames[0]?.filename ?? "boundary"}:${frames[0]?.function ?? "unknown"}`,
53501
- $issue_name: `CLI ${command} defect`,
53251
+ $exception_fingerprint: `cli.${command}.${kind}:${frames[0]?.filename ?? "boundary"}:${frames[0]?.function ?? "unknown"}`,
53252
+ $issue_name: `${kind === "CLI_DEFECT" ? "CLI" : "SDK"} ${command} defect`,
53502
53253
  $exception_list: [{
53503
- type: "CLI_DEFECT",
53504
- value: "CLI command failed",
53254
+ type: kind,
53255
+ value: kind === "CLI_DEFECT" ? "CLI command failed" : "SDK operation failed",
53505
53256
  mechanism: {
53506
53257
  handled: true,
53507
- type: "capxul_cli_boundary"
53258
+ type: kind === "CLI_DEFECT" ? "capxul_cli_boundary" : "capxul_cli_sdk_boundary"
53508
53259
  },
53509
53260
  stacktrace: {
53510
53261
  type: "raw",
@@ -53664,7 +53415,8 @@ const runCommand = (options, work) => Effect.gen(function* () {
53664
53415
  outcome: "succeeded",
53665
53416
  data: result.data
53666
53417
  }, result.lines);
53667
- }), options.network);
53418
+ return result;
53419
+ }), options.network).pipe(Effect.asVoid);
53668
53420
  });
53669
53421
  //#endregion
53670
53422
  //#region src/platform/capxul.ts
@@ -55259,27 +55011,25 @@ const saveOrganizationSelection = (config, authUserId, organizationId, stillAuth
55259
55011
  });
55260
55012
  //#endregion
55261
55013
  //#region src/org.ts
55262
- /**
55263
- * The exact Organization a read uses when the caller named no ID: the saved read
55264
- * default first, then the recorded recovery handle for this person's
55265
- * Organization journey. `recoverable` marks the handle source, whose Organization
55266
- * may still run its setup lane and be absent from the own-access list.
55267
- */
55014
+ /** Resolve a scoped local pointer without treating it as backend authority. */
55268
55015
  const readResolvedOrganization = (config, authUserId, organizationId) => Effect.gen(function* () {
55269
- if (organizationId !== null) return {
55270
- organizationId,
55271
- recoverable: false
55272
- };
55273
- const selected = yield* readOrganizationSelection(config, authUserId);
55274
- if (selected !== null) return {
55275
- organizationId: selected,
55276
- recoverable: false
55277
- };
55278
- const recovery = yield* readOrganizationRecovery(config, authUserId);
55279
- return {
55280
- organizationId: recovery?.organizationId ?? null,
55281
- recoverable: recovery?.organizationId !== null && recovery?.organizationId !== void 0
55282
- };
55016
+ const selected = organizationId ?? (yield* readOrganizationSelection(config, authUserId));
55017
+ if (selected !== null) return selected;
55018
+ return (yield* readOrganizationRecovery(config, authUserId))?.organizationId ?? null;
55019
+ });
55020
+ const listUnfinishedSetups = (client) => Effect.gen(function* () {
55021
+ const setups = [];
55022
+ let cursor;
55023
+ do {
55024
+ const page = yield* Effect.promise((signal) => client.onboarding.listOrganizationSetups({
55025
+ ...cursor === void 0 ? {} : { cursor },
55026
+ limit: 50
55027
+ }, { signal })).pipe(Effect.flatMap(resultValue));
55028
+ setups.push(...page.page);
55029
+ if (page.isDone) return setups;
55030
+ if (page.cursor === null || page.cursor === cursor) return yield* Effect.fail(Errors.invalidInput("cursor", "Organization setup page did not advance"));
55031
+ cursor = page.cursor;
55032
+ } while (true);
55283
55033
  });
55284
55034
  /**
55285
55035
  * A ready Organization this command reports must satisfy current access.
@@ -55290,6 +55040,51 @@ const readResolvedOrganization = (config, authUserId, organizationId) => Effect.
55290
55040
  * Organization the person cannot reach refuses instead of reporting its state.
55291
55041
  */
55292
55042
  const requireCurrentAccess = (client, organizationId, lifecycle) => lifecycle.status !== "ready" ? Effect.void : Effect.promise((signal) => client.orgs({ signal })).pipe(Effect.flatMap(resultValue), Effect.flatMap((organizations) => organizations.some((organization) => organization.id === organizationId) ? Effect.void : Effect.fail(Errors.invalidInput("org", "The Organization is not accessible."))));
55043
+ const setupIsTerminal = (setup) => setup.status === "ready" || setup.status === "failed" || setup.status === "awaitingAuthorization" || setup.status === "needsAttention" && setup.nextCheckAt === null;
55044
+ /** One exact subscription owns the wait; the backend owns every follow-up check. */
55045
+ const observeOrganizationSetup = (scoped, organizationId, initial, onValue) => {
55046
+ if (initial !== null) onValue?.(initial);
55047
+ return initial !== null && setupIsTerminal(initial) ? Effect.succeed(initial) : Effect.promise((signal) => new Promise((resolve) => {
55048
+ let closed = false;
55049
+ let unsubscribe = null;
55050
+ const finish = (result) => {
55051
+ if (closed) return;
55052
+ closed = true;
55053
+ signal.removeEventListener("abort", onAbort);
55054
+ unsubscribe?.();
55055
+ resolve(result);
55056
+ };
55057
+ const onAbort = () => finish({
55058
+ ok: false,
55059
+ error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.organization.setup })
55060
+ });
55061
+ signal.addEventListener("abort", onAbort, { once: true });
55062
+ scoped.setup.subscribe((snapshot) => {
55063
+ if (closed || snapshot.status === "loading") return;
55064
+ if (snapshot.status === "error") return finish({
55065
+ ok: false,
55066
+ error: snapshot.error
55067
+ });
55068
+ if (String(snapshot.value.orgId) !== String(organizationId)) return finish({
55069
+ ok: false,
55070
+ error: Errors.invalidInput("orgId", "Organization setup scope does not match")
55071
+ });
55072
+ onValue?.(snapshot.value);
55073
+ if (setupIsTerminal(snapshot.value)) finish({
55074
+ ok: true,
55075
+ value: snapshot.value
55076
+ });
55077
+ }, { signal }).then((result) => {
55078
+ if (!result.ok) return finish(result);
55079
+ unsubscribe = result.value;
55080
+ if (closed) unsubscribe();
55081
+ }).catch((cause) => finish({
55082
+ ok: false,
55083
+ error: Errors.unknown(cause)
55084
+ }));
55085
+ if (signal.aborted) onAbort();
55086
+ })).pipe(Effect.flatMap(resultValue));
55087
+ };
55293
55088
  const readOrganization = (config, command, input) => Effect.gen(function* () {
55294
55089
  const timeout = yield* Schema.decodeUnknownEffect(Schema.Int.check(Schema.isBetween({
55295
55090
  minimum: 1,
@@ -55307,17 +55102,30 @@ const readOrganization = (config, command, input) => Effect.gen(function* () {
55307
55102
  catch: () => inputRequired("Provide a valid Organization ID.")
55308
55103
  });
55309
55104
  const { client, session, stillAuthenticated } = yield* restoreAuthenticatedClient(config, input.email);
55310
- const organizations = yield* Effect.promise((signal) => client.orgs({ signal })).pipe(Effect.flatMap(resultValue));
55105
+ const local = command === "list" ? null : yield* readResolvedOrganization(config, session.authUserId, organizationId);
55106
+ const setupRead = command === "status" || command === "wait";
55107
+ let unfinished = [];
55108
+ if (setupRead && local === null) unfinished = yield* listUnfinishedSetups(client);
55109
+ if (setupRead && unfinished.length > 1) return yield* Effect.fail(inputRequired("Provide --org to select one unfinished Organization setup."));
55110
+ const resolved = setupRead && local === null && unfinished.length === 1 ? unfinished[0].orgId : local;
55111
+ const exactSetupRead = setupRead && resolved !== null;
55112
+ const organizations = exactSetupRead ? [] : yield* Effect.promise((signal) => client.orgs({ signal })).pipe(Effect.flatMap(resultValue));
55113
+ if (command === "list") unfinished = yield* listUnfinishedSetups(client);
55311
55114
  if (command === "list") return {
55312
- data: { organizations },
55313
- lines: organizations.map((org) => JSON.stringify({
55115
+ data: {
55116
+ organizations,
55117
+ unfinishedSetups: unfinished
55118
+ },
55119
+ lines: [...organizations.map((org) => JSON.stringify({
55314
55120
  id: org.id,
55315
55121
  name: org.name,
55316
55122
  address: org.account.address
55317
- }))
55123
+ })), ...unfinished.map((setup) => JSON.stringify({
55124
+ id: setup.orgId,
55125
+ setup: setup.status
55126
+ }))]
55318
55127
  };
55319
- const resolved = yield* readResolvedOrganization(config, session.authUserId, organizationId);
55320
- organizationId = resolved.organizationId;
55128
+ organizationId = resolved;
55321
55129
  if (organizationId === null) {
55322
55130
  const runtime = yield* CliRuntime;
55323
55131
  if (!runtime.tty || runtime.ci || runtime.mode === "json" || organizations.length === 0) return yield* Effect.fail(inputRequired("Provide --org or select a read default with org use."));
@@ -55332,7 +55140,7 @@ const readOrganization = (config, command, input) => Effect.gen(function* () {
55332
55140
  }))
55333
55141
  });
55334
55142
  }
55335
- if (!organizations.some((org) => org.id === organizationId) && !resolved.recoverable) return yield* Effect.fail(Errors.invalidInput("org", "The Organization is not accessible."));
55143
+ if (!exactSetupRead && !organizations.some((org) => org.id === organizationId)) return yield* Effect.fail(Errors.invalidInput("org", "The Organization is not accessible."));
55336
55144
  if (command === "use") {
55337
55145
  yield* saveOrganizationSelection(config, session.authUserId, organizationId, stillAuthenticated);
55338
55146
  return {
@@ -55382,24 +55190,16 @@ const readOrganization = (config, command, input) => Effect.gen(function* () {
55382
55190
  lines: [JSON.stringify(matches[0])]
55383
55191
  };
55384
55192
  }
55385
- const read = Effect.promise((signal) => scoped.getLifecycle({ signal })).pipe(Effect.flatMap(resultValue));
55193
+ let lastObserved = null;
55386
55194
  const observed = yield* Effect.gen(function* () {
55387
- let lifecycle = yield* read;
55388
- if (resolved.recoverable) yield* requireCurrentAccess(client, organizationId, lifecycle);
55389
- if (command !== "wait") return lifecycle;
55390
- while (lifecycle.status !== "ready" && lifecycle.status !== "failed") {
55391
- yield* Effect.sleep(1e3);
55392
- lifecycle = yield* read;
55393
- }
55394
- if (resolved.recoverable) yield* requireCurrentAccess(client, organizationId, lifecycle);
55195
+ const lifecycle = command === "wait" ? yield* observeOrganizationSetup(scoped, organizationId, null, (value) => {
55196
+ lastObserved = value;
55197
+ }) : yield* Effect.promise((signal) => scoped.setup.get({ signal })).pipe(Effect.flatMap(resultValue));
55198
+ lastObserved = lifecycle;
55199
+ yield* requireCurrentAccess(client, organizationId, lifecycle);
55395
55200
  return lifecycle;
55396
55201
  }).pipe(Effect.timeoutOption(timeout * 1e3));
55397
- if (Option.isNone(observed)) return yield* Effect.fail(new CliFailure({
55398
- code: "NETWORK_ERROR",
55399
- message: "The Organization read exceeded its deadline.",
55400
- exitCode: 5,
55401
- outcome: "failed"
55402
- }));
55202
+ if (Option.isNone(observed)) return yield* Effect.fail(organizationWaitTimeout(String(organizationId), lastObserved));
55403
55203
  const lifecycle = observed.value;
55404
55204
  return {
55405
55205
  data: {
@@ -55418,10 +55218,7 @@ const requiredText = (label, value) => Effect.gen(function* () {
55418
55218
  return trimmed;
55419
55219
  });
55420
55220
  /** An optional flag contributes nothing when it is absent or blank. */
55421
- const optionalText = (value) => {
55422
- const trimmed = value?.trim() ?? "";
55423
- return trimmed.length === 0 ? void 0 : trimmed;
55424
- };
55221
+ const optionalText = (value) => value?.trim() || void 0;
55425
55222
  /**
55426
55223
  * Bounded local validation for `org create`. Every refusal here precedes any
55427
55224
  * authenticated service, browser signer, or mutation.
@@ -55486,6 +55283,7 @@ const makeOrganizationProgress = (mode, run, persist) => {
55486
55283
  const heldSet = /* @__PURE__ */ new Set();
55487
55284
  const written = /* @__PURE__ */ new Set();
55488
55285
  let committed = null;
55286
+ let lastObserved = null;
55489
55287
  let persisted = null;
55490
55288
  let readyAllowed = false;
55491
55289
  let failure = null;
@@ -55519,11 +55317,10 @@ const makeOrganizationProgress = (mode, run, persist) => {
55519
55317
  queued.push(text);
55520
55318
  };
55521
55319
  const render = (state) => {
55522
- const organizationId = state.organizationId;
55523
- if (organizationId === null) return null;
55320
+ const organizationId = state.orgId;
55524
55321
  if (!retain(String(organizationId))) return null;
55525
- const status = state.lifecycle?.status;
55526
- if (status === void 0) return null;
55322
+ lastObserved = state;
55323
+ const status = state.status;
55527
55324
  return {
55528
55325
  text: `${mode === "json" ? JSON.stringify({
55529
55326
  type: "organization.lifecycle",
@@ -55558,6 +55355,7 @@ const makeOrganizationProgress = (mode, run, persist) => {
55558
55355
  },
55559
55356
  /** The committed ID this command observed, or null when it observed none. */
55560
55357
  committed: () => committed,
55358
+ lastObserved: () => lastObserved,
55561
55359
  failure: () => failure,
55562
55360
  flush: async () => {
55563
55361
  while (queued.length > 0) {
@@ -55603,7 +55401,9 @@ const confirmWrite = (preview) => Effect.gen(function* () {
55603
55401
  */
55604
55402
  const organizationPreview = (client, organizationId, recovery, requestedHandle) => organizationId === null ? Effect.gen(function* () {
55605
55403
  const organizations = yield* Effect.promise((signal) => client.orgs({ signal })).pipe(Effect.flatMap(resultValue));
55404
+ const unfinished = yield* listUnfinishedSetups(client);
55606
55405
  const lines = organizations.length === 0 ? ["Existing Organizations: none"] : [`Existing Organizations: ${organizations.length}`, ...organizations.map((organization) => ` ${JSON.stringify(String(organization.id))} ${JSON.stringify(organization.name)}`)];
55406
+ lines.push(...unfinished.map((setup) => `Unfinished setup: ${JSON.stringify(String(setup.orgId))} (${setup.status})`));
55607
55407
  if (recovery === null) return {
55608
55408
  lines,
55609
55409
  recovery,
@@ -55620,7 +55420,7 @@ const organizationPreview = (client, organizationId, recovery, requestedHandle)
55620
55420
  recovery,
55621
55421
  recoveryLifecycle: null
55622
55422
  };
55623
- const lifecycle = yield* Effect.promise((signal) => client.org(exact).getLifecycle({ signal })).pipe(Effect.flatMap(resultValue));
55423
+ const lifecycle = yield* Effect.promise((signal) => client.org(exact).setup.get({ signal })).pipe(Effect.flatMap(resultValue));
55624
55424
  yield* requireCurrentAccess(client, exact, lifecycle);
55625
55425
  return {
55626
55426
  lines: [
@@ -55633,7 +55433,7 @@ const organizationPreview = (client, organizationId, recovery, requestedHandle)
55633
55433
  };
55634
55434
  }) : Effect.gen(function* () {
55635
55435
  return {
55636
- lines: [`Current lifecycle: ${(yield* Effect.promise((signal) => client.org(organizationId).getLifecycle({ signal })).pipe(Effect.flatMap(resultValue))).status}`],
55436
+ lines: [`Current lifecycle: ${(yield* Effect.promise((signal) => client.org(organizationId).setup.get({ signal })).pipe(Effect.flatMap(resultValue))).status}`],
55637
55437
  recovery,
55638
55438
  recoveryLifecycle: null
55639
55439
  };
@@ -55648,28 +55448,15 @@ const createOrganizationQuestion = (handle, preview) => {
55648
55448
  return preview.recoveryLifecycle?.status === "ready" ? "Return this ready Organization?" : "Resume this Organization's setup?";
55649
55449
  };
55650
55450
  /**
55651
- * Settle one exact Organization lifecycle read: poll every second with no
55652
- * overlapping read until the lane is ready or failed. The command's own deadline
55653
- * bounds this loop together with the write that preceded it.
55654
- */
55655
- const settleOrganizationLifecycle = (read) => Effect.gen(function* () {
55656
- let lifecycle = yield* Effect.promise(read).pipe(Effect.flatMap(resultValue));
55657
- while (lifecycle.status !== "ready" && lifecycle.status !== "failed") {
55658
- yield* Effect.sleep(1e3);
55659
- lifecycle = yield* Effect.promise(read).pipe(Effect.flatMap(resultValue));
55660
- }
55661
- return lifecycle;
55662
- });
55663
- /**
55664
55451
  * Resume the exact durable Organization lane through the SDK recovery owner, then
55665
55452
  * settle that exact lifecycle. It never creates an Organization and never
55666
55453
  * resubmits a recorded bootstrap submission.
55667
55454
  */
55668
- const resumeOrganizationSetup = (operation, scoped, deadline) => Effect.gen(function* () {
55669
- yield* Effect.promise(() => scoped.retrySetup({ signal: deadline.signal })).pipe(Effect.flatMap(resultValue));
55670
- const lifecycle = yield* settleOrganizationLifecycle(() => scoped.getLifecycle({ signal: deadline.signal }));
55671
- yield* requireReadyLifecycle(operation, lifecycle);
55672
- return lifecycle;
55455
+ const resumeOrganizationSetup = (scoped, deadline, observe) => Effect.gen(function* () {
55456
+ const current = yield* Effect.promise(() => scoped.setup.get({ signal: deadline.signal })).pipe(Effect.flatMap(resultValue));
55457
+ observe?.(current);
55458
+ const updated = current.status === "awaitingAuthorization" ? yield* Effect.promise(() => scoped.setup.authorize({ signal: deadline.signal })).pipe(Effect.flatMap(resultValue)) : yield* Effect.promise(() => scoped.setup.resume({ signal: deadline.signal })).pipe(Effect.flatMap(resultValue));
55459
+ return yield* observeOrganizationSetup(scoped, updated.orgId, updated, observe);
55673
55460
  });
55674
55461
  /**
55675
55462
  * A prepared handle owns the next durable Organization for that handle, so a
@@ -55691,28 +55478,19 @@ const preparedJourneyRefusal = (handle) => new CliFailure({
55691
55478
  * Organization reaches ready.
55692
55479
  */
55693
55480
  const readCreateRoute = (client, recovery, handle, signal) => Effect.gen(function* () {
55694
- if (recovery === null) return {
55695
- kind: "create",
55696
- continuesRecorded: false
55697
- };
55481
+ if (recovery === null) return { kind: "create" };
55698
55482
  if (recovery.organizationId === null) {
55699
- if (recovery.handle === handle) return {
55700
- kind: "create",
55701
- continuesRecorded: true
55702
- };
55483
+ if (recovery.handle === handle) return { kind: "create" };
55703
55484
  return yield* Effect.fail(preparedJourneyRefusal(recovery.handle));
55704
55485
  }
55705
- const lifecycle = yield* Effect.promise(() => client.org(recovery.organizationId).getLifecycle({ signal })).pipe(Effect.flatMap(resultValue));
55486
+ const lifecycle = yield* Effect.promise(() => client.org(recovery.organizationId).setup.get({ signal })).pipe(Effect.flatMap(resultValue));
55706
55487
  if (recovery.handle === handle) return {
55707
55488
  kind: "recover",
55708
55489
  organizationId: recovery.organizationId,
55709
55490
  handle: recovery.handle,
55710
55491
  lifecycle
55711
55492
  };
55712
- if (lifecycle.status === "ready") return {
55713
- kind: "create",
55714
- continuesRecorded: false
55715
- };
55493
+ if (lifecycle.status === "ready") return { kind: "create" };
55716
55494
  return yield* Effect.fail(Errors.wrongState({
55717
55495
  method: CAPXUL_OPERATIONS.onboarding.completeOrganization,
55718
55496
  currentState: lifecycle.status,
@@ -55740,12 +55518,26 @@ const organizationWriteDefect = () => new CliFailure({
55740
55518
  * command stops and the signer forwards nothing further, while the durable
55741
55519
  * backend lane keeps running and stays resumable by `org retry`.
55742
55520
  */
55743
- const organizationWaitTimeout = () => new CliFailure({
55744
- code: "NETWORK_ERROR",
55745
- message: "The Organization did not settle within the command deadline.",
55746
- exitCode: 5,
55747
- outcome: "failed"
55748
- });
55521
+ const organizationWaitTimeout = (organizationId, lastObserved) => {
55522
+ const issue = lastObserved?.issue ?? lastObserved?.lastSendIssue;
55523
+ return new CliFailure({
55524
+ code: "CLI_DEADLINE",
55525
+ message: lastObserved?.nextCheckAt != null && (lastObserved.status === "processing" || lastObserved.status === "rechecking" || lastObserved.status === "needsAttention") ? "Stopped waiting. Organization setup continues in the background." : "Stopped waiting. Read the Organization setup status.",
55526
+ exitCode: 5,
55527
+ outcome: "failed",
55528
+ ...issue?.error?.mode === void 0 ? {} : { mode: issue.error.mode },
55529
+ details: {
55530
+ ...issue?.error === void 0 ? {} : allowlistedDetails(issue.error),
55531
+ ...organizationId === null ? {} : { organizationId },
55532
+ ...lastObserved === null ? {} : { lastObservedSetup: {
55533
+ status: lastObserved.status,
55534
+ nextCheckAt: lastObserved.nextCheckAt,
55535
+ recovery: lastObserved.recovery
55536
+ } },
55537
+ ...issue === null || issue === void 0 ? {} : { setupReason: issue.reason }
55538
+ }
55539
+ });
55540
+ };
55749
55541
  /**
55750
55542
  * The command-scoped browser signer for one Organization write.
55751
55543
  *
@@ -55767,6 +55559,23 @@ const organizationWaitTimeout = () => new CliFailure({
55767
55559
  const organizationWriteSigner = (config, opened, run, beforeSignature) => Effect.gen(function* () {
55768
55560
  const runtime = yield* CliRuntime;
55769
55561
  const invocation = yield* Ref.get(runtime.current);
55562
+ const timed = async (stage, work) => {
55563
+ const started = Date.now();
55564
+ let outcome = "succeeded";
55565
+ try {
55566
+ return await work();
55567
+ } catch (cause) {
55568
+ outcome = "failed";
55569
+ throw cause;
55570
+ } finally {
55571
+ await run(logEngineeringInfo("cli.signer.wait", {
55572
+ signer_stage: stage,
55573
+ duration_ms: Math.max(0, Date.now() - started),
55574
+ outcome,
55575
+ ...invocation === null ? {} : { invocation_id: invocation.invocationId }
55576
+ })).catch(() => void 0);
55577
+ }
55578
+ };
55770
55579
  const listeners = /* @__PURE__ */ new Set();
55771
55580
  let bridge = null;
55772
55581
  let stopStatus = null;
@@ -55795,7 +55604,7 @@ const organizationWriteSigner = (config, opened, run, beforeSignature) => Effect
55795
55604
  return (bootstrap) => {
55796
55605
  return {
55797
55606
  source: open(bootstrap).source,
55798
- getAddress: () => live(bootstrap).getAddress(),
55607
+ getAddress: () => timed("address", () => live(bootstrap).getAddress()),
55799
55608
  statusStore: {
55800
55609
  status: () => bridge?.signer.statusStore?.status() ?? "unknown",
55801
55610
  subscribe: (listener) => {
@@ -55805,7 +55614,7 @@ const organizationWriteSigner = (config, opened, run, beforeSignature) => Effect
55805
55614
  };
55806
55615
  }
55807
55616
  },
55808
- ensureWalletReady: () => live(bootstrap).ensureWalletReady?.() ?? Promise.resolve(),
55617
+ ensureWalletReady: () => timed("readiness", () => live(bootstrap).ensureWalletReady?.() ?? Promise.resolve()),
55809
55618
  resetSession: () => {
55810
55619
  const stopped = bridge;
55811
55620
  stopStatus?.();
@@ -55816,29 +55625,40 @@ const organizationWriteSigner = (config, opened, run, beforeSignature) => Effect
55816
55625
  },
55817
55626
  async signUserOpHash(hash) {
55818
55627
  await beforeSignature();
55819
- return live(bootstrap).signUserOpHash(hash);
55628
+ return timed("sign", () => live(bootstrap).signUserOpHash(hash));
55820
55629
  }
55821
55630
  };
55822
55631
  };
55823
55632
  });
55824
55633
  /** Cancellation is reported before any other work the interrupted write would do. */
55825
55634
  const cancelledWrite = (operation, signal) => signal?.aborted === true ? Errors.cancelled({ operation }) : null;
55826
- /** The public onboarding result the CLI scopes every later read to. */
55827
- const onboardingOrganizationId = (value) => Effect.try({
55828
- try: () => toOrgId(value),
55829
- catch: () => new CliFailure({
55830
- code: "PROVIDER_ERROR",
55831
- message: "The onboarding result did not carry an Organization ID.",
55832
- exitCode: 5,
55833
- outcome: "failed"
55834
- })
55835
- });
55836
55635
  /** A write is successful only against a ready Organization. */
55837
- const requireReadyLifecycle = (operation, lifecycle) => lifecycle.status === "ready" ? Effect.void : Effect.fail(Errors.wrongState({
55838
- method: operation,
55839
- currentState: lifecycle.status,
55840
- validStates: ["ready"]
55841
- }));
55636
+ const requireReadyLifecycle = (operation, lifecycle) => {
55637
+ if (lifecycle.status === "ready") return Effect.void;
55638
+ const issue = lifecycle.issue;
55639
+ if (issue?.error !== void 0) {
55640
+ const error = issue.error;
55641
+ return Effect.fail(new CapxulError(error.code, error.message, {
55642
+ details: {
55643
+ ...error.details,
55644
+ organizationId: String(lifecycle.orgId),
55645
+ setupReason: issue.reason
55646
+ },
55647
+ ...error.mode === void 0 ? {} : { mode: error.mode },
55648
+ ...error.chain === void 0 ? {} : { chain: error.chain }
55649
+ }));
55650
+ }
55651
+ const fallback = Errors.wrongState({
55652
+ method: operation,
55653
+ currentState: lifecycle.status,
55654
+ validStates: ["ready"],
55655
+ organizationId: String(lifecycle.orgId)
55656
+ });
55657
+ return Effect.fail(new CapxulError(fallback.code, fallback.message, { details: {
55658
+ ...fallback.details,
55659
+ ...issue === null ? {} : { setupReason: issue.reason }
55660
+ } }));
55661
+ };
55842
55662
  /**
55843
55663
  * Create one Organization through the public onboarding lane: confirm the exact
55844
55664
  * draft, subscribe to the committed Organization projection, complete with an
@@ -55894,12 +55714,9 @@ const createOrganization = (config, input) => Effect.gen(function* () {
55894
55714
  openfortSignerFactory
55895
55715
  });
55896
55716
  const recovery = yield* openOrganizationRecovery(config, session.authUserId, stillAuthenticated);
55897
- const persistRecovery = (organizationId) => Effect.gen(function* () {
55898
- const committed = yield* onboardingOrganizationId(organizationId);
55899
- yield* recovery.save({
55900
- handle: draft.handle,
55901
- organizationId: committed
55902
- });
55717
+ const persistRecovery = (organizationId) => recovery.save({
55718
+ handle: draft.handle,
55719
+ organizationId: toOrgId(organizationId)
55903
55720
  });
55904
55721
  const progress = makeOrganizationProgress(runtime.mode, run, (organizationId) => run(persistRecovery(organizationId)));
55905
55722
  yield* Ref.set(progressRef, progress);
@@ -55916,7 +55733,6 @@ const createOrganization = (config, input) => Effect.gen(function* () {
55916
55733
  if (route.kind === "recover") {
55917
55734
  if (route.lifecycle.status === "ready") {
55918
55735
  yield* requireCurrentAccess(client, route.organizationId, route.lifecycle);
55919
- progress.allowReady();
55920
55736
  return {
55921
55737
  organizationId: route.organizationId,
55922
55738
  lifecycle: route.lifecycle
@@ -55924,9 +55740,12 @@ const createOrganization = (config, input) => Effect.gen(function* () {
55924
55740
  }
55925
55741
  progress.notice(recoveryNotice(runtime.mode, route));
55926
55742
  yield* flushProgress;
55927
- const lifecycle = yield* resumeOrganizationSetup(operation, client.org(route.organizationId), deadline);
55743
+ const lifecycle = yield* resumeOrganizationSetup(client.org(route.organizationId), deadline, progress.observe);
55744
+ yield* flushProgress;
55745
+ yield* requireReadyLifecycle(operation, lifecycle);
55928
55746
  yield* requireCurrentAccess(client, route.organizationId, lifecycle);
55929
55747
  progress.allowReady();
55748
+ yield* flushProgress;
55930
55749
  return {
55931
55750
  organizationId: route.organizationId,
55932
55751
  lifecycle
@@ -55936,24 +55755,25 @@ const createOrganization = (config, input) => Effect.gen(function* () {
55936
55755
  handle: draft.handle,
55937
55756
  organizationId: null
55938
55757
  });
55939
- const unsubscribe = client.onboarding.subscribeOrganization(progress.observe);
55940
- const completed = yield* Effect.promise(() => client.onboarding.completeOrganization(draft, {
55758
+ const begun = yield* Effect.promise(() => client.onboarding.beginOrganization(draft, {
55941
55759
  intent: "create",
55942
55760
  signal: deadline.signal
55943
- })).pipe(Effect.ensuring(Effect.sync(unsubscribe)));
55944
- if (!completed.ok) {
55761
+ }));
55762
+ if (!begun.ok) {
55945
55763
  yield* flushProgress;
55946
- if (refusedOrganizationHandle(completed.error) && progress.committed() === null) yield* recovery.release();
55947
- return yield* Effect.fail(completed.error);
55764
+ if (refusedOrganizationHandle(begun.error) && progress.committed() === null) yield* recovery.release();
55765
+ return yield* Effect.fail(begun.error);
55948
55766
  }
55949
- const onboarding = completed.value;
55950
- const organizationId = yield* onboardingOrganizationId(onboarding.organizationId);
55767
+ const organizationId = begun.value.orgId;
55951
55768
  progress.commit(String(organizationId));
55769
+ progress.observe(begun.value.setup);
55952
55770
  yield* flushProgress;
55953
55771
  const scoped = client.org(organizationId);
55954
- const lifecycle = yield* settleOrganizationLifecycle(() => scoped.getLifecycle({ signal: deadline.signal }));
55772
+ const started = begun.value.setup.status === "awaitingAuthorization" ? yield* Effect.promise(() => scoped.setup.authorize({ signal: deadline.signal })).pipe(Effect.flatMap(resultValue)) : begun.value.setup;
55773
+ const lifecycle = yield* observeOrganizationSetup(scoped, organizationId, started, progress.observe);
55774
+ yield* flushProgress;
55955
55775
  yield* requireReadyLifecycle(operation, lifecycle);
55956
- if (route.continuesRecorded) yield* requireCurrentAccess(client, organizationId, lifecycle);
55776
+ yield* requireCurrentAccess(client, organizationId, lifecycle);
55957
55777
  progress.allowReady();
55958
55778
  yield* flushProgress;
55959
55779
  return {
@@ -55967,7 +55787,7 @@ const createOrganization = (config, input) => Effect.gen(function* () {
55967
55787
  catch: (cause) => cause
55968
55788
  }).pipe(Effect.catch(() => Effect.void));
55969
55789
  }))).pipe(Effect.timeoutOption(timeout * 1e3));
55970
- if (Option.isNone(settled)) return yield* Effect.fail(organizationWaitTimeout());
55790
+ if (Option.isNone(settled)) return yield* Effect.fail(organizationWaitTimeout(progress.committed(), progress.lastObserved()));
55971
55791
  const { organizationId, lifecycle } = settled.value;
55972
55792
  return {
55973
55793
  data: {
@@ -56018,8 +55838,13 @@ const retryOrganization = (config, input) => Effect.gen(function* () {
56018
55838
  openfortSignerFactory
56019
55839
  });
56020
55840
  const scoped = client.org(organizationId);
56021
- const settled = yield* resumeOrganizationSetup(operation, scoped, deadline).pipe(Effect.onInterrupt(() => Effect.sync(() => deadline.abort()))).pipe(Effect.timeoutOption(timeout * 1e3));
56022
- if (Option.isNone(settled)) return yield* Effect.fail(organizationWaitTimeout());
55841
+ let lastObserved = null;
55842
+ const settled = yield* resumeOrganizationSetup(scoped, deadline, (setup) => {
55843
+ lastObserved = setup;
55844
+ }).pipe(Effect.onInterrupt(() => Effect.sync(() => deadline.abort()))).pipe(Effect.timeoutOption(timeout * 1e3));
55845
+ if (Option.isNone(settled)) return yield* Effect.fail(organizationWaitTimeout(String(organizationId), lastObserved));
55846
+ yield* requireReadyLifecycle(operation, settled.value);
55847
+ yield* requireCurrentAccess(client, organizationId, settled.value);
56023
55848
  return {
56024
55849
  data: {
56025
55850
  organizationId,