@dharma-ai-labs/agent-fabric 0.2.198 → 0.2.200

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.
Files changed (36) hide show
  1. package/AGENT_FABRIC_ONBOARDING.md +2 -0
  2. package/dist/bootstrapRelayOrdering.test.js +28 -2
  3. package/dist/bootstrapRelayOrdering.test.js.map +1 -1
  4. package/dist/bootstrapStartupPreflight.test.js +10 -0
  5. package/dist/bootstrapStartupPreflight.test.js.map +1 -1
  6. package/dist/bootstrapTargetPreflight.test.d.ts +2 -0
  7. package/dist/bootstrapTargetPreflight.test.d.ts.map +1 -0
  8. package/dist/bootstrapTargetPreflight.test.js +70 -0
  9. package/dist/bootstrapTargetPreflight.test.js.map +1 -0
  10. package/dist/codexBootstrapCompletion.test.js +16 -1
  11. package/dist/codexBootstrapCompletion.test.js.map +1 -1
  12. package/dist/codexSetupPortalIngress.test.js +61 -1
  13. package/dist/codexSetupPortalIngress.test.js.map +1 -1
  14. package/dist/codexSetupSessionHandoff.test.js +4 -2
  15. package/dist/codexSetupSessionHandoff.test.js.map +1 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +32 -14
  18. package/dist/index.js.map +1 -1
  19. package/dist/relayAutostart.d.ts +4 -2
  20. package/dist/relayAutostart.d.ts.map +1 -1
  21. package/dist/relayAutostart.js +20 -3
  22. package/dist/relayAutostart.js.map +1 -1
  23. package/dist/repositoryOnboardingCaller.test.js +22 -5
  24. package/dist/repositoryOnboardingCaller.test.js.map +1 -1
  25. package/dist/schemas/wsl-relay-host.v1.schema.json +18 -0
  26. package/dist/startupCommitScope.test.js +6 -0
  27. package/dist/startupCommitScope.test.js.map +1 -1
  28. package/dist/wslRelayHost.d.ts +30 -0
  29. package/dist/wslRelayHost.d.ts.map +1 -0
  30. package/dist/wslRelayHost.js +269 -0
  31. package/dist/wslRelayHost.js.map +1 -0
  32. package/dist/wslRelayHost.test.d.ts +2 -0
  33. package/dist/wslRelayHost.test.d.ts.map +1 -0
  34. package/dist/wslRelayHost.test.js +308 -0
  35. package/dist/wslRelayHost.test.js.map +1 -0
  36. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -54,7 +54,7 @@ import { registerRepositoryRoleMetadata, discoverRepositoryRoleMetadata } from '
54
54
  import { askRepositoryRoleQuestion, readRepositoryRoleReply } from './repositoryRoleQuestion.js';
55
55
  import { deriveRepositoryRole } from './repositoryRoleDerivation.js';
56
56
  import { withOnboardingStage } from './onboardingStage.js';
57
- import { reportCodexSetupFailure } from './codexSetupDiagnostic.js';
57
+ import { classifyCodexSetupFailure, reportCodexSetupFailure } from './codexSetupDiagnostic.js';
58
58
  import { waitForRepositoryReadiness } from './repositoryReadinessWait.js';
59
59
  import { connectDemoDevice, verifyDemoDevice } from './demoEnrollment.js';
60
60
  import { performDemoPeerAction, withDemoDeviceLock } from './demoPeer.js';
@@ -104,7 +104,7 @@ import { assertCodexSetupExecutionLease } from './codexSetupAdmission.js';
104
104
  import { parseLocalCodexSetupReadiness } from '@dharma-ai-labs/agent-fabric-local-vault/setup-readiness';
105
105
  import { writeBootstrapHostJson, writeBootstrapHostText } from './bootstrapHostFiles.js';
106
106
  export { openCooperativeInboxSession } from './cooperativeInboxSession.js';
107
- const VERSION = '0.2.198';
107
+ const VERSION = '0.2.200';
108
108
  const USAGE = CLI_USAGE;
109
109
  const execFileAsync = promisify(execFile);
110
110
  const LOCAL_PROVIDER_IDS = ['codex', 'claude', 'agy', 'hermes'];
@@ -2083,8 +2083,10 @@ async function startRelayDaemon(policyPath) {
2083
2083
  const supervisorState = await relaySupervisorProcessState();
2084
2084
  if (supervisorState === 'unknown')
2085
2085
  throw new Error('Relay supervisor process state is unknown.');
2086
- if (supervisorState === 'stopped') {
2087
- const startupBackend = (await relayAutostartStatus({ home: dharmaHome() })).backend;
2086
+ const startup = await step(() => relayAutostartStatus({ home: dharmaHome() }));
2087
+ const hostPending = startup.restartCoverage === 'wsl-host-logon' && startup.hostLifecycle !== 'running';
2088
+ if (supervisorState === 'stopped' || hostPending) {
2089
+ const startupBackend = startup.backend;
2088
2090
  // A setup turn cannot own a supervisor intended to outlive that turn.
2089
2091
  if (hostScope || startupBackend === 'container-entrypoint' || startupBackend === 'systemd-user') {
2090
2092
  await step(() => startRelayAutostart({ home: dharmaHome() }));
@@ -2715,7 +2717,8 @@ async function observeCodexBootstrapRuntime(prepared, vault, firstLearning, inte
2715
2717
  || resolve(startup.workspace) !== startup.workspace
2716
2718
  || startup.policy !== resolve(startup.workspace, '.dharma', 'approved-policy.json')
2717
2719
  || startup.launcher !== resolve(startup.workspace, '.dharma', 'bin', 'dharma')
2718
- || startup.backend === 'container-entrypoint' && startupState.lifecycle !== 'running') {
2720
+ || startup.backend === 'container-entrypoint' && startupState.lifecycle !== 'running'
2721
+ || startupState.restartCoverage === 'wsl-host-logon' && startupState.hostLifecycle !== 'running') {
2719
2722
  throw new Error('setup_runtime_startup_unconfirmed');
2720
2723
  }
2721
2724
  // A standard relay can retain another repository as its same-device anchor.
@@ -3237,7 +3240,7 @@ async function codexPortalSetup(flags) {
3237
3240
  if (!completed || completed.operationId !== prepared.intent.operationId
3238
3241
  || completed.setupReference !== setupReference || !UUID_PATTERN.test(completed.readinessReceiptId)) {
3239
3242
  return { ok: false, stage: 'setup_host_unconfirmed', code: 'codex_setup_ingress_readiness_unconfirmed',
3240
- nativeThreadId: host.threadId, nativeTurnId: host.turnId };
3243
+ nativeThreadId: host.threadId, nativeTurnId: host.turnId, diagnostics: host.diagnostics };
3241
3244
  }
3242
3245
  const config = await readDeviceConfig();
3243
3246
  if (!config || config.organizationId !== organizationId || normalizeHqUrl(config.hqUrl) !== origin
@@ -3245,7 +3248,7 @@ async function codexPortalSetup(flags) {
3245
3248
  || config.setupClaimRepositoryFingerprint !== prepared.intent.repositoryFingerprint) {
3246
3249
  return { ok: false, stage: 'setup_host_unconfirmed', effects: 'unconfirmed',
3247
3250
  code: 'codex_setup_ingress_readiness_unconfirmed', setupReference,
3248
- nativeThreadId: host.threadId, nativeTurnId: host.turnId };
3251
+ nativeThreadId: host.threadId, nativeTurnId: host.turnId, diagnostics: host.diagnostics };
3249
3252
  }
3250
3253
  // One supported grant-free reconciliation, only for this consumed reference.
3251
3254
  // No replacement identity, grant replay or automatic provider-turn retry.
@@ -3282,7 +3285,8 @@ async function codexPortalSetup(flags) {
3282
3285
  'codex_setup_owned_close_unconfirmed', 'codex_setup_owned_completion_unconfirmed']);
3283
3286
  return { ok: false, stage: 'setup_host_unconfirmed',
3284
3287
  code: error instanceof Error && known.has(error.message) ? error.message : 'codex_setup_ingress_unconfirmed',
3285
- requiresSupportedRecovery: true };
3288
+ requiresSupportedRecovery: true,
3289
+ diagnostics: [...(host?.diagnostics ?? []).slice(0, 15), classifyCodexSetupFailure(error, 'bootstrap')] };
3286
3290
  }
3287
3291
  finally {
3288
3292
  controller.abort();
@@ -3291,8 +3295,9 @@ async function codexPortalSetup(flags) {
3291
3295
  try {
3292
3296
  await host?.close();
3293
3297
  }
3294
- catch {
3295
- return { ok: false, stage: 'setup_host_unconfirmed', code: 'codex_setup_owned_close_unconfirmed' };
3298
+ catch (error) {
3299
+ return { ok: false, stage: 'setup_host_unconfirmed', code: 'codex_setup_owned_close_unconfirmed',
3300
+ diagnostics: [...(host?.diagnostics ?? []).slice(0, 15), classifyCodexSetupFailure(error, 'completion')] };
3296
3301
  }
3297
3302
  }
3298
3303
  }
@@ -3363,6 +3368,15 @@ async function bootstrap(flags, hostScope) {
3363
3368
  }
3364
3369
  if (!joinedBindingId && joinedFingerprint)
3365
3370
  throw new Error('repository_join_selection_invalid');
3371
+ // Qualify the original host/plan above before reading enrollment metadata.
3372
+ // Refuse foreign context before checkout creation or private authority input.
3373
+ const targetConfig = await step(() => readDeviceConfig());
3374
+ if (targetConfig && !flags.has('replace-existing-enrollment')
3375
+ && (targetConfig.organizationId !== organizationId || normalizeHqUrl(targetConfig.hqUrl) !== hqUrl)) {
3376
+ return { ok: false, stage: 'connection_context', code: 'connection_context_mismatch',
3377
+ effects: false, grantRedeemed: false, enrollmentChanged: false,
3378
+ message: 'The existing local connection does not match the requested organization and portal. Select the intended installation; no repository selection or setup authority was used.' };
3379
+ }
3366
3380
  let repositorySelection;
3367
3381
  try {
3368
3382
  if (flags.has('repository-url-base64url') && typeof selectedRemote !== 'string') {
@@ -3448,7 +3462,8 @@ async function bootstrap(flags, hostScope) {
3448
3462
  const code = error instanceof Error && error.message.startsWith('autostart_conflict:')
3449
3463
  ? 'autostart_conflict' : error instanceof Error && error.message.startsWith('relay_runtime_upgrade_required:')
3450
3464
  ? 'relay_runtime_upgrade_required' : error instanceof Error && error.message.startsWith('relay_workspace_conflict:')
3451
- ? 'relay_workspace_conflict' : 'startup_preflight_unavailable';
3465
+ ? 'relay_workspace_conflict' : error instanceof Error && error.message === 'wsl_host_startup_unavailable'
3466
+ ? 'wsl_host_startup_unavailable' : 'startup_preflight_unavailable';
3452
3467
  return { ok: false, stage: 'startup_preflight', code, grantRedeemed: false, enrollmentChanged: false,
3453
3468
  message: code === 'relay_runtime_upgrade_required'
3454
3469
  ? 'Upgrade the existing enrolled startup runtime through the supported same-device update flow before retrying; setup has not redeemed authority or changed enrollment.'
@@ -3456,7 +3471,9 @@ async function bootstrap(flags, hostScope) {
3456
3471
  ? 'This Linux user already has a startup entry owned by another installation. Use the existing enrolled installation or an eligible clean client; setup has not redeemed authority or changed enrollment.'
3457
3472
  : code === 'relay_workspace_conflict'
3458
3473
  ? 'The existing startup anchor does not match this device and its approved repository policy. Recover that enrolled repository through the supported same-device flow before retrying; setup has not redeemed authority or changed enrollment.'
3459
- : 'Startup ownership could not be verified. Resolve the supported startup prerequisite before retrying; setup has not redeemed authority or changed enrollment.' };
3474
+ : code === 'wsl_host_startup_unavailable'
3475
+ ? 'The WSL host startup owner could not be verified. Restore the supported user-logon host binding before retrying; setup has not redeemed authority or changed enrollment.'
3476
+ : 'Startup ownership could not be verified. Resolve the supported startup prerequisite before retrying; setup has not redeemed authority or changed enrollment.' };
3460
3477
  }
3461
3478
  }
3462
3479
  if (grantMode === 'prompt')
@@ -3759,11 +3776,12 @@ async function bootstrap(flags, hostScope) {
3759
3776
  const role = repositoryReceipt.repositoryRole;
3760
3777
  const roleReady = Boolean(role);
3761
3778
  const relayReady = relay.state === 'running';
3762
- const observedAutostart = autostart.backend === 'container-entrypoint'
3779
+ const observedAutostart = autostart.backend === 'container-entrypoint' || autostart.restartCoverage === 'wsl-host-logon'
3763
3780
  ? await step(() => relayAutostartStatus({ home: dharmaHome() })) : autostart;
3764
3781
  const startupReady = !['win32', 'linux', 'darwin'].includes(process.platform)
3765
3782
  || observedAutostart.state === 'enabled'
3766
- && (observedAutostart.backend !== 'container-entrypoint' || observedAutostart.lifecycle === 'running');
3783
+ && (observedAutostart.backend !== 'container-entrypoint' || observedAutostart.lifecycle === 'running')
3784
+ && (observedAutostart.restartCoverage !== 'wsl-host-logon' || observedAutostart.hostLifecycle === 'running');
3767
3785
  const complete = sharedRepositoryReady && namedSessionReady && firstLearningReady
3768
3786
  && roleReady && relayReady && startupReady;
3769
3787
  return {