@dharma-ai-labs/agent-fabric 0.2.210 → 0.2.211
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/containerRelayLifecycle.d.ts +1 -0
- package/dist/containerRelayLifecycle.d.ts.map +1 -1
- package/dist/containerRelayLifecycle.js +12 -0
- package/dist/containerRelayLifecycle.js.map +1 -1
- package/dist/containerRelayLifecycle.test.js +38 -6
- package/dist/containerRelayLifecycle.test.js.map +1 -1
- package/dist/containerRelayRuntimeTrust.test.js +10 -0
- package/dist/containerRelayRuntimeTrust.test.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +117 -7
- package/dist/index.js.map +1 -1
- package/dist/maintenanceControlCaller.test.d.ts +2 -0
- package/dist/maintenanceControlCaller.test.d.ts.map +1 -0
- package/dist/maintenanceControlCaller.test.js +119 -0
- package/dist/maintenanceControlCaller.test.js.map +1 -0
- package/dist/namedSessionStoppedLock.d.ts +34 -0
- package/dist/namedSessionStoppedLock.d.ts.map +1 -0
- package/dist/namedSessionStoppedLock.js +108 -0
- package/dist/namedSessionStoppedLock.js.map +1 -0
- package/dist/namedSessionStoppedLock.test.d.ts +2 -0
- package/dist/namedSessionStoppedLock.test.d.ts.map +1 -0
- package/dist/namedSessionStoppedLock.test.js +104 -0
- package/dist/namedSessionStoppedLock.test.js.map +1 -0
- package/dist/relayAutostart.d.ts +3 -0
- package/dist/relayAutostart.d.ts.map +1 -1
- package/dist/relayAutostart.js +45 -6
- package/dist/relayAutostart.js.map +1 -1
- package/dist/relayAutostart.test.js +49 -1
- package/dist/relayAutostart.test.js.map +1 -1
- package/dist/relayRuntimeUpgrade.d.ts +1 -0
- package/dist/relayRuntimeUpgrade.d.ts.map +1 -1
- package/dist/relayRuntimeUpgrade.js +3 -3
- package/dist/relayRuntimeUpgrade.js.map +1 -1
- package/dist/relayRuntimeUpgradeCaller.test.js +76 -0
- package/dist/relayRuntimeUpgradeCaller.test.js.map +1 -1
- package/dist/relaySigningMaintenanceUpgrade.d.ts +44 -0
- package/dist/relaySigningMaintenanceUpgrade.d.ts.map +1 -0
- package/dist/relaySigningMaintenanceUpgrade.js +249 -0
- package/dist/relaySigningMaintenanceUpgrade.js.map +1 -0
- package/dist/relaySigningMaintenanceUpgrade.test.d.ts +2 -0
- package/dist/relaySigningMaintenanceUpgrade.test.d.ts.map +1 -0
- package/dist/relaySigningMaintenanceUpgrade.test.js +230 -0
- package/dist/relaySigningMaintenanceUpgrade.test.js.map +1 -0
- package/dist/schemas/local-signing-maintenance-upgrade-journal.schema.json +34 -0
- package/dist/schemas/local-signing-maintenance-upgrade.schema.json +33 -0
- package/dist/usage.d.ts.map +1 -1
- package/dist/usage.js +3 -2
- package/dist/usage.js.map +1 -1
- package/dist/wslRelayHost.d.ts +2 -0
- package/dist/wslRelayHost.d.ts.map +1 -1
- package/dist/wslRelayHost.js +35 -0
- package/dist/wslRelayHost.js.map +1 -1
- package/dist/wslRelayHost.test.js +81 -4
- package/dist/wslRelayHost.test.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -21,11 +21,13 @@ import { runDeviceSigningMaintenanceController } from './deviceSigningMaintenanc
|
|
|
21
21
|
import { withLegacySigningMaintenanceBoundary } from './legacySigningMaintenanceBoundary.js';
|
|
22
22
|
import { superviseRelay } from './relaySupervisor.js';
|
|
23
23
|
import { currentRepositoryRelayFailure, repositoryRelayObservationReady, runRegisteredRepositoryRelays, selectRepositoryRelayRegistrations, serializeRelayWork, waitForRelayRefresh, withRepositoryRelayStage } from './repositoryRelaySupervisor.js';
|
|
24
|
-
import { assertRelayStartupOwnership, disableRelayAutostart, enableRelayAutostart, inspectOwnedRelayAutostart, relayAutostartStatus, startRelayAutostart, stopRelayAutostart } from './relayAutostart.js';
|
|
24
|
+
import { assertRelayStartupOwnership, assertRelayAutostartPaused, disableRelayAutostart, enableRelayAutostart, inspectOwnedRelayAutostart, relayAutostartStatus, startRelayAutostart, stopRelayAutostart } from './relayAutostart.js';
|
|
25
25
|
import { runOwnedContainerEntrypoint, readContainerProcessIdentity } from './containerRelayLifecycle.js';
|
|
26
26
|
import { readWorkspaceRegistry } from './workspaceRegistry.js';
|
|
27
27
|
import { appendRecoveredWorkspace, applyRegistryRecoveryFile, inspectRegistryRecoveryFile, resolveRegistryRecoveryProjection } from './workspaceRegistryRecovery.js';
|
|
28
28
|
import { relayRuntimeObservationReady, upgradeRelayRuntime } from './relayRuntimeUpgrade.js';
|
|
29
|
+
import { reconcileStoppedNamedSessionLock } from './namedSessionStoppedLock.js';
|
|
30
|
+
import { upgradeRelayForSigningMaintenance } from './relaySigningMaintenanceUpgrade.js';
|
|
29
31
|
import { activateMaintenanceRestart, maintainNamedSession, recoverStoppedNamedSession } from './namedSessionMaintenance.js';
|
|
30
32
|
import { assertNamedSessionStartupRegistration } from './namedSessionAdmission.js';
|
|
31
33
|
import { recoverableContainerJournal } from './containerRelayRecovery.js';
|
|
@@ -112,7 +114,7 @@ import { parseLocalCodexSetupReadiness } from '@dharma-ai-labs/agent-fabric-loca
|
|
|
112
114
|
import { writeBootstrapHostJson, writeBootstrapHostText } from './bootstrapHostFiles.js';
|
|
113
115
|
export { openCooperativeInboxSession } from './cooperativeInboxSession.js';
|
|
114
116
|
import { inspectNamedCodexRecoveryToolDeclaration } from './codexSigningRecoveryTool.js';
|
|
115
|
-
const VERSION = '0.2.
|
|
117
|
+
const VERSION = '0.2.211';
|
|
116
118
|
const USAGE = CLI_USAGE;
|
|
117
119
|
const execFileAsync = promisify(execFile);
|
|
118
120
|
const LOCAL_PROVIDER_IDS = ['codex', 'claude', 'agy', 'hermes'];
|
|
@@ -177,6 +179,18 @@ export function formatCommandOutput(value) {
|
|
|
177
179
|
}
|
|
178
180
|
export function commandExitCode(argv, value) {
|
|
179
181
|
const { positional, flags } = parseCliOptions(argv);
|
|
182
|
+
if (positional[0] === 'relay' && positional[1] === 'upgrade'
|
|
183
|
+
&& (flags.has('stage-signing-maintenance') || flags.has('finish-signing-maintenance'))) {
|
|
184
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
185
|
+
return 2;
|
|
186
|
+
const receipt = value;
|
|
187
|
+
if (receipt.schema !== 'dharma.local-signing-maintenance-upgrade/v1' || receipt.ready !== false
|
|
188
|
+
|| receipt.nativeContinuationAuthorized !== false)
|
|
189
|
+
return 2;
|
|
190
|
+
return flags.get('apply') !== true ? receipt.state === 'planned' ? 0 : 2
|
|
191
|
+
: flags.has('finish-signing-maintenance') ? receipt.state === 'completed' && receipt.upgradeComplete === true ? 0 : 2
|
|
192
|
+
: receipt.state === 'staged' && receipt.upgradeComplete === false ? 0 : 2;
|
|
193
|
+
}
|
|
180
194
|
if (positional[0] === 'signing-recovery') {
|
|
181
195
|
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
182
196
|
return 2;
|
|
@@ -2014,6 +2028,15 @@ async function installStableRepositoryLauncher(workspace) {
|
|
|
2014
2028
|
return { shell: '.dharma/bin/dharma', windows: '.dharma/bin/dharma.cmd' };
|
|
2015
2029
|
}
|
|
2016
2030
|
async function relayUpgrade(flags) {
|
|
2031
|
+
const stageMaintenance = flags.has('stage-signing-maintenance'), finishMaintenance = flags.has('finish-signing-maintenance');
|
|
2032
|
+
const maintenance = stageMaintenance || finishMaintenance;
|
|
2033
|
+
if (maintenance && process.platform !== 'linux')
|
|
2034
|
+
throw new Error('relay_signing_maintenance_linux_required');
|
|
2035
|
+
if (stageMaintenance && finishMaintenance || maintenance && flags.has('rollback')
|
|
2036
|
+
|| ['stage-signing-maintenance', 'finish-signing-maintenance'].some(key => flags.has(key) && flags.get(key) !== true)
|
|
2037
|
+
|| maintenance && ['apply', 'dry-run'].some(key => flags.has(key) && flags.get(key) !== true)
|
|
2038
|
+
|| flags.has('previous-upgrade-sha256') && !stageMaintenance)
|
|
2039
|
+
throw new Error('relay_signing_maintenance_options_invalid');
|
|
2017
2040
|
const config = await readDeviceConfig();
|
|
2018
2041
|
if (!config)
|
|
2019
2042
|
throw new Error('relay_upgrade_enrollment_required');
|
|
@@ -2057,10 +2080,46 @@ async function relayUpgrade(flags) {
|
|
|
2057
2080
|
const npmCliPath = process.platform === 'linux' && !flags.has('rollback') ? await resolveRepositoryNpmCli() : undefined;
|
|
2058
2081
|
const codexDirectory = !flags.has('rollback')
|
|
2059
2082
|
? await resolveRepositoryCodexDirectory({ searchPath: providerProcessEnvironment(process.env).PATH }) : undefined;
|
|
2060
|
-
const
|
|
2083
|
+
const upgrade = maintenance ? upgradeRelayForSigningMaintenance : upgradeRelayRuntime;
|
|
2084
|
+
const receipt = await upgrade({ home, workspace, version: VERSION,
|
|
2061
2085
|
organizationId: config.organizationId, deviceId: config.deviceId, workspaceId: selected.workspaceId,
|
|
2062
|
-
dryRun: !flags.has('apply'), rollback: flags.has('rollback')
|
|
2086
|
+
dryRun: !flags.has('apply'), rollback: flags.has('rollback'),
|
|
2087
|
+
trustGeneration: config.serverSigningKeyset?.generation ?? 0, finish: finishMaintenance,
|
|
2088
|
+
...(flags.has('previous-upgrade-sha256') ? { previousUpgradeSha256: String(flags.get('previous-upgrade-sha256')) } : {}) }, {
|
|
2063
2089
|
assertStopped,
|
|
2090
|
+
assertStartupPaused: () => assertRelayAutostartPaused(startupOptions),
|
|
2091
|
+
stageStartup: (version, restore) => enableRelayAutostart({ ...startupOptions, workspace,
|
|
2092
|
+
launcher: startup.launcher, policy: startup.policy, version, restoreCodexHome: restore.codexHome, pauseForSigningMaintenance: true }),
|
|
2093
|
+
assertNamedDisabled: async () => {
|
|
2094
|
+
const entries = await readdir(resolve(home, 'sessions'), { withFileTypes: true });
|
|
2095
|
+
const names = entries.filter(entry => entry.isDirectory() && /^[a-z][a-z0-9-]{0,47}$/.test(entry.name));
|
|
2096
|
+
if (names.length !== 1)
|
|
2097
|
+
throw Error('relay_signing_maintenance_session_scope_unavailable');
|
|
2098
|
+
const registration = await readNamedSession(home, names[0].name);
|
|
2099
|
+
if (!registration || registration.enabled || registration.identity.organizationId !== config.organizationId
|
|
2100
|
+
|| registration.identity.deviceId !== config.deviceId || registration.identity.workspaceId !== selected.workspaceId)
|
|
2101
|
+
throw Error('relay_signing_maintenance_session_scope_unavailable');
|
|
2102
|
+
try {
|
|
2103
|
+
await lstat(resolve(home, 'sessions', names[0].name, 'service.lock'));
|
|
2104
|
+
throw Error('relay_signing_maintenance_session_lock_requires_reconciliation');
|
|
2105
|
+
}
|
|
2106
|
+
catch (error) {
|
|
2107
|
+
if (error.code !== 'ENOENT')
|
|
2108
|
+
throw error;
|
|
2109
|
+
}
|
|
2110
|
+
},
|
|
2111
|
+
assertRecoveredTrust: async (previousGeneration) => {
|
|
2112
|
+
const current = await readDeviceConfig(), keyset = current?.serverSigningKeyset;
|
|
2113
|
+
if (!current || current.organizationId !== config.organizationId || current.deviceId !== config.deviceId
|
|
2114
|
+
|| current.hqUrl !== config.hqUrl || current.relayUrl !== config.relayUrl || current.enrolledAt !== config.enrolledAt
|
|
2115
|
+
|| current.connectionMode !== config.connectionMode
|
|
2116
|
+
|| current.installationId !== config.installationId || current.publicKeyEd25519 !== config.publicKeyEd25519
|
|
2117
|
+
|| current.setupClaimReference !== config.setupClaimReference || current.setupClaimRepositoryFingerprint !== config.setupClaimRepositoryFingerprint
|
|
2118
|
+
|| !keyset || keyset.generation <= previousGeneration || !validateTrustedServerSigningKeysetContract(keyset).ok
|
|
2119
|
+
|| !verifyInitialServerSigningKeyset(keyset, createPublicKey({ key: { kty: 'OKP', crv: 'Ed25519', x: current.serverPublicKeyEd25519 }, format: 'jwk' }), current.organizationId).ok)
|
|
2120
|
+
throw Error('relay_signing_maintenance_trust_not_recovered');
|
|
2121
|
+
await loadDeviceEnrollmentAnchor({ config: current, readOnly: true });
|
|
2122
|
+
},
|
|
2064
2123
|
recoverableJournal: startup.backend === 'container-entrypoint' ? recoverableContainerJournal : undefined,
|
|
2065
2124
|
inspectStartup: async () => {
|
|
2066
2125
|
const current = await inspectOwnedRelayAutostart(startupOptions);
|
|
@@ -2120,7 +2179,8 @@ async function relayUpgrade(flags) {
|
|
|
2120
2179
|
throw new Error('relay_upgrade_receiver_unconfirmed');
|
|
2121
2180
|
},
|
|
2122
2181
|
});
|
|
2123
|
-
const validation = await validateContract(resolve(fileURLToPath(new URL('.', import.meta.url)), 'schemas'), 'https://schemas.dharma-ai.io/local-
|
|
2182
|
+
const validation = await validateContract(resolve(fileURLToPath(new URL('.', import.meta.url)), 'schemas'), maintenance ? 'https://schemas.dharma-ai.io/local-signing-maintenance-upgrade/v1'
|
|
2183
|
+
: 'https://schemas.dharma-ai.io/local-relay-upgrade/v1', receipt);
|
|
2124
2184
|
if (!validation.ok)
|
|
2125
2185
|
throw new Error('relay_upgrade_receipt_invalid');
|
|
2126
2186
|
return receipt;
|
|
@@ -5316,6 +5376,11 @@ async function namedSessionCommand(action, flags) {
|
|
|
5316
5376
|
const hostScope = currentBootstrapHostScope();
|
|
5317
5377
|
const setupSessionScope = currentAcceptedSetupSessionScope();
|
|
5318
5378
|
const supervisorOwner = currentNamedSessionChildOwner();
|
|
5379
|
+
if (action === 'reconcile-stopped-lock' && (hostScope || setupSessionScope || supervisorOwner
|
|
5380
|
+
|| [...flags.keys()].some(k => !['name', 'workspace-id', 'registration-sha256', 'lock-sha256', 'apply', 'dry-run', 'json'].includes(k))
|
|
5381
|
+
|| ['apply', 'dry-run', 'json'].some(k => flags.has(k) && flags.get(k) !== true)
|
|
5382
|
+
|| flags.has('apply') && flags.has('dry-run')))
|
|
5383
|
+
throw Error('named_session_stopped_lock_options_invalid');
|
|
5319
5384
|
if (hostScope && (supervisorOwner || setupSessionScope))
|
|
5320
5385
|
throw new Error('named_session_child_owner_conflict');
|
|
5321
5386
|
if (setupSessionScope && !['start', 'status', 'readiness'].includes(action))
|
|
@@ -5338,7 +5403,7 @@ async function namedSessionCommand(action, flags) {
|
|
|
5338
5403
|
await release?.();
|
|
5339
5404
|
};
|
|
5340
5405
|
try {
|
|
5341
|
-
if (['start', 'serve'].includes(action) && flags.has('apply')) {
|
|
5406
|
+
if (['start', 'serve'].includes(action) && flags.has('apply') || action === 'reconcile-stopped-lock') {
|
|
5342
5407
|
startupAdmission = await step(() => acquireNamedSessionStartupAdmission());
|
|
5343
5408
|
}
|
|
5344
5409
|
let childMessage;
|
|
@@ -5373,6 +5438,36 @@ async function namedSessionCommand(action, flags) {
|
|
|
5373
5438
|
bindingId: existing?.bindingId ?? null };
|
|
5374
5439
|
}
|
|
5375
5440
|
}
|
|
5441
|
+
if (action === 'reconcile-stopped-lock') {
|
|
5442
|
+
if (!existing)
|
|
5443
|
+
throw Error('named_session_stopped_lock_unconfirmed');
|
|
5444
|
+
return await reconcileStoppedNamedSessionLock({ home: dharmaHome(), name, registration: existing,
|
|
5445
|
+
registrationSha256: required(flags, 'registration-sha256'), lockSha256: required(flags, 'lock-sha256'), apply: flags.has('apply') }, {
|
|
5446
|
+
assertTopology: async () => {
|
|
5447
|
+
await assertRelayAutostartPaused({ home: dharmaHome() });
|
|
5448
|
+
if (await relayProcessState(dharmaHome()) !== 'stopped' || await relaySupervisorProcessState(dharmaHome()) !== 'stopped')
|
|
5449
|
+
throw Error('named_session_stopped_lock_unconfirmed');
|
|
5450
|
+
try {
|
|
5451
|
+
await namedSessionRequest(dharmaHome(), name, { action: 'status' }, { diagnostic: true });
|
|
5452
|
+
throw Error('named_session_stopped_lock_unconfirmed');
|
|
5453
|
+
}
|
|
5454
|
+
catch (error) {
|
|
5455
|
+
if (!(error instanceof NamedSessionTransportFailure) || error.diagnostic.phase !== 'connect'
|
|
5456
|
+
|| !['ENOENT', 'ECONNREFUSED'].includes(String(error.diagnostic.osCode)))
|
|
5457
|
+
throw Error('named_session_stopped_lock_unconfirmed');
|
|
5458
|
+
}
|
|
5459
|
+
},
|
|
5460
|
+
processState: async (pid) => {
|
|
5461
|
+
try {
|
|
5462
|
+
process.kill(pid, 0);
|
|
5463
|
+
return 'running';
|
|
5464
|
+
}
|
|
5465
|
+
catch (error) {
|
|
5466
|
+
return error.code === 'ESRCH' ? 'stopped' : 'unknown';
|
|
5467
|
+
}
|
|
5468
|
+
},
|
|
5469
|
+
});
|
|
5470
|
+
}
|
|
5376
5471
|
if (action === 'readiness') {
|
|
5377
5472
|
if (!existing?.enabled)
|
|
5378
5473
|
throw new Error('named_session_readiness_unavailable');
|
|
@@ -9649,9 +9744,24 @@ export async function run(argv) {
|
|
|
9649
9744
|
if (command === 'relay' && subcommand === 'autostart') {
|
|
9650
9745
|
if (positional[2] === 'status')
|
|
9651
9746
|
return relayAutostartStatus({ home: dharmaHome() });
|
|
9747
|
+
if (positional[2] === 'pause') {
|
|
9748
|
+
if ([...flags.keys()].some(k => !['apply', 'dry-run', 'json'].includes(k))
|
|
9749
|
+
|| [...flags.values()].some(v => v !== true) || flags.has('apply') && flags.has('dry-run'))
|
|
9750
|
+
throw Error('relay_pause_options_invalid');
|
|
9751
|
+
return withRelayStartupMutation(async () => {
|
|
9752
|
+
const registration = await inspectOwnedRelayAutostart({ home: dharmaHome() });
|
|
9753
|
+
if (registration.backend !== 'container-entrypoint')
|
|
9754
|
+
throw Error('relay_pause_container_required');
|
|
9755
|
+
if (!flags.has('apply'))
|
|
9756
|
+
return { ok: true, planned: true, state: 'pause_planned', backend: registration.backend };
|
|
9757
|
+
await stopRelayAutostart({ home: dharmaHome() });
|
|
9758
|
+
await assertRelayAutostartPaused({ home: dharmaHome() });
|
|
9759
|
+
return { ok: true, planned: false, state: 'paused', backend: registration.backend, registrationPreserved: true };
|
|
9760
|
+
});
|
|
9761
|
+
}
|
|
9652
9762
|
if (positional[2] === 'disable')
|
|
9653
9763
|
return withRelayStartupMutation(() => disableRelayAutostart({ home: dharmaHome() }));
|
|
9654
|
-
throw new Error('Use dharma relay autostart status or
|
|
9764
|
+
throw new Error('Use dharma relay autostart status, pause or disable.');
|
|
9655
9765
|
}
|
|
9656
9766
|
if (command === 'relay' && subcommand === 'supervise')
|
|
9657
9767
|
return relaySupervise(flags);
|