@polydeukes/adapter-claude-code 0.6.0 → 0.7.1
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/README.ko.md +49 -40
- package/README.md +49 -55
- package/dist/bin.d.ts +9 -0
- package/dist/bin.js +30 -0
- package/dist/hook.d.ts +51 -0
- package/dist/hook.js +142 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/init.d.ts +57 -0
- package/dist/init.js +594 -0
- package/dist/resolve-umbrella.d.ts +24 -0
- package/dist/resolve-umbrella.js +52 -0
- package/dist/session-evidence.d.ts +34 -0
- package/dist/session-evidence.js +46 -0
- package/dist/session-vocabulary.d.ts +1 -1
- package/dist/session-vocabulary.js +1 -1
- package/package.json +8 -4
- package/dist/run-adapter-path.d.ts +0 -53
- package/dist/run-adapter-path.js +0 -88
package/README.ko.md
CHANGED
|
@@ -1,40 +1,49 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
1
|
+
# `@polydeukes/adapter-claude-code`
|
|
2
|
+
|
|
3
|
+
[English](./README.md) · **한국어**
|
|
4
|
+
|
|
5
|
+
이 어댑터는 Claude Code 세션 표면의 설치 단위입니다. Claude Code PreToolUse 페이로드를
|
|
6
|
+
약속(covenant) 입력 IR로 변환하고, 판정기를 스폰하며, 프로젝트에 세션 표면을 등록하는
|
|
7
|
+
`pdks-claude-code` 실행 파일을 제공합니다. 우산 패키지가 세션 표면에 주입할 읽기 함수를
|
|
8
|
+
만드는 팩터리도 제공합니다.
|
|
9
|
+
|
|
10
|
+
`polydeukes`와 함께 설치합니다. `polydeukes`는 이 패키지의 `peerDependency`입니다.
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
npm install --save-dev polydeukes @polydeukes/adapter-claude-code
|
|
14
|
+
npx pdks-claude-code init
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
<a id="overview"></a>
|
|
18
|
+
## 개요
|
|
19
|
+
|
|
20
|
+
공개 계약 심볼은 다음과 같습니다.
|
|
21
|
+
|
|
22
|
+
- `runHook`
|
|
23
|
+
- `sessionSourceReader`
|
|
24
|
+
- `sessionChannelReader`
|
|
25
|
+
- `sessionEvidenceFromPayload`
|
|
26
|
+
- `transcriptPathFromPayload`
|
|
27
|
+
- `transcriptFromJsonlFile`
|
|
28
|
+
- `COMMAND_ARGS`
|
|
29
|
+
- `MUTATING_TOOLS`
|
|
30
|
+
- `SHELL_TOOLS`
|
|
31
|
+
|
|
32
|
+
<a id="examples"></a>
|
|
33
|
+
## 예제
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { runHook } from '@polydeukes/adapter-claude-code';
|
|
37
|
+
|
|
38
|
+
// 표준 입력에서 페이로드를 읽어 repoRoot에서 `pdks covenant check --enforce block`을 스폰하고
|
|
39
|
+
// 그 자식 프로세스의 종료 코드를 돌려줍니다. 생성된 훅 위임자가 부르는 함수입니다.
|
|
40
|
+
const { exitCode } = runHook({ repoRoot: process.cwd() });
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
<a id="see-also"></a>
|
|
44
|
+
## 같이 보기
|
|
45
|
+
|
|
46
|
+
- [`@polydeukes/adapter-claude-code` 패키지
|
|
47
|
+
레퍼런스](../../docs/reference/packages/adapter-claude-code.ko.md)
|
|
48
|
+
- [우산의 진입점](../../docs/reference/packages/polydeukes.ko.md#polydeukes-entry-points)
|
|
49
|
+
- [판정기(`covenant` 모듈)](../../docs/reference/packages/polydeukes.ko.md#covenant-module)
|
package/README.md
CHANGED
|
@@ -1,55 +1,49 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
**English** ·
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
See the [project repository](https://github.com/huskyhoochu/polydeukes) for the architecture
|
|
51
|
-
blueprint and design rationale.
|
|
52
|
-
|
|
53
|
-
## License
|
|
54
|
-
|
|
55
|
-
MIT
|
|
1
|
+
# `@polydeukes/adapter-claude-code`
|
|
2
|
+
|
|
3
|
+
**English** · [한국어](./README.ko.md)
|
|
4
|
+
|
|
5
|
+
This adapter is the install unit for the Claude Code session surface. It translates Claude Code
|
|
6
|
+
PreToolUse payloads into covenant input IR, spawns the judge, and ships the `pdks-claude-code`
|
|
7
|
+
bin that registers the surface in a project. It also provides the session-side reader factories
|
|
8
|
+
the umbrella injects.
|
|
9
|
+
|
|
10
|
+
Install it next to `polydeukes`, which it names as a `peerDependency`:
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
npm install --save-dev polydeukes @polydeukes/adapter-claude-code
|
|
14
|
+
npx pdks-claude-code init
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
<a id="overview"></a>
|
|
18
|
+
## Overview
|
|
19
|
+
|
|
20
|
+
Public contract symbols include:
|
|
21
|
+
|
|
22
|
+
- `runHook`
|
|
23
|
+
- `sessionSourceReader`
|
|
24
|
+
- `sessionChannelReader`
|
|
25
|
+
- `sessionEvidenceFromPayload`
|
|
26
|
+
- `transcriptPathFromPayload`
|
|
27
|
+
- `transcriptFromJsonlFile`
|
|
28
|
+
- `COMMAND_ARGS`
|
|
29
|
+
- `MUTATING_TOOLS`
|
|
30
|
+
- `SHELL_TOOLS`
|
|
31
|
+
|
|
32
|
+
<a id="examples"></a>
|
|
33
|
+
## Examples
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { runHook } from '@polydeukes/adapter-claude-code';
|
|
37
|
+
|
|
38
|
+
// Reads the payload from stdin, spawns `pdks covenant check --enforce block` in repoRoot,
|
|
39
|
+
// and returns that child's exit code. This is what the generated hook delegator calls.
|
|
40
|
+
const { exitCode } = runHook({ repoRoot: process.cwd() });
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
<a id="see-also"></a>
|
|
44
|
+
## See also
|
|
45
|
+
|
|
46
|
+
- [`@polydeukes/adapter-claude-code` package
|
|
47
|
+
reference](../../docs/reference/packages/adapter-claude-code.md)
|
|
48
|
+
- [The umbrella's entry points](../../docs/reference/packages/polydeukes.md#polydeukes-entry-points)
|
|
49
|
+
- [The judge (`covenant` module)](../../docs/reference/packages/polydeukes.md#covenant-module)
|
package/dist/bin.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* `pdks-claude-code` — this adapter's bin.
|
|
4
|
+
*
|
|
5
|
+
* A thin argv shim over one subcommand. Anything else prints usage and exits 2: an unknown
|
|
6
|
+
* argument must never be read as `init`, because a typo would then install into whatever
|
|
7
|
+
* directory the user happened to be in.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
package/dist/bin.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* `pdks-claude-code` — this adapter's bin.
|
|
4
|
+
*
|
|
5
|
+
* A thin argv shim over one subcommand. Anything else prints usage and exits 2: an unknown
|
|
6
|
+
* argument must never be read as `init`, because a typo would then install into whatever
|
|
7
|
+
* directory the user happened to be in.
|
|
8
|
+
*/
|
|
9
|
+
import { initClaudeCode } from './init.js';
|
|
10
|
+
const args = process.argv.slice(2);
|
|
11
|
+
if (args.length === 1 && args[0] === 'init') {
|
|
12
|
+
try {
|
|
13
|
+
const { created, skipped } = initClaudeCode({ projectRoot: process.cwd() });
|
|
14
|
+
for (const path of created) {
|
|
15
|
+
process.stdout.write(`created ${path}\n`);
|
|
16
|
+
}
|
|
17
|
+
for (const path of skipped) {
|
|
18
|
+
process.stdout.write(`skipped ${path} (already present)\n`);
|
|
19
|
+
}
|
|
20
|
+
process.exit(0);
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
// A precondition failure leaves zero files; the message names what the user has to do
|
|
24
|
+
// before running this again.
|
|
25
|
+
process.stderr.write(`pdks-claude-code init failed: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
26
|
+
process.exit(2);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
process.stderr.write('usage: pdks-claude-code init\n');
|
|
30
|
+
process.exit(2);
|
package/dist/hook.d.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `runHook` — the session surface's entry point: one PreToolUse payload in, one
|
|
3
|
+
* `pdks covenant check` process out, its status back as the exit code.
|
|
4
|
+
*
|
|
5
|
+
* This package judges nothing and writes no telemetry row. It builds the agent-neutral IR
|
|
6
|
+
* — the translated payload, this host's tool roster, the file-change evidence, the session
|
|
7
|
+
* evidence — and hands it to the umbrella's bin on stdin. Every verdict, and every row, is
|
|
8
|
+
* the child's.
|
|
9
|
+
*
|
|
10
|
+
* A failure before the spawn travels IN the spawn: the failure sentence replaces the IR on
|
|
11
|
+
* stdin, the child fails closed on it as non-JSON, and the one row that call earns is
|
|
12
|
+
* written by the one writer. Only an unresolvable `polydeukes` skips the spawn, because
|
|
13
|
+
* then there is no writer at all.
|
|
14
|
+
*/
|
|
15
|
+
/** The spawn seam's parameters — what the child is asked to run, where, and on stdin. */
|
|
16
|
+
export type RunHookSpawnSpec = {
|
|
17
|
+
command: string;
|
|
18
|
+
args: string[];
|
|
19
|
+
cwd: string;
|
|
20
|
+
stdin: string;
|
|
21
|
+
};
|
|
22
|
+
/** {@link runHook} input — the project being judged, the payload, and the spawn seam. */
|
|
23
|
+
export type RunHookSpec = {
|
|
24
|
+
/**
|
|
25
|
+
* The project root: the config the child discovers, and the install graph `polydeukes`
|
|
26
|
+
* is located in. A delegator derives it from its own location, never from a cwd a host
|
|
27
|
+
* chose.
|
|
28
|
+
*/
|
|
29
|
+
repoRoot: string;
|
|
30
|
+
/** Raw hook stdin — one PreToolUse payload as JSON. Absent reads fd 0. */
|
|
31
|
+
rawPayload?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Injected spawn seam. Absent spawns node on the located bin with stdout and stderr
|
|
34
|
+
* inherited, so the child's break reason reaches the host.
|
|
35
|
+
*/
|
|
36
|
+
spawn?: (spec: RunHookSpawnSpec) => {
|
|
37
|
+
status: number | null;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
/** {@link runHook} result — the exit code the hook process leaves with. */
|
|
41
|
+
export type RunHookOutcome = {
|
|
42
|
+
exitCode: 0 | 2;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Judge one PreToolUse payload by spawning the umbrella's judge over its IR.
|
|
46
|
+
*
|
|
47
|
+
* Only a child status of 0 passes through as 0. A crashed child (1) or a signalled one
|
|
48
|
+
* (null) is not a verdict, and forwarding either as-is would let the host read a non-2 as
|
|
49
|
+
* "not blocked".
|
|
50
|
+
*/
|
|
51
|
+
export declare function runHook(spec: RunHookSpec): RunHookOutcome;
|
package/dist/hook.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `runHook` — the session surface's entry point: one PreToolUse payload in, one
|
|
3
|
+
* `pdks covenant check` process out, its status back as the exit code.
|
|
4
|
+
*
|
|
5
|
+
* This package judges nothing and writes no telemetry row. It builds the agent-neutral IR
|
|
6
|
+
* — the translated payload, this host's tool roster, the file-change evidence, the session
|
|
7
|
+
* evidence — and hands it to the umbrella's bin on stdin. Every verdict, and every row, is
|
|
8
|
+
* the child's.
|
|
9
|
+
*
|
|
10
|
+
* A failure before the spawn travels IN the spawn: the failure sentence replaces the IR on
|
|
11
|
+
* stdin, the child fails closed on it as non-JSON, and the one row that call earns is
|
|
12
|
+
* written by the one writer. Only an unresolvable `polydeukes` skips the spawn, because
|
|
13
|
+
* then there is no writer at all.
|
|
14
|
+
*/
|
|
15
|
+
import { spawnSync } from 'node:child_process';
|
|
16
|
+
import { readFileSync } from 'node:fs';
|
|
17
|
+
import { EXIT_BREAK_BLOCKING, EXIT_UPHOLD } from '@polydeukes/core';
|
|
18
|
+
import { collectFileChanges } from './file-changes.js';
|
|
19
|
+
import { findUmbrellaBin, UMBRELLA_PACKAGE } from './resolve-umbrella.js';
|
|
20
|
+
import { sessionEvidenceFromPayload } from './session-evidence.js';
|
|
21
|
+
import { COMMAND_ARGS, MUTATING_TOOLS, SHELL_TOOLS } from './session-vocabulary.js';
|
|
22
|
+
import { buildCovenantInput } from './up-translate.js';
|
|
23
|
+
/** The subcommand and posture the session surface always spawns with. */
|
|
24
|
+
const CHECK_ARGS = ['covenant', 'check', '--enforce', 'block'];
|
|
25
|
+
/** The prefix a pre-spawn failure travels under, so an operator can find it in the log. */
|
|
26
|
+
const FAILURE_PREFIX = 'adapter-claude-code failed before spawn:';
|
|
27
|
+
/**
|
|
28
|
+
* Real-fs pre-state reader for file changes — `null` only for true absence (ENOENT).
|
|
29
|
+
*
|
|
30
|
+
* Any other read failure (permissions, a directory target, fd exhaustion) throws: `null` is
|
|
31
|
+
* the IR's creation sentinel, and a poisoned `pre: null` on an existing file would let a
|
|
32
|
+
* path-family discipline uphold the overwrite. The caller turns the throw into a failure
|
|
33
|
+
* sentence the child fails closed on.
|
|
34
|
+
*/
|
|
35
|
+
function readPreStateFromDisk(filePath) {
|
|
36
|
+
try {
|
|
37
|
+
return readFileSync(filePath, 'utf-8');
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
if (error.code === 'ENOENT')
|
|
41
|
+
return null;
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/** A pre-spawn failure carrying the step that produced it — the operator's only trace. */
|
|
46
|
+
class PreSpawnFailure extends Error {
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Build the IR one payload proves, as the JSON text the child reads from stdin.
|
|
50
|
+
*
|
|
51
|
+
* Throws {@link PreSpawnFailure} naming the step that failed. The four steps fail for
|
|
52
|
+
* different reasons and need different repairs, so each names itself rather than sharing
|
|
53
|
+
* one sentence.
|
|
54
|
+
*/
|
|
55
|
+
function buildStdin(rawPayload) {
|
|
56
|
+
let payload;
|
|
57
|
+
try {
|
|
58
|
+
payload = JSON.parse(rawPayload);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
throw new PreSpawnFailure(`the payload is not JSON (${error instanceof Error ? error.message : String(error)})`);
|
|
62
|
+
}
|
|
63
|
+
const built = buildCovenantInput([payload]);
|
|
64
|
+
if (built.ok !== true) {
|
|
65
|
+
throw new PreSpawnFailure('the payload is not a PreToolUse envelope this adapter translates');
|
|
66
|
+
}
|
|
67
|
+
// Attached to the call it belongs to: this path translates exactly one payload, so the
|
|
68
|
+
// one evidence rides toolCalls[0]. Left ABSENT rather than null when unprovable — the
|
|
69
|
+
// protocol refuses a null fileChange, and a call the judge should fall back on would
|
|
70
|
+
// fail closed instead.
|
|
71
|
+
let evidence;
|
|
72
|
+
try {
|
|
73
|
+
evidence = collectFileChanges(payload, readPreStateFromDisk);
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
throw new PreSpawnFailure(`the pre-state of the target could not be read (${error instanceof Error ? error.message : String(error)})`);
|
|
77
|
+
}
|
|
78
|
+
let session;
|
|
79
|
+
try {
|
|
80
|
+
session = sessionEvidenceFromPayload({ rawPayload });
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
throw new PreSpawnFailure(`the session evidence could not be gathered (${error instanceof Error ? error.message : String(error)})`);
|
|
84
|
+
}
|
|
85
|
+
return JSON.stringify({
|
|
86
|
+
...built.value,
|
|
87
|
+
toolCalls: evidence === null
|
|
88
|
+
? built.value.toolCalls
|
|
89
|
+
: built.value.toolCalls.map((call, index) => index === 0 ? { ...call, fileChange: evidence } : call),
|
|
90
|
+
tools: { mutating: MUTATING_TOOLS, shell: SHELL_TOOLS, commandArgs: COMMAND_ARGS },
|
|
91
|
+
...(session === undefined ? {} : { session }),
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
/** The default seam: node on the located bin, the child's own output reaching the host. */
|
|
95
|
+
function spawnCovenantCheck(spec) {
|
|
96
|
+
return spawnSync(spec.command, spec.args, {
|
|
97
|
+
cwd: spec.cwd,
|
|
98
|
+
input: spec.stdin,
|
|
99
|
+
stdio: ['pipe', 'inherit', 'inherit'],
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Judge one PreToolUse payload by spawning the umbrella's judge over its IR.
|
|
104
|
+
*
|
|
105
|
+
* Only a child status of 0 passes through as 0. A crashed child (1) or a signalled one
|
|
106
|
+
* (null) is not a verdict, and forwarding either as-is would let the host read a non-2 as
|
|
107
|
+
* "not blocked".
|
|
108
|
+
*/
|
|
109
|
+
export function runHook(spec) {
|
|
110
|
+
const bin = findUmbrellaBin(spec.repoRoot);
|
|
111
|
+
if (bin === undefined) {
|
|
112
|
+
// The one outcome with no row anywhere: nothing to spawn means no writer exists. The
|
|
113
|
+
// line names the package because installing it is the operator's next action.
|
|
114
|
+
process.stderr.write(`covenant hook failed closed: cannot use '${UMBRELLA_PACKAGE}' from ${spec.repoRoot} — ` +
|
|
115
|
+
'install or update it there, then try again\n');
|
|
116
|
+
return { exitCode: EXIT_BREAK_BLOCKING };
|
|
117
|
+
}
|
|
118
|
+
const rawPayload = spec.rawPayload ?? readFileSync(0, 'utf-8');
|
|
119
|
+
let stdin;
|
|
120
|
+
try {
|
|
121
|
+
stdin = buildStdin(rawPayload);
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
stdin = `${FAILURE_PREFIX} ${error instanceof Error ? error.message : String(error)}\n`;
|
|
125
|
+
// The child fails closed on this line as non-JSON, but its own stderr names only the
|
|
126
|
+
// parse failure. The reason reaches the operator from here.
|
|
127
|
+
process.stderr.write(stdin);
|
|
128
|
+
}
|
|
129
|
+
const spawn = spec.spawn ?? spawnCovenantCheck;
|
|
130
|
+
const { status } = spawn({
|
|
131
|
+
command: process.execPath,
|
|
132
|
+
args: [bin, ...CHECK_ARGS],
|
|
133
|
+
cwd: spec.repoRoot,
|
|
134
|
+
stdin,
|
|
135
|
+
});
|
|
136
|
+
if (status !== EXIT_UPHOLD && status !== EXIT_BREAK_BLOCKING) {
|
|
137
|
+
// Not a verdict: the judge crashed or was signalled, so no row was written. Exit 2 is
|
|
138
|
+
// still right for the host; the line is what tells the operator this was not a break.
|
|
139
|
+
process.stderr.write(`covenant hook failed closed: the judge exited with status ${String(status)} before a verdict\n`);
|
|
140
|
+
}
|
|
141
|
+
return { exitCode: status === EXIT_UPHOLD ? EXIT_UPHOLD : EXIT_BREAK_BLOCKING };
|
|
142
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
* this package is the boundary where Claude Code's vocabulary is translated away before it
|
|
8
8
|
* reaches the core.
|
|
9
9
|
*/
|
|
10
|
-
export { type
|
|
10
|
+
export { type RunHookOutcome, type RunHookSpec, runHook } from './hook.ts';
|
|
11
11
|
export { type SessionChannelReaderSpec, sessionChannelReader, } from './session-channel-reader.ts';
|
|
12
|
+
export { type SessionEvidenceFromPayloadSpec, type SessionEvidenceOutcome, sessionEvidenceFromPayload, } from './session-evidence.ts';
|
|
12
13
|
export { type SessionSourceReaderSpec, sessionSourceReader } from './session-source-reader.ts';
|
|
13
14
|
export { COMMAND_ARGS, MUTATING_TOOLS, SHELL_TOOLS, type TranscriptPathFromPayloadSpec, transcriptPathFromPayload, } from './session-vocabulary.ts';
|
|
14
15
|
export { type TranscriptFromJsonlFileSpec, transcriptFromJsonlFile } from './transcript.ts';
|
package/dist/index.js
CHANGED
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
* this package is the boundary where Claude Code's vocabulary is translated away before it
|
|
8
8
|
* reaches the core.
|
|
9
9
|
*/
|
|
10
|
-
export {
|
|
10
|
+
export { runHook } from './hook.js';
|
|
11
11
|
export { sessionChannelReader, } from './session-channel-reader.js';
|
|
12
|
+
export { sessionEvidenceFromPayload, } from './session-evidence.js';
|
|
12
13
|
export { sessionSourceReader } from './session-source-reader.js';
|
|
13
14
|
export { COMMAND_ARGS, MUTATING_TOOLS, SHELL_TOOLS, transcriptPathFromPayload, } from './session-vocabulary.js';
|
|
14
15
|
export { transcriptFromJsonlFile } from './transcript.js';
|
package/dist/init.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `initClaudeCode` — the Claude Code session-surface installer.
|
|
3
|
+
*
|
|
4
|
+
* One command wires a project into the session surface: prove `polydeukes` resolves, spawn
|
|
5
|
+
* its agent-neutral scaffold (`pdks init`, which writes the config and the telemetry ignore
|
|
6
|
+
* line), then add what this package owns — the delegator hook file, its
|
|
7
|
+
* `.claude/settings.json` registration, the discipline file that tells an agent the docs
|
|
8
|
+
* query exists, and the classification skill that turns a described problem into a config
|
|
9
|
+
* entry.
|
|
10
|
+
*
|
|
11
|
+
* Preflight comes first and nothing is written before it clears. A generated hook whose
|
|
12
|
+
* import can never resolve blocks every call through its own fail-closed catch, and a tree
|
|
13
|
+
* that also has no config and no valve to open cannot be edited back into shape from inside
|
|
14
|
+
* the session.
|
|
15
|
+
*
|
|
16
|
+
* Nothing existing is overwritten. The settings file in particular is merged, never
|
|
17
|
+
* replaced: a consumer's other PreToolUse registrations and permissions are live
|
|
18
|
+
* configuration, and replacing them would disarm every other tool they wired.
|
|
19
|
+
*/
|
|
20
|
+
/** What one install left behind, per artifact. */
|
|
21
|
+
export type InitClaudeCodeReport = {
|
|
22
|
+
created: string[];
|
|
23
|
+
skipped: string[];
|
|
24
|
+
};
|
|
25
|
+
/** {@link initClaudeCode} input — the target tree and its two seams. */
|
|
26
|
+
export type InitClaudeCodeSpec = {
|
|
27
|
+
/** Project root to install into — every write below is relative to it. */
|
|
28
|
+
projectRoot: string;
|
|
29
|
+
/**
|
|
30
|
+
* Preflight seam: the absolute path of the umbrella's `pdks` bin as reachable from the
|
|
31
|
+
* given root, or a throw when the umbrella cannot be resolved there. ABSENT uses the real
|
|
32
|
+
* resolution, anchored at that root and nowhere else — anchoring it at the installer's
|
|
33
|
+
* own module would answer for the installer's install graph rather than the target
|
|
34
|
+
* project's, which is precisely the case that must fail.
|
|
35
|
+
*/
|
|
36
|
+
resolvePolydeukes?: (projectRoot: string) => string;
|
|
37
|
+
/**
|
|
38
|
+
* The `pdks init` spawn seam. ABSENT spawns node on the located bin with the child's
|
|
39
|
+
* output inherited.
|
|
40
|
+
*/
|
|
41
|
+
spawnScaffold?: (spec: {
|
|
42
|
+
command: string;
|
|
43
|
+
args: string[];
|
|
44
|
+
cwd: string;
|
|
45
|
+
}) => {
|
|
46
|
+
status: number | null;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Install the Claude Code session surface into `spec.projectRoot`, skipping whatever is
|
|
51
|
+
* already there and reporting both halves per artifact.
|
|
52
|
+
*
|
|
53
|
+
* Throws before any write when the umbrella cannot be resolved from that root, when the
|
|
54
|
+
* settings file cannot be parsed, or when the scaffold refuses — all three leave zero files.
|
|
55
|
+
* Translating a throw into exit 2 with the install command is the bin's job.
|
|
56
|
+
*/
|
|
57
|
+
export declare function initClaudeCode(spec: InitClaudeCodeSpec): InitClaudeCodeReport;
|