@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/LICENSE +21 -0
- package/README.md +56 -0
- package/dist/catalog.d.ts +19 -0
- package/dist/catalog.d.ts.map +1 -0
- package/dist/catalog.js +28 -0
- package/dist/catalog.js.map +1 -0
- package/dist/claude.d.ts +28 -0
- package/dist/claude.d.ts.map +1 -0
- package/dist/claude.js +311 -0
- package/dist/claude.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp.d.ts +31 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +78 -0
- package/dist/mcp.js.map +1 -0
- package/dist/probe.d.ts +3 -0
- package/dist/probe.d.ts.map +1 -0
- package/dist/probe.js +102 -0
- package/dist/probe.js.map +1 -0
- package/dist/session.d.ts +70 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +2582 -0
- package/dist/session.js.map +1 -0
- package/dist/transcript.d.ts +11 -0
- package/dist/transcript.d.ts.map +1 -0
- package/dist/transcript.js +214 -0
- package/dist/transcript.js.map +1 -0
- package/package.json +64 -0
- package/src/catalog.ts +29 -0
- package/src/claude.ts +353 -0
- package/src/index.ts +21 -0
- package/src/mcp.ts +75 -0
- package/src/probe.ts +104 -0
- package/src/session.ts +2635 -0
- package/src/transcript.ts +217 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Luiz Fernando Softov <lfs@softov.dev>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# @ahpd/agent-claude
|
|
2
|
+
|
|
3
|
+
The Claude backend for [`@ahpd/server`](https://www.npmjs.com/package/@ahpd/server).
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @ahpd/agent-claude @ahpd/server @microsoft/agent-host-protocol
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Use
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { createHost, listen } from '@ahpd/server';
|
|
15
|
+
import { claude } from '@ahpd/agent-claude';
|
|
16
|
+
|
|
17
|
+
const path = process.cwd();
|
|
18
|
+
const host = createHost({ path, agents: [claude({ paths: [path] })] });
|
|
19
|
+
await listen({ port: 9187 }, (peer) => host.accept(peer));
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
`createHost` takes a list of agents, so this can run alongside other backends.
|
|
23
|
+
|
|
24
|
+
## What it does
|
|
25
|
+
|
|
26
|
+
It starts the [Claude agent SDK](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk), converts its message stream into AHP state actions, and reads Claude's transcript files.
|
|
27
|
+
|
|
28
|
+
| export | |
|
|
29
|
+
| --- | --- |
|
|
30
|
+
| `claude(options)` | the `Agent` to pass to `createHost` |
|
|
31
|
+
| `createSession(options)` | one live session |
|
|
32
|
+
| `catalogue(dir)` | Claude's sessions in a directory, as rows a host can list |
|
|
33
|
+
| `turnsOf(sessionId, dir)` | a past session read from its transcript, as turns |
|
|
34
|
+
| `probe(options)` | runs a CLI at startup to read the available models and commands |
|
|
35
|
+
|
|
36
|
+
## Supported
|
|
37
|
+
|
|
38
|
+
Turns and streaming, tool calls and approvals, questions from the agent, model and effort selection, permission modes, MCP servers and OAuth sign-in, skills and slash commands, multiple chats per session, forking a chat from a turn, truncating a chat back to a turn, session titles, token usage, and context compaction.
|
|
39
|
+
|
|
40
|
+
Sessions the host is not running are read from Claude's transcripts, so clients can browse and read them without starting a process. The agent starts when a turn is sent.
|
|
41
|
+
|
|
42
|
+
## Credentials
|
|
43
|
+
|
|
44
|
+
Sessions use whatever the Claude CLI is signed in with. A client can push a token instead. Pushed tokens are held per connection and are not used for other clients' sessions.
|
|
45
|
+
|
|
46
|
+
## Documentation
|
|
47
|
+
|
|
48
|
+
| | |
|
|
49
|
+
| --- | --- |
|
|
50
|
+
| [AGENT.md](https://github.com/softov/ahpd/blob/main/docs/AGENT.md) | The `Agent` and `Session` contracts this implements |
|
|
51
|
+
| [AHP.md](https://github.com/softov/ahpd/blob/main/docs/AHP.md) | Which actions are served, which are refused, and why |
|
|
52
|
+
|
|
53
|
+
## License
|
|
54
|
+
|
|
55
|
+
MIT © Softov
|
|
56
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Listed } from '@ahpd/server';
|
|
2
|
+
/**
|
|
3
|
+
* Claude's own sessions, as rows a host can list.
|
|
4
|
+
*
|
|
5
|
+
* Renames the SDK's session listing into `Listed`. The SDK is the authority on
|
|
6
|
+
* which sessions exist; this module only maps the fields - which is why it is
|
|
7
|
+
* here and not beside the URI helpers in `@ahpd/server`: a host serving some
|
|
8
|
+
* other harness has a different answer to the same question, and no reason to
|
|
9
|
+
* load this one to find that out.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* What this backend is a catalogue *of*.
|
|
13
|
+
*
|
|
14
|
+
* `dir`, not `cwd` - the option that scopes a listing to one project is spelled
|
|
15
|
+
* `dir`, and an unrecognised key is ignored rather than refused, so the wrong
|
|
16
|
+
* spelling answers with every session on the machine and looks like it worked.
|
|
17
|
+
*/
|
|
18
|
+
export declare function catalogue(dir: string): Promise<Listed[]>;
|
|
19
|
+
//# sourceMappingURL=catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C;;;;;;;;GAQG;AACH;;;;;;GAMG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAS9D"}
|
package/dist/catalog.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { listSessions } from '@anthropic-ai/claude-agent-sdk';
|
|
2
|
+
/**
|
|
3
|
+
* Claude's own sessions, as rows a host can list.
|
|
4
|
+
*
|
|
5
|
+
* Renames the SDK's session listing into `Listed`. The SDK is the authority on
|
|
6
|
+
* which sessions exist; this module only maps the fields - which is why it is
|
|
7
|
+
* here and not beside the URI helpers in `@ahpd/server`: a host serving some
|
|
8
|
+
* other harness has a different answer to the same question, and no reason to
|
|
9
|
+
* load this one to find that out.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* What this backend is a catalogue *of*.
|
|
13
|
+
*
|
|
14
|
+
* `dir`, not `cwd` - the option that scopes a listing to one project is spelled
|
|
15
|
+
* `dir`, and an unrecognised key is ignored rather than refused, so the wrong
|
|
16
|
+
* spelling answers with every session on the machine and looks like it worked.
|
|
17
|
+
*/
|
|
18
|
+
export async function catalogue(dir) {
|
|
19
|
+
const found = await listSessions({ dir });
|
|
20
|
+
return found.map((info) => ({
|
|
21
|
+
id: info.sessionId,
|
|
22
|
+
title: info.customTitle ?? info.summary ?? info.firstPrompt ?? 'Session',
|
|
23
|
+
createdAt: new Date(info.createdAt ?? info.lastModified).toISOString(),
|
|
24
|
+
modifiedAt: new Date(info.lastModified).toISOString(),
|
|
25
|
+
workingDirectories: [`file://${info.cwd ?? dir}`],
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAG9D;;;;;;;;GAQG;AACH;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAW;IACzC,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IAC1C,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC1B,EAAE,EAAE,IAAI,CAAC,SAAS;QAClB,KAAK,EAAE,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,WAAW,IAAI,SAAS;QACxE,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE;QACtE,UAAU,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE;QACrD,kBAAkB,EAAE,CAAC,UAAU,IAAI,CAAC,GAAG,IAAI,GAAG,EAAE,CAAC;KAClD,CAAC,CAAC,CAAC;AACN,CAAC"}
|
package/dist/claude.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Agent } from '@ahpd/server';
|
|
2
|
+
/**
|
|
3
|
+
* Claude Code, as an agent backend.
|
|
4
|
+
*
|
|
5
|
+
* Everything the host would otherwise have to know about one particular
|
|
6
|
+
* harness: which settings it takes, where its past sessions are kept, and how
|
|
7
|
+
* to start one. The host asks through `Agent` and imports none of this.
|
|
8
|
+
*/
|
|
9
|
+
/** How to build the Claude backend. */
|
|
10
|
+
export interface ClaudeOptions {
|
|
11
|
+
/**
|
|
12
|
+
* The directories it will work in, and the ones it lists.
|
|
13
|
+
*
|
|
14
|
+
* The first is where a session goes when the client names none. A client
|
|
15
|
+
* may name any of the others and nothing else: a host that ran the agent
|
|
16
|
+
* wherever it was told is one anybody who can reach the port can point at
|
|
17
|
+
* any directory on the machine.
|
|
18
|
+
*
|
|
19
|
+
* This is also the catalogue's scope, so a directory left out is one whose
|
|
20
|
+
* sessions are neither listed nor openable.
|
|
21
|
+
*/
|
|
22
|
+
paths: string[];
|
|
23
|
+
/** The id clients name. `claude` unless something else already is. */
|
|
24
|
+
provider?: string;
|
|
25
|
+
}
|
|
26
|
+
/** Claude Code on one or more directories, ready to be handed to `createHost`. */
|
|
27
|
+
export declare function claude(options: ClaudeOptions): Agent;
|
|
28
|
+
//# sourceMappingURL=claude.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../src/claude.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,KAAK,EAAc,MAAM,cAAc,CAAC;AAYtD;;;;;;GAMG;AAEH,uCAAuC;AACvC,MAAM,WAAW,aAAa;IAC5B;;;;;;;;;;OAUG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,kFAAkF;AAClF,wBAAgB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,KAAK,CAmTpD"}
|
package/dist/claude.js
ADDED
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import { probe } from './probe.js';
|
|
2
|
+
import { serversFor } from './mcp.js';
|
|
3
|
+
import { createSession, EFFORT_LABELS, EFFORTS } from './session.js';
|
|
4
|
+
import { turnsOf } from './transcript.js';
|
|
5
|
+
import { catalogue } from './catalog.js';
|
|
6
|
+
import { within } from '@ahpd/server';
|
|
7
|
+
/**
|
|
8
|
+
* The resource a token for this backend is for.
|
|
9
|
+
*
|
|
10
|
+
* Named once, because it is the identifier a client must send back verbatim:
|
|
11
|
+
* the protocol says `authenticate`'s `resource` MUST match one the server
|
|
12
|
+
* advertised, so this string appearing twice with a typo between them is a
|
|
13
|
+
* token nothing will accept.
|
|
14
|
+
*/
|
|
15
|
+
const ANTHROPIC = 'https://api.anthropic.com';
|
|
16
|
+
/** Claude Code on one or more directories, ready to be handed to `createHost`. */
|
|
17
|
+
export function claude(options) {
|
|
18
|
+
const dirs = options.paths;
|
|
19
|
+
const dir = dirs[0];
|
|
20
|
+
if (dir === undefined)
|
|
21
|
+
throw new Error('claude() needs at least one directory to work in.');
|
|
22
|
+
/**
|
|
23
|
+
* Which directory a session goes in.
|
|
24
|
+
*
|
|
25
|
+
* Named, or the first. Anything else is refused rather than quietly
|
|
26
|
+
* replaced - a directory accepted and then ignored is a session running
|
|
27
|
+
* somewhere nobody asked for, with nothing on screen to say so.
|
|
28
|
+
*/
|
|
29
|
+
const workingDirectory = (asked) => {
|
|
30
|
+
if (asked === undefined)
|
|
31
|
+
return dir;
|
|
32
|
+
/*
|
|
33
|
+
* Under a served directory, not equal to one.
|
|
34
|
+
*
|
|
35
|
+
* This compared for equality, so a host told to serve `/home/you` served
|
|
36
|
+
* that one directory and refused every project inside it - which is the
|
|
37
|
+
* only kind of directory anybody opens. An editor asks for its workspace
|
|
38
|
+
* folder, and that is never the path somebody passed to `--path`.
|
|
39
|
+
*/
|
|
40
|
+
if (!dirs.some((served) => within(served, asked))) {
|
|
41
|
+
throw new Error(`This host does not serve ${asked}. It serves ${dirs.join(', ')}.`);
|
|
42
|
+
}
|
|
43
|
+
// What was asked for, not the root it sits under: the session runs where
|
|
44
|
+
// the client said.
|
|
45
|
+
return asked;
|
|
46
|
+
};
|
|
47
|
+
/*
|
|
48
|
+
* What the probe learned about output styles.
|
|
49
|
+
*
|
|
50
|
+
* The schema is otherwise fixed, but this one property's choices belong to
|
|
51
|
+
* the harness rather than to the protocol - a person's own styles live in
|
|
52
|
+
* their settings - so it is learned once at startup, the way models are,
|
|
53
|
+
* and the control is simply absent until it is known.
|
|
54
|
+
*/
|
|
55
|
+
let styles = [];
|
|
56
|
+
/**
|
|
57
|
+
* Whether the models this harness offers carry effort controls of their own.
|
|
58
|
+
*
|
|
59
|
+
* A model's `configSchema` and the session-wide `effortLevel` reach the same
|
|
60
|
+
* setting, and a client draws both - so a person is shown two effort
|
|
61
|
+
* controls, on two different values, for one thing. The model's is the
|
|
62
|
+
* truthful one: it lists what that model actually supports, where the
|
|
63
|
+
* session-wide key lists all five whatever is chosen. So this backend offers
|
|
64
|
+
* the session key only while there is nothing better.
|
|
65
|
+
*/
|
|
66
|
+
let perModelEffort = false;
|
|
67
|
+
let style;
|
|
68
|
+
/**
|
|
69
|
+
* What a session can be told to do differently.
|
|
70
|
+
*
|
|
71
|
+
* One schema, used by `resolveSessionConfig` (before a session exists) and
|
|
72
|
+
* by every session's own state (after one does). Two copies would drift, and
|
|
73
|
+
* the composer would offer one set of controls on the new-session screen and
|
|
74
|
+
* a different set the moment a session opened.
|
|
75
|
+
*
|
|
76
|
+
* `sessionMutable` is what each row turns on: the permission mode, the model
|
|
77
|
+
* and the effort level are things the CLI takes on a *running* session.
|
|
78
|
+
* `thinking` is fixed when the query is built, so offering it live would be
|
|
79
|
+
* a switch that flips back.
|
|
80
|
+
*/
|
|
81
|
+
const schema = () => ({
|
|
82
|
+
// A JSON Schema object, and it has to say so: `type` is required, and a
|
|
83
|
+
// schema without it matches nothing a client validates.
|
|
84
|
+
type: 'object',
|
|
85
|
+
properties: {
|
|
86
|
+
/*
|
|
87
|
+
* One axis, and the CLI's own five values.
|
|
88
|
+
*
|
|
89
|
+
* The protocol's config schema is generic and a backend advertises what
|
|
90
|
+
* it has - VS Code's own hosts advertise different properties for
|
|
91
|
+
* Copilot and for Claude, and a client draws whatever it is given. Its
|
|
92
|
+
* Claude host says why in as many words: it collapses the platform's
|
|
93
|
+
* `autoApprove` x `mode` two-axis surface onto one `permissionMode`
|
|
94
|
+
* matching the SDK's enum, and *omits* `autoApprove`, `mode`,
|
|
95
|
+
* `isolation` and `branch` deliberately, because the pickers key off
|
|
96
|
+
* property names and omitting them suppresses a mode and branch UI that
|
|
97
|
+
* would not mean anything here.
|
|
98
|
+
*
|
|
99
|
+
* The wording is that host's too, so one session reads the same however
|
|
100
|
+
* it is opened. `auto` was missing here and is a real mode the CLI
|
|
101
|
+
* takes: the agent deciding, per call, whether it needs to ask.
|
|
102
|
+
*/
|
|
103
|
+
permissionMode: {
|
|
104
|
+
scope: 'session',
|
|
105
|
+
type: 'string',
|
|
106
|
+
title: 'Approvals',
|
|
107
|
+
description: 'How the agent handles tool approvals.',
|
|
108
|
+
enum: ['default', 'acceptEdits', 'plan', 'auto', 'bypassPermissions'],
|
|
109
|
+
enumLabels: [
|
|
110
|
+
'Ask Before Edits',
|
|
111
|
+
'Edit Automatically',
|
|
112
|
+
'Plan Mode',
|
|
113
|
+
'Auto Mode',
|
|
114
|
+
'Bypass Permissions',
|
|
115
|
+
],
|
|
116
|
+
enumDescriptions: [
|
|
117
|
+
'Asks before editing files.',
|
|
118
|
+
'Edits files without asking, and asks before using other tools.',
|
|
119
|
+
'Creates a plan before making changes.',
|
|
120
|
+
'Decides whether to ask for each tool operation.',
|
|
121
|
+
'Runs all tools without asking.',
|
|
122
|
+
],
|
|
123
|
+
default: 'default',
|
|
124
|
+
sessionMutable: true,
|
|
125
|
+
},
|
|
126
|
+
/*
|
|
127
|
+
* The model is not a config property.
|
|
128
|
+
*
|
|
129
|
+
* A session has no model; each message has one. The choices are carried
|
|
130
|
+
* on the agent (`RootState.agents[].models`) and the choice on the turn.
|
|
131
|
+
* `session/configChanged` with a `model` key is still honoured, but the
|
|
132
|
+
* model is not advertised here as a control of its own.
|
|
133
|
+
*/
|
|
134
|
+
...(perModelEffort ? {} : {
|
|
135
|
+
effortLevel: {
|
|
136
|
+
scope: 'chat',
|
|
137
|
+
type: 'string',
|
|
138
|
+
title: 'Effort',
|
|
139
|
+
description: 'How hard it thinks before answering.',
|
|
140
|
+
enum: [...EFFORTS],
|
|
141
|
+
enumLabels: EFFORTS.map((one) => EFFORT_LABELS[one]),
|
|
142
|
+
default: 'high',
|
|
143
|
+
sessionMutable: true,
|
|
144
|
+
},
|
|
145
|
+
}),
|
|
146
|
+
// Learned, so absent until the probe has answered and absent for good
|
|
147
|
+
// on a harness that has no styles.
|
|
148
|
+
...(styles.length > 0
|
|
149
|
+
? {
|
|
150
|
+
outputStyle: {
|
|
151
|
+
scope: 'session',
|
|
152
|
+
type: 'string',
|
|
153
|
+
title: 'Output style',
|
|
154
|
+
description: 'The voice it answers in.',
|
|
155
|
+
enum: styles,
|
|
156
|
+
enumLabels: styles.map((name) => name.charAt(0).toUpperCase() + name.slice(1)),
|
|
157
|
+
...(style !== undefined ? { default: style } : {}),
|
|
158
|
+
sessionMutable: true,
|
|
159
|
+
},
|
|
160
|
+
}
|
|
161
|
+
: {}),
|
|
162
|
+
thinking: {
|
|
163
|
+
type: 'string',
|
|
164
|
+
title: 'Thinking',
|
|
165
|
+
description: 'Fixed when the session is created.',
|
|
166
|
+
enum: ['adaptive', 'disabled'],
|
|
167
|
+
enumLabels: ['Adaptive', 'Off'],
|
|
168
|
+
enumDescriptions: ['The agent decides when to think', 'No extended thinking'],
|
|
169
|
+
default: 'adaptive',
|
|
170
|
+
sessionMutable: false,
|
|
171
|
+
},
|
|
172
|
+
/*
|
|
173
|
+
* Per-tool allow and deny, which is the slope the mode above is a cliff.
|
|
174
|
+
*
|
|
175
|
+
* A platform key rather than one of this backend's invention: it is what
|
|
176
|
+
* the reference client's permission picker writes when somebody approves
|
|
177
|
+
* a tool "in this session", and its own Claude host advertises it
|
|
178
|
+
* unchanged because the SDK takes `allowedTools` / `disallowedTools`
|
|
179
|
+
* natively. Without it the only way to stop being asked about the one
|
|
180
|
+
* command you trust is `bypassPermissions`, which stops asking about
|
|
181
|
+
* everything.
|
|
182
|
+
*
|
|
183
|
+
* An object, and the first config value here that is not a string. The
|
|
184
|
+
* protocol declares the bag `Record<string, unknown>`; this host used to
|
|
185
|
+
* declare it `Record<string, string>`, which is why nothing of this
|
|
186
|
+
* shape could be carried at all.
|
|
187
|
+
*/
|
|
188
|
+
permissions: {
|
|
189
|
+
scope: 'session',
|
|
190
|
+
type: 'object',
|
|
191
|
+
title: 'Permissions',
|
|
192
|
+
description: 'Per-tool session permissions. Updated when a tool is approved for this session.',
|
|
193
|
+
properties: {
|
|
194
|
+
allow: { type: 'array', title: 'Allowed tools', items: { type: 'string', title: 'Tool name' } },
|
|
195
|
+
deny: { type: 'array', title: 'Denied tools', items: { type: 'string', title: 'Tool name' } },
|
|
196
|
+
},
|
|
197
|
+
default: { allow: [], deny: [] },
|
|
198
|
+
// Unlike `thinking`, this one really can move on a running session:
|
|
199
|
+
// the SDK takes the lists when the query is built, and `canUseTool`
|
|
200
|
+
// is where this host already sits between the agent and the person.
|
|
201
|
+
sessionMutable: true,
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
});
|
|
205
|
+
const defaults = () => ({
|
|
206
|
+
permissionMode: 'default',
|
|
207
|
+
// Beside its schema or not at all: a value with no property to draw it is
|
|
208
|
+
// a control a client cannot show and cannot change.
|
|
209
|
+
...(perModelEffort ? {} : { effortLevel: 'high' }),
|
|
210
|
+
thinking: 'adaptive',
|
|
211
|
+
permissions: { allow: [], deny: [] },
|
|
212
|
+
...(style !== undefined ? { outputStyle: style } : {}),
|
|
213
|
+
});
|
|
214
|
+
return {
|
|
215
|
+
provider: options.provider ?? 'claude',
|
|
216
|
+
displayName: 'Claude Code',
|
|
217
|
+
// Both, because the SDK resumes at a named prompt: `resumeSessionAt` with
|
|
218
|
+
// `forkSession` continues from a turn under a new id, and a side chat is
|
|
219
|
+
// an unresumed session handed what that turn said.
|
|
220
|
+
chats: { fork: true, sideChat: true },
|
|
221
|
+
// The SDK takes `additionalDirectories` at startup, so a session works in
|
|
222
|
+
// as many as it was given; the first is the process root and is fixed.
|
|
223
|
+
multipleDirectories: true,
|
|
224
|
+
description: `The Claude Agent SDK, on ${dirs.join(', ')}`,
|
|
225
|
+
schema,
|
|
226
|
+
defaults,
|
|
227
|
+
directories: () => [...dirs],
|
|
228
|
+
// The styles are kept as well as handed on: `schema()` is asked before any
|
|
229
|
+
// session exists, and it can only offer what has already been learned.
|
|
230
|
+
probe: async () => {
|
|
231
|
+
const offered = await probe(dir);
|
|
232
|
+
styles = offered.outputStyles ?? [];
|
|
233
|
+
style = offered.outputStyle;
|
|
234
|
+
perModelEffort = offered.models.some((model) => model.configSchema !== undefined);
|
|
235
|
+
return offered;
|
|
236
|
+
},
|
|
237
|
+
// Every directory it serves, as one list. A session is listed by the
|
|
238
|
+
// catalogue of the directory it ran in, and a host serving several has
|
|
239
|
+
// one catalogue.
|
|
240
|
+
list: async () => (await Promise.all(dirs.map((served) => catalogue(served)))).flat(),
|
|
241
|
+
// Whichever directory holds it. The transcript reader wants the one the
|
|
242
|
+
// session ran in, and only its own catalogue knows which that was.
|
|
243
|
+
transcript: async (id) => {
|
|
244
|
+
for (const served of dirs) {
|
|
245
|
+
const rows = await catalogue(served).catch(() => []);
|
|
246
|
+
if (rows.some((row) => row.id === id))
|
|
247
|
+
return turnsOf(id, served);
|
|
248
|
+
}
|
|
249
|
+
return undefined;
|
|
250
|
+
},
|
|
251
|
+
/*
|
|
252
|
+
* The one resource this backend can be given a token for.
|
|
253
|
+
*
|
|
254
|
+
* `required: false`, and that is the honest declaration rather than the
|
|
255
|
+
* lenient one: this daemon runs as whoever started it and inherits their
|
|
256
|
+
* `claude login` or `ANTHROPIC_API_KEY`, so it works with nothing pushed
|
|
257
|
+
* at all. Saying `required: true` would refuse clients that would
|
|
258
|
+
* otherwise be perfectly able to open a session.
|
|
259
|
+
*/
|
|
260
|
+
protectedResources: [{
|
|
261
|
+
resource: ANTHROPIC,
|
|
262
|
+
resource_name: 'Anthropic API',
|
|
263
|
+
authorization_servers: ['https://console.anthropic.com'],
|
|
264
|
+
required: false,
|
|
265
|
+
}],
|
|
266
|
+
create: (start) => createSession({
|
|
267
|
+
uri: start.uri,
|
|
268
|
+
chatUri: start.chatUri,
|
|
269
|
+
cwd: workingDirectory(start.workingDirectory),
|
|
270
|
+
/*
|
|
271
|
+
* The MCP servers, declared by this host rather than found by the CLI.
|
|
272
|
+
*
|
|
273
|
+
* The same files the CLI reads - `.mcp.json` beside the project and
|
|
274
|
+
* `mcpServers` in `~/.claude.json` - handed to the SDK so they are
|
|
275
|
+
* *its* servers. That is what makes a token a client signed in with
|
|
276
|
+
* applicable: `setMcpServers` re-declares only what the SDK was given.
|
|
277
|
+
*/
|
|
278
|
+
mcpServers: serversFor([workingDirectory(start.workingDirectory), ...(start.additional ?? [])]),
|
|
279
|
+
// Each one checked the way the first is: a directory this host does not
|
|
280
|
+
// serve is not one an agent may be pointed at, however it arrived.
|
|
281
|
+
...(start.additional && start.additional.length > 0
|
|
282
|
+
? { additional: start.additional.map((one) => workingDirectory(one)) }
|
|
283
|
+
: {}),
|
|
284
|
+
// The host's own tools, offered to the model beside this backend's.
|
|
285
|
+
...(start.tools && start.tools.length > 0 ? { tools: start.tools } : {}),
|
|
286
|
+
settings: start.settings,
|
|
287
|
+
schema: start.schema,
|
|
288
|
+
emit: start.emit,
|
|
289
|
+
...(start.seedCustomizations ? { seedCustomizations: start.seedCustomizations } : {}),
|
|
290
|
+
...(start.resume !== undefined ? { resume: start.resume } : {}),
|
|
291
|
+
...(start.forkAt !== undefined ? { forkAt: start.forkAt } : {}),
|
|
292
|
+
...(start.rewindAt !== undefined ? { rewindAt: start.rewindAt } : {}),
|
|
293
|
+
...(start.context !== undefined ? { context: start.context } : {}),
|
|
294
|
+
...(start.seed ? { seed: start.seed } : {}),
|
|
295
|
+
...(start.onFileEdit ? { onFileEdit: start.onFileEdit } : {}),
|
|
296
|
+
...(start.onHandshake ? { onHandshake: start.onHandshake } : {}),
|
|
297
|
+
/*
|
|
298
|
+
* A pushed token, as the variable the CLI reads.
|
|
299
|
+
*
|
|
300
|
+
* Which variable that is, is this file's business and not the host's:
|
|
301
|
+
* the host knows a token belongs to `https://api.anthropic.com` and
|
|
302
|
+
* stops there, which is what keeps `createHost` the protocol and
|
|
303
|
+
* nothing else.
|
|
304
|
+
*/
|
|
305
|
+
...(start.credentials?.[ANTHROPIC]
|
|
306
|
+
? { env: { ANTHROPIC_API_KEY: start.credentials[ANTHROPIC] } }
|
|
307
|
+
: {}),
|
|
308
|
+
}),
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
//# sourceMappingURL=claude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../src/claude.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Claude backend, as an `Agent` this host can be handed.
|
|
3
|
+
*
|
|
4
|
+
* One implementation of the contract `@ahpd/server` declares, and the only
|
|
5
|
+
* thing in either package that knows what the Claude harness is: it starts the
|
|
6
|
+
* agent SDK, translates its message stream into the state actions the protocol
|
|
7
|
+
* describes, and reads a transcript somebody else's session left on disk.
|
|
8
|
+
*
|
|
9
|
+
* A host that wants a different harness registers a different `Agent` and
|
|
10
|
+
* never loads this. A host that wants both registers both - `createHost` takes
|
|
11
|
+
* a list, and cannot tell one from another.
|
|
12
|
+
*/
|
|
13
|
+
export { catalogue } from './catalog.js';
|
|
14
|
+
export { claude } from './claude.js';
|
|
15
|
+
export type { ClaudeOptions } from './claude.js';
|
|
16
|
+
export { createSession, EFFORTS, EFFORT_LABELS } from './session.js';
|
|
17
|
+
export type { Published } from './session.js';
|
|
18
|
+
export { probe } from './probe.js';
|
|
19
|
+
export { turnsOf } from './transcript.js';
|
|
20
|
+
export { protectedResource, urlOf } from './mcp.js';
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACrE,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Claude backend, as an `Agent` this host can be handed.
|
|
3
|
+
*
|
|
4
|
+
* One implementation of the contract `@ahpd/server` declares, and the only
|
|
5
|
+
* thing in either package that knows what the Claude harness is: it starts the
|
|
6
|
+
* agent SDK, translates its message stream into the state actions the protocol
|
|
7
|
+
* describes, and reads a transcript somebody else's session left on disk.
|
|
8
|
+
*
|
|
9
|
+
* A host that wants a different harness registers a different `Agent` and
|
|
10
|
+
* never loads this. A host that wants both registers both - `createHost` takes
|
|
11
|
+
* a list, and cannot tell one from another.
|
|
12
|
+
*/
|
|
13
|
+
export { catalogue } from './catalog.js';
|
|
14
|
+
export { claude } from './claude.js';
|
|
15
|
+
export { createSession, EFFORTS, EFFORT_LABELS } from './session.js';
|
|
16
|
+
export { probe } from './probe.js';
|
|
17
|
+
export { turnsOf } from './transcript.js';
|
|
18
|
+
export { protectedResource, urlOf } from './mcp.js';
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAErE,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/mcp.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** The MCP servers a session runs with, read from the files the CLI reads. */
|
|
2
|
+
import type { Bag } from '@ahpd/server';
|
|
3
|
+
/**
|
|
4
|
+
* Every MCP server configured for a directory, by name.
|
|
5
|
+
*
|
|
6
|
+
* The CLI finds these itself and this host normally leaves it to. It reads
|
|
7
|
+
* them here for one reason: a server the *SDK* was given is one
|
|
8
|
+
* `setMcpServers` can re-declare, and a server that came from a settings file
|
|
9
|
+
* is not - so a token a client signs in with has nowhere to go unless this
|
|
10
|
+
* host owns the declaration. The files are the CLI's own: `.mcp.json` beside
|
|
11
|
+
* the project, and `mcpServers` in `~/.claude.json`.
|
|
12
|
+
*
|
|
13
|
+
* A file that is missing, unreadable or not JSON contributes nothing. This is
|
|
14
|
+
* a best effort by design: the CLI still reads the same files, and a server
|
|
15
|
+
* this misses is a server that works exactly as it did before.
|
|
16
|
+
*/
|
|
17
|
+
export declare function serversFor(directories: string[]): Record<string, Bag>;
|
|
18
|
+
/** The URL an http or sse server lives at, or nothing for a stdio one. */
|
|
19
|
+
export declare const urlOf: (config: unknown) => string | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* What an MCP server says about signing into it, per RFC 9728.
|
|
22
|
+
*
|
|
23
|
+
* `<url>/.well-known/oauth-protected-resource`, which is where an OAuth
|
|
24
|
+
* protected resource publishes its metadata and where a client looks to find
|
|
25
|
+
* the authorization server. Answers the discovered document, or a bare one
|
|
26
|
+
* naming the server itself: the URL *is* the canonical resource identifier,
|
|
27
|
+
* so an incomplete answer is still a true one - what a client loses is the
|
|
28
|
+
* one-click sign-in, not the knowledge that it needs to sign in.
|
|
29
|
+
*/
|
|
30
|
+
export declare function protectedResource(url: string, name: string, ms?: number): Promise<Bag>;
|
|
31
|
+
//# sourceMappingURL=mcp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAK9E,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAExC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAsBrE;AAED,0EAA0E;AAC1E,eAAO,MAAM,KAAK,GAAI,QAAQ,OAAO,KAAG,MAAM,GAAG,SAMhD,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAU5F"}
|