aismemory 0.8.3 → 0.8.4

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 (166) hide show
  1. package/README.md +146 -3
  2. package/dist/__tests__/agent-key-mode.test.js +46 -5
  3. package/dist/__tests__/agent-key-mode.test.js.map +1 -1
  4. package/dist/__tests__/ais-http.test.js +22 -0
  5. package/dist/__tests__/ais-http.test.js.map +1 -1
  6. package/dist/__tests__/auto-enroll-key.test.js +20 -1
  7. package/dist/__tests__/auto-enroll-key.test.js.map +1 -1
  8. package/dist/__tests__/cli-info.test.js +8 -4
  9. package/dist/__tests__/cli-info.test.js.map +1 -1
  10. package/dist/__tests__/client-credential-expiry.test.d.ts +1 -0
  11. package/dist/__tests__/client-credential-expiry.test.js +319 -0
  12. package/dist/__tests__/client-credential-expiry.test.js.map +1 -0
  13. package/dist/__tests__/declared-agent.test.d.ts +1 -0
  14. package/dist/__tests__/declared-agent.test.js +60 -0
  15. package/dist/__tests__/declared-agent.test.js.map +1 -0
  16. package/dist/__tests__/doctor.test.js +21 -2
  17. package/dist/__tests__/doctor.test.js.map +1 -1
  18. package/dist/__tests__/dream-poll.test.d.ts +1 -0
  19. package/dist/__tests__/dream-poll.test.js +130 -0
  20. package/dist/__tests__/dream-poll.test.js.map +1 -0
  21. package/dist/__tests__/enable-key-auth.test.d.ts +1 -0
  22. package/dist/__tests__/enable-key-auth.test.js +180 -0
  23. package/dist/__tests__/enable-key-auth.test.js.map +1 -0
  24. package/dist/__tests__/existing-hashes.test.js +3 -6
  25. package/dist/__tests__/existing-hashes.test.js.map +1 -1
  26. package/dist/__tests__/full-context-view-forwarding.test.js +20 -1
  27. package/dist/__tests__/full-context-view-forwarding.test.js.map +1 -1
  28. package/dist/__tests__/hooks.test.d.ts +1 -0
  29. package/dist/__tests__/hooks.test.js +455 -0
  30. package/dist/__tests__/hooks.test.js.map +1 -0
  31. package/dist/__tests__/hydration.test.js +2 -0
  32. package/dist/__tests__/hydration.test.js.map +1 -1
  33. package/dist/__tests__/install.test.js +28 -1
  34. package/dist/__tests__/install.test.js.map +1 -1
  35. package/dist/__tests__/invite-accept.test.js +167 -3
  36. package/dist/__tests__/invite-accept.test.js.map +1 -1
  37. package/dist/__tests__/list-all-agents.test.js +17 -15
  38. package/dist/__tests__/list-all-agents.test.js.map +1 -1
  39. package/dist/__tests__/mcp-instructions.test.d.ts +1 -0
  40. package/dist/__tests__/mcp-instructions.test.js +26 -0
  41. package/dist/__tests__/mcp-instructions.test.js.map +1 -0
  42. package/dist/__tests__/mcp-tools.test.js +65 -0
  43. package/dist/__tests__/mcp-tools.test.js.map +1 -1
  44. package/dist/__tests__/memory-export.test.d.ts +1 -0
  45. package/dist/__tests__/memory-export.test.js +78 -0
  46. package/dist/__tests__/memory-export.test.js.map +1 -0
  47. package/dist/__tests__/owner-credentials.test.d.ts +1 -0
  48. package/dist/__tests__/owner-credentials.test.js +250 -0
  49. package/dist/__tests__/owner-credentials.test.js.map +1 -0
  50. package/dist/__tests__/owner-keychain-agent-load.test.d.ts +1 -0
  51. package/dist/__tests__/owner-keychain-agent-load.test.js +57 -0
  52. package/dist/__tests__/owner-keychain-agent-load.test.js.map +1 -0
  53. package/dist/__tests__/recall-order-by.test.d.ts +1 -0
  54. package/dist/__tests__/recall-order-by.test.js +115 -0
  55. package/dist/__tests__/recall-order-by.test.js.map +1 -0
  56. package/dist/__tests__/remember-duplicate-truth.test.js +11 -0
  57. package/dist/__tests__/remember-duplicate-truth.test.js.map +1 -1
  58. package/dist/__tests__/resolve-agent-preference.test.js +19 -8
  59. package/dist/__tests__/resolve-agent-preference.test.js.map +1 -1
  60. package/dist/__tests__/signin-keychain.test.d.ts +1 -0
  61. package/dist/__tests__/signin-keychain.test.js +79 -0
  62. package/dist/__tests__/signin-keychain.test.js.map +1 -0
  63. package/dist/__tests__/startup-identity.test.d.ts +1 -0
  64. package/dist/__tests__/startup-identity.test.js +213 -0
  65. package/dist/__tests__/startup-identity.test.js.map +1 -0
  66. package/dist/__tests__/sync-auth.test.d.ts +1 -0
  67. package/dist/__tests__/sync-auth.test.js +69 -0
  68. package/dist/__tests__/sync-auth.test.js.map +1 -0
  69. package/dist/__tests__/sync-doc.test.d.ts +1 -0
  70. package/dist/__tests__/sync-doc.test.js +13 -0
  71. package/dist/__tests__/sync-doc.test.js.map +1 -0
  72. package/dist/__tests__/sync-memory-cli.test.js +1 -1
  73. package/dist/__tests__/sync-memory-cli.test.js.map +1 -1
  74. package/dist/__tests__/tool-args.test.js +6 -0
  75. package/dist/__tests__/tool-args.test.js.map +1 -1
  76. package/dist/agent-key-mode.js +22 -22
  77. package/dist/agent-key-mode.js.map +1 -1
  78. package/dist/agent-preference.d.ts +4 -0
  79. package/dist/agent-preference.js +7 -1
  80. package/dist/agent-preference.js.map +1 -1
  81. package/dist/ais-http-error.d.ts +5 -0
  82. package/dist/ais-http-error.js +10 -0
  83. package/dist/ais-http-error.js.map +1 -1
  84. package/dist/ais-http.js +8 -4
  85. package/dist/ais-http.js.map +1 -1
  86. package/dist/auto-handoff.js +2 -1
  87. package/dist/auto-handoff.js.map +1 -1
  88. package/dist/cli/doctor.d.ts +8 -0
  89. package/dist/cli/doctor.js +19 -0
  90. package/dist/cli/doctor.js.map +1 -1
  91. package/dist/cli/enable-key-auth.js +39 -18
  92. package/dist/cli/enable-key-auth.js.map +1 -1
  93. package/dist/cli/export-harness.d.ts +13 -0
  94. package/dist/cli/export-harness.js +110 -0
  95. package/dist/cli/export-harness.js.map +1 -0
  96. package/dist/cli/hooks.d.ts +62 -0
  97. package/dist/cli/hooks.js +634 -0
  98. package/dist/cli/hooks.js.map +1 -0
  99. package/dist/cli/install.d.ts +4 -0
  100. package/dist/cli/install.js +44 -5
  101. package/dist/cli/install.js.map +1 -1
  102. package/dist/cli/invite-accept.d.ts +36 -1
  103. package/dist/cli/invite-accept.js +135 -1
  104. package/dist/cli/invite-accept.js.map +1 -1
  105. package/dist/cli/owner-credentials.d.ts +52 -0
  106. package/dist/cli/owner-credentials.js +387 -0
  107. package/dist/cli/owner-credentials.js.map +1 -0
  108. package/dist/cli/sync-memory.js +7 -9
  109. package/dist/cli/sync-memory.js.map +1 -1
  110. package/dist/cli-info.js +6 -1
  111. package/dist/cli-info.js.map +1 -1
  112. package/dist/credential-expiry.d.ts +10 -0
  113. package/dist/credential-expiry.js +41 -0
  114. package/dist/credential-expiry.js.map +1 -0
  115. package/dist/declared-agent.d.ts +20 -0
  116. package/dist/declared-agent.js +40 -0
  117. package/dist/declared-agent.js.map +1 -0
  118. package/dist/device-poll.d.ts +1 -0
  119. package/dist/device-poll.js.map +1 -1
  120. package/dist/dream-poll.d.ts +19 -0
  121. package/dist/dream-poll.js +93 -0
  122. package/dist/dream-poll.js.map +1 -0
  123. package/dist/env-agent.d.ts +6 -1
  124. package/dist/env-agent.js +18 -5
  125. package/dist/env-agent.js.map +1 -1
  126. package/dist/hydration.js +2 -1
  127. package/dist/hydration.js.map +1 -1
  128. package/dist/index.js +124 -16
  129. package/dist/index.js.map +1 -1
  130. package/dist/key-auth.d.ts +13 -3
  131. package/dist/key-auth.js +27 -5
  132. package/dist/key-auth.js.map +1 -1
  133. package/dist/mcp/tools.js +37 -20
  134. package/dist/mcp/tools.js.map +1 -1
  135. package/dist/mcp-instructions.d.ts +6 -0
  136. package/dist/mcp-instructions.js +7 -0
  137. package/dist/mcp-instructions.js.map +1 -0
  138. package/dist/memory-export.d.ts +30 -0
  139. package/dist/memory-export.js +116 -0
  140. package/dist/memory-export.js.map +1 -0
  141. package/dist/pipeline/bulk-store.d.ts +2 -5
  142. package/dist/pipeline/bulk-store.js +2 -4
  143. package/dist/pipeline/bulk-store.js.map +1 -1
  144. package/dist/pipeline/existing-hashes.d.ts +2 -5
  145. package/dist/pipeline/existing-hashes.js +1 -2
  146. package/dist/pipeline/existing-hashes.js.map +1 -1
  147. package/dist/pipeline/sync-auth.d.ts +12 -0
  148. package/dist/pipeline/sync-auth.js +64 -0
  149. package/dist/pipeline/sync-auth.js.map +1 -0
  150. package/dist/refresh.js +2 -1
  151. package/dist/refresh.js.map +1 -1
  152. package/dist/run-pass-mode.js +8 -13
  153. package/dist/run-pass-mode.js.map +1 -1
  154. package/dist/signin-keychain.d.ts +54 -0
  155. package/dist/signin-keychain.js +200 -0
  156. package/dist/signin-keychain.js.map +1 -0
  157. package/dist/startup-identity.d.ts +71 -0
  158. package/dist/startup-identity.js +213 -0
  159. package/dist/startup-identity.js.map +1 -0
  160. package/dist/tool-args.d.ts +10 -0
  161. package/dist/tool-args.js +39 -0
  162. package/dist/tool-args.js.map +1 -1
  163. package/dist/types.d.ts +8 -0
  164. package/dist/workspace-key-mode.js +19 -19
  165. package/dist/workspace-key-mode.js.map +1 -1
  166. package/package.json +1 -1
@@ -20,6 +20,7 @@ export declare class DeviceFlowRestartedError extends Error {
20
20
  }
21
21
  export interface PollTokenResponse {
22
22
  access_token?: string;
23
+ refresh_token?: string;
23
24
  expires_in?: number;
24
25
  error?: string;
25
26
  pending_reason?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"device-poll.js","sourceRoot":"","sources":["../src/device-poll.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,gFAAgF;AAChF,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAE5C,+EAA+E;AAC/E,MAAM,OAAO,wBAAyB,SAAQ,KAAK;IAG/B;IACA;IAHT,qBAAqB,GAAG,IAAI,CAAC;IACtC,YACkB,kBAA0B,EAC1B,WAAmB;QAEnC,KAAK,CACH,oDAAoD;YAClD,UAAU,kBAAkB,IAAI;YAChC,SAAS,WAAW,EAAE,CACzB,CAAC;QAPc,uBAAkB,GAAlB,kBAAkB,CAAQ;QAC1B,gBAAW,GAAX,WAAW,CAAQ;QAOnC,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;IACzC,CAAC;CACF;AA4BD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAwB,EACxB,IAAkB;IAElB,MAAM,EACJ,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,KAAK,GAAG,GAAW,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,EAChC,cAAc,GAAG,KAAK,GACvB,GAAG,IAAI,CAAC;IAET,MAAM,QAAQ,GAAG,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,SAAS;IACpD,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;IAEvC,OAAO,KAAK,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC1B,MAAM,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;QAE9D,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,WAAW,CAAC,CAAC;QAEzC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,IAAI,CAAC,KAAK,KAAK,uBAAuB,EAAE,CAAC;YAC3C,sBAAsB;YACtB,MAAM,GAAG,GAAG,KAAK,EAAE,CAAC;YACpB,IAAI,GAAG,GAAG,eAAe,IAAI,qBAAqB,EAAE,CAAC;gBACnD,eAAe,GAAG,GAAG,CAAC;gBACtB,IAAI,IAAI,CAAC,cAAc,KAAK,WAAW,EAAE,CAAC;oBACxC,UAAU,CAAC,kDAAkD,CAAC,CAAC;gBACjE,CAAC;qBAAM,CAAC;oBACN,UAAU,CAAC,yBAAyB,CAAC,CAAC;gBACxC,CAAC;YACH,CAAC;YACD,SAAS;QACX,CAAC;QAED,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YAC/B,MAAM,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;YAC9D,SAAS;QACX,CAAC;QAED,IAAI,IAAI,CAAC,KAAK,KAAK,eAAe,EAAE,CAAC;YACnC,mEAAmE;YACnE,MAAM,OAAO,GAAG,MAAM,YAAY,EAAE,CAAC;YACrC,MAAM,IAAI,wBAAwB,CAChC,OAAO,CAAC,yBAAyB,EACjC,OAAO,CAAC,SAAS,CAClB,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,CAAC,KAAK,KAAK,eAAe,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAClD,CAAC;QAED,sCAAsC;QACtC,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,CAAC,KAAK,IAAI,kBAAkB,EAAE,CAAC,CAAC;IACnF,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;AAC9C,CAAC"}
1
+ {"version":3,"file":"device-poll.js","sourceRoot":"","sources":["../src/device-poll.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,gFAAgF;AAChF,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAE5C,+EAA+E;AAC/E,MAAM,OAAO,wBAAyB,SAAQ,KAAK;IAG/B;IACA;IAHT,qBAAqB,GAAG,IAAI,CAAC;IACtC,YACkB,kBAA0B,EAC1B,WAAmB;QAEnC,KAAK,CACH,oDAAoD;YAClD,UAAU,kBAAkB,IAAI;YAChC,SAAS,WAAW,EAAE,CACzB,CAAC;QAPc,uBAAkB,GAAlB,kBAAkB,CAAQ;QAC1B,gBAAW,GAAX,WAAW,CAAQ;QAOnC,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;IACzC,CAAC;CACF;AA6BD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAwB,EACxB,IAAkB;IAElB,MAAM,EACJ,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,KAAK,GAAG,GAAW,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,EAChC,cAAc,GAAG,KAAK,GACvB,GAAG,IAAI,CAAC;IAET,MAAM,QAAQ,GAAG,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,SAAS;IACpD,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;IAEvC,OAAO,KAAK,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC1B,MAAM,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;QAE9D,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,WAAW,CAAC,CAAC;QAEzC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,IAAI,CAAC,KAAK,KAAK,uBAAuB,EAAE,CAAC;YAC3C,sBAAsB;YACtB,MAAM,GAAG,GAAG,KAAK,EAAE,CAAC;YACpB,IAAI,GAAG,GAAG,eAAe,IAAI,qBAAqB,EAAE,CAAC;gBACnD,eAAe,GAAG,GAAG,CAAC;gBACtB,IAAI,IAAI,CAAC,cAAc,KAAK,WAAW,EAAE,CAAC;oBACxC,UAAU,CAAC,kDAAkD,CAAC,CAAC;gBACjE,CAAC;qBAAM,CAAC;oBACN,UAAU,CAAC,yBAAyB,CAAC,CAAC;gBACxC,CAAC;YACH,CAAC;YACD,SAAS;QACX,CAAC;QAED,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YAC/B,MAAM,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;YAC9D,SAAS;QACX,CAAC;QAED,IAAI,IAAI,CAAC,KAAK,KAAK,eAAe,EAAE,CAAC;YACnC,mEAAmE;YACnE,MAAM,OAAO,GAAG,MAAM,YAAY,EAAE,CAAC;YACrC,MAAM,IAAI,wBAAwB,CAChC,OAAO,CAAC,yBAAyB,EACjC,OAAO,CAAC,SAAS,CAClB,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,CAAC,KAAK,KAAK,eAAe,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAClD,CAAC;QAED,sCAAsC;QACtC,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,CAAC,KAAK,IAAI,kBAAkB,EAAE,CAAC,CAAC;IACnF,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,19 @@
1
+ export declare const DEFAULT_DREAM_POLL_MS = 120000;
2
+ export declare const DEFAULT_DREAM_POLL_INTERVAL_MS = 2000;
3
+ export declare function getDreamPollMs(env?: Record<string, string | undefined>): number;
4
+ export declare function getDreamPollIntervalMs(env?: Record<string, string | undefined>): number;
5
+ export interface DreamPollOptions {
6
+ /** GET /v1/agents/:agentId/dream/:runId through the caller's own auth mode. */
7
+ getStatus: (runId: string) => Promise<unknown>;
8
+ deadlineMs?: number;
9
+ intervalMs?: number;
10
+ sleep?: (ms: number) => Promise<void>;
11
+ now?: () => number;
12
+ }
13
+ /**
14
+ * Resolve a dream POST response. A finished (old synchronous) response is
15
+ * returned untouched. A 202 is polled to completion: completed/partial return
16
+ * {success:true, data:<run>}, failed throws with the server's error text, and
17
+ * a spent deadline returns a non-error "still running" result.
18
+ */
19
+ export declare function resolveDreamResponse(response: unknown, opts: DreamPollOptions): Promise<unknown>;
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Async dream handling (CORBOT-F88FD791). A dream cycle can outlast the 20 s
3
+ * per-request cap, so the server answers POST /dream either with the finished
4
+ * run (200, the original shape) or, when the run is still going, 202 with
5
+ * {runId, status:'running', pollUrl}. This module turns the 202 back into the
6
+ * synchronous result by polling GET /dream/:runId, so callers see one shape.
7
+ *
8
+ * The overall wait is AIS_DREAM_POLL_MS (default 120000) and is separate from
9
+ * AIS_MCP_REQUEST_TIMEOUT_MS: every poll GET still carries the per-request cap.
10
+ */
11
+ import { isAisRequestTimeout, AisRequestTimeoutError } from './request-timeout.js';
12
+ export const DEFAULT_DREAM_POLL_MS = 120_000;
13
+ export const DEFAULT_DREAM_POLL_INTERVAL_MS = 2_000;
14
+ function positiveEnvMs(raw, fallback) {
15
+ const parsed = Number(raw?.trim());
16
+ return raw !== undefined && raw.trim() !== '' && Number.isFinite(parsed) && parsed > 0
17
+ ? parsed
18
+ : fallback;
19
+ }
20
+ export function getDreamPollMs(env = process.env) {
21
+ return positiveEnvMs(env['AIS_DREAM_POLL_MS'], DEFAULT_DREAM_POLL_MS);
22
+ }
23
+ export function getDreamPollIntervalMs(env = process.env) {
24
+ return positiveEnvMs(env['AIS_DREAM_POLL_INTERVAL_MS'], DEFAULT_DREAM_POLL_INTERVAL_MS);
25
+ }
26
+ function asRecord(value) {
27
+ return typeof value === 'object' && value !== null && !Array.isArray(value)
28
+ ? value
29
+ : null;
30
+ }
31
+ /** The accepted-but-unfinished body of a 202, or null for a finished (200) result. */
32
+ function acceptedRun(response) {
33
+ const data = asRecord(asRecord(response)?.['data']);
34
+ if (data === null)
35
+ return null;
36
+ const runId = data['runId'];
37
+ if (data['status'] === 'running' && typeof runId === 'string' && runId !== '') {
38
+ return { runId };
39
+ }
40
+ return null;
41
+ }
42
+ function stillRunning(runId) {
43
+ return {
44
+ success: true,
45
+ data: {
46
+ runId,
47
+ status: 'running',
48
+ message: `Dream run ${runId} is still running on the server; it will finish on its own. ` +
49
+ 'Calling dream again while it is active returns this same run; once it has finished, a new call starts a fresh cycle.',
50
+ },
51
+ };
52
+ }
53
+ /**
54
+ * Resolve a dream POST response. A finished (old synchronous) response is
55
+ * returned untouched. A 202 is polled to completion: completed/partial return
56
+ * {success:true, data:<run>}, failed throws with the server's error text, and
57
+ * a spent deadline returns a non-error "still running" result.
58
+ */
59
+ export async function resolveDreamResponse(response, opts) {
60
+ const accepted = acceptedRun(response);
61
+ if (accepted === null)
62
+ return response;
63
+ const { runId } = accepted;
64
+ const now = opts.now ?? Date.now;
65
+ const sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
66
+ const intervalMs = opts.intervalMs ?? getDreamPollIntervalMs();
67
+ const deadline = now() + (opts.deadlineMs ?? getDreamPollMs());
68
+ while (now() < deadline) {
69
+ await sleep(Math.min(intervalMs, Math.max(0, deadline - now())));
70
+ let status;
71
+ try {
72
+ status = await opts.getStatus(runId);
73
+ }
74
+ catch (err) {
75
+ // A single slow poll is not a failed run; keep waiting until the deadline.
76
+ if (isAisRequestTimeout(err) || err instanceof AisRequestTimeoutError)
77
+ continue;
78
+ throw err;
79
+ }
80
+ const run = asRecord(asRecord(status)?.['data']);
81
+ const state = run?.['status'];
82
+ if (run === null)
83
+ continue;
84
+ if (state === 'completed' || state === 'partial')
85
+ return { success: true, data: run };
86
+ if (state === 'failed') {
87
+ const detail = typeof run['error'] === 'string' && run['error'] !== '' ? run['error'] : 'no error text';
88
+ throw new Error(`Dream run ${runId} failed: ${detail}`);
89
+ }
90
+ }
91
+ return stillRunning(runId);
92
+ }
93
+ //# sourceMappingURL=dream-poll.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dream-poll.js","sourceRoot":"","sources":["../src/dream-poll.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,10 @@ export interface TenantAgentSummary {
8
8
  * Throws with a message suitable for stderr when the id is missing or unknown.
9
9
  */
10
10
  export declare function assertEnvAgentInTenant(envAgentId: string, agents: TenantAgentSummary[]): TenantAgentSummary;
11
+ /** AIS_AGENT_NAME names no agent, or more than one, in the tenant (CORBOT-C1A01EB3). */
12
+ export declare class EnvAgentNameError extends Error {
13
+ constructor(message: string);
14
+ }
11
15
  export interface AgentSelection {
12
16
  agentId: string;
13
17
  reason: 'env-name' | 'preferred' | 'first-active' | 'fallback';
@@ -17,7 +21,8 @@ export interface AgentSelection {
17
21
  /**
18
22
  * Pick which agent this session connects to (CORBOT-B0FA4A79).
19
23
  *
20
- * Priority: AIS_AGENT_NAME match > previously bonded agent > first active >
24
+ * Priority: AIS_AGENT_NAME match (throws EnvAgentNameError on no match or
25
+ * several) > previously bonded agent > first active >
21
26
  * fallback (fresh provisional agent when the tenant has none). The bonded
22
27
  * preference is the load-bearing part: without it, a re-auth reconnected a
23
28
  * multi-agent user to whichever agent the server listed first — a different
package/dist/env-agent.js CHANGED
@@ -11,10 +11,18 @@ export function assertEnvAgentInTenant(envAgentId, agents) {
11
11
  throw new Error(`AIS_AGENT_ID="${envAgentId}" is not a valid agent in this tenant. ` +
12
12
  `Available: ${available || '(none)'}`);
13
13
  }
14
+ /** AIS_AGENT_NAME names no agent, or more than one, in the tenant (CORBOT-C1A01EB3). */
15
+ export class EnvAgentNameError extends Error {
16
+ constructor(message) {
17
+ super(message);
18
+ this.name = 'EnvAgentNameError';
19
+ }
20
+ }
14
21
  /**
15
22
  * Pick which agent this session connects to (CORBOT-B0FA4A79).
16
23
  *
17
- * Priority: AIS_AGENT_NAME match > previously bonded agent > first active >
24
+ * Priority: AIS_AGENT_NAME match (throws EnvAgentNameError on no match or
25
+ * several) > previously bonded agent > first active >
18
26
  * fallback (fresh provisional agent when the tenant has none). The bonded
19
27
  * preference is the load-bearing part: without it, a re-auth reconnected a
20
28
  * multi-agent user to whichever agent the server listed first — a different
@@ -29,11 +37,16 @@ export function selectAgentForSession(opts) {
29
37
  return { agentId: opts.fallbackAgentId, reason: 'fallback', notes };
30
38
  }
31
39
  if (opts.envAgentName) {
32
- const match = opts.agents.find((a) => a.name.toLowerCase() === opts.envAgentName.toLowerCase());
33
- if (match) {
34
- return { agentId: match.id, reason: 'env-name', notes };
40
+ const wanted = opts.envAgentName.toLowerCase();
41
+ const matches = opts.agents.filter((a) => a.name.toLowerCase() === wanted);
42
+ if (matches.length === 1) {
43
+ return { agentId: matches[0].id, reason: 'env-name', notes };
44
+ }
45
+ // An explicit name asks for one identity: never connect as a different agent.
46
+ if (matches.length === 0) {
47
+ throw new EnvAgentNameError(`AIS_AGENT_NAME="${opts.envAgentName}" matches no agent. Available: ${opts.agents.map((a) => a.name).join(', ')}`);
35
48
  }
36
- notes.push(`AIS_AGENT_NAME="${opts.envAgentName}" not found. Available: ${opts.agents.map((a) => a.name).join(', ')}`);
49
+ throw new EnvAgentNameError(`AIS_AGENT_NAME="${opts.envAgentName}" matches ${matches.length} agents (${matches.map((a) => a.id).join(', ')}). Set AIS_AGENT_ID to the one this session should use.`);
37
50
  }
38
51
  if (opts.preferredAgentId) {
39
52
  const match = opts.agents.find((a) => a.id === opts.preferredAgentId);
@@ -1 +1 @@
1
- {"version":3,"file":"env-agent.js","sourceRoot":"","sources":["../src/env-agent.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,UAAkB,EAClB,MAA4B;IAE5B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,UAAU,CAAC,CAAC;IAC9D,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClF,MAAM,IAAI,KAAK,CACb,iBAAiB,UAAU,yCAAyC;QAClE,cAAc,SAAS,IAAI,QAAQ,EAAE,CACxC,CAAC;AACJ,CAAC;AASD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAQrC;IACC,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IACtE,CAAC;IAED,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,YAAa,CAAC,WAAW,EAAE,CAAC,CAAC;QACjG,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;QAC1D,CAAC;QACD,KAAK,CAAC,IAAI,CACR,mBAAmB,IAAI,CAAC,YAAY,2BAA2B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC3G,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACtE,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;QAC3D,CAAC;QACD,KAAK,CAAC,IAAI,CACR,2BAA2B,IAAI,CAAC,gBAAgB,wCAAwC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,EAAE,IAAI,CACzI,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC;AACxE,CAAC"}
1
+ {"version":3,"file":"env-agent.js","sourceRoot":"","sources":["../src/env-agent.ts"],"names":[],"mappings":"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"}
package/dist/hydration.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { getAisRequestTimeoutMs } from './request-timeout.js';
2
+ import { withDeclaredAgent } from './declared-agent.js';
2
3
  const LOG_PREFIX = '[aismemory]';
3
4
  function redactHydrationMessage(message) {
4
5
  return message
@@ -29,7 +30,7 @@ export async function hydrateIdentity(aisUrl, agentId, token, memoriesLimit) {
29
30
  try {
30
31
  const query = memoriesLimit === undefined ? '' : `?memoriesLimit=${memoriesLimit}`;
31
32
  const res = await fetch(`${aisUrl}/v1/agents/${agentId}/full-context${query}`, {
32
- headers: { Authorization: `Bearer ${token}` },
33
+ headers: withDeclaredAgent({ Authorization: `Bearer ${token}` }),
33
34
  signal: AbortSignal.timeout(getAisRequestTimeoutMs()),
34
35
  });
35
36
  if (!res.ok) {
@@ -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
@@ -11,23 +11,25 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
11
11
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
12
12
  import { mkdirSync, writeFileSync } from 'node:fs';
13
13
  import { join } from 'node:path';
14
- import { tryKeyAuth, enrollKeyIfNeeded, hasEnrolledKey } from './key-auth.js';
14
+ import { tryKeyAuth, enrollKeyIfNeeded, formatAutoEnrollFailureStderr, hasEnrolledKey } from './key-auth.js';
15
15
  import { isCredsStale, isNoRegisteredKeysAuthError } from './auth-staleness.js';
16
16
  import { AisHttpError } from './ais-http-error.js';
17
17
  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
- import { loadOAuthCredentials, loadNonStaleDiskBearer, saveOAuthCredentials, } from './oauth-credentials.js';
20
+ import { credentialsFilePath, loadOAuthCredentials, loadNonStaleDiskBearer, saveOAuthCredentials, } from './oauth-credentials.js';
21
21
  import { clearPendingDeviceFlow, isResumableDeviceFlow, loadPendingDeviceFlow, savePendingDeviceFlow, } from './pending-device-flow.js';
22
22
  import { saveAgentPreference, loadAgentPreference, migrateCredentialsFileIfNeeded } from './agent-preference.js';
23
+ import { credentialsFromOwnerKeychain, isSigninKeychainAvailable, ownerUserIdFromAccessToken, requireOwnerKeychainCredentials, saveOwnerSignInToKeychain, } from './signin-keychain.js';
23
24
  import { createTokenManager, isNoRegisteredKeyFailure } from './token-manager.js';
24
25
  import { hydrateIdentity } from './hydration.js';
25
26
  import { assemblePrompt } from './prompt-resource.js';
26
27
  import { startRefreshTimer, stopRefreshTimer } from './refresh.js';
27
28
  import { ActivityTracker, setupAutoHandoff } from './auto-handoff.js';
28
- import { assertEnvAgentInTenant, selectAgentForSession } from './env-agent.js';
29
+ import { assertEnvAgentInTenant, EnvAgentNameError, selectAgentForSession } from './env-agent.js';
29
30
  import { emitTelemetry, hashAgentId } from './telemetry.js';
30
31
  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';
32
+ import { setDeclaredAgentSource } from './declared-agent.js';
31
33
  import { identityCredentialFingerprint, loadSessionIdentity, verifyPinnedIdentity } from './session-identity.js';
32
34
  import { runPollLoop, DeviceFlowRestartedError } from './device-poll.js';
33
35
  import { loadAgentApiKeyConfig, AgentApiKeyConfigError, } from './agent-key-mode.js';
@@ -35,7 +37,9 @@ import { loadWorkspaceKeyConfig, WorkspaceKeyConfigError, } from './workspace-ke
35
37
  import { loadRunPassConfig, RunPassConfigError, } from './run-pass-mode.js';
36
38
  import { createAgentKeyCallToolHandler, createOAuthCallToolHandler, createRunPassCallToolHandler, createWorkspaceKeyCallToolHandler, } from './mcp/tools.js';
37
39
  import { readPackageVersion, startVersionCheck } from './version-check.js';
40
+ import { AIS_MCP_INSTRUCTIONS } from './mcp-instructions.js';
38
41
  import { HUMAN_HOWTO_TEXT, resolveInfoRequest } from './cli-info.js';
42
+ import { describeStartupIdentity, findDuplicateServerNames, formatDuplicateServerWarning, formatStartupIdentityLine, setServerNameConflicts, setStartupIdentity, } from './startup-identity.js';
39
43
  import { AGENT_ARCHIVE_DESCRIPTION, AGENT_ARCHIVE_INPUT_SCHEMA, AGENT_DELETE_ALIAS_DESCRIPTION } from './agent-archive.js';
40
44
  // ── Config ──────────────────────────────────────────────
41
45
  const AIS_URL = process.env['AIS_URL']?.trim() || DEFAULT_AIS_URL;
@@ -52,8 +56,12 @@ function loadCredentials() {
52
56
  // owns the live session and this v1 disk bearer must never be treated
53
57
  // as it (F4) — see the hasEnrolledKey() guard at the bottom of main().
54
58
  migrateCredentialsFileIfNeeded();
59
+ const pref = loadAgentPreference();
60
+ const fromKeychain = pref ? credentialsFromOwnerKeychain(AIS_URL, pref) : null;
61
+ if (fromKeychain)
62
+ return fromKeychain;
55
63
  const data = loadOAuthCredentials();
56
- if (!data)
64
+ if (!data?.token)
57
65
  return null;
58
66
  if (isCredsStale(data.expiresAt, Date.now())) {
59
67
  stderr('Saved credentials expired or expiring soon. Re-authenticating...');
@@ -65,6 +73,23 @@ function loadCredentials() {
65
73
  function stderr(msg) {
66
74
  process.stderr.write(`[aismemory] ${msg}\n`);
67
75
  }
76
+ /**
77
+ * CORBOT-5D16CF2A: one stderr line naming the client version, the agent and
78
+ * where its credential comes from, so version drift and a shadowed config
79
+ * entry are visible at startup. Also kept for whoami. Never prints a value.
80
+ */
81
+ function reportStartupIdentity(input) {
82
+ const identity = describeStartupIdentity(PACKAGE_VERSION, input);
83
+ setStartupIdentity(identity);
84
+ stderr(formatStartupIdentityLine(identity));
85
+ }
86
+ /** CORBOT-5D16CF2A: warn when the launching config defines this server name in several scopes. */
87
+ function reportDuplicateServerNames() {
88
+ const conflicts = findDuplicateServerNames({ home: homedir(), cwd: process.cwd() });
89
+ setServerNameConflicts(conflicts);
90
+ for (const conflict of conflicts)
91
+ stderr(`Warning: ${formatDuplicateServerWarning(conflict)}`);
92
+ }
68
93
  function rejectRunPassWithKeyEnv(env) {
69
94
  if (env['AIS_RUN_PASS_FILE'] === undefined)
70
95
  return;
@@ -195,7 +220,11 @@ async function resolveAgent(token, fallbackAgentId, fallbackTenantId, preferredA
195
220
  }
196
221
  return { agentId: selection.agentId, tenantId: fallbackTenantId };
197
222
  }
198
- catch {
223
+ catch (error) {
224
+ if (error instanceof EnvAgentNameError) {
225
+ stderr(error.message);
226
+ throw error;
227
+ }
199
228
  stderr(`Could not list agents. Using new agent: ${fallbackAgentId}`);
200
229
  return { agentId: fallbackAgentId, tenantId: fallbackTenantId };
201
230
  }
@@ -454,7 +483,35 @@ flowRef) {
454
483
  // a regression versus 0.6.2, which always persisted the token and
455
484
  // reconnected silently. migrateCredentialsFileIfNeeded() (agent-preference.ts)
456
485
  // is what later removes this token from disk, once a key gets enrolled.
457
- if (hasEnrolledKey()) {
486
+ const refreshToken = pollResp.refresh_token;
487
+ const ownerUserId = ownerUserIdFromAccessToken(creds.token);
488
+ const keychainPersisted = !sessionIdentity &&
489
+ typeof refreshToken === 'string' &&
490
+ refreshToken.length > 0 &&
491
+ ownerUserId !== null &&
492
+ isSigninKeychainAvailable();
493
+ if (keychainPersisted) {
494
+ try {
495
+ saveOwnerSignInToKeychain({
496
+ aisUrl: AIS_URL,
497
+ accessToken: creds.token,
498
+ refreshToken,
499
+ expiresAt: creds.expiresAt,
500
+ });
501
+ saveAgentPreference({ agentId: creds.agentId, tenantId: creds.tenantId, ownerUserId });
502
+ }
503
+ catch (err) {
504
+ const message = err instanceof Error ? err.message : String(err);
505
+ stderr(`Could not store owner sign-in in the OS keychain (${message}); saving to disk instead.`);
506
+ if (hasEnrolledKey()) {
507
+ saveAgentPreference({ agentId: creds.agentId, tenantId: creds.tenantId, ownerUserId });
508
+ }
509
+ else {
510
+ saveOAuthCredentials(creds);
511
+ }
512
+ }
513
+ }
514
+ else if (hasEnrolledKey()) {
458
515
  if (!sessionIdentity)
459
516
  saveAgentPreference({ agentId: creds.agentId, tenantId: creds.tenantId });
460
517
  }
@@ -486,6 +543,7 @@ const tools = [
486
543
  type: { type: 'string', enum: ['fact', 'event', 'lesson', 'context', 'goal', 'task'], description: 'Memory type' },
487
544
  importance: { type: 'number', minimum: 0, maximum: 1, description: 'Importance (0-1, default 0.5)' },
488
545
  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.' },
546
+ supersedes: { type: 'string', description: 'Optional: the id of an older memory of yours that this one replaces (e.g. a lesson that turned out wrong). The old memory is kept but no longer returned by recall. Refused if that id is not one of your memories or is already superseded.' },
489
547
  },
490
548
  required: ['content'],
491
549
  },
@@ -495,6 +553,7 @@ const tools = [
495
553
  description: "Search memories by natural language query. Set principalAgentId to search a DIFFERENT " +
496
554
  "agent's memories under a 'memory:read' grant from that agent's owner. " +
497
555
  "Each memory carries createdAt, updatedAt (its last edit), and tags. " +
556
+ "Pass orderBy='newest' with type or tags to get the newest matching memories first. " +
498
557
  "Memories superseded by a newer one are left out; to list or page through every memory, " +
499
558
  "use the REST list route described in the aismemory README (cursor paging, sortBy=updatedAt, includeSuperseded=true)." + BOND_LINK_NOTE,
500
559
  inputSchema: {
@@ -504,6 +563,7 @@ const tools = [
504
563
  limit: { type: 'number', description: 'Max results (default 10)' },
505
564
  type: { type: 'string', enum: ['fact', 'event', 'lesson', 'context', 'goal', 'task'], description: 'Filter by type' },
506
565
  tags: { type: 'array', items: { type: 'string' }, description: 'Only memories carrying ALL of these tags. A hard filter: results are never widened past it.' },
566
+ orderBy: { type: 'string', enum: ['newest'], description: "Set 'newest' to list matching memories newest-first (createdAt descending) instead of ranking by meaning. Use it when you store near-duplicate memories, such as repeated task memories that differ by a counter, and need the latest one first. The query text is not used for ranking, and 'newest' needs type or tags. Default (omitted): ranked search, unchanged." },
507
567
  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." },
508
568
  },
509
569
  required: ['query'],
@@ -554,12 +614,13 @@ const tools = [
554
614
  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.' },
555
615
  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." },
556
616
  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.' },
617
+ contextWindowSize: { type: 'number', description: "Your model's context window in tokens (1000-10000000). The skills budget scales with it; omit for the server default." },
557
618
  },
558
619
  },
559
620
  },
560
621
  {
561
622
  name: 'dream',
562
- description: 'Trigger a memory consolidation dream cycle — promotes important memories and archives old ones. Promotion only scans the session tier; active-tier memories move via context-clear or handoff, not dream.',
623
+ description: 'Trigger a memory consolidation dream cycle — promotes important memories and archives old ones. Promotion only scans the session tier; active-tier memories move via context-clear or handoff, not dream. A long cycle runs server-side; the call waits up to AIS_DREAM_POLL_MS (default 120 s) and, if still running, returns status "running" with the runId — the run keeps going on the server; calling dream again while it is active returns the same runId.',
563
624
  inputSchema: { type: 'object', properties: {} },
564
625
  },
565
626
  {
@@ -807,7 +868,7 @@ async function runWorkspaceKeyModeServer(config) {
807
868
  // Mutable copy so agent_load can switch the active agent.
808
869
  let activeConfig = { ...config };
809
870
  stderr(`Workspace key auth mode — agent starts at ${activeConfig.agentId} (agent_load can switch).`);
810
- const server = new Server({ name: 'aismemory', version: PACKAGE_VERSION }, { capabilities: { tools: {}, prompts: {} } });
871
+ const server = new Server({ name: 'aismemory', version: PACKAGE_VERSION }, { capabilities: { tools: {}, prompts: {} }, instructions: AIS_MCP_INSTRUCTIONS });
811
872
  server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools }));
812
873
  server.setRequestHandler(ListPromptsRequestSchema, async () => ({ prompts: [] }));
813
874
  server.setRequestHandler(GetPromptRequestSchema, async (request) => {
@@ -834,7 +895,7 @@ async function runWorkspaceKeyModeServer(config) {
834
895
  */
835
896
  async function runPassModeServer(config) {
836
897
  stderr(`Run-pass auth mode — agent fixed to ${config.agentId}; pass file ${config.runPassFile}`);
837
- const server = new Server({ name: 'aismemory', version: PACKAGE_VERSION }, { capabilities: { tools: {}, prompts: {} } });
898
+ const server = new Server({ name: 'aismemory', version: PACKAGE_VERSION }, { capabilities: { tools: {}, prompts: {} }, instructions: AIS_MCP_INSTRUCTIONS });
838
899
  server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools }));
839
900
  server.setRequestHandler(ListPromptsRequestSchema, async () => ({ prompts: [] }));
840
901
  server.setRequestHandler(GetPromptRequestSchema, async (request) => {
@@ -863,7 +924,7 @@ async function runPassModeServer(config) {
863
924
  */
864
925
  async function runAgentKeyModeServer(config) {
865
926
  stderr(`Agent API key auth mode — agent fixed to ${config.agentId} (no device flow, no DID key-auth).`);
866
- const server = new Server({ name: 'aismemory', version: PACKAGE_VERSION }, { capabilities: { tools: {}, prompts: {} } });
927
+ const server = new Server({ name: 'aismemory', version: PACKAGE_VERSION }, { capabilities: { tools: {}, prompts: {} }, instructions: AIS_MCP_INSTRUCTIONS });
867
928
  server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools }));
868
929
  server.setRequestHandler(ListPromptsRequestSchema, async () => ({ prompts: [] }));
869
930
  server.setRequestHandler(GetPromptRequestSchema, async (request) => {
@@ -891,6 +952,10 @@ async function main() {
891
952
  (await import('./cli/install.js')).main(process.argv.slice(3));
892
953
  return;
893
954
  }
955
+ if (process.argv[2] === 'hooks') {
956
+ await (await import('./cli/hooks.js')).main(process.argv.slice(3));
957
+ return; // hook commands fail open and set process.exitCode themselves
958
+ }
894
959
  if (process.argv[2] === 'enable-key-auth') {
895
960
  await import('./cli/enable-key-auth.js');
896
961
  return; // CLI calls process.exit() itself
@@ -907,10 +972,19 @@ async function main() {
907
972
  await (await import('./cli/pull-memory.js')).main(process.argv.slice(3));
908
973
  return;
909
974
  }
975
+ if (process.argv[2] === 'export-harness') {
976
+ await (await import('./cli/export-harness.js')).main(process.argv.slice(3));
977
+ return;
978
+ }
910
979
  if (process.argv[2] === 'invite') {
911
980
  await (await import('./cli/invite-accept.js')).runFromCli(process.argv.slice(3));
912
981
  return;
913
982
  }
983
+ const ownerCommand = process.argv[2];
984
+ if (ownerCommand === 'rotate-token' || ownerCommand === 'api-keys' || ownerCommand === 'agents') {
985
+ await (await import('./cli/owner-credentials.js')).runFromCli(ownerCommand, process.argv.slice(3));
986
+ return;
987
+ }
914
988
  // CORBOT-73753A98: a person at a terminal gets a how-to; MCP clients pipe stdin and see nothing new.
915
989
  const humanAtTerminal = process.stdin.isTTY === true;
916
990
  if (humanAtTerminal) {
@@ -921,7 +995,9 @@ async function main() {
921
995
  // not wait on a third-party registry, and the answer is only needed later,
922
996
  // when whoami or full_context is called. Resolves to a skip when offline.
923
997
  void startVersionCheck({ currentVersion: PACKAGE_VERSION, onUpdateAvailable: stderr });
998
+ reportDuplicateServerNames();
924
999
  sessionIdentity = loadSessionIdentity();
1000
+ setDeclaredAgentSource(() => sessionIdentity?.agentId);
925
1001
  const adapterEnv = { ...process.env, AIS_AGENT_ID: sessionIdentity?.agentId };
926
1002
  rejectRunPassWithKeyEnv(adapterEnv);
927
1003
  // Explicit key auth modes keep their existing order when AIS_RUN_PASS_FILE is
@@ -939,6 +1015,7 @@ async function main() {
939
1015
  throw err;
940
1016
  }
941
1017
  if (workspaceKeyConfig) {
1018
+ reportStartupIdentity({ kind: 'workspace-key', env: adapterEnv, agentId: workspaceKeyConfig.agentId });
942
1019
  await runWorkspaceKeyModeServer(workspaceKeyConfig);
943
1020
  return;
944
1021
  }
@@ -958,6 +1035,7 @@ async function main() {
958
1035
  throw err;
959
1036
  }
960
1037
  if (agentKeyConfig) {
1038
+ reportStartupIdentity({ kind: 'agent-api-key', env: adapterEnv, agentId: agentKeyConfig.agentId });
961
1039
  await runAgentKeyModeServer(agentKeyConfig);
962
1040
  return;
963
1041
  }
@@ -975,6 +1053,7 @@ async function main() {
975
1053
  throw err;
976
1054
  }
977
1055
  if (runPassConfig) {
1056
+ reportStartupIdentity({ kind: 'run-pass', runPassFile: runPassConfig.runPassFile, agentId: runPassConfig.agentId });
978
1057
  await runPassModeServer(runPassConfig);
979
1058
  return;
980
1059
  }
@@ -987,6 +1066,17 @@ async function main() {
987
1066
  // 401s NO_REGISTERED_KEYS but this bearer still works for REST memory.
988
1067
  const diskBearerFallback = loadNonStaleDiskBearer();
989
1068
  let creds = loadCredentials();
1069
+ const keyEnrolledAtStartup = hasEnrolledKey();
1070
+ const startupPreference = loadAgentPreference();
1071
+ reportStartupIdentity({
1072
+ kind: 'oauth',
1073
+ ...(sessionIdentity ? { sessionAgentId: sessionIdentity.agentId } : {}),
1074
+ enrolledKeyDir: keyEnrolledAtStartup ? join(homedir(), '.aismemory', 'keys') : null,
1075
+ diskAgentId: creds?.agentId ?? null,
1076
+ credentialsFile: credentialsFilePath(),
1077
+ ...(keyEnrolledAtStartup ? { preferredAgentId: startupPreference?.agentId } : {}),
1078
+ ...(startupPreference?.ownerUserId ? { keychainOwnerSession: true } : {}),
1079
+ });
990
1080
  let activeFlow = null;
991
1081
  let postAuthDone = false;
992
1082
  // Fires the auth.key.success telemetry event + the one-line stderr
@@ -1032,9 +1122,15 @@ async function main() {
1032
1122
  resolveIdentity: async (token) => {
1033
1123
  const claims = decodeJwtClaims(token);
1034
1124
  const tenantId = claims.tenantId ?? '';
1035
- const resolved = await resolveAgent(token, '', tenantId, loadAgentPreference()?.agentId);
1036
- if (!sessionIdentity)
1037
- saveAgentPreference({ agentId: resolved.agentId, tenantId: resolved.tenantId || tenantId });
1125
+ const pref = loadAgentPreference();
1126
+ const resolved = await resolveAgent(token, '', tenantId, pref?.agentId);
1127
+ if (!sessionIdentity) {
1128
+ saveAgentPreference({
1129
+ agentId: resolved.agentId,
1130
+ tenantId: resolved.tenantId || tenantId,
1131
+ ...(pref?.ownerUserId ? { ownerUserId: pref.ownerUserId } : {}),
1132
+ });
1133
+ }
1038
1134
  return { agentId: resolved.agentId, tenantId: resolved.tenantId || tenantId };
1039
1135
  },
1040
1136
  onEvent: (event, detail) => {
@@ -1046,7 +1142,7 @@ async function main() {
1046
1142
  },
1047
1143
  });
1048
1144
  // Created here so `agent_load` and post-auth setup can reference it via closure.
1049
- const server = new Server({ name: 'aismemory', version: PACKAGE_VERSION }, { capabilities: { tools: {}, prompts: {} } });
1145
+ const server = new Server({ name: 'aismemory', version: PACKAGE_VERSION }, { capabilities: { tools: {}, prompts: {} }, instructions: AIS_MCP_INSTRUCTIONS });
1050
1146
  /**
1051
1147
  * Wait briefly for the in-flight device-flow poll to complete. If the user
1052
1148
  * has already approved, this returns the fresh credentials. If not, throws
@@ -1058,6 +1154,18 @@ async function main() {
1058
1154
  * the next tool call without having to restart the MCP process.
1059
1155
  */
1060
1156
  async function ensureCredentials(softTimeoutMs = 7000) {
1157
+ // CORBOT-EBCB2D2B: owner terminal sign-in uses the workspace credential
1158
+ // in the OS keychain (not the DID key or a stale disk bearer) so
1159
+ // agent_load can resolve agents by name via GET /v1/resolve.
1160
+ const ownerPref = loadAgentPreference();
1161
+ if (ownerPref?.ownerUserId) {
1162
+ creds = requireOwnerKeychainCredentials(AIS_URL, ownerPref, sessionAgentOverride?.agentId);
1163
+ if (!postAuthDone) {
1164
+ postAuthDone = true;
1165
+ void runPostAuth(creds);
1166
+ }
1167
+ return creds;
1168
+ }
1061
1169
  // ── Key-enrolled path: all auth flows through the TokenManager ────────
1062
1170
  // The manager owns authenticate + background renewal + backoff; on a
1063
1171
  // sustained AIS outage it rejects with AisUnreachableError, which we let
@@ -1168,8 +1276,8 @@ async function main() {
1168
1276
  stderr('DID key enrolled — future sessions re-authenticate silently (no re-bond)');
1169
1277
  emitTelemetry({ event: 'auth.key.autoenroll', agentIdHash: hashAgentId(c.agentId), status: 'ok' });
1170
1278
  }
1171
- else if (enroll.reason.startsWith('register-failed')) {
1172
- stderr(`DID key auto-enroll failed (will retry next session): ${enroll.reason}`);
1279
+ else if (enroll.reason.startsWith('register-failed') || enroll.reason.startsWith('register-refused')) {
1280
+ stderr(formatAutoEnrollFailureStderr(enroll.reason));
1173
1281
  emitTelemetry({ event: 'auth.key.autoenroll', agentIdHash: hashAgentId(c.agentId), status: 'error', error: enroll.reason });
1174
1282
  }
1175
1283
  try {