@polydeukes/sdk-ts
TypeScript에서 판정기를 호출합니다.
checkCovenant에 약속(covenant) 입력 IR을 전달하면pdks covenant check의 판정 결과를 값으로 반환합니다.베타입니다.
polydeukes·@polydeukes/core와 함께 설치하며, 둘 다 이 패키지의peerDependencies입니다.
담당하는 기능
섹션 제목: “담당하는 기능”판정받는 프로젝트에서 polydeukes를 찾고, 실행 파일의 표준 입력으로 IR을 전달한 뒤
자식 프로세스의 종료 코드를 판정 결과로 변환합니다. 실제 판정은 자식 프로세스가 수행합니다.
| 단위 | 하는 일 |
|---|---|
checkCovenant |
판정받는 프로젝트에서 pdks covenant check를 스폰하고 판정 결과를 돌려줍니다 |
| 우산 패키지 찾기 | repoRoot의 설치 그래프에서 polydeukes를 찾아 pdks 실행 파일을 읽습니다 |
| 판정 결과 변환 | 종료 코드 0은 upheld, 2는 blocked, 그 밖은 모두 unjudged입니다 |
텔레메트리는 자식 프로세스가 판정 중에 기록합니다. SDK는 중복 행을 추가하지 않습니다.
pnpm add @polydeukes/sdk-ts polydeukes @polydeukes/core별도의 초기화 명령은 필요하지 않습니다. 우산 패키지가 SDK가 스폰할 판정기를 공급하고, 코어가
호출자가 채우는 CovenantInput 타입을 공급합니다.
checkCovenant
섹션 제목: “checkCovenant”이 패키지는 ESM 전용입니다("type": "module", import 조건만 있고 require는 없음).
호출하는 파일이 .mjs이거나 그 package.json이 "type": "module"을 선언해야 합니다.
import { checkCovenant } from '@polydeukes/sdk-ts';
const verdict = await checkCovenant({ repoRoot: '/path/to/the/project', input: { toolCalls: [ { name: 'writeFile', args: { path: 'src/index.ts', content: 'export const answer = 42;\n' }, fileChange: { kind: 'modify', path: 'src/index.ts', pre: 'export const answer = 41;\n', post: 'export const answer = 42;\n', }, }, ], subagentSpawns: [], userMessages: [], tools: { mutating: ['writeFile', 'rm'], shell: ['exec'], commandArgs: ['command'] }, },});IR은 호출자의 것입니다. 이 패키지는 IR을 읽지도 채우지도 않습니다. session도 actor도
자기 명부도 더하지 않으며, 위의 tools 값도 호출자 자신의 도구 이름입니다. subagentSpawns와
userMessages는 필수 배열이므로 둘 다 없는 호출자는 빈 배열을 보냅니다. world 키는 판정기가
거부합니다. 러너가 세계를 디스크의 프로젝트에서 읽으며, 클라이언트가 세계를 고르면 무엇을
판정할지를 고르는 것이 되기 때문입니다.
type CheckCovenantSpec = { repoRoot: string; input: CovenantInput; enforce?: 'advise' | 'block'; spawn?: (spec: CheckCovenantSpawnSpec) => Promise<{ status: number | null; stderr: string }>;};
type CheckCovenantSpawnSpec = { command: string; args: string[]; cwd: string; stdin: string };| 필드 | 무엇인가 |
|---|---|
repoRoot |
판정받는 프로젝트입니다. 설정 발견, 세계 축, 자식의 cwd, 우산 패키지를 찾는 설치 그래프가 모두 여기 걸립니다 |
input |
호출자 자신의 IR이며 자식의 표준 입력으로 원문 그대로 갑니다 |
enforce |
실행 전체에 대한 관측자의 기본 자세입니다. 적지 않으면 block입니다 |
spawn |
자식 프로세스 실행 함수를 지정합니다. 생략하면 현재 프로세스의 Node.js 실행 파일을 사용합니다 |
enforce의 기본값은 block입니다. 이것은 표면의 강제 수준이지 항목의 것이 아닙니다.
보호 경로와 enforce: block을 단 항목이 호출을 멈추고, 나머지 위반은 종료 코드 0에
advised로 기록됩니다. 항목 자신의 강제 수준은 다른 표면에서와 같이 느슨한 쪽이 이기도록
조합됩니다. @polydeukes/adapter-claude-code, @polydeukes/adapter-grok,
@polydeukes/adapter-codex도 같은 수준으로 판정기를 스폰합니다.
기본 스폰은 파일 서술자를 하나도 상속하지 않습니다. 호출자가 자기 서술자를 갖지 않을 수 있고, 상속한 stdout이 닫혀 있으면 자식이 답하기 전에 EPIPE로 죽기 때문입니다. stderr는 모아서 돌려주고, 판정기가 stdout에는 판정 결과를 쓰지 않으므로 stdout은 흘려보내고 버립니다.
판정 결과 셋
섹션 제목: “판정 결과 셋”type CheckCovenantVerdict = | { verdict: 'upheld'; advisories: string } | { verdict: 'blocked'; reason: string } | { verdict: 'unjudged'; reason: string };| 판정 결과 | 자식의 상태 | 호출자에게 뜻하는 것 |
|---|---|---|
upheld |
0 |
호출이 판정을 받았고 아무것도 막지 않았습니다. advisories는 자식의 stderr 원문이며 그 실행이 낸 권고 줄을 싣습니다. 진행하면 됩니다 |
blocked |
2 |
호출이 판정을 받았고 무언가 막았습니다. reason은 자식의 stderr 원문입니다. 진행하지 않습니다 |
unjudged |
그 밖의 상태이거나 우산 패키지가 없음 | 판정이 일어나지 않았습니다. reason이 어느 쪽인지 말합니다. 이것을 통과로 읽으면 판정기가 설치되지 않은 프로젝트에서 모든 호출이 지나갑니다 |
SDK는 blocked.reason과 upheld.advisories를 데이터로 반환합니다. 소비자는 이 내용을
모델에게 전달하거나 이슈 또는 로그에 기록할 수 있습니다. SDK는 별도의 증인 인자를 받지 않습니다.
무인 루프에서 결과를 처리하는 방법은
규율 작성하기를 참고하세요.
실패 예제
섹션 제목: “실패 예제”프로젝트에 polydeukes가 설치돼 있지 않으면 checkCovenant는 unjudged를 반환합니다.
const verdict = await checkCovenant({ repoRoot: '/tmp/project-without-polydeukes', input });
// {// verdict: 'unjudged',// reason: 'no polydeukes in the install graph of /tmp/project-without-polydeukes:// install it to have this input judged',// }자식 프로세스는 돌지 않고 텔레메트리 로그에도 아무것도 더해지지 않습니다. 행은 판정이 일어나는 자리에 쓰이는데, 판정이 일어나지 않았기 때문입니다.
선언된 한계
섹션 제목: “선언된 한계”- IR은 호출자가 만듭니다. 도구 명부와 변경 전 상태와 봉투는 호스트가 아는 사실이므로, 그것을 아는 소비자가 채웁니다. 이 패키지는 그중 무엇도 공급하지 않습니다.
- SDK가 여는 것은 세션 표면뿐입니다. 입력이 표준 입력의 IR로 가고, 그것이 이 실행을 세션
표면 판정으로 만듭니다. 끝난 변경 집합을 가진 호출자는 대신 셸에서
pdks covenant check --diff에 통합 diff를 파이프합니다. - 여기서는 텔레메트리 행을 쓰지 않습니다. 행은 모두 자식이 씁니다.
unjudged는 통과가 아닙니다. 판정기가 답하지 않았다는 사실을 기록하며, 판정기가 없는 프로젝트에서 무엇을 허용할지는 소비자가 정합니다.