@ahpd/agent-claude 0.1.0

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/dist/mcp.js ADDED
@@ -0,0 +1,78 @@
1
+ /** The MCP servers a session runs with, read from the files the CLI reads. */
2
+ import { readFileSync } from 'node:fs';
3
+ import { homedir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ /**
6
+ * Every MCP server configured for a directory, by name.
7
+ *
8
+ * The CLI finds these itself and this host normally leaves it to. It reads
9
+ * them here for one reason: a server the *SDK* was given is one
10
+ * `setMcpServers` can re-declare, and a server that came from a settings file
11
+ * is not - so a token a client signs in with has nowhere to go unless this
12
+ * host owns the declaration. The files are the CLI's own: `.mcp.json` beside
13
+ * the project, and `mcpServers` in `~/.claude.json`.
14
+ *
15
+ * A file that is missing, unreadable or not JSON contributes nothing. This is
16
+ * a best effort by design: the CLI still reads the same files, and a server
17
+ * this misses is a server that works exactly as it did before.
18
+ */
19
+ export function serversFor(directories) {
20
+ const found = {};
21
+ const files = [
22
+ join(homedir(), '.claude.json'),
23
+ ...directories.map((dir) => join(dir, '.mcp.json')),
24
+ ];
25
+ for (const file of files) {
26
+ let held;
27
+ // Synchronous on purpose: these are two small files read once when a
28
+ // session is created, and a backend's `create` answers with a session
29
+ // rather than a promise of one.
30
+ try {
31
+ held = JSON.parse(readFileSync(file, 'utf8'));
32
+ }
33
+ catch {
34
+ continue;
35
+ }
36
+ const bag = typeof held === 'object' && held !== null ? held : {};
37
+ const servers = typeof bag.mcpServers === 'object' && bag.mcpServers !== null ? bag.mcpServers : {};
38
+ for (const [name, config] of Object.entries(servers)) {
39
+ // Later wins: a project's own `.mcp.json` is nearer than the home file,
40
+ // which is the order the CLI resolves them in.
41
+ if (typeof config === 'object' && config !== null)
42
+ found[name] = config;
43
+ }
44
+ }
45
+ return found;
46
+ }
47
+ /** The URL an http or sse server lives at, or nothing for a stdio one. */
48
+ export const urlOf = (config) => {
49
+ const bag = typeof config === 'object' && config !== null ? config : {};
50
+ const url = typeof bag.url === 'string' ? bag.url : undefined;
51
+ if (url === undefined)
52
+ return undefined;
53
+ const kind = typeof bag.type === 'string' ? bag.type : 'http';
54
+ return kind === 'http' || kind === 'sse' ? url : undefined;
55
+ };
56
+ /**
57
+ * What an MCP server says about signing into it, per RFC 9728.
58
+ *
59
+ * `<url>/.well-known/oauth-protected-resource`, which is where an OAuth
60
+ * protected resource publishes its metadata and where a client looks to find
61
+ * the authorization server. Answers the discovered document, or a bare one
62
+ * naming the server itself: the URL *is* the canonical resource identifier,
63
+ * so an incomplete answer is still a true one - what a client loses is the
64
+ * one-click sign-in, not the knowledge that it needs to sign in.
65
+ */
66
+ export async function protectedResource(url, name, ms = 15_000) {
67
+ const bare = { resource: url, resource_name: name };
68
+ const found = new URL(url);
69
+ const at = `${found.origin}/.well-known/oauth-protected-resource${found.pathname.replace(/\/+$/, '')}`;
70
+ const said = await fetch(at, { signal: AbortSignal.timeout(ms) })
71
+ .then((answer) => (answer.ok ? answer.json() : undefined))
72
+ .catch(() => undefined);
73
+ if (typeof said !== 'object' || said === null)
74
+ return bare;
75
+ const metadata = said;
76
+ return typeof metadata.resource === 'string' ? metadata : bare;
77
+ }
78
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Offered } from '@ahpd/server';
2
+ export declare function probe(cwd: string): Promise<Offered>;
3
+ //# sourceMappingURL=probe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probe.d.ts","sourceRoot":"","sources":["../src/probe.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAO,OAAO,EAAE,MAAM,cAAc,CAAC;AA+CjD,wBAAsB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAsDzD"}
package/dist/probe.js ADDED
@@ -0,0 +1,102 @@
1
+ import { query } from '@anthropic-ai/claude-agent-sdk';
2
+ import { customizationsOf, EFFORT_LABELS, EFFORTS } from './session.js';
3
+ /**
4
+ * Reads what the agent backend offers, once, without creating a session.
5
+ *
6
+ * Clients ask `resolveSessionConfig` before creating anything, so the models
7
+ * and commands have to be known before any session exists. This starts one
8
+ * short-lived agent process at startup, asks it over the control protocol,
9
+ * and closes it. No prompt is sent and no transcript is written.
10
+ */
11
+ const bag = (value) => (typeof value === 'object' && value !== null ? value : {});
12
+ const list = (value) => (Array.isArray(value) ? value : []);
13
+ const str = (value) => (typeof value === 'string' ? value : undefined);
14
+ /**
15
+ * How hard *this* model can be told to think, as its own config schema.
16
+ *
17
+ * Per model and not per session, which is the whole point: the CLI reports a
18
+ * different `supportedEffortLevels` for each - some take all five, some take
19
+ * one, and some take none - so a single session-wide effort control offers
20
+ * levels the chosen model may not have, and accepts one it will then ignore.
21
+ * A model that supports none gets no schema and a client draws no control,
22
+ * which is the honest form of "this one does not think harder on request".
23
+ *
24
+ * `thinkingLevel` is the key, because that is the one the reference client's
25
+ * picker writes into `ModelSelection.config` for both of its providers.
26
+ */
27
+ const thinkingFor = (efforts) => {
28
+ if (efforts.length === 0)
29
+ return {};
30
+ return {
31
+ configSchema: {
32
+ type: 'object',
33
+ properties: {
34
+ thinkingLevel: {
35
+ type: 'string',
36
+ title: 'Thinking Level',
37
+ description: 'Controls how much reasoning effort Claude uses.',
38
+ enum: [...efforts],
39
+ enumLabels: efforts.map((one) => EFFORT_LABELS[one] ?? one),
40
+ ...(efforts.includes('high') ? { default: 'high' } : {}),
41
+ },
42
+ },
43
+ },
44
+ };
45
+ };
46
+ export async function probe(cwd) {
47
+ // A prompt that never yields. The query needs one to exist; it does not need
48
+ // one to answer what it can do.
49
+ async function* silence() {
50
+ await new Promise(() => { });
51
+ // eslint-disable-next-line no-unreachable
52
+ return;
53
+ }
54
+ const handle = query({ prompt: silence(), options: { cwd } });
55
+ try {
56
+ const [init, mcp, skills] = await Promise.all([
57
+ handle.initializationResult().then((answer) => bag(answer)),
58
+ // Best effort beside the one that matters: a harness with no MCP servers
59
+ // and one that will not say are the same empty list here, and neither is
60
+ // worth failing the probe over.
61
+ handle.mcpServerStatus().then((answer) => (Array.isArray(answer) ? answer : [])).catch(() => []),
62
+ handle.reloadSkills().then((answer) => list(bag(answer).skills)).catch(() => []),
63
+ ]);
64
+ const styles = list(init.available_output_styles).filter((s) => typeof s === 'string');
65
+ return {
66
+ customizations: customizationsOf(init, mcp, skills),
67
+ // Only when the harness has them. An empty list would draw a picker
68
+ // with nothing in it, which is worse than no control.
69
+ ...(styles.length > 0 ? { outputStyles: styles } : {}),
70
+ ...(str(init.output_style) ? { outputStyle: str(init.output_style) } : {}),
71
+ models: list(init.models)
72
+ // `value`, not `id`.
73
+ .map((raw) => {
74
+ const model = bag(raw);
75
+ return {
76
+ id: str(model.value) ?? '',
77
+ name: str(model.displayName) ?? str(model.value) ?? '',
78
+ ...thinkingFor(list(model.supportedEffortLevels).filter((one) => typeof one === 'string')),
79
+ };
80
+ })
81
+ .filter((model) => model.id !== ''),
82
+ commands: list(init.commands)
83
+ .map((raw) => {
84
+ const command = bag(raw);
85
+ return {
86
+ name: str(command.name) ?? '',
87
+ ...(str(command.description) ? { description: str(command.description) } : {}),
88
+ ...(str(command.argumentHint) ? { argumentHint: str(command.argumentHint) } : {}),
89
+ };
90
+ })
91
+ .filter((command) => command.name !== ''),
92
+ };
93
+ }
94
+ catch {
95
+ // A harness that will not answer offers nothing, which is a real answer.
96
+ return { models: [], commands: [], customizations: [] };
97
+ }
98
+ finally {
99
+ handle.close();
100
+ }
101
+ }
102
+ //# sourceMappingURL=probe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probe.js","sourceRoot":"","sources":["../src/probe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ import type { PermissionMode } from '@anthropic-ai/claude-agent-sdk';
2
+ import type { Bag, Session, SessionOptions } from '@ahpd/server';
3
+ /**
4
+ * The effort levels this backend has, weakest first.
5
+ *
6
+ * One list, because two of them drifted: a model's own `thinkingLevel` form
7
+ * and the session-wide `effortLevel` key are the same five words reaching the
8
+ * same setting, and a client that read one set of labels from one control and
9
+ * another set from the other is being told they are different things.
10
+ */
11
+ export declare const EFFORTS: readonly ["low", "medium", "high", "xhigh", "max"];
12
+ /** What a person reads instead of an effort level. The reference client's words. */
13
+ export declare const EFFORT_LABELS: Record<typeof EFFORTS[number], string>;
14
+ /**
15
+ * RFC 9728 metadata for a server that needs signing in.
16
+ *
17
+ * `resource` is the one field the protocol requires of it - the canonical
18
+ * identifier a client's `authenticate` must name - so it is the one this
19
+ * spells out; the rest is whatever the server published.
20
+ */
21
+ export type Published = Bag & {
22
+ resource: string;
23
+ };
24
+ /**
25
+ * What the session was handed, in the protocol's shape.
26
+ *
27
+ * Eight `CustomizationType`s and one flat list. `disableUserInvocation` is
28
+ * what decides whether a skill or prompt appears after a slash - offering one
29
+ * the host will refuse is worse than not offering it at all.
30
+ *
31
+ * The source is the CLI's *control* protocol, not its message stream:
32
+ * `initializationResult()` and `mcpServerStatus()` answer without a turn
33
+ * having happened. That matters because everything here is what a client
34
+ * needs **before** anybody says anything - the models to pick from, the
35
+ * commands behind a slash. Waiting for the `init` message would mean a
36
+ * composer that can only offer them once the conversation has started, which
37
+ * is exactly too late.
38
+ */
39
+ export declare function customizationsOf(init: Bag, mcp: unknown[], skills?: unknown[], wanted?: Map<string, Published>): Bag[];
40
+ /**
41
+ * A permission mode a client asked for in somebody else's vocabulary.
42
+ *
43
+ * This backend advertises `permissionMode` and its own four values, which is
44
+ * what the protocol asks a backend to do - the config schema is deliberately
45
+ * generic, and VS Code's own hosts advertise different properties for Copilot
46
+ * and for Claude. So the schema stays this harness's.
47
+ *
48
+ * What arrives is another matter. A client draws controls from the schema and
49
+ * *also* dispatches two conventional keys of its own: `autoApprove` (how much
50
+ * may run unasked) and `mode` (how the agent works). VS Code sends both at
51
+ * session creation whatever a host advertises, and this host used to answer
52
+ * `autoApprove is not a config key this backend takes` and leave the session
53
+ * where it was.
54
+ *
55
+ * So they are accepted and mapped here, on the way in, and nothing about what
56
+ * is advertised changes. Planning wins over any approval level - a plan that
57
+ * ran a command would not be a plan - and `autopilot` is the mode axis saying
58
+ * what `autoApprove` says at its top, which is why VS Code's own migration
59
+ * moved `autoApprove: 'autopilot'` onto that axis.
60
+ *
61
+ * `assisted` is the inexact one: VS Code means "assess the risk first" and
62
+ * this harness has no risk model, so it gets `acceptEdits`, which is the rung
63
+ * it does have in that place.
64
+ *
65
+ * Undefined for a key or a value neither axis knows, so a caller refuses it
66
+ * rather than collapsing it into `default`.
67
+ */
68
+ export declare function permissionFor(key: string, value: string): PermissionMode | undefined;
69
+ export declare function createSession(options: SessionOptions): Session;
70
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAIrE,OAAO,KAAK,EAAE,GAAG,EAA6B,OAAO,EAAE,cAAc,EAAY,MAAM,cAAc,CAAC;AAEtG;;;;;;;GAOG;AACH,eAAO,MAAM,OAAO,oDAAqD,CAAC;AAE1E,oFAAoF;AACpF,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,OAAO,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAEhE,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,GAAG,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAsEnD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,MAAM,GAAE,OAAO,EAAO,EAAE,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,GAAG,EAAE,CA4L1H;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAYpF;AAiGD,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAgpE9D"}