@dharma-ai-labs/agent-fabric 0.2.103 → 0.2.104

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 (61) hide show
  1. package/dist/demoSupervisor.d.ts +34 -0
  2. package/dist/demoSupervisor.d.ts.map +1 -0
  3. package/dist/demoSupervisor.js +164 -0
  4. package/dist/demoSupervisor.js.map +1 -0
  5. package/dist/demoSupervisor.test.d.ts +2 -0
  6. package/dist/demoSupervisor.test.d.ts.map +1 -0
  7. package/dist/demoSupervisor.test.js +249 -0
  8. package/dist/demoSupervisor.test.js.map +1 -0
  9. package/dist/demoWatchControl.d.ts +60 -0
  10. package/dist/demoWatchControl.d.ts.map +1 -0
  11. package/dist/demoWatchControl.js +128 -0
  12. package/dist/demoWatchControl.js.map +1 -0
  13. package/dist/demoWatchControl.test.d.ts +2 -0
  14. package/dist/demoWatchControl.test.d.ts.map +1 -0
  15. package/dist/demoWatchControl.test.js +184 -0
  16. package/dist/demoWatchControl.test.js.map +1 -0
  17. package/dist/demoWatchHealth.d.ts +26 -0
  18. package/dist/demoWatchHealth.d.ts.map +1 -0
  19. package/dist/demoWatchHealth.js +177 -0
  20. package/dist/demoWatchHealth.js.map +1 -0
  21. package/dist/demoWatchHealth.test.d.ts +2 -0
  22. package/dist/demoWatchHealth.test.d.ts.map +1 -0
  23. package/dist/demoWatchHealth.test.js +175 -0
  24. package/dist/demoWatchHealth.test.js.map +1 -0
  25. package/dist/demoWatchRegistry.d.ts +17 -0
  26. package/dist/demoWatchRegistry.d.ts.map +1 -0
  27. package/dist/demoWatchRegistry.js +170 -0
  28. package/dist/demoWatchRegistry.js.map +1 -0
  29. package/dist/demoWatchRegistry.test.d.ts +2 -0
  30. package/dist/demoWatchRegistry.test.d.ts.map +1 -0
  31. package/dist/demoWatchRegistry.test.js +146 -0
  32. package/dist/demoWatchRegistry.test.js.map +1 -0
  33. package/dist/index.d.ts +5 -1
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +236 -71
  36. package/dist/index.js.map +1 -1
  37. package/dist/index.test.js +68 -4
  38. package/dist/index.test.js.map +1 -1
  39. package/dist/pidLock.test.d.ts +2 -0
  40. package/dist/pidLock.test.d.ts.map +1 -0
  41. package/dist/pidLock.test.js +172 -0
  42. package/dist/pidLock.test.js.map +1 -0
  43. package/dist/relayAutostart.d.ts +17 -6
  44. package/dist/relayAutostart.d.ts.map +1 -1
  45. package/dist/relayAutostart.js +124 -19
  46. package/dist/relayAutostart.js.map +1 -1
  47. package/dist/relayAutostart.test.js +158 -1
  48. package/dist/relayAutostart.test.js.map +1 -1
  49. package/dist/relaySupervisor.test.js +75 -1
  50. package/dist/relaySupervisor.test.js.map +1 -1
  51. package/dist/repositoryOnboardingCaller.test.js +21 -0
  52. package/dist/repositoryOnboardingCaller.test.js.map +1 -1
  53. package/dist/schemas/demo-watch-control.v1.schema.json +27 -0
  54. package/dist/schemas/demo-watch-health.v1.schema.json +24 -0
  55. package/dist/schemas/demo-watch-registration.v1.schema.json +18 -0
  56. package/dist/schemas/relay-autostart.v2.schema.json +23 -0
  57. package/dist/usage.d.ts +1 -1
  58. package/dist/usage.d.ts.map +1 -1
  59. package/dist/usage.js +1 -1
  60. package/dist/usage.js.map +1 -1
  61. package/package.json +1 -1
@@ -7,7 +7,7 @@ import { join } from 'node:path';
7
7
  import test from 'node:test';
8
8
  import { fileURLToPath, pathToFileURL } from 'node:url';
9
9
  import { promisify } from 'node:util';
10
- import { acceptedTrajectoryHead, activateAgyPlugin, attestAgySkillActivation, attestHermesSkillBundleActivation, actionDecisionCapabilityFreshUntil, canonicalFilesystemPath, controlAgentDecisionUrl, installAvailableNativeAgentFabricBootstraps, assertCapsuleAuthorizedByCurrentPolicy, assertRecoveredTaskWorkspacePolicy, assertTaskWorkspacePolicy, assertTaskSkillPin, installNativeAgentFabricBootstrap, installClaudeReadOnlyProjectPermissions, installRepositoryAgentFabricSkill, isDirectExecution, isTransientBootstrapError, loadAgentFabricOnboardingContract, loadOrCreateInstallationId, materializeWorkspacePolicy, applyServerEvidencePolicy, materializeInlineSkillFiles, validateSkillBundleSources, nativeSkillDirectory, nativeSkillDirectoryForWorkspace, nativeSkillRootMatchingAuthorization, normalizeGitRemoteIdentity, postTaskOutcome, parseCliOptions, parseSelectedProviderIds, pathExistsOrThrow, portalUrl, providerHintFromEnvironment, providerHintFromProcessArgv, probeRelayConnection, preflightBootstrapWorkspaceIdentity, rawLocalRetentionDays, syncPendingRetentionCapsules, requireCompletedBootstrapEvidence, retryBootstrapOnboarding, synchronizeBootstrapEvidence, deferUnavailableRelayRetention, recoverLegacySkillBundleIdAfterAuthorizationFailure, installedBundleIdForSkillPollAfterAuthorizationFailure, recoveredTaskPolicyWasSuperseded, acquireRelayProcessLease, acquireRelaySupervisorLease, relayProcessState, relaySupervisorProcessState, releaseDailyContentUpload, reserveDailyContentUpload, run, runAssistantCommand, sourceRepositoryFingerprint, stableRepositoryLauncherContents, summarizeBootstrapOrganizationApi, ensureAgyReadOnlyAttestationPermission, attestAgySkillBundleActivation, responseTextFromEvent, taskResponsePreview, taskReceiptSession, taskSkillPinFailureCode, verifyAgentFabricSkillInstallation, waitForRelayReadiness, withWorkspacePolicyRefreshLock, withWorkspaceSkillActivationLock, } from './index.js';
10
+ import { acceptedTrajectoryHead, activateAgyPlugin, attestAgySkillActivation, attestHermesSkillBundleActivation, actionDecisionCapabilityFreshUntil, canonicalFilesystemPath, controlAgentDecisionUrl, installAvailableNativeAgentFabricBootstraps, assertCapsuleAuthorizedByCurrentPolicy, assertRecoveredTaskWorkspacePolicy, assertTaskWorkspacePolicy, assertTaskSkillPin, installNativeAgentFabricBootstrap, installClaudeReadOnlyProjectPermissions, installRepositoryAgentFabricSkill, isDirectExecution, isTransientBootstrapError, loadAgentFabricOnboardingContract, loadOrCreateInstallationId, materializeWorkspacePolicy, applyServerEvidencePolicy, materializeInlineSkillFiles, validateSkillBundleSources, nativeSkillDirectory, nativeSkillDirectoryForWorkspace, nativeSkillRootMatchingAuthorization, normalizeGitRemoteIdentity, postTaskOutcome, parseCliOptions, parseSelectedProviderIds, pathExistsOrThrow, portalUrl, providerHintFromEnvironment, providerHintFromProcessArgv, probeRelayConnection, preflightBootstrapWorkspaceIdentity, rawLocalRetentionDays, syncPendingRetentionCapsules, requireCompletedBootstrapEvidence, retryBootstrapOnboarding, synchronizeBootstrapEvidence, deferUnavailableRelayRetention, recoverLegacySkillBundleIdAfterAuthorizationFailure, installedBundleIdForSkillPollAfterAuthorizationFailure, recoveredTaskPolicyWasSuperseded, acquireRelayProcessLease, acquireRelaySupervisorLease, relayProcessState, relaySupervisorProcessState, releaseDailyContentUpload, reserveDailyContentUpload, run, runAssistantCommand, sourceRepositoryFingerprint, stableRepositoryLauncherContents, summarizeBootstrapOrganizationApi, ensureAgyReadOnlyAttestationPermission, attestAgySkillBundleActivation, responseTextFromEvent, taskResponsePreview, taskReceiptSession, taskSkillPinFailureCode, verifyAgentFabricSkillInstallation, waitForRelayReadiness, withWorkspacePolicyRefreshLock, withRelayStartupMutation, withWorkspaceSkillActivationLock, } from './index.js';
11
11
  import { canonicalize, signCanonicalObject } from '@dharma-ai-labs/agent-fabric-contracts';
12
12
  import { buildTrajectoryCapsule, trajectoryCapsuleHash } from '@dharma-ai-labs/agent-fabric-evidence-reduction';
13
13
  import { CLI_USAGE } from './usage.js';
@@ -276,6 +276,65 @@ test('repository launchers stay version-pinned without depending on the npm-exec
276
276
  assert.equal(launcher.shell.includes('/_npx/'), false);
277
277
  assert.equal(launcher.windows.includes('node_modules'), false);
278
278
  });
279
+ test('managed launchers pin the verified runtime directory without importing credentials', () => {
280
+ const linux = stableRepositoryLauncherContents('0.2.103', {
281
+ platform: 'linux', nodeDirectory: "/home/Agent's Runtime/bin",
282
+ });
283
+ assert.match(linux.shell, /export PATH='\/home\/Agent'\\''s Runtime\/bin':"\$PATH"/);
284
+ assert.match(linux.shell, /agent-fabric@0\.2\.103/);
285
+ const windows = stableRepositoryLauncherContents('0.2.103', {
286
+ platform: 'win32', nodeDirectory: 'C:\\Runtime % folder\\node',
287
+ });
288
+ assert.match(windows.windows, /setlocal DisableDelayedExpansion/);
289
+ assert.match(windows.windows, /set "PATH=C:\\Runtime %% folder\\node;%PATH%"/);
290
+ assert.doesNotMatch(linux.shell + windows.windows, /--grant|token|credential/);
291
+ for (const nodeDirectory of ['relative/bin', '/tmp/node\ncommand', '/tmp/node\0command']) {
292
+ assert.throws(() => stableRepositoryLauncherContents('0.2.103', { platform: 'linux', nodeDirectory }), /runtime/i);
293
+ }
294
+ assert.throws(() => stableRepositoryLauncherContents('0.2.103;command'), /version/i);
295
+ });
296
+ test('managed POSIX launcher selects its pinned npm even under a minimal startup PATH', {
297
+ skip: process.platform === 'win32',
298
+ }, async () => {
299
+ const root = await mkdtemp(join(tmpdir(), "dharma-launcher's-runtime-"));
300
+ const bin = join(root, 'bin');
301
+ await mkdir(bin);
302
+ await writeFile(join(bin, 'npm'), '#!/bin/sh\nprintf "%s\\n" "verified-runtime" "$@"\n', { mode: 0o700 });
303
+ const launcher = join(root, 'dharma');
304
+ await writeFile(launcher, stableRepositoryLauncherContents('0.2.103', {
305
+ platform: 'linux', nodeDirectory: bin,
306
+ }).shell, { mode: 0o700 });
307
+ const { stdout } = await execFileAsync('/bin/sh', [launcher, 'relay', 'supervise', '--demo-only'], {
308
+ env: { PATH: '/usr/bin:/bin' },
309
+ });
310
+ assert.deepEqual(stdout.trim().split('\n'), ['verified-runtime', 'exec', '--yes', '--',
311
+ '@dharma-ai-labs/agent-fabric@0.2.103', 'relay', 'supervise', '--demo-only']);
312
+ });
313
+ test('Demo watch controls support no-write plans through the actual CLI dispatch', async () => {
314
+ const root = await mkdtemp(join(tmpdir(), 'dharma-watch-cli-plan-'));
315
+ await execFileAsync('git', ['init', root]);
316
+ await execFileAsync('git', ['-C', root, 'remote', 'add', 'origin', 'https://github.com/example/repo']);
317
+ for (const command of ['watch-enable', 'watch-status', 'watch-disable']) {
318
+ const receipt = await run(['demo', command, '--dry-run', '--portal-url', 'https://example.com',
319
+ '--organization-id', 'org_test', '--repository-id', '00000000-0000-4000-8000-000000000001',
320
+ '--normalized-repository', 'github.com/example/repo', '--workspace', root]);
321
+ assert.equal(receipt.stage, 'demo_watch_plan');
322
+ }
323
+ await assert.rejects(readFile(join(root, '.dharma', 'bin', 'dharma')), { code: 'ENOENT' });
324
+ });
325
+ test('all startup mutations share one user-level lock and release it on failure', async () => {
326
+ const home = await mkdtemp(join(tmpdir(), 'dharma-startup-mutation-'));
327
+ let active = 0;
328
+ let maximum = 0;
329
+ await Promise.all(Array.from({ length: 5 }, () => withRelayStartupMutation(async () => {
330
+ maximum = Math.max(maximum, ++active);
331
+ await new Promise(resolve => setTimeout(resolve, 20));
332
+ active -= 1;
333
+ }, home)));
334
+ assert.equal(maximum, 1);
335
+ await assert.rejects(withRelayStartupMutation(async () => { throw new Error('fixture'); }, home), /fixture/);
336
+ assert.equal(await withRelayStartupMutation(async () => 'released', home), 'released');
337
+ });
279
338
  test('bootstrap validates stable repository identity before grant redemption', async () => {
280
339
  const root = await mkdtemp(join(tmpdir(), 'dharma-bootstrap-preflight-'));
281
340
  await execFileAsync('git', ['init', root]);
@@ -874,10 +933,15 @@ test('status reports verified relay state and hides local identifiers by default
874
933
  await writeFile(join(home, 'relay', 'last-successful-poll.json'), JSON.stringify({
875
934
  at: acknowledgedAt, workspaceId: 'workspace_private', version: '0.2.103',
876
935
  }));
936
+ const stale = await run(['status']);
937
+ assert.deepEqual(stale.reconnect, { state: 'awaiting_acknowledgement', lastSuccessfulPollAt: null });
938
+ await writeFile(join(home, 'relay', 'last-successful-poll.json'), JSON.stringify({
939
+ at: acknowledgedAt, workspaceId: 'workspace_private', version: version.version,
940
+ }));
877
941
  const acknowledged = await run(['status']);
878
942
  assert.deepEqual(acknowledged.reconnect, { state: 'acknowledged_recently', lastSuccessfulPollAt: acknowledgedAt });
879
943
  await writeFile(join(home, 'relay', 'last-successful-poll.json'), JSON.stringify({
880
- at: acknowledgedAt, workspaceId: 'foreign_workspace', version: '0.2.103',
944
+ at: acknowledgedAt, workspaceId: 'foreign_workspace', version: version.version,
881
945
  }));
882
946
  const foreign = await run(['status']);
883
947
  assert.deepEqual(foreign.reconnect, { state: 'awaiting_acknowledgement', lastSuccessfulPollAt: null });
@@ -1814,13 +1878,13 @@ test('relay probe opens an authenticated session without polling or leasing work
1814
1878
  },
1815
1879
  openSession: async (version) => {
1816
1880
  sessions += 1;
1817
- assert.equal(version, '0.2.103');
1881
+ assert.equal(version, '0.2.104');
1818
1882
  return { ok: true };
1819
1883
  },
1820
1884
  }));
1821
1885
  assert.equal(sessions, 1);
1822
1886
  assert.deepEqual(result, {
1823
- ok: true, connected: true, organizationId: 'org_test', deviceId: 'device_test', relayVersion: '0.2.103',
1887
+ ok: true, connected: true, organizationId: 'org_test', deviceId: 'device_test', relayVersion: '0.2.104',
1824
1888
  });
1825
1889
  });
1826
1890
  test('relay probe fails closed when the server does not acknowledge the session', async () => {