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.
- package/LICENSE +21 -0
- package/README.md +59 -0
- package/dist/auden-paths.d.ts +8 -0
- package/dist/auden-paths.d.ts.map +1 -0
- package/dist/auden-paths.js +10 -0
- package/dist/auden-paths.js.map +1 -0
- package/dist/bin.d.ts +11 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +13 -0
- package/dist/bin.js.map +1 -0
- package/dist/chunk.d.ts +3 -0
- package/dist/chunk.d.ts.map +1 -0
- package/dist/chunk.js +13 -0
- package/dist/chunk.js.map +1 -0
- package/dist/commands/doctor.d.ts +13 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +125 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/eval/index.d.ts +2 -0
- package/dist/commands/eval/index.d.ts.map +1 -0
- package/dist/commands/eval/index.js +2 -0
- package/dist/commands/eval/index.js.map +1 -0
- package/dist/commands/eval/run.d.ts +38 -0
- package/dist/commands/eval/run.d.ts.map +1 -0
- package/dist/commands/eval/run.js +179 -0
- package/dist/commands/eval/run.js.map +1 -0
- package/dist/commands/guides/active.d.ts +2 -0
- package/dist/commands/guides/active.d.ts.map +1 -0
- package/dist/commands/guides/active.js +38 -0
- package/dist/commands/guides/active.js.map +1 -0
- package/dist/commands/guides/index.d.ts +2 -0
- package/dist/commands/guides/index.d.ts.map +1 -0
- package/dist/commands/guides/index.js +13 -0
- package/dist/commands/guides/index.js.map +1 -0
- package/dist/commands/guides/project.d.ts +13 -0
- package/dist/commands/guides/project.d.ts.map +1 -0
- package/dist/commands/guides/project.js +71 -0
- package/dist/commands/guides/project.js.map +1 -0
- package/dist/commands/guides/search.d.ts +8 -0
- package/dist/commands/guides/search.d.ts.map +1 -0
- package/dist/commands/guides/search.js +46 -0
- package/dist/commands/guides/search.js.map +1 -0
- package/dist/commands/init.d.ts +43 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +436 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/mcp.d.ts +23 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +55 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/pull.d.ts +38 -0
- package/dist/commands/pull.d.ts.map +1 -0
- package/dist/commands/pull.js +127 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/rules/export.d.ts +140 -0
- package/dist/commands/rules/export.d.ts.map +1 -0
- package/dist/commands/rules/export.js +635 -0
- package/dist/commands/rules/export.js.map +1 -0
- package/dist/commands/rules/import.d.ts +33 -0
- package/dist/commands/rules/import.d.ts.map +1 -0
- package/dist/commands/rules/import.js +122 -0
- package/dist/commands/rules/import.js.map +1 -0
- package/dist/commands/rules/index.d.ts +2 -0
- package/dist/commands/rules/index.d.ts.map +1 -0
- package/dist/commands/rules/index.js +13 -0
- package/dist/commands/rules/index.js.map +1 -0
- package/dist/commands/rules/watch.d.ts +43 -0
- package/dist/commands/rules/watch.d.ts.map +1 -0
- package/dist/commands/rules/watch.js +125 -0
- package/dist/commands/rules/watch.js.map +1 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +61 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/suggest.d.ts +8 -0
- package/dist/commands/suggest.d.ts.map +1 -0
- package/dist/commands/suggest.js +43 -0
- package/dist/commands/suggest.js.map +1 -0
- package/dist/commands/sync.d.ts +23 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +193 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/verdict/index.d.ts +2 -0
- package/dist/commands/verdict/index.d.ts.map +1 -0
- package/dist/commands/verdict/index.js +11 -0
- package/dist/commands/verdict/index.js.map +1 -0
- package/dist/commands/verdict/record.d.ts +18 -0
- package/dist/commands/verdict/record.d.ts.map +1 -0
- package/dist/commands/verdict/record.js +60 -0
- package/dist/commands/verdict/record.js.map +1 -0
- package/dist/config.d.ts +96 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +246 -0
- package/dist/config.js.map +1 -0
- package/dist/context/pull.d.ts +40 -0
- package/dist/context/pull.d.ts.map +1 -0
- package/dist/context/pull.js +46 -0
- package/dist/context/pull.js.map +1 -0
- package/dist/dashboard-health.d.ts +20 -0
- package/dist/dashboard-health.d.ts.map +1 -0
- package/dist/dashboard-health.js +24 -0
- package/dist/dashboard-health.js.map +1 -0
- package/dist/eval-provider.d.ts +30 -0
- package/dist/eval-provider.d.ts.map +1 -0
- package/dist/eval-provider.js +359 -0
- package/dist/eval-provider.js.map +1 -0
- package/dist/eval-summary.d.ts +24 -0
- package/dist/eval-summary.d.ts.map +1 -0
- package/dist/eval-summary.js +30 -0
- package/dist/eval-summary.js.map +1 -0
- package/dist/feedback/extract.d.ts +6 -0
- package/dist/feedback/extract.d.ts.map +1 -0
- package/dist/feedback/extract.js +580 -0
- package/dist/feedback/extract.js.map +1 -0
- package/dist/http-retry.d.ts +23 -0
- package/dist/http-retry.d.ts.map +1 -0
- package/dist/http-retry.js +54 -0
- package/dist/http-retry.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/client.d.ts +70 -0
- package/dist/mcp/client.d.ts.map +1 -0
- package/dist/mcp/client.js +121 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/mcp/scope.d.ts +30 -0
- package/dist/mcp/scope.d.ts.map +1 -0
- package/dist/mcp/scope.js +64 -0
- package/dist/mcp/scope.js.map +1 -0
- package/dist/mcp/server.d.ts +57 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +427 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/write-items.d.ts +34 -0
- package/dist/mcp/write-items.d.ts.map +1 -0
- package/dist/mcp/write-items.js +59 -0
- package/dist/mcp/write-items.js.map +1 -0
- package/dist/rules/deletions-client.d.ts +16 -0
- package/dist/rules/deletions-client.d.ts.map +1 -0
- package/dist/rules/deletions-client.js +40 -0
- package/dist/rules/deletions-client.js.map +1 -0
- package/dist/rules/diff.d.ts +19 -0
- package/dist/rules/diff.d.ts.map +1 -0
- package/dist/rules/diff.js +36 -0
- package/dist/rules/diff.js.map +1 -0
- package/dist/rules/discover.d.ts +81 -0
- package/dist/rules/discover.d.ts.map +1 -0
- package/dist/rules/discover.js +307 -0
- package/dist/rules/discover.js.map +1 -0
- package/dist/rules/file-origin.d.ts +16 -0
- package/dist/rules/file-origin.d.ts.map +1 -0
- package/dist/rules/file-origin.js +31 -0
- package/dist/rules/file-origin.js.map +1 -0
- package/dist/rules/global-flag.d.ts +12 -0
- package/dist/rules/global-flag.d.ts.map +1 -0
- package/dist/rules/global-flag.js +15 -0
- package/dist/rules/global-flag.js.map +1 -0
- package/dist/rules/import-client.d.ts +37 -0
- package/dist/rules/import-client.d.ts.map +1 -0
- package/dist/rules/import-client.js +98 -0
- package/dist/rules/import-client.js.map +1 -0
- package/dist/rules/init-pull.d.ts +34 -0
- package/dist/rules/init-pull.d.ts.map +1 -0
- package/dist/rules/init-pull.js +43 -0
- package/dist/rules/init-pull.js.map +1 -0
- package/dist/rules/member-files-client.d.ts +17 -0
- package/dist/rules/member-files-client.d.ts.map +1 -0
- package/dist/rules/member-files-client.js +29 -0
- package/dist/rules/member-files-client.js.map +1 -0
- package/dist/rules/path-contains.d.ts +9 -0
- package/dist/rules/path-contains.d.ts.map +1 -0
- package/dist/rules/path-contains.js +17 -0
- package/dist/rules/path-contains.js.map +1 -0
- package/dist/rules/payload.d.ts +13 -0
- package/dist/rules/payload.d.ts.map +1 -0
- package/dist/rules/payload.js +35 -0
- package/dist/rules/payload.js.map +1 -0
- package/dist/rules/pull-bundle.d.ts +13 -0
- package/dist/rules/pull-bundle.d.ts.map +1 -0
- package/dist/rules/pull-bundle.js +32 -0
- package/dist/rules/pull-bundle.js.map +1 -0
- package/dist/rules/watch.d.ts +121 -0
- package/dist/rules/watch.d.ts.map +1 -0
- package/dist/rules/watch.js +457 -0
- package/dist/rules/watch.js.map +1 -0
- package/dist/skill-template.d.ts +19 -0
- package/dist/skill-template.d.ts.map +1 -0
- package/dist/skill-template.js +174 -0
- package/dist/skill-template.js.map +1 -0
- package/dist/sync-batches.d.ts +37 -0
- package/dist/sync-batches.d.ts.map +1 -0
- package/dist/sync-batches.js +67 -0
- package/dist/sync-batches.js.map +1 -0
- package/dist/sync-client.d.ts +22 -0
- package/dist/sync-client.d.ts.map +1 -0
- package/dist/sync-client.js +38 -0
- package/dist/sync-client.js.map +1 -0
- package/dist/sync-response.d.ts +23 -0
- package/dist/sync-response.d.ts.map +1 -0
- package/dist/sync-response.js +22 -0
- package/dist/sync-response.js.map +1 -0
- package/dist/token-verify.d.ts +14 -0
- package/dist/token-verify.d.ts.map +1 -0
- package/dist/token-verify.js +30 -0
- package/dist/token-verify.js.map +1 -0
- package/dist/usage/extract.d.ts +31 -0
- package/dist/usage/extract.d.ts.map +1 -0
- package/dist/usage/extract.js +200 -0
- package/dist/usage/extract.js.map +1 -0
- package/dist/usage/providers.d.ts +8 -0
- package/dist/usage/providers.d.ts.map +1 -0
- package/dist/usage/providers.js +23 -0
- package/dist/usage/providers.js.map +1 -0
- package/dist/verdict-queue.d.ts +50 -0
- package/dist/verdict-queue.d.ts.map +1 -0
- package/dist/verdict-queue.js +131 -0
- package/dist/verdict-queue.js.map +1 -0
- 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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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"}
|