auden 0.1.0-alpha.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 (219) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +59 -0
  3. package/dist/auden-paths.d.ts +8 -0
  4. package/dist/auden-paths.d.ts.map +1 -0
  5. package/dist/auden-paths.js +10 -0
  6. package/dist/auden-paths.js.map +1 -0
  7. package/dist/bin.d.ts +11 -0
  8. package/dist/bin.d.ts.map +1 -0
  9. package/dist/bin.js +13 -0
  10. package/dist/bin.js.map +1 -0
  11. package/dist/chunk.d.ts +3 -0
  12. package/dist/chunk.d.ts.map +1 -0
  13. package/dist/chunk.js +13 -0
  14. package/dist/chunk.js.map +1 -0
  15. package/dist/commands/doctor.d.ts +13 -0
  16. package/dist/commands/doctor.d.ts.map +1 -0
  17. package/dist/commands/doctor.js +125 -0
  18. package/dist/commands/doctor.js.map +1 -0
  19. package/dist/commands/eval/index.d.ts +2 -0
  20. package/dist/commands/eval/index.d.ts.map +1 -0
  21. package/dist/commands/eval/index.js +2 -0
  22. package/dist/commands/eval/index.js.map +1 -0
  23. package/dist/commands/eval/run.d.ts +38 -0
  24. package/dist/commands/eval/run.d.ts.map +1 -0
  25. package/dist/commands/eval/run.js +179 -0
  26. package/dist/commands/eval/run.js.map +1 -0
  27. package/dist/commands/guides/active.d.ts +2 -0
  28. package/dist/commands/guides/active.d.ts.map +1 -0
  29. package/dist/commands/guides/active.js +38 -0
  30. package/dist/commands/guides/active.js.map +1 -0
  31. package/dist/commands/guides/index.d.ts +2 -0
  32. package/dist/commands/guides/index.d.ts.map +1 -0
  33. package/dist/commands/guides/index.js +13 -0
  34. package/dist/commands/guides/index.js.map +1 -0
  35. package/dist/commands/guides/project.d.ts +13 -0
  36. package/dist/commands/guides/project.d.ts.map +1 -0
  37. package/dist/commands/guides/project.js +71 -0
  38. package/dist/commands/guides/project.js.map +1 -0
  39. package/dist/commands/guides/search.d.ts +8 -0
  40. package/dist/commands/guides/search.d.ts.map +1 -0
  41. package/dist/commands/guides/search.js +46 -0
  42. package/dist/commands/guides/search.js.map +1 -0
  43. package/dist/commands/init.d.ts +43 -0
  44. package/dist/commands/init.d.ts.map +1 -0
  45. package/dist/commands/init.js +436 -0
  46. package/dist/commands/init.js.map +1 -0
  47. package/dist/commands/mcp.d.ts +23 -0
  48. package/dist/commands/mcp.d.ts.map +1 -0
  49. package/dist/commands/mcp.js +55 -0
  50. package/dist/commands/mcp.js.map +1 -0
  51. package/dist/commands/pull.d.ts +38 -0
  52. package/dist/commands/pull.d.ts.map +1 -0
  53. package/dist/commands/pull.js +127 -0
  54. package/dist/commands/pull.js.map +1 -0
  55. package/dist/commands/rules/export.d.ts +140 -0
  56. package/dist/commands/rules/export.d.ts.map +1 -0
  57. package/dist/commands/rules/export.js +635 -0
  58. package/dist/commands/rules/export.js.map +1 -0
  59. package/dist/commands/rules/import.d.ts +33 -0
  60. package/dist/commands/rules/import.d.ts.map +1 -0
  61. package/dist/commands/rules/import.js +122 -0
  62. package/dist/commands/rules/import.js.map +1 -0
  63. package/dist/commands/rules/index.d.ts +2 -0
  64. package/dist/commands/rules/index.d.ts.map +1 -0
  65. package/dist/commands/rules/index.js +13 -0
  66. package/dist/commands/rules/index.js.map +1 -0
  67. package/dist/commands/rules/watch.d.ts +43 -0
  68. package/dist/commands/rules/watch.d.ts.map +1 -0
  69. package/dist/commands/rules/watch.js +125 -0
  70. package/dist/commands/rules/watch.js.map +1 -0
  71. package/dist/commands/status.d.ts +2 -0
  72. package/dist/commands/status.d.ts.map +1 -0
  73. package/dist/commands/status.js +61 -0
  74. package/dist/commands/status.js.map +1 -0
  75. package/dist/commands/suggest.d.ts +8 -0
  76. package/dist/commands/suggest.d.ts.map +1 -0
  77. package/dist/commands/suggest.js +43 -0
  78. package/dist/commands/suggest.js.map +1 -0
  79. package/dist/commands/sync.d.ts +23 -0
  80. package/dist/commands/sync.d.ts.map +1 -0
  81. package/dist/commands/sync.js +193 -0
  82. package/dist/commands/sync.js.map +1 -0
  83. package/dist/commands/verdict/index.d.ts +2 -0
  84. package/dist/commands/verdict/index.d.ts.map +1 -0
  85. package/dist/commands/verdict/index.js +11 -0
  86. package/dist/commands/verdict/index.js.map +1 -0
  87. package/dist/commands/verdict/record.d.ts +18 -0
  88. package/dist/commands/verdict/record.d.ts.map +1 -0
  89. package/dist/commands/verdict/record.js +60 -0
  90. package/dist/commands/verdict/record.js.map +1 -0
  91. package/dist/config.d.ts +96 -0
  92. package/dist/config.d.ts.map +1 -0
  93. package/dist/config.js +246 -0
  94. package/dist/config.js.map +1 -0
  95. package/dist/context/pull.d.ts +40 -0
  96. package/dist/context/pull.d.ts.map +1 -0
  97. package/dist/context/pull.js +46 -0
  98. package/dist/context/pull.js.map +1 -0
  99. package/dist/dashboard-health.d.ts +20 -0
  100. package/dist/dashboard-health.d.ts.map +1 -0
  101. package/dist/dashboard-health.js +24 -0
  102. package/dist/dashboard-health.js.map +1 -0
  103. package/dist/eval-provider.d.ts +30 -0
  104. package/dist/eval-provider.d.ts.map +1 -0
  105. package/dist/eval-provider.js +359 -0
  106. package/dist/eval-provider.js.map +1 -0
  107. package/dist/eval-summary.d.ts +24 -0
  108. package/dist/eval-summary.d.ts.map +1 -0
  109. package/dist/eval-summary.js +30 -0
  110. package/dist/eval-summary.js.map +1 -0
  111. package/dist/feedback/extract.d.ts +6 -0
  112. package/dist/feedback/extract.d.ts.map +1 -0
  113. package/dist/feedback/extract.js +580 -0
  114. package/dist/feedback/extract.js.map +1 -0
  115. package/dist/http-retry.d.ts +23 -0
  116. package/dist/http-retry.d.ts.map +1 -0
  117. package/dist/http-retry.js +54 -0
  118. package/dist/http-retry.js.map +1 -0
  119. package/dist/index.d.ts +6 -0
  120. package/dist/index.d.ts.map +1 -0
  121. package/dist/index.js +33 -0
  122. package/dist/index.js.map +1 -0
  123. package/dist/mcp/client.d.ts +70 -0
  124. package/dist/mcp/client.d.ts.map +1 -0
  125. package/dist/mcp/client.js +121 -0
  126. package/dist/mcp/client.js.map +1 -0
  127. package/dist/mcp/scope.d.ts +30 -0
  128. package/dist/mcp/scope.d.ts.map +1 -0
  129. package/dist/mcp/scope.js +64 -0
  130. package/dist/mcp/scope.js.map +1 -0
  131. package/dist/mcp/server.d.ts +57 -0
  132. package/dist/mcp/server.d.ts.map +1 -0
  133. package/dist/mcp/server.js +427 -0
  134. package/dist/mcp/server.js.map +1 -0
  135. package/dist/mcp/write-items.d.ts +34 -0
  136. package/dist/mcp/write-items.d.ts.map +1 -0
  137. package/dist/mcp/write-items.js +59 -0
  138. package/dist/mcp/write-items.js.map +1 -0
  139. package/dist/rules/deletions-client.d.ts +16 -0
  140. package/dist/rules/deletions-client.d.ts.map +1 -0
  141. package/dist/rules/deletions-client.js +40 -0
  142. package/dist/rules/deletions-client.js.map +1 -0
  143. package/dist/rules/diff.d.ts +19 -0
  144. package/dist/rules/diff.d.ts.map +1 -0
  145. package/dist/rules/diff.js +36 -0
  146. package/dist/rules/diff.js.map +1 -0
  147. package/dist/rules/discover.d.ts +81 -0
  148. package/dist/rules/discover.d.ts.map +1 -0
  149. package/dist/rules/discover.js +307 -0
  150. package/dist/rules/discover.js.map +1 -0
  151. package/dist/rules/file-origin.d.ts +16 -0
  152. package/dist/rules/file-origin.d.ts.map +1 -0
  153. package/dist/rules/file-origin.js +31 -0
  154. package/dist/rules/file-origin.js.map +1 -0
  155. package/dist/rules/global-flag.d.ts +12 -0
  156. package/dist/rules/global-flag.d.ts.map +1 -0
  157. package/dist/rules/global-flag.js +15 -0
  158. package/dist/rules/global-flag.js.map +1 -0
  159. package/dist/rules/import-client.d.ts +37 -0
  160. package/dist/rules/import-client.d.ts.map +1 -0
  161. package/dist/rules/import-client.js +98 -0
  162. package/dist/rules/import-client.js.map +1 -0
  163. package/dist/rules/init-pull.d.ts +34 -0
  164. package/dist/rules/init-pull.d.ts.map +1 -0
  165. package/dist/rules/init-pull.js +43 -0
  166. package/dist/rules/init-pull.js.map +1 -0
  167. package/dist/rules/member-files-client.d.ts +17 -0
  168. package/dist/rules/member-files-client.d.ts.map +1 -0
  169. package/dist/rules/member-files-client.js +29 -0
  170. package/dist/rules/member-files-client.js.map +1 -0
  171. package/dist/rules/path-contains.d.ts +9 -0
  172. package/dist/rules/path-contains.d.ts.map +1 -0
  173. package/dist/rules/path-contains.js +17 -0
  174. package/dist/rules/path-contains.js.map +1 -0
  175. package/dist/rules/payload.d.ts +13 -0
  176. package/dist/rules/payload.d.ts.map +1 -0
  177. package/dist/rules/payload.js +35 -0
  178. package/dist/rules/payload.js.map +1 -0
  179. package/dist/rules/pull-bundle.d.ts +13 -0
  180. package/dist/rules/pull-bundle.d.ts.map +1 -0
  181. package/dist/rules/pull-bundle.js +32 -0
  182. package/dist/rules/pull-bundle.js.map +1 -0
  183. package/dist/rules/watch.d.ts +121 -0
  184. package/dist/rules/watch.d.ts.map +1 -0
  185. package/dist/rules/watch.js +457 -0
  186. package/dist/rules/watch.js.map +1 -0
  187. package/dist/skill-template.d.ts +19 -0
  188. package/dist/skill-template.d.ts.map +1 -0
  189. package/dist/skill-template.js +174 -0
  190. package/dist/skill-template.js.map +1 -0
  191. package/dist/sync-batches.d.ts +37 -0
  192. package/dist/sync-batches.d.ts.map +1 -0
  193. package/dist/sync-batches.js +67 -0
  194. package/dist/sync-batches.js.map +1 -0
  195. package/dist/sync-client.d.ts +22 -0
  196. package/dist/sync-client.d.ts.map +1 -0
  197. package/dist/sync-client.js +38 -0
  198. package/dist/sync-client.js.map +1 -0
  199. package/dist/sync-response.d.ts +23 -0
  200. package/dist/sync-response.d.ts.map +1 -0
  201. package/dist/sync-response.js +22 -0
  202. package/dist/sync-response.js.map +1 -0
  203. package/dist/token-verify.d.ts +14 -0
  204. package/dist/token-verify.d.ts.map +1 -0
  205. package/dist/token-verify.js +30 -0
  206. package/dist/token-verify.js.map +1 -0
  207. package/dist/usage/extract.d.ts +31 -0
  208. package/dist/usage/extract.d.ts.map +1 -0
  209. package/dist/usage/extract.js +200 -0
  210. package/dist/usage/extract.js.map +1 -0
  211. package/dist/usage/providers.d.ts +8 -0
  212. package/dist/usage/providers.d.ts.map +1 -0
  213. package/dist/usage/providers.js +23 -0
  214. package/dist/usage/providers.js.map +1 -0
  215. package/dist/verdict-queue.d.ts +50 -0
  216. package/dist/verdict-queue.d.ts.map +1 -0
  217. package/dist/verdict-queue.js +131 -0
  218. package/dist/verdict-queue.js.map +1 -0
  219. package/package.json +72 -0
@@ -0,0 +1,54 @@
1
+ const DEFAULT_MAX_ATTEMPTS = 4;
2
+ const DEFAULT_BASE_DELAY_MS = 500;
3
+ const DEFAULT_MAX_DELAY_MS = 8_000;
4
+ function defaultSleep(ms) {
5
+ return new Promise((resolve) => setTimeout(resolve, ms));
6
+ }
7
+ function isRetryableStatus(status) {
8
+ return status >= 500 && status < 600;
9
+ }
10
+ // Full jitter (0-100% of the exponential value) so a fleet of CLIs recovering
11
+ // from a shared outage doesn't all retry in lockstep.
12
+ function backoffDelay(attempt, baseDelayMs, maxDelayMs) {
13
+ const exp = Math.min(maxDelayMs, baseDelayMs * 2 ** (attempt - 1));
14
+ return Math.round(Math.random() * exp);
15
+ }
16
+ /**
17
+ * Fetch with bounded retry + exponential backoff, retrying only on transport
18
+ * failures (network error, timeout) and 5xx responses — a 4xx means the
19
+ * request itself is wrong and retrying it would just fail the same way
20
+ * again. Returns the final `Response` even when it's still non-ok once
21
+ * attempts are exhausted, so the caller's existing `!response.ok` handling
22
+ * keeps working unchanged; re-throws the last transport error if every
23
+ * attempt failed without ever getting a response.
24
+ */
25
+ export async function fetchWithRetry(fetchImpl, url, init, options = {}) {
26
+ const maxAttempts = options.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;
27
+ const baseDelayMs = options.baseDelayMs ?? DEFAULT_BASE_DELAY_MS;
28
+ const maxDelayMs = options.maxDelayMs ?? DEFAULT_MAX_DELAY_MS;
29
+ const sleepFn = options.sleepFn ?? defaultSleep;
30
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
31
+ const isLastAttempt = attempt === maxAttempts;
32
+ let response;
33
+ try {
34
+ response = await fetchImpl(url, init);
35
+ }
36
+ catch (err) {
37
+ if (isLastAttempt)
38
+ throw err;
39
+ const delay = backoffDelay(attempt, baseDelayMs, maxDelayMs);
40
+ options.onRetry?.(attempt, delay, err instanceof Error ? err.message : String(err));
41
+ await sleepFn(delay);
42
+ continue;
43
+ }
44
+ if (response.ok || !isRetryableStatus(response.status) || isLastAttempt) {
45
+ return response;
46
+ }
47
+ const delay = backoffDelay(attempt, baseDelayMs, maxDelayMs);
48
+ options.onRetry?.(attempt, delay, `HTTP ${response.status}`);
49
+ await sleepFn(delay);
50
+ }
51
+ // Unreachable — the loop above always returns or throws by the last attempt.
52
+ throw new Error('fetchWithRetry: exhausted attempts without a result');
53
+ }
54
+ //# sourceMappingURL=http-retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-retry.js","sourceRoot":"","sources":["../src/http-retry.ts"],"names":[],"mappings":"AAaA,MAAM,oBAAoB,GAAG,CAAC,CAAA;AAC9B,MAAM,qBAAqB,GAAG,GAAG,CAAA;AACjC,MAAM,oBAAoB,GAAG,KAAK,CAAA;AAElC,SAAS,YAAY,CAAC,EAAU;IAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;AAC1D,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAc;IACvC,OAAO,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG,CAAA;AACtC,CAAC;AAED,8EAA8E;AAC9E,sDAAsD;AACtD,SAAS,YAAY,CAAC,OAAe,EAAE,WAAmB,EAAE,UAAkB;IAC5E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,WAAW,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAA;IAClE,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAA;AACxC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,SAAuB,EACvB,GAAW,EACX,IAAiB,EACjB,UAAwB,EAAE;IAE1B,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,oBAAoB,CAAA;IAC/D,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,qBAAqB,CAAA;IAChE,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,oBAAoB,CAAA;IAC7D,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,YAAY,CAAA;IAE/C,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;QACxD,MAAM,aAAa,GAAG,OAAO,KAAK,WAAW,CAAA;QAE7C,IAAI,QAAkB,CAAA;QACtB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;QACvC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,aAAa;gBAAE,MAAM,GAAG,CAAA;YAC5B,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,CAAC,CAAA;YAC5D,OAAO,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;YACnF,MAAM,OAAO,CAAC,KAAK,CAAC,CAAA;YACpB,SAAQ;QACV,CAAC;QAED,IAAI,QAAQ,CAAC,EAAE,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,aAAa,EAAE,CAAC;YACxE,OAAO,QAAQ,CAAA;QACjB,CAAC;QAED,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,CAAC,CAAA;QAC5D,OAAO,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;QAC5D,MAAM,OAAO,CAAC,KAAK,CAAC,CAAA;IACtB,CAAC;IAED,6EAA6E;IAC7E,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAA;AACxE,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * index.ts – exports the root citty command so it can be imported
3
+ * by the docs generator and tests without spawning a subprocess.
4
+ */
5
+ export declare const mainCommand: import("citty").CommandDef<import("citty").ArgsDef>;
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAeH,eAAO,MAAM,WAAW,qDAmBtB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * index.ts – exports the root citty command so it can be imported
3
+ * by the docs generator and tests without spawning a subprocess.
4
+ */
5
+ import { createRequire } from 'node:module';
6
+ import { defineCommand } from 'citty';
7
+ // Resolve the version from package.json at runtime so `auden --version`
8
+ // always matches the published version (the release workflow bumps
9
+ // package.json via `npm version`; a hardcoded string here would drift).
10
+ // Works from both src/ (tests) and dist/ (published) — each sits one
11
+ // level below the package root.
12
+ const { version } = createRequire(import.meta.url)('../package.json');
13
+ export const mainCommand = defineCommand({
14
+ meta: {
15
+ name: 'auden',
16
+ version,
17
+ description: 'Auden – on-device AI agent toolkit',
18
+ },
19
+ subCommands: {
20
+ doctor: () => import('./commands/doctor.js').then((m) => m.doctorCommand),
21
+ init: () => import('./commands/init.js').then((m) => m.initCommand),
22
+ eval: () => import('./commands/eval/index.js').then((m) => m.evalCommand),
23
+ guides: () => import('./commands/guides/index.js').then((m) => m.guidesCommand),
24
+ mcp: () => import('./commands/mcp.js').then((m) => m.mcpCommand),
25
+ pull: () => import('./commands/pull.js').then((m) => m.pullCommand),
26
+ rules: () => import('./commands/rules/index.js').then((m) => m.rulesCommand),
27
+ sync: () => import('./commands/sync.js').then((m) => m.syncCommand),
28
+ status: () => import('./commands/status.js').then((m) => m.statusCommand),
29
+ verdict: () => import('./commands/verdict/index.js').then((m) => m.verdictCommand),
30
+ suggest: () => import('./commands/suggest.js').then((m) => m.suggestCommand),
31
+ },
32
+ });
33
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAErC,wEAAwE;AACxE,mEAAmE;AACnE,wEAAwE;AACxE,qEAAqE;AACrE,gCAAgC;AAChC,MAAM,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAEnE,CAAA;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAC;IACvC,IAAI,EAAE;QACJ,IAAI,EAAE,OAAO;QACb,OAAO;QACP,WAAW,EAAE,oCAAoC;KAClD;IACD,WAAW,EAAE;QACX,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;QACzE,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;QACnE,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;QACzE,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,4BAA4B,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;QAC/E,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC;QAChE,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;QACnE,KAAK,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC;QAC5E,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;QACnE,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;QACzE,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,6BAA6B,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC;QAClF,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC;KAC7E;CACF,CAAC,CAAA"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Thin HTTP client for the dashboard's context REST surface
3
+ * (`/api/v1/context/*`). It is the *only* thing the MCP server talks to — the
4
+ * CLI never opens a DB connection (server owns data, CLI owns the machine).
5
+ *
6
+ * Mirrors the error handling of `rules/pull-bundle.ts`: throw on a non-2xx
7
+ * status (with any response detail), on invalid JSON, and on a response whose
8
+ * shape does not match the protocol schema. Every response is validated with
9
+ * the shared `@auden.to/protocol` `parse*` wrapper so a drifting server contract
10
+ * fails loudly instead of feeding an agent malformed data.
11
+ */
12
+ import type { BundleListResponse, ContextItem, ContextItemsResponse, InboxArchiveResponse, InboxListResponse, PushContentType, TransformGrade } from '@auden.to/protocol';
13
+ export type ContextClientConfig = {
14
+ dashboardUrl: string;
15
+ token: string;
16
+ fetchFn?: typeof fetch;
17
+ };
18
+ export type PullContextParams = {
19
+ bundle: string;
20
+ query?: string | undefined;
21
+ types?: string[] | undefined;
22
+ limit?: number | undefined;
23
+ };
24
+ export type PushContextParams = {
25
+ bundle: string;
26
+ name: string;
27
+ contentType: PushContentType;
28
+ content: string;
29
+ /** Present → update the canonical item in place (PUT); absent → create (POST). */
30
+ itemId?: string | undefined;
31
+ origin?: string | undefined;
32
+ /**
33
+ * Optimistic-concurrency precondition for an update (the `version` last read
34
+ * from the item). When it no longer matches the server's current version the
35
+ * PUT is rejected with 409 instead of clobbering a concurrent edit. Update
36
+ * only — ignored on create.
37
+ */
38
+ expectedVersion?: number | undefined;
39
+ /**
40
+ * Ids of the caller-owned context items the pushed document was produced
41
+ * from (create only). When the user's own guidance covers the transform,
42
+ * the server grades it and records the verdict.
43
+ */
44
+ sourceItemIds?: string[] | undefined;
45
+ };
46
+ export type PushContextResult = {
47
+ item: ContextItem;
48
+ /** True when a new item was created, false when an existing one was updated. */
49
+ created: boolean;
50
+ /**
51
+ * The transform grade the server recorded when `sourceItemIds` was sent and
52
+ * grading ran. Absent when no sources were cited or when grading
53
+ * infrastructure couldn't run (no server LLM, over quota, eval failure).
54
+ */
55
+ transform?: TransformGrade | undefined;
56
+ };
57
+ export type ListInboxParams = {
58
+ /** ISO timestamp lower bound (already resolved from any relative window). */
59
+ since?: string | undefined;
60
+ types?: string[] | undefined;
61
+ };
62
+ export type ContextClient = {
63
+ listBundles(): Promise<BundleListResponse>;
64
+ pullContext(params: PullContextParams): Promise<ContextItemsResponse>;
65
+ pushContext(params: PushContextParams): Promise<PushContextResult>;
66
+ listInbox(params: ListInboxParams): Promise<InboxListResponse>;
67
+ archiveInbox(ids: string[]): Promise<InboxArchiveResponse>;
68
+ };
69
+ export declare function createContextClient(config: ContextClientConfig): ContextClient;
70
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/mcp/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH,OAAO,KAAK,EACV,kBAAkB,EAClB,WAAW,EACX,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,eAAe,EACf,cAAc,EACf,MAAM,oBAAoB,CAAA;AAE3B,MAAM,MAAM,mBAAmB,GAAG;IAChC,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,OAAO,KAAK,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAA;IAC5B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC3B,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,eAAe,CAAA;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAA;CACrC,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,WAAW,CAAA;IACjB,gFAAgF;IAChF,OAAO,EAAE,OAAO,CAAA;IAChB;;;;OAIG;IACH,SAAS,CAAC,EAAE,cAAc,GAAG,SAAS,CAAA;CACvC,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAA;CAC7B,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,WAAW,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAAA;IAC1C,WAAW,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAA;IACrE,WAAW,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAA;IAClE,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAA;IAC9D,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAA;CAC3D,CAAA;AAkCD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,aAAa,CA8H9E"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Thin HTTP client for the dashboard's context REST surface
3
+ * (`/api/v1/context/*`). It is the *only* thing the MCP server talks to — the
4
+ * CLI never opens a DB connection (server owns data, CLI owns the machine).
5
+ *
6
+ * Mirrors the error handling of `rules/pull-bundle.ts`: throw on a non-2xx
7
+ * status (with any response detail), on invalid JSON, and on a response whose
8
+ * shape does not match the protocol schema. Every response is validated with
9
+ * the shared `@auden.to/protocol` `parse*` wrapper so a drifting server contract
10
+ * fails loudly instead of feeding an agent malformed data.
11
+ */
12
+ import { parseBundleListResponse, parseContextItemsResponse, parseInboxArchiveResponse, parseInboxListResponse, parsePushContextResponse, parseUpdateContextItemResponse, } from '@auden.to/protocol';
13
+ function joinUrl(base, path) {
14
+ return `${base.replace(/\/+$/, '')}${path}`;
15
+ }
16
+ async function requestJson(fetchFn, url, init, label) {
17
+ const response = await fetchFn(url, init);
18
+ if (!response.ok) {
19
+ const detail = await response.text().catch(() => '');
20
+ throw new Error(`${label} failed with ${response.status}${detail ? `: ${detail}` : ''}`);
21
+ }
22
+ try {
23
+ return await response.json();
24
+ }
25
+ catch {
26
+ throw new Error(`${label} response was not valid JSON.`);
27
+ }
28
+ }
29
+ function parseOrThrow(parse, data, label) {
30
+ try {
31
+ return parse(data);
32
+ }
33
+ catch {
34
+ throw new Error(`${label} response was malformed.`);
35
+ }
36
+ }
37
+ export function createContextClient(config) {
38
+ const fetchFn = config.fetchFn ?? fetch;
39
+ const authHeaders = { Authorization: `Bearer ${config.token}` };
40
+ const jsonHeaders = { ...authHeaders, 'Content-Type': 'application/json' };
41
+ return {
42
+ async listBundles() {
43
+ const data = await requestJson(fetchFn, joinUrl(config.dashboardUrl, '/api/v1/context/bundles'), { headers: authHeaders }, 'List bundles');
44
+ return parseOrThrow(parseBundleListResponse, data, 'List bundles');
45
+ },
46
+ async pullContext(params) {
47
+ const search = new URLSearchParams();
48
+ if (params.types && params.types.length > 0) {
49
+ search.set('types', params.types.join(','));
50
+ }
51
+ if (params.query && params.query.trim() !== '') {
52
+ search.set('query', params.query.trim());
53
+ }
54
+ if (params.limit !== undefined) {
55
+ search.set('limit', String(params.limit));
56
+ }
57
+ const qs = search.toString();
58
+ const path = `/api/v1/context/bundles/${encodeURIComponent(params.bundle)}/items${qs ? `?${qs}` : ''}`;
59
+ const data = await requestJson(fetchFn, joinUrl(config.dashboardUrl, path), { headers: authHeaders }, 'Pull context');
60
+ return parseOrThrow(parseContextItemsResponse, data, 'Pull context');
61
+ },
62
+ async pushContext(params) {
63
+ const path = `/api/v1/context/bundles/${encodeURIComponent(params.bundle)}/items`;
64
+ // Truthiness, not `!== undefined`: an empty `itemId` from a direct caller
65
+ // must not route into the update path and PUT a blank id.
66
+ if (params.itemId) {
67
+ // The PUT body has no sourceItemIds field, so citing sources on an
68
+ // update would be silently dropped (no grade, no error). Fail fast
69
+ // instead — mirrors the server's own 400 on PUT.
70
+ if (params.sourceItemIds) {
71
+ throw new Error('sourceItemIds applies to newly created items — omit itemId to grade a transform.');
72
+ }
73
+ const data = await requestJson(fetchFn, joinUrl(config.dashboardUrl, path), {
74
+ method: 'PUT',
75
+ headers: jsonHeaders,
76
+ body: JSON.stringify({
77
+ itemId: params.itemId,
78
+ name: params.name,
79
+ content: params.content,
80
+ expectedVersion: params.expectedVersion,
81
+ }),
82
+ }, 'Update context');
83
+ const parsed = parseOrThrow(parseUpdateContextItemResponse, data, 'Update context');
84
+ return { item: parsed.item, created: false };
85
+ }
86
+ const data = await requestJson(fetchFn, joinUrl(config.dashboardUrl, path), {
87
+ method: 'POST',
88
+ headers: jsonHeaders,
89
+ body: JSON.stringify({
90
+ name: params.name,
91
+ contentType: params.contentType,
92
+ content: params.content,
93
+ origin: params.origin,
94
+ sourceItemIds: params.sourceItemIds,
95
+ }),
96
+ }, 'Push context');
97
+ return parseOrThrow(parsePushContextResponse, data, 'Push context');
98
+ },
99
+ async listInbox(params) {
100
+ const search = new URLSearchParams();
101
+ if (params.since)
102
+ search.set('since', params.since);
103
+ if (params.types && params.types.length > 0) {
104
+ search.set('types', params.types.join(','));
105
+ }
106
+ const qs = search.toString();
107
+ const path = `/api/v1/context/inbox${qs ? `?${qs}` : ''}`;
108
+ const data = await requestJson(fetchFn, joinUrl(config.dashboardUrl, path), { headers: authHeaders }, 'List inbox');
109
+ return parseOrThrow(parseInboxListResponse, data, 'List inbox');
110
+ },
111
+ async archiveInbox(ids) {
112
+ const data = await requestJson(fetchFn, joinUrl(config.dashboardUrl, '/api/v1/context/inbox/archive'), {
113
+ method: 'POST',
114
+ headers: jsonHeaders,
115
+ body: JSON.stringify({ ids }),
116
+ }, 'Archive inbox');
117
+ return parseOrThrow(parseInboxArchiveResponse, data, 'Archive inbox');
118
+ },
119
+ };
120
+ }
121
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/mcp/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Pure helpers for scoping the `auden mcp` server: resolving the `since`
3
+ * window an agent asks for into an ISO timestamp the REST inbox endpoint
4
+ * understands, and enforcing the local bundle allowlist. Kept free of I/O so
5
+ * they unit-test directly.
6
+ */
7
+ /**
8
+ * Resolve a caller-supplied `since` value into an ISO-8601 timestamp for the
9
+ * `GET /api/v1/context/inbox?since=` query. Accepts either an absolute ISO
10
+ * timestamp (passed through, normalized) or a relative window like `"24h"` /
11
+ * `"7d"` / `"30m"`, resolved against `now`. Returns `undefined` for an empty
12
+ * value (meaning "no lower bound") and throws on anything unparseable so a
13
+ * typo surfaces instead of silently widening the window.
14
+ *
15
+ * `now` is a parameter (not `new Date()`) so the resolution is deterministic
16
+ * and testable.
17
+ */
18
+ export declare function resolveSince(value: string, now: Date): string | undefined;
19
+ /**
20
+ * Parse a `--bundles a,b,c` flag into an allowlist of slugs. Returns `null`
21
+ * (meaning "no restriction") when the flag is empty, so the caller can treat
22
+ * "unset" and "empty" identically.
23
+ */
24
+ export declare function parseBundleAllowlist(raw: string): string[] | null;
25
+ /**
26
+ * True when `slug` may be reached given `allowlist`. A `null` allowlist means
27
+ * unrestricted; otherwise the slug must be listed explicitly.
28
+ */
29
+ export declare function isBundleAllowed(slug: string, allowlist: string[] | null): boolean;
30
+ //# sourceMappingURL=scope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../src/mcp/scope.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,CAmBzE;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAMjE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,GAAG,OAAO,CAGjF"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Pure helpers for scoping the `auden mcp` server: resolving the `since`
3
+ * window an agent asks for into an ISO timestamp the REST inbox endpoint
4
+ * understands, and enforcing the local bundle allowlist. Kept free of I/O so
5
+ * they unit-test directly.
6
+ */
7
+ // A relative window: `<number><unit>` where unit is m(inutes), h(ours), or
8
+ // d(ays). Whitespace between the number and unit is tolerated ("24 h").
9
+ const RELATIVE_WINDOW = /^(\d+)\s*([mhd])$/i;
10
+ const UNIT_MS = {
11
+ m: 60_000,
12
+ h: 3_600_000,
13
+ d: 86_400_000,
14
+ };
15
+ /**
16
+ * Resolve a caller-supplied `since` value into an ISO-8601 timestamp for the
17
+ * `GET /api/v1/context/inbox?since=` query. Accepts either an absolute ISO
18
+ * timestamp (passed through, normalized) or a relative window like `"24h"` /
19
+ * `"7d"` / `"30m"`, resolved against `now`. Returns `undefined` for an empty
20
+ * value (meaning "no lower bound") and throws on anything unparseable so a
21
+ * typo surfaces instead of silently widening the window.
22
+ *
23
+ * `now` is a parameter (not `new Date()`) so the resolution is deterministic
24
+ * and testable.
25
+ */
26
+ export function resolveSince(value, now) {
27
+ const trimmed = value.trim();
28
+ if (!trimmed)
29
+ return undefined;
30
+ const relative = RELATIVE_WINDOW.exec(trimmed);
31
+ if (relative) {
32
+ const amount = Number.parseInt(relative[1], 10);
33
+ const unit = relative[2].toLowerCase();
34
+ return new Date(now.getTime() - amount * UNIT_MS[unit]).toISOString();
35
+ }
36
+ const absolute = new Date(trimmed);
37
+ if (Number.isNaN(absolute.getTime())) {
38
+ throw new Error(`Invalid "since" value: ${JSON.stringify(value)} — use an ISO timestamp ` +
39
+ 'or a relative window like "24h", "7d", or "30m".');
40
+ }
41
+ return absolute.toISOString();
42
+ }
43
+ /**
44
+ * Parse a `--bundles a,b,c` flag into an allowlist of slugs. Returns `null`
45
+ * (meaning "no restriction") when the flag is empty, so the caller can treat
46
+ * "unset" and "empty" identically.
47
+ */
48
+ export function parseBundleAllowlist(raw) {
49
+ const slugs = raw
50
+ .split(',')
51
+ .map((s) => s.trim())
52
+ .filter((s) => s !== '');
53
+ return slugs.length > 0 ? slugs : null;
54
+ }
55
+ /**
56
+ * True when `slug` may be reached given `allowlist`. A `null` allowlist means
57
+ * unrestricted; otherwise the slug must be listed explicitly.
58
+ */
59
+ export function isBundleAllowed(slug, allowlist) {
60
+ if (!allowlist)
61
+ return true;
62
+ return allowlist.includes(slug);
63
+ }
64
+ //# sourceMappingURL=scope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/mcp/scope.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,2EAA2E;AAC3E,wEAAwE;AACxE,MAAM,eAAe,GAAG,oBAAoB,CAAA;AAE5C,MAAM,OAAO,GAA2B;IACtC,CAAC,EAAE,MAAM;IACT,CAAC,EAAE,SAAS;IACZ,CAAC,EAAE,UAAU;CACd,CAAA;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,GAAS;IACnD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAA;IAC5B,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAA;IAE9B,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAC9C,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAA;QAChD,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,CAAA;QACvC,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAE,CAAC,CAAC,WAAW,EAAE,CAAA;IACxE,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAA;IAClC,IAAI,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CACb,0BAA0B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,0BAA0B;YACvE,kDAAkD,CACrD,CAAA;IACH,CAAC;IACD,OAAO,QAAQ,CAAC,WAAW,EAAE,CAAA;AAC/B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAW;IAC9C,MAAM,KAAK,GAAG,GAAG;SACd,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAA;IAC1B,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAA;AACxC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,SAA0B;IACtE,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAA;IAC3B,OAAO,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;AACjC,CAAC"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * The Auden MCP server. Exposes the context layer (`/api/v1/context/*`) to any
3
+ * agent as a small set of tools over stdio (`list_bundles`, `pull_context`,
4
+ * `push_context`, `list_inbox`, `pull_inbox`, `archive_inbox`), so an agent
5
+ * configures it once (in `.mcp.json` / Claude Code / Cursor) instead of wiring
6
+ * each source. The server name (`auden`) namespaces them, so tool names stay
7
+ * bare underscores — dots are outside the Anthropic/Claude Code tool-name charset.
8
+ *
9
+ * Every tool maps 1:1 to a REST route on the dashboard via `ContextClient`. The
10
+ * server acts as the user (it reuses the CLI token) and constrains exposure
11
+ * locally: `readOnly` refuses mutating tools, and `bundles` (an allowlist)
12
+ * limits which bundles are reachable — the "wire once, still scoped" answer.
13
+ *
14
+ * Argument validation is Valibot (never Zod) per repo convention; the low-level
15
+ * `Server` is used precisely so tool input schemas are plain JSON Schema and
16
+ * incoming arguments are validated by our own Valibot schemas rather than the
17
+ * SDK's Zod shapes.
18
+ */
19
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
20
+ import type { ContextClient } from './client.js';
21
+ import type { WriteItemsDeps } from './write-items.js';
22
+ export type McpServerDeps = {
23
+ client: ContextClient;
24
+ /** When true, mutating tools (push_context, archive_inbox) are refused. */
25
+ readOnly: boolean;
26
+ /** Bundle allowlist; null means every bundle the caller owns is reachable. */
27
+ bundles: string[] | null;
28
+ /** Injectable clock so relative `since` windows resolve deterministically. */
29
+ now?: () => Date;
30
+ /** Injectable filesystem for `writeToDir`, for tests. */
31
+ writeDeps?: WriteItemsDeps;
32
+ };
33
+ export type ToolResult = {
34
+ content: {
35
+ type: 'text';
36
+ text: string;
37
+ }[];
38
+ isError?: boolean;
39
+ };
40
+ export type ToolDefinition = {
41
+ name: string;
42
+ description: string;
43
+ inputSchema: Record<string, unknown>;
44
+ handler: (args: unknown) => Promise<ToolResult>;
45
+ };
46
+ /**
47
+ * Build the tool definitions (name, JSON-Schema input, handler). Exposed
48
+ * separately from `createMcpServer` so handlers unit-test directly against a
49
+ * mocked client without a transport.
50
+ */
51
+ export declare function buildTools(deps: McpServerDeps): ToolDefinition[];
52
+ /**
53
+ * Wire the tools into an MCP `Server` with stdio-ready request handlers. The
54
+ * caller connects a transport (`await server.connect(new StdioServerTransport())`).
55
+ */
56
+ export declare function createMcpServer(deps: McpServerDeps): Server;
57
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAQH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAA;AAUlE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEtD,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,aAAa,CAAA;IACrB,2EAA2E;IAC3E,QAAQ,EAAE,OAAO,CAAA;IACjB,8EAA8E;IAC9E,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;IACxB,8EAA8E;IAC9E,GAAG,CAAC,EAAE,MAAM,IAAI,CAAA;IAChB,yDAAyD;IACzD,SAAS,CAAC,EAAE,cAAc,CAAA;CAC3B,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACzC,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACpC,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,UAAU,CAAC,CAAA;CAChD,CAAA;AAoFD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,aAAa,GAAG,cAAc,EAAE,CA0PhE;AAiED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CA0B3D"}