aismemory 0.7.5 → 0.8.2

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 (133) hide show
  1. package/README.md +247 -7
  2. package/dist/__tests__/agent-archive.test.d.ts +1 -0
  3. package/dist/__tests__/agent-archive.test.js +153 -0
  4. package/dist/__tests__/agent-archive.test.js.map +1 -0
  5. package/dist/__tests__/agent-key-mode.test.js +121 -6
  6. package/dist/__tests__/agent-key-mode.test.js.map +1 -1
  7. package/dist/__tests__/agent-load-persistence.test.js +22 -6
  8. package/dist/__tests__/agent-load-persistence.test.js.map +1 -1
  9. package/dist/__tests__/ais-http.test.js +23 -3
  10. package/dist/__tests__/ais-http.test.js.map +1 -1
  11. package/dist/__tests__/auto-handoff.test.js +56 -0
  12. package/dist/__tests__/auto-handoff.test.js.map +1 -1
  13. package/dist/__tests__/bond-link-survives-exit.test.d.ts +1 -0
  14. package/dist/__tests__/bond-link-survives-exit.test.js +177 -0
  15. package/dist/__tests__/bond-link-survives-exit.test.js.map +1 -0
  16. package/dist/__tests__/credential-resolution.test.js +56 -8
  17. package/dist/__tests__/credential-resolution.test.js.map +1 -1
  18. package/dist/__tests__/credential-whoami.test.d.ts +8 -0
  19. package/dist/__tests__/credential-whoami.test.js +93 -0
  20. package/dist/__tests__/credential-whoami.test.js.map +1 -0
  21. package/dist/__tests__/device-flow-gate-e2e.test.js +6 -4
  22. package/dist/__tests__/device-flow-gate-e2e.test.js.map +1 -1
  23. package/dist/__tests__/doctor.test.js +176 -85
  24. package/dist/__tests__/doctor.test.js.map +1 -1
  25. package/dist/__tests__/full-context-view-forwarding.test.d.ts +1 -0
  26. package/dist/__tests__/full-context-view-forwarding.test.js +80 -0
  27. package/dist/__tests__/full-context-view-forwarding.test.js.map +1 -0
  28. package/dist/__tests__/hydration.test.js +56 -1
  29. package/dist/__tests__/hydration.test.js.map +1 -1
  30. package/dist/__tests__/install.test.d.ts +1 -0
  31. package/dist/__tests__/install.test.js +126 -0
  32. package/dist/__tests__/install.test.js.map +1 -0
  33. package/dist/__tests__/integration.test.js +1 -0
  34. package/dist/__tests__/integration.test.js.map +1 -1
  35. package/dist/__tests__/lost-agent.test.js +51 -0
  36. package/dist/__tests__/lost-agent.test.js.map +1 -1
  37. package/dist/__tests__/mcp-tools.test.js +210 -3
  38. package/dist/__tests__/mcp-tools.test.js.map +1 -1
  39. package/dist/__tests__/memory-write-failure.test.js +4 -8
  40. package/dist/__tests__/memory-write-failure.test.js.map +1 -1
  41. package/dist/__tests__/no-registered-keys-disk-bearer-fallback.test.js +4 -7
  42. package/dist/__tests__/no-registered-keys-disk-bearer-fallback.test.js.map +1 -1
  43. package/dist/__tests__/pending-device-flow-e2e.test.js +22 -1
  44. package/dist/__tests__/pending-device-flow-e2e.test.js.map +1 -1
  45. package/dist/__tests__/pending-device-flow-resume.test.d.ts +1 -0
  46. package/dist/__tests__/pending-device-flow-resume.test.js +104 -0
  47. package/dist/__tests__/pending-device-flow-resume.test.js.map +1 -0
  48. package/dist/__tests__/prompt-resource.test.js +1 -0
  49. package/dist/__tests__/prompt-resource.test.js.map +1 -1
  50. package/dist/__tests__/provisional-register-mcp-remember.test.js +4 -8
  51. package/dist/__tests__/provisional-register-mcp-remember.test.js.map +1 -1
  52. package/dist/__tests__/reconnect-survival-e2e.test.js +3 -4
  53. package/dist/__tests__/reconnect-survival-e2e.test.js.map +1 -1
  54. package/dist/__tests__/refresh.test.js +24 -2
  55. package/dist/__tests__/refresh.test.js.map +1 -1
  56. package/dist/__tests__/request-timeout.test.d.ts +1 -0
  57. package/dist/__tests__/request-timeout.test.js +40 -0
  58. package/dist/__tests__/request-timeout.test.js.map +1 -0
  59. package/dist/__tests__/resolve-agent-preference-e2e.test.js +15 -3
  60. package/dist/__tests__/resolve-agent-preference-e2e.test.js.map +1 -1
  61. package/dist/__tests__/retry-after.test.d.ts +4 -0
  62. package/dist/__tests__/retry-after.test.js +134 -0
  63. package/dist/__tests__/retry-after.test.js.map +1 -0
  64. package/dist/__tests__/run-pass-mode.test.d.ts +1 -0
  65. package/dist/__tests__/run-pass-mode.test.js +130 -0
  66. package/dist/__tests__/run-pass-mode.test.js.map +1 -0
  67. package/dist/__tests__/session-identity.test.d.ts +1 -0
  68. package/dist/__tests__/session-identity.test.js +213 -0
  69. package/dist/__tests__/session-identity.test.js.map +1 -0
  70. package/dist/__tests__/version-check.test.js +1 -1
  71. package/dist/__tests__/workspace-key-mode.test.js +194 -16
  72. package/dist/__tests__/workspace-key-mode.test.js.map +1 -1
  73. package/dist/agent-archive.d.ts +36 -0
  74. package/dist/agent-archive.js +69 -0
  75. package/dist/agent-archive.js.map +1 -0
  76. package/dist/agent-key-mode.js +86 -29
  77. package/dist/agent-key-mode.js.map +1 -1
  78. package/dist/ais-http-error.d.ts +7 -2
  79. package/dist/ais-http-error.js +18 -5
  80. package/dist/ais-http-error.js.map +1 -1
  81. package/dist/ais-http.d.ts +2 -0
  82. package/dist/ais-http.js +41 -19
  83. package/dist/ais-http.js.map +1 -1
  84. package/dist/auto-handoff.js +33 -1
  85. package/dist/auto-handoff.js.map +1 -1
  86. package/dist/cli/doctor.d.ts +5 -2
  87. package/dist/cli/doctor.js +72 -15
  88. package/dist/cli/doctor.js.map +1 -1
  89. package/dist/cli/install.d.ts +6 -0
  90. package/dist/cli/install.js +52 -0
  91. package/dist/cli/install.js.map +1 -0
  92. package/dist/cli/orientation.d.ts +2 -0
  93. package/dist/cli/orientation.js +31 -1
  94. package/dist/cli/orientation.js.map +1 -1
  95. package/dist/credential-whoami.d.ts +50 -0
  96. package/dist/credential-whoami.js +91 -0
  97. package/dist/credential-whoami.js.map +1 -0
  98. package/dist/hydration.js +8 -0
  99. package/dist/hydration.js.map +1 -1
  100. package/dist/index.js +213 -50
  101. package/dist/index.js.map +1 -1
  102. package/dist/mcp/tools.d.ts +18 -4
  103. package/dist/mcp/tools.js +107 -12
  104. package/dist/mcp/tools.js.map +1 -1
  105. package/dist/pending-device-flow.d.ts +31 -0
  106. package/dist/pending-device-flow.js +38 -0
  107. package/dist/pending-device-flow.js.map +1 -1
  108. package/dist/refresh.js +5 -1
  109. package/dist/refresh.js.map +1 -1
  110. package/dist/request-timeout.d.ts +26 -0
  111. package/dist/request-timeout.js +49 -0
  112. package/dist/request-timeout.js.map +1 -0
  113. package/dist/retry-after.d.ts +26 -0
  114. package/dist/retry-after.js +42 -0
  115. package/dist/retry-after.js.map +1 -0
  116. package/dist/run-pass-mode.d.ts +16 -0
  117. package/dist/run-pass-mode.js +274 -0
  118. package/dist/run-pass-mode.js.map +1 -0
  119. package/dist/session-identity.d.ts +40 -0
  120. package/dist/session-identity.js +179 -0
  121. package/dist/session-identity.js.map +1 -0
  122. package/dist/telemetry.d.ts +1 -1
  123. package/dist/telemetry.js.map +1 -1
  124. package/dist/tool-args.d.ts +13 -1
  125. package/dist/tool-args.js +27 -1
  126. package/dist/tool-args.js.map +1 -1
  127. package/dist/types.d.ts +32 -0
  128. package/dist/workspace-key-mode.js +100 -26
  129. package/dist/workspace-key-mode.js.map +1 -1
  130. package/package.json +4 -6
  131. package/dist/harness-identity.d.ts +0 -17
  132. package/dist/harness-identity.js +0 -105
  133. package/dist/harness-identity.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"hydration.js","sourceRoot":"","sources":["../src/hydration.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hydration.js","sourceRoot":"","sources":["../src/hydration.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -18,7 +18,7 @@ import { aisGet, aisPost, DEFAULT_AIS_URL } from './ais-http.js';
18
18
  import { CallToolRequestSchema, GetPromptRequestSchema, ListPromptsRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
19
19
  import { homedir } from 'node:os';
20
20
  import { loadOAuthCredentials, loadNonStaleDiskBearer, saveOAuthCredentials, } from './oauth-credentials.js';
21
- import { clearPendingDeviceFlow, loadPendingDeviceFlow, savePendingDeviceFlow, } from './pending-device-flow.js';
21
+ import { clearPendingDeviceFlow, isResumableDeviceFlow, loadPendingDeviceFlow, savePendingDeviceFlow, } from './pending-device-flow.js';
22
22
  import { saveAgentPreference, loadAgentPreference, migrateCredentialsFileIfNeeded } from './agent-preference.js';
23
23
  import { createTokenManager, isNoRegisteredKeyFailure } from './token-manager.js';
24
24
  import { hydrateIdentity } from './hydration.js';
@@ -28,16 +28,19 @@ import { ActivityTracker, setupAutoHandoff } from './auto-handoff.js';
28
28
  import { assertEnvAgentInTenant, selectAgentForSession } from './env-agent.js';
29
29
  import { emitTelemetry, hashAgentId } from './telemetry.js';
30
30
  import { INBOX_MAX_BODY_CHARS, INBOX_MAX_TASK_ID_CHARS, INBOX_MIN_TTL_SECONDS, INBOX_MAX_TTL_SECONDS, INBOX_DEFAULT_TTL_SECONDS, INBOX_MAX_PAGE_SIZE, INBOX_DEFAULT_PAGE_SIZE, INBOX_MAX_ACK_IDS, GOAL_MAX_TITLE_CHARS, GOAL_MAX_DESCRIPTION_CHARS, GOAL_MAX_CRITERIA_ITEMS, GOAL_DEFAULT_PAGE_SIZE, GOAL_MAX_PAGE_SIZE, } from './tool-args.js';
31
- import { loadHarnessIdentity, installHarnessIdentity, optionValue, verifyPinnedIdentity } from './harness-identity.js';
31
+ import { identityCredentialFingerprint, loadSessionIdentity, verifyPinnedIdentity } from './session-identity.js';
32
32
  import { runPollLoop, DeviceFlowRestartedError } from './device-poll.js';
33
33
  import { loadAgentApiKeyConfig, AgentApiKeyConfigError, } from './agent-key-mode.js';
34
34
  import { loadWorkspaceKeyConfig, WorkspaceKeyConfigError, } from './workspace-key-mode.js';
35
- import { createAgentKeyCallToolHandler, createOAuthCallToolHandler, createWorkspaceKeyCallToolHandler, } from './mcp/tools.js';
35
+ import { loadRunPassConfig, RunPassConfigError, } from './run-pass-mode.js';
36
+ import { createAgentKeyCallToolHandler, createOAuthCallToolHandler, createRunPassCallToolHandler, createWorkspaceKeyCallToolHandler, } from './mcp/tools.js';
36
37
  import { readPackageVersion, startVersionCheck } from './version-check.js';
38
+ import { AGENT_ARCHIVE_DESCRIPTION, AGENT_ARCHIVE_INPUT_SCHEMA, AGENT_DELETE_ALIAS_DESCRIPTION } from './agent-archive.js';
37
39
  // ── Config ──────────────────────────────────────────────
38
40
  const AIS_URL = process.env['AIS_URL']?.trim() || DEFAULT_AIS_URL;
39
41
  const PACKAGE_VERSION = readPackageVersion();
40
- let harnessIdentity = null;
42
+ const RUN_PASS_CONFLICTING_KEY_ENV_NAMES = ['AIS_WORKSPACE_KEY', 'AIS_API_KEY', 'AIS_AGENT_API_KEY'];
43
+ let sessionIdentity = null;
41
44
  // ── Credential persistence ──────────────────────────────
42
45
  function loadCredentials() {
43
46
  // F5a (CORBOT-48DD2E25): migrate a legacy v1 file to v2 (ids only) BEFORE
@@ -61,6 +64,16 @@ function loadCredentials() {
61
64
  function stderr(msg) {
62
65
  process.stderr.write(`[aismemory] ${msg}\n`);
63
66
  }
67
+ function rejectRunPassWithKeyEnv(env) {
68
+ if (env['AIS_RUN_PASS_FILE'] === undefined)
69
+ return;
70
+ const conflictingKeyName = RUN_PASS_CONFLICTING_KEY_ENV_NAMES.find((keyName) => env[keyName] !== undefined);
71
+ if (conflictingKeyName === undefined)
72
+ return;
73
+ stderr(`Refusing to start: AIS_RUN_PASS_FILE and ${conflictingKeyName} are both set. ` +
74
+ 'Run-pass mode must not silently fall back to a long-lived key; unset one variable.');
75
+ process.exit(1);
76
+ }
64
77
  function isSafeClaudeSessionId(sessionId) {
65
78
  return sessionId !== '.' && sessionId !== '..' && /^[A-Za-z0-9._-]+$/.test(sessionId);
66
79
  }
@@ -131,8 +144,8 @@ async function resolveAgentForLoad(token, query) {
131
144
  * User can override with AIS_AGENT_ID or AIS_AGENT_NAME env vars.
132
145
  */
133
146
  async function resolveAgent(token, fallbackAgentId, fallbackTenantId, preferredAgentId) {
134
- // The harness pin overrides shared preferences and must belong to this tenant.
135
- const envAgentId = harnessIdentity?.agentId;
147
+ // This session's own identity overrides shared preferences and must belong to this tenant.
148
+ const envAgentId = sessionIdentity?.agentId;
136
149
  if (envAgentId) {
137
150
  const agents = await listAllAgents(token);
138
151
  try {
@@ -207,14 +220,79 @@ class BondPendingError extends Error {
207
220
  `${verificationUri}\n\n` +
208
221
  `Send nothing else: not this message, not a code, not a key, not a command, not JSON. ` +
209
222
  `Your human opens the link, signs in, and presses Bond. When they say it is done, retry this tool.\n` +
210
- `The link expires in 30 minutes. An agent nobody bonds is archived after 7 days, with its memories.`);
223
+ `The link expires in 30 minutes and is only redeemed while this tool is running — if it stops, ` +
224
+ `start it again before your human presses Bond and the same link still works. ` +
225
+ `An agent nobody bonds is archived after 7 days, with its memories.`);
211
226
  this.verificationUri = verificationUri;
212
227
  this.userCode = userCode;
213
228
  this.name = 'BondPendingError';
214
229
  }
215
230
  }
231
+ /**
232
+ * Wire the poll loop onto a freshly built flow. Shared by the mint path and
233
+ * the resume path so a change to the poll/dead bookkeeping lands in one place.
234
+ */
235
+ function attachDeviceFlowPoll(flow, interval) {
236
+ // flowRef points into the live flow object so auto-restart can update the
237
+ // surfaced URL without the caller needing to restart the MCP process.
238
+ const flowRef = flow;
239
+ const poll = pollForToken(flow.device_code, interval, flow.agent_id, flow.provisional_tenant_id, flowRef);
240
+ flow.poll = poll;
241
+ // Mark the flow dead as soon as its poll rejects so the next
242
+ // `ensureCredentials` call starts a fresh flow. The `.catch` here is purely
243
+ // for state-tracking — the original rejection is still observed by callers
244
+ // racing `flow.poll`. We swallow on this branch to suppress unhandled
245
+ // rejection warnings between rejection and the next ensureCredentials call.
246
+ poll.catch(() => {
247
+ flow.dead = true;
248
+ });
249
+ return flow;
250
+ }
251
+ /**
252
+ * Pick up the device code a previous process already minted, instead of
253
+ * asking the server for a new one (CORBOT-7F3EC71C).
254
+ *
255
+ * The bond link is redeemable for its full 30 minutes server-side, but
256
+ * `/v1/oauth/device/authorize` expires every unclaimed claim token for the
257
+ * agent before it issues the next one (OAuthDeviceService `tryReuseProvisional`).
258
+ * So the act of restarting — which an IDE does to its stdio MCP server
259
+ * constantly — used to kill the exact link the agent had just relayed to its
260
+ * human, and the human clicked a page that no longer meant anything.
261
+ * Resuming polls the same code and re-surfaces the same URL, so the link that
262
+ * left the building stays the link that works.
263
+ */
264
+ function resumeDeviceFlow(saved) {
265
+ emitTelemetry({ event: 'auth.device_flow.resume' });
266
+ const remainingMin = Math.max(1, Math.round((Date.parse(saved.codeExpiresAt) - Date.now()) / 60_000));
267
+ stderr('');
268
+ stderr('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
269
+ stderr(' aismemory — still waiting on the bond link already sent');
270
+ stderr('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
271
+ stderr(` Bond URL : ${saved.verificationUriComplete}`);
272
+ stderr(` Code : ${saved.userCode}`);
273
+ stderr(` Same link as before — good for about ${remainingMin} more min.`);
274
+ stderr('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
275
+ return attachDeviceFlowPoll({
276
+ device_code: saved.deviceCode,
277
+ user_code: saved.userCode,
278
+ verification_uri_complete: saved.verificationUriComplete,
279
+ agent_id: saved.agentId,
280
+ provisional_tenant_id: saved.provisionalTenantId,
281
+ provisional_token: saved.provisionalToken,
282
+ dead: false,
283
+ }, saved.interval ?? DEFAULT_DEVICE_POLL_INTERVAL_S);
284
+ }
285
+ /** Fallback poll interval when a resumed record predates the stored field. */
286
+ const DEFAULT_DEVICE_POLL_INTERVAL_S = 5;
216
287
  async function startDeviceFlow(priorProvisionalToken) {
217
288
  emitTelemetry({ event: 'auth.device_flow.start' });
289
+ // A caller that passes a prior provisional token has just watched its flow
290
+ // die (expired, denied, timed out), so its code is spent — mint, never
291
+ // resume. Only a process with no flow of its own looks on disk.
292
+ const resumable = priorProvisionalToken ? null : loadPendingDeviceFlow();
293
+ if (isResumableDeviceFlow(resumable)) {
294
+ return resumeDeviceFlow(resumable);
295
+ }
218
296
  stderr('Starting authentication...');
219
297
  // CORBOT-8F96A8EF: when this process has no in-flight flow of its own,
220
298
  // fall back to the provisional token left on disk by an earlier process.
@@ -246,32 +324,23 @@ async function startDeviceFlow(priorProvisionalToken) {
246
324
  agentId: agent_id,
247
325
  provisionalTenantId: provisional_tenant_id,
248
326
  startedAt: new Date().toISOString(),
327
+ deviceCode: device_code,
328
+ userCode: user_code,
329
+ verificationUriComplete: verification_uri_complete,
330
+ interval,
331
+ codeExpiresAt: new Date(Date.now() + authRes.data.expires_in * 1000).toISOString(),
249
332
  });
250
- const flow = {
333
+ return attachDeviceFlowPoll({
251
334
  device_code,
252
335
  user_code,
253
336
  verification_uri_complete,
254
337
  agent_id,
255
338
  provisional_tenant_id,
256
339
  provisional_token,
257
- // poll is assigned below after flowRef is captured so pollForToken holds
258
- // a reference to the live flow object for URL updates on auto-restart.
340
+ // poll is assigned by attachDeviceFlowPoll, which captures the live flow
341
+ // object so pollForToken can update the surfaced URL on auto-restart.
259
342
  dead: false,
260
- };
261
- // flowRef points into the live flow object so auto-restart can update the
262
- // surfaced URL without the caller needing to restart the MCP process.
263
- const flowRef = flow;
264
- const poll = pollForToken(device_code, interval, agent_id, provisional_tenant_id, flowRef);
265
- flow.poll = poll;
266
- // Mark the flow dead as soon as its poll rejects so the next
267
- // `ensureCredentials` call starts a fresh flow. The `.catch` here is purely
268
- // for state-tracking — the original rejection is still observed by callers
269
- // racing `flow.poll`. We swallow on this branch to suppress unhandled
270
- // rejection warnings between rejection and the next ensureCredentials call.
271
- poll.catch(() => {
272
- flow.dead = true;
273
- });
274
- return flow;
343
+ }, interval);
275
344
  }
276
345
  async function pollForToken(device_code, interval, agent_id, provisional_tenant_id,
277
346
  /** Mutable ref so auto-restart can update the surfaced URL and provisional token in ActiveDeviceFlow */
@@ -332,6 +401,11 @@ flowRef) {
332
401
  agentId: authRes.data.agent_id,
333
402
  provisionalTenantId: authRes.data.provisional_tenant_id,
334
403
  startedAt: new Date().toISOString(),
404
+ deviceCode: authRes.data.device_code,
405
+ userCode: authRes.data.user_code,
406
+ verificationUriComplete: authRes.data.verification_uri_complete,
407
+ interval: authRes.data.interval,
408
+ codeExpiresAt: new Date(Date.now() + authRes.data.expires_in * 1000).toISOString(),
335
409
  });
336
410
  stderr('');
337
411
  stderr('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
@@ -380,10 +454,10 @@ flowRef) {
380
454
  // reconnected silently. migrateCredentialsFileIfNeeded() (agent-preference.ts)
381
455
  // is what later removes this token from disk, once a key gets enrolled.
382
456
  if (hasEnrolledKey()) {
383
- if (!harnessIdentity)
457
+ if (!sessionIdentity)
384
458
  saveAgentPreference({ agentId: creds.agentId, tenantId: creds.tenantId });
385
459
  }
386
- else if (!harnessIdentity) {
460
+ else if (!sessionIdentity) {
387
461
  saveOAuthCredentials(creds);
388
462
  }
389
463
  // The flow is finished: this agent is bonded and reachable by id from the
@@ -410,6 +484,7 @@ const tools = [
410
484
  content: { type: 'string', description: 'The memory content to store' },
411
485
  type: { type: 'string', enum: ['fact', 'event', 'lesson', 'context', 'goal', 'task'], description: 'Memory type' },
412
486
  importance: { type: 'number', minimum: 0, maximum: 1, description: 'Importance (0-1, default 0.5)' },
487
+ tags: { type: 'array', items: { type: 'string' }, description: 'Optional tags to filter on later, e.g. ["work", "acme"]. At most 20; each 1-64 characters of a-z 0-9 . _ : - (stored lower-case). Tags are a filter, not a permission — use separate agents to wall off e.g. work from personal.' },
413
488
  },
414
489
  required: ['content'],
415
490
  },
@@ -417,13 +492,17 @@ const tools = [
417
492
  {
418
493
  name: 'recall',
419
494
  description: "Search memories by natural language query. Set principalAgentId to search a DIFFERENT " +
420
- "agent's memories under a 'memory:read' grant from that agent's owner." + BOND_LINK_NOTE,
495
+ "agent's memories under a 'memory:read' grant from that agent's owner. " +
496
+ "Each memory carries createdAt, updatedAt (its last edit), and tags. " +
497
+ "Memories superseded by a newer one are left out; to list or page through every memory, " +
498
+ "use the REST list route described in the aismemory README (cursor paging, sortBy=updatedAt, includeSuperseded=true)." + BOND_LINK_NOTE,
421
499
  inputSchema: {
422
500
  type: 'object',
423
501
  properties: {
424
502
  query: { type: 'string', description: 'Search query' },
425
503
  limit: { type: 'number', description: 'Max results (default 10)' },
426
504
  type: { type: 'string', enum: ['fact', 'event', 'lesson', 'context', 'goal', 'task'], description: 'Filter by type' },
505
+ tags: { type: 'array', items: { type: 'string' }, description: 'Only memories carrying ALL of these tags. A hard filter: results are never widened past it.' },
427
506
  principalAgentId: { type: 'string', description: "Optional: search ANOTHER agent's memories instead of your own (its agent UUID). Requires that agent's owner to have granted you the 'memory:read' scope and that you share a tenant; otherwise the call is refused with 403. Read-only — your own identity and write access are unchanged." },
428
507
  },
429
508
  required: ['query'],
@@ -431,18 +510,49 @@ const tools = [
431
510
  },
432
511
  {
433
512
  name: 'whoami',
434
- description: 'Get the current agent identity — name, DID, status, description.' + BOND_LINK_NOTE,
513
+ description: 'Get the current agent identity — name, DID, status, description — and, when running on an API key, what that credential can and cannot do: mode, tenant, the sub-resources it may reach, its restrictions and when it expires. `selfDescribed: false` means the server predates that answer and only liveness was confirmed.'
514
+ + BOND_LINK_NOTE,
435
515
  inputSchema: { type: 'object', properties: {} },
436
516
  },
517
+ {
518
+ name: 'orientation_check',
519
+ description: 'Run the same expected-environment orientation check "aismemory doctor --orientation" runs from a local file, ' +
520
+ 'reachable here for a filesystem-free surface. Pass an owner-approved manifest (host, account, required channels, ' +
521
+ 'and the wider tool-server/connector surface this agent expects — names and purposes only, never a secret value) ' +
522
+ 'plus this session\'s self-reported evidence. Returns PASS/FAIL per item; read-only, never self-healing, never grants anything.',
523
+ inputSchema: {
524
+ type: 'object',
525
+ properties: {
526
+ version: { type: 'number', enum: [1], description: 'Manifest format version. Always 1.' },
527
+ identity: { type: 'string', description: 'This agent\'s AIS identity (uuid).' },
528
+ requirements: {
529
+ type: 'object',
530
+ description: 'Owner-approved expectations: { host, account, channels: ["ais","mcp","inbox"], environment?: [{name, kind, purpose, required, permission?, dataEnvironment?}] }.',
531
+ },
532
+ current: { type: 'object', description: 'This session\'s observed { host, account, session } marker.' },
533
+ evidence: { type: 'object', description: 'This session\'s self-reported evidence: { session, host, account, credentials, credentialSource, channels: {ais,mcp,inbox}, environment?: {[name]: "pass"|"missing"|"unknown"} }.' },
534
+ relocation: { type: 'object', description: '{ verified, observedAction? } — whether relocation off the expected host/account is a verified, human-confirmed capability.' },
535
+ activationUrl: { type: 'string', description: 'Optional AIS device-flow activation door URL, echoed back as bondUrl.' },
536
+ },
537
+ required: ['version', 'identity', 'requirements', 'current', 'evidence', 'relocation'],
538
+ },
539
+ },
437
540
  {
438
541
  name: 'full_context',
439
- description: 'Load the full agent context — identity, personality, goals, facts, skills, and last handoff. ' +
440
- "Set principalAgentId to load ANOTHER agent's context under a 'memory:read' grant." + BOND_LINK_NOTE,
542
+ description: 'Load the full agent context — identity, personality, goals, facts, skills, last handoff, and the operating layer: the constitution rules that govern this agent and the index of skills it has, under one sha256 version you can compare between two machines. ' +
543
+ "Set principalAgentId to load ANOTHER agent's context under a 'memory:read' grant. " +
544
+ 'Every view is bounded: the default view budgets to 6000 tokens, and anything the ceiling cut is ' +
545
+ "named in the response's receipt.omitted rather than dropped silently — goal titles are cut to 200 " +
546
+ "characters with the goal's memory id in the payload, so the whole body is one memory-by-id fetch away. " +
547
+ "Pass view='lean' for continuity only (last handoff first, recent memories) or view='bootstrap' " +
548
+ 'for a cross-harness session start (adds goals and inbox). maxTokens sets the ceiling on any view.' + BOND_LINK_NOTE,
441
549
  inputSchema: {
442
550
  type: 'object',
443
551
  properties: {
444
552
  principalAgentId: { type: 'string', description: "Optional: search ANOTHER agent's memories instead of your own (its agent UUID). Requires that agent's owner to have granted you the 'memory:read' scope and that you share a tenant; otherwise the call is refused with 403. Read-only — your own identity and write access are unchanged." },
445
- memoriesLimit: { type: 'number', description: 'Number of memories to load (1-50, default 5). Lower values reduce context size.' },
553
+ memoriesLimit: { type: 'number', description: 'Number of memories to load (1-50, default 5). Lower values reduce context size. Governs recent memories only — on the full view that is a small share of the payload, so prefer view to bound the whole response.' },
554
+ view: { type: 'string', enum: ['full', 'lean', 'bootstrap'], description: "Which projection to load. 'full' (default) is everything the stores hold, bounded to 6000 tokens. 'lean' is continuity only — last handoff first, then recent memories. 'bootstrap' is lean plus goals and inbox, for starting a session in another harness. All three honour maxTokens." },
555
+ maxTokens: { type: 'number', description: 'Token ceiling (500-20000; default 6000 for full, 2000 for lean, 3000 for bootstrap). Content is evicted from the tail until the payload fits — assembled context sections, then facts, then goals, then recent memories on the full view — and each eviction is named in receipt.omitted. Identity, the operating layer and the last handoff are never dropped.' },
446
556
  },
447
557
  },
448
558
  },
@@ -654,6 +764,18 @@ const tools = [
654
764
  required: ['goalId', 'success'],
655
765
  },
656
766
  },
767
+ // Owner-only lifecycle (CORBOT-BA5AADB0): archive, plus the agent_delete
768
+ // alias, which archives too. Key modes refuse both (agent-key-mode.ts).
769
+ {
770
+ name: 'agent_archive',
771
+ description: AGENT_ARCHIVE_DESCRIPTION,
772
+ inputSchema: AGENT_ARCHIVE_INPUT_SCHEMA,
773
+ },
774
+ {
775
+ name: 'agent_delete',
776
+ description: AGENT_DELETE_ALIAS_DESCRIPTION,
777
+ inputSchema: AGENT_ARCHIVE_INPUT_SCHEMA,
778
+ },
657
779
  ];
658
780
  // ── MCP Server ──────────────────────────────────────────
659
781
  /**
@@ -693,7 +815,8 @@ async function runWorkspaceKeyModeServer(config) {
693
815
  server.setRequestHandler(CallToolRequestSchema, createWorkspaceKeyCallToolHandler({
694
816
  aisUrl: AIS_URL,
695
817
  activityTracker,
696
- getHarnessIdentity: () => harnessIdentity,
818
+ getSessionIdentity: () => sessionIdentity,
819
+ setSessionIdentity: (next) => { sessionIdentity = next; },
697
820
  getActiveConfig: () => activeConfig,
698
821
  setActiveConfig: (next) => { activeConfig = next; },
699
822
  stderr,
@@ -702,6 +825,30 @@ async function runWorkspaceKeyModeServer(config) {
702
825
  await server.connect(transport);
703
826
  stderr(`MCP server running (workspace key mode). Tools: ${tools.map((t) => t.name).join(', ')}`);
704
827
  }
828
+ /**
829
+ * MCP server entrypoint for run-pass auth mode (CORBOT-662A4B3A).
830
+ *
831
+ * The pass itself is never stored in process state: each tool request re-reads
832
+ * AIS_RUN_PASS_FILE and sends the current content as x-run-pass only.
833
+ */
834
+ async function runPassModeServer(config) {
835
+ stderr(`Run-pass auth mode — agent fixed to ${config.agentId}; pass file ${config.runPassFile}`);
836
+ const server = new Server({ name: 'aismemory', version: PACKAGE_VERSION }, { capabilities: { tools: {}, prompts: {} } });
837
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools }));
838
+ server.setRequestHandler(ListPromptsRequestSchema, async () => ({ prompts: [] }));
839
+ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
840
+ throw new Error(`Unknown prompt: ${request.params.name}`);
841
+ });
842
+ server.setRequestHandler(CallToolRequestSchema, createRunPassCallToolHandler({
843
+ aisUrl: AIS_URL,
844
+ activityTracker,
845
+ config,
846
+ getSessionIdentity: () => sessionIdentity,
847
+ }));
848
+ const transport = new StdioServerTransport();
849
+ await server.connect(transport);
850
+ stderr(`MCP server running (run-pass mode). Tools: ${tools.map((t) => t.name).join(', ')}`);
851
+ }
705
852
  /**
706
853
  * MCP server entrypoint for agent-API-key auth mode (CORBOT-B1D3244C).
707
854
  *
@@ -725,7 +872,7 @@ async function runAgentKeyModeServer(config) {
725
872
  aisUrl: AIS_URL,
726
873
  activityTracker,
727
874
  config,
728
- getHarnessIdentity: () => harnessIdentity,
875
+ getSessionIdentity: () => sessionIdentity,
729
876
  }));
730
877
  const transport = new StdioServerTransport();
731
878
  await server.connect(transport);
@@ -733,6 +880,10 @@ async function runAgentKeyModeServer(config) {
733
880
  }
734
881
  async function main() {
735
882
  // Subcommand dispatch — CLI entrypoints exit before MCP server startup.
883
+ if (process.argv[2] === 'install') {
884
+ (await import('./cli/install.js')).main(process.argv.slice(3));
885
+ return;
886
+ }
736
887
  if (process.argv[2] === 'enable-key-auth') {
737
888
  await import('./cli/enable-key-auth.js');
738
889
  return; // CLI calls process.exit() itself
@@ -749,23 +900,17 @@ async function main() {
749
900
  await (await import('./cli/pull-memory.js')).main(process.argv.slice(3));
750
901
  return;
751
902
  }
752
- if (process.argv[2] === 'install') {
753
- const source = optionValue(process.argv.slice(3), '--manifest');
754
- if (!source)
755
- throw new Error('Usage: aismemory install --manifest <file>');
756
- const pin = installHarnessIdentity(source);
757
- process.stdout.write(`Installed identity pin for ${pin.harness}: ${pin.agentId}. Launch: aismemory --harness ${pin.harness}\nVerify: aismemory doctor --harness ${pin.harness}\n`);
758
- return;
759
- }
760
903
  // CORBOT-7B8A1D16: ask the npm registry, at most about once a day, whether a
761
904
  // newer aismemory has been published. Deliberately not awaited — startup must
762
905
  // not wait on a third-party registry, and the answer is only needed later,
763
906
  // when whoami or full_context is called. Resolves to a skip when offline.
764
907
  void startVersionCheck({ currentVersion: PACKAGE_VERSION, onUpdateAvailable: stderr });
765
- harnessIdentity = loadHarnessIdentity();
766
- const adapterEnv = { ...process.env, AIS_AGENT_ID: harnessIdentity?.agentId };
767
- // Workspace key auth mode (CORBOT-3103ED88) — multi-agent workspace
768
- // credentials. Checked FIRST: workspace key -> agent API key -> device flow.
908
+ sessionIdentity = loadSessionIdentity();
909
+ const adapterEnv = { ...process.env, AIS_AGENT_ID: sessionIdentity?.agentId };
910
+ rejectRunPassWithKeyEnv(adapterEnv);
911
+ // Explicit key auth modes keep their existing order when AIS_RUN_PASS_FILE is
912
+ // unset: workspace key -> agent API key -> device flow. A run pass combined
913
+ // with any key env var is refused above.
769
914
  let workspaceKeyConfig;
770
915
  try {
771
916
  workspaceKeyConfig = loadWorkspaceKeyConfig(adapterEnv);
@@ -800,6 +945,23 @@ async function main() {
800
945
  await runAgentKeyModeServer(agentKeyConfig);
801
946
  return;
802
947
  }
948
+ // Run-pass auth mode (CORBOT-662A4B3A) — short-lived per-run credential
949
+ // written by the launcher. It must not read or require any key env var.
950
+ let runPassConfig;
951
+ try {
952
+ runPassConfig = loadRunPassConfig(adapterEnv);
953
+ }
954
+ catch (err) {
955
+ if (err instanceof RunPassConfigError) {
956
+ stderr(err.message);
957
+ process.exit(1);
958
+ }
959
+ throw err;
960
+ }
961
+ if (runPassConfig) {
962
+ await runPassModeServer(runPassConfig);
963
+ return;
964
+ }
803
965
  // Lazy-auth state. We connect the MCP transport before the user has approved
804
966
  // the device flow so Claude Code's 30s connection timeout is not blocked on
805
967
  // human approval. The first tool call surfaces the bond URL via its result.
@@ -855,7 +1017,7 @@ async function main() {
855
1017
  const claims = decodeJwtClaims(token);
856
1018
  const tenantId = claims.tenantId ?? '';
857
1019
  const resolved = await resolveAgent(token, '', tenantId, loadAgentPreference()?.agentId);
858
- if (!harnessIdentity)
1020
+ if (!sessionIdentity)
859
1021
  saveAgentPreference({ agentId: resolved.agentId, tenantId: resolved.tenantId || tenantId });
860
1022
  return { agentId: resolved.agentId, tenantId: resolved.tenantId || tenantId };
861
1023
  },
@@ -979,7 +1141,7 @@ async function main() {
979
1141
  }
980
1142
  /** Identity hydration, prompt refresh, and auto-handoff — all post-auth. */
981
1143
  async function runPostAuth(credentials) {
982
- const c = { ...credentials, agentId: harnessIdentity?.agentId ?? credentials.agentId };
1144
+ const c = { ...credentials, agentId: sessionIdentity?.agentId ?? credentials.agentId };
983
1145
  // Auto-enroll a DID key so re-auth stays silent after the 7-day bond
984
1146
  // token expires. Without this, key enrollment was a manual opt-in step
985
1147
  // (`enable-key-auth`) and every normal user was re-prompted to bond at
@@ -1007,7 +1169,7 @@ async function main() {
1007
1169
  setupAutoHandoff(AIS_URL, c.agentId, c.token, activityTracker, () => {
1008
1170
  stopRefreshTimer();
1009
1171
  stderr('Session handoff saved');
1010
- }, () => verifyPinnedIdentity(harnessIdentity, c.agentId, () => aisGet(`/v1/agents/${c.agentId}`, c.token)));
1172
+ }, () => verifyPinnedIdentity(sessionIdentity, c.agentId, () => aisGet(`/v1/agents/${c.agentId}`, c.token), { credentialKey: identityCredentialFingerprint('oauth-bearer', c.token) }));
1011
1173
  }
1012
1174
  catch (e) {
1013
1175
  stderr(`Post-auth setup failed: ${e instanceof Error ? e.message : String(e)}`);
@@ -1035,7 +1197,8 @@ async function main() {
1035
1197
  aisUrl: AIS_URL,
1036
1198
  server,
1037
1199
  activityTracker,
1038
- getHarnessIdentity: () => harnessIdentity,
1200
+ getSessionIdentity: () => sessionIdentity,
1201
+ setSessionIdentity: (next) => { sessionIdentity = next; },
1039
1202
  getCredentials: () => creds,
1040
1203
  setCredentials: (next) => { creds = next; },
1041
1204
  setSessionAgentOverride: (next) => { sessionAgentOverride = next; },