kiokuko-dsh 0.1.60 → 0.1.62
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/PERMISSIONS.md +1 -1
- package/README.ja.md +1 -1
- package/README.ko.md +1 -1
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/dist/client.cjs +2 -2
- package/dist/dsh/config.d.ts +1 -0
- package/dist/dsh/config.d.ts.map +1 -1
- package/dist/dsh/lisp/attachment-input.d.ts +26 -0
- package/dist/dsh/lisp/attachment-input.d.ts.map +1 -0
- package/dist/dsh/lisp/attachment-input.js +47 -0
- package/dist/dsh/lisp/attachment-input.js.map +1 -0
- package/dist/dsh/lisp/contracts.d.ts +2 -1
- package/dist/dsh/lisp/contracts.d.ts.map +1 -1
- package/dist/dsh/lisp/contracts.js +1 -0
- package/dist/dsh/lisp/contracts.js.map +1 -1
- package/dist/dsh/lisp/manager.d.ts +13 -1
- package/dist/dsh/lisp/manager.d.ts.map +1 -1
- package/dist/dsh/lisp/manager.js +180 -21
- package/dist/dsh/lisp/manager.js.map +1 -1
- package/dist/dsh/lisp/surface.d.ts.map +1 -1
- package/dist/dsh/lisp/surface.js +76 -8
- package/dist/dsh/lisp/surface.js.map +1 -1
- package/dist/dsh/lisp/worker.d.ts +3 -0
- package/dist/dsh/lisp/worker.d.ts.map +1 -1
- package/dist/dsh/lisp/worker.js +4 -2
- package/dist/dsh/lisp/worker.js.map +1 -1
- package/dist/dsh/setup.d.ts +1 -1
- package/dist/dsh/setup.d.ts.map +1 -1
- package/dist/dsh/skill-prompts.json +1 -1
- package/dist/dsh/standard-skill-deployment.d.ts +1 -1
- package/dist/dsh/standard-skill-deployment.d.ts.map +1 -1
- package/dist/dsh/standard-skill-deployment.js +1 -1
- package/dist/dsh/standard-skill-deployment.js.map +1 -1
- package/dist/dsh/standard-skill-integrity.js +1 -1
- package/dist/dsh/standard-skills.d.ts +8 -1
- package/dist/dsh/standard-skills.d.ts.map +1 -1
- package/dist/dsh/standard-skills.js +14 -1
- package/dist/dsh/standard-skills.js.map +1 -1
- package/docs/dsh-plugin.md +16 -7
- package/docs/lisp.md +16 -0
- package/package.json +2 -2
- package/skills/kiokuko-lisp/SKILL.md +12 -2
- package/skills/kiokuko-soul/SKILL.md +1 -0
- package/skills/one-shot-software-completion/SKILL.md +85 -0
- package/skills/one-shot-software-completion/references/boundaries-and-lifecycle.md +56 -0
- package/skills/one-shot-software-completion/references/discovery-and-scope.md +67 -0
- package/skills/one-shot-software-completion/references/failure-recovery.md +43 -0
- package/skills/one-shot-software-completion/references/verification-and-completion.md +62 -0
package/PERMISSIONS.md
CHANGED
|
@@ -15,7 +15,7 @@ Kiokuko operation.
|
|
|
15
15
|
not a backup of the workspace or whole session. Later step inputs do not
|
|
16
16
|
replace it. Storage failure cannot veto the native turn; observed model or
|
|
17
17
|
tool execution prevents automatic input replay.
|
|
18
|
-
- On enabled plugin load, synchronizes all
|
|
18
|
+
- On enabled plugin load, synchronizes all nine bundled Skills and their
|
|
19
19
|
references to `~/.agents/skills/` before registering the DSH surfaces. Creates
|
|
20
20
|
missing files and atomically replaces files carrying their exact Kiokuko
|
|
21
21
|
management marker. Leaves unrelated files untouched and refuses unmanaged
|
package/README.ja.md
CHANGED
|
@@ -50,7 +50,7 @@ minimumReleaseAgeExclude:
|
|
|
50
50
|
- kiokuko-dsh
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
起動時に、日本語出力を含む全
|
|
53
|
+
起動時に、日本語出力を含む全9 Skillと参照ファイルを `~/.agents/skills/` へ同期します。不足分を作成し、管理対象の旧版を更新します。非管理ファイルは上書きしません。他のエージェントではSkillカタログの再読み込みが必要です。
|
|
54
54
|
|
|
55
55
|
起動時には、起動ディレクトリの `AGENTS.md` にある既存の Kiokuko 管理ブロックも更新し、その外側の指示は保持します。パッケージ更新後は DSH を再起動してください。別の作業ディレクトリや配備コピーの確認・修復は[セットアップ手順](docs/dsh-plugin.md#what-setup-updates-and-when)を参照してください。`kiokuko use` は DSH のセットアップコマンドではありません。
|
|
56
56
|
|
package/README.ko.md
CHANGED
|
@@ -52,7 +52,7 @@ minimumReleaseAgeExclude:
|
|
|
52
52
|
- kiokuko-dsh
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
-
시작 시 일본어 출력 Skill을 포함한 번들 Skill
|
|
55
|
+
시작 시 일본어 출력 Skill을 포함한 번들 Skill 9개와 참조 파일을 `~/.agents/skills/`에 동기화합니다. 누락된 파일을 만들고 관리 대상 복사본을 업데이트하며, 비관리 파일은 덮어쓰지 않습니다. 다른 에이전트에서는 Skill 카탈로그를 다시 로드해야 합니다.
|
|
56
56
|
|
|
57
57
|
시작 시 시작 디렉터리의 `AGENTS.md`에 있는 기존 Kiokuko 관리 블록도 갱신하며, 블록 밖의 지침은 보존합니다. 패키지 업데이트 후 DSH를 다시 시작하세요. 다른 작업 디렉터리나 오래된 복사본의 확인 및 복구는 [설정 절차](docs/dsh-plugin.md#what-setup-updates-and-when)를 참고하세요. `kiokuko use`는 DSH 설정 명령이 아닙니다.
|
|
58
58
|
|
package/README.md
CHANGED
|
@@ -51,7 +51,7 @@ minimumReleaseAgeExclude:
|
|
|
51
51
|
- kiokuko-dsh
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
At startup, all
|
|
54
|
+
At startup, all nine bundled Skills (including Japanese output) and their references are synchronized to `~/.agents/skills/`. Missing files are created and managed copies are updated; unmanaged files are preserved. Other agents must reload their Skill catalog.
|
|
55
55
|
|
|
56
56
|
Startup also refreshes an existing Kiokuko managed block in the startup directory’s `AGENTS.md`, preserving your other instructions. Restart DSH after updating the package. See [setup and verification](docs/dsh-plugin.md#what-setup-updates-and-when) for another workspace or stale copies; `kiokuko use` is not the DSH setup command.
|
|
57
57
|
|
package/README.zh-CN.md
CHANGED
|
@@ -52,7 +52,7 @@ minimumReleaseAgeExclude:
|
|
|
52
52
|
- kiokuko-dsh
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
-
启动时会将包括日语输出在内的全部
|
|
55
|
+
启动时会将包括日语输出在内的全部9个内置 Skill 及其引用文件同步到 `~/.agents/skills/`,创建缺失文件并更新受管理的副本,不覆盖非受管理文件。其他代理需要重新加载 Skill 目录。
|
|
56
56
|
|
|
57
57
|
启动时也会更新启动目录中 `AGENTS.md` 的现有 Kiokuko 管理块,保留块外的指令。更新包后请重启 DSH。其他工作目录或旧副本的检查与修复请参阅[设置步骤](docs/dsh-plugin.md#what-setup-updates-and-when)。`kiokuko use` 不是 DSH 的设置命令。
|
|
58
58
|
|
package/dist/client.cjs
CHANGED
|
@@ -323,7 +323,7 @@ window.__ModuleLoader__.load({
|
|
|
323
323
|
};
|
|
324
324
|
if (!status?.enabled && !error)
|
|
325
325
|
return null;
|
|
326
|
-
const label = { READY: '実行可能', EVALUATING: '処理中', PREFLIGHT: '起動中', STOPPING: '停止中', RECOVERY_REQUIRED: '確認が必要', STOP_UNCONFIRMED: '停止未確認' }[status?.state ?? ''] ?? '状態不明';
|
|
326
|
+
const label = { READY: '実行可能', SUSPENDED: '休止中(次回自動起動)', EVALUATING: '処理中', PREFLIGHT: '起動中', STOPPING: '停止中', RECOVERY_REQUIRED: '確認が必要', STOP_UNCONFIRMED: '停止未確認' }[status?.state ?? ''] ?? '状態不明';
|
|
327
327
|
return jsxs(Fragment, { children: [jsx('button', { type: 'button', ref: trigger, onClick: () => setOpen(true), children: `Lisp: ${label}` }),
|
|
328
328
|
jsx('dialog', { ref: dialog, onCancel: () => setOpen(false), 'aria-label': 'Lisp の状態と復旧', style: { maxWidth: 'min(720px, 90vw)', maxHeight: '85vh' },
|
|
329
329
|
children: jsxs('section', { children: [jsx('h2', { children: `Lisp: ${label}` }),
|
|
@@ -333,7 +333,7 @@ window.__ModuleLoader__.load({
|
|
|
333
333
|
...(details ? [jsx('pre', { style: { whiteSpace: 'pre-wrap', overflowWrap: 'anywhere' }, children: details })] : []),
|
|
334
334
|
jsx('p', { children: '未確定の変更は自動で再実行・復元しません。詳細は /kioku-lisp diagnostics でも確認できます。' }),
|
|
335
335
|
jsx('button', { type: 'button', disabled: busy, onClick: () => void act('cancel'), children: '停止する' }),
|
|
336
|
-
jsx('button', { type: 'button', disabled: busy || status?.state
|
|
336
|
+
jsx('button', { type: 'button', disabled: busy || ['STOP_UNCONFIRMED', 'SUSPENDED'].includes(status?.state ?? ''), onClick: () => void act('recover'), children: '照合して新しい Lisp を起動' }),
|
|
337
337
|
jsx('button', { type: 'button', onClick: () => setOpen(false), children: '閉じる' }),
|
|
338
338
|
] }) })] });
|
|
339
339
|
}
|
package/dist/dsh/config.d.ts
CHANGED
|
@@ -72,6 +72,7 @@ export declare const Config: z.ZodObject<{
|
|
|
72
72
|
timeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
73
73
|
startupTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
74
74
|
maxWorkers: z.ZodDefault<z.ZodNumber>;
|
|
75
|
+
idleTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
75
76
|
maxOutputBytes: z.ZodDefault<z.ZodNumber>;
|
|
76
77
|
}, z.core.$strict>>;
|
|
77
78
|
akinatorMemory: z.ZodPrefault<z.ZodObject<{
|
package/dist/dsh/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/dsh/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAA;AACxE,OAAO,EAAE,oBAAoB,EAAE,CAAA;AAC/B,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAA;AACxE,OAAO,EAAE,qBAAqB,EAAE,CAAA;AAChC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AAChE,OAAO,EAAE,kBAAkB,EAAE,CAAA;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,UAAU,EAAE,CAAA;AACrB,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAE,gBAAgB,EAAE,CAAA;AAK3B,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqBrB,CAAA;AACF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAA;AACnD,eAAO,MAAM,gBAAgB;;kBAA6D,CAAA;AAC1F,eAAO,MAAM,kBAAkB;;;;;kBAAyG,CAAA;AACxI,eAAO,MAAM,gBAAgB;;;;;;;;;kBAMlB,CAAA;AACX,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAC/D,mEAAmE;AACnE,eAAO,MAAM,MAAM
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/dsh/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAA;AACxE,OAAO,EAAE,oBAAoB,EAAE,CAAA;AAC/B,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAA;AACxE,OAAO,EAAE,qBAAqB,EAAE,CAAA;AAChC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AAChE,OAAO,EAAE,kBAAkB,EAAE,CAAA;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,UAAU,EAAE,CAAA;AACrB,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAE,gBAAgB,EAAE,CAAA;AAK3B,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqBrB,CAAA;AACF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAA;AACnD,eAAO,MAAM,gBAAgB;;kBAA6D,CAAA;AAC1F,eAAO,MAAM,kBAAkB;;;;;kBAAyG,CAAA;AACxI,eAAO,MAAM,gBAAgB;;;;;;;;;kBAMlB,CAAA;AACX,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAC/D,mEAAmE;AACnE,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAajB,CAAA;AACF,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,CAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
interface FileRef {
|
|
2
|
+
attachmentId: string;
|
|
3
|
+
name: string;
|
|
4
|
+
bytes: number;
|
|
5
|
+
}
|
|
6
|
+
export interface LispAttachmentStore {
|
|
7
|
+
fileHostPath?(ref: FileRef): string | undefined;
|
|
8
|
+
readFileStream?(ref: FileRef, signal?: AbortSignal): AsyncIterable<Uint8Array>;
|
|
9
|
+
}
|
|
10
|
+
export interface LispAttachmentSession {
|
|
11
|
+
snapshotEvents?(): readonly unknown[];
|
|
12
|
+
}
|
|
13
|
+
export interface AttachmentInput {
|
|
14
|
+
source: {
|
|
15
|
+
path: string;
|
|
16
|
+
attachmentId: string;
|
|
17
|
+
size: number;
|
|
18
|
+
hash: string;
|
|
19
|
+
};
|
|
20
|
+
size: number;
|
|
21
|
+
read(): Promise<Buffer>;
|
|
22
|
+
}
|
|
23
|
+
/** Only durable user-file parts in this live session confer attachment access. */
|
|
24
|
+
export declare function attachmentInput(session: LispAttachmentSession, store: LispAttachmentStore | undefined, path: string, signal?: AbortSignal): AttachmentInput;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=attachment-input.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachment-input.d.ts","sourceRoot":"","sources":["../../../src/dsh/lisp/attachment-input.ts"],"names":[],"mappings":"AAGA,UAAU,OAAO;IAAG,YAAY,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AACvE,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAA;IAC/C,cAAc,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,aAAa,CAAC,UAAU,CAAC,CAAA;CAC/E;AACD,MAAM,WAAW,qBAAqB;IAAG,cAAc,CAAC,IAAI,SAAS,OAAO,EAAE,CAAA;CAAE;AAChF,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IAC1E,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;CACxB;AAED,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,OAAO,EAAE,qBAAqB,EAAE,KAAK,EAAE,mBAAmB,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,eAAe,CAmC3J"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { FILE_BYTES, LispError, fail } from './contracts.js';
|
|
3
|
+
/** Only durable user-file parts in this live session confer attachment access. */
|
|
4
|
+
export function attachmentInput(session, store, path, signal) {
|
|
5
|
+
if (!store?.fileHostPath || !store.readFileStream || !session.snapshotEvents) {
|
|
6
|
+
throw new LispError('ATTACHMENT_UNAVAILABLE', 'このホストでは Lisp への添付入力を利用できません。', 'DSH の添付サービスを確認するか、ファイルを作業フォルダに置いて相対パスで指定してください。');
|
|
7
|
+
}
|
|
8
|
+
for (const raw of session.snapshotEvents()) {
|
|
9
|
+
const event = raw;
|
|
10
|
+
if (event?.type !== 'user/message' || event.data?.source?.kind !== 'user' || !Array.isArray(event.data.content))
|
|
11
|
+
continue;
|
|
12
|
+
for (const rawPart of event.data.content) {
|
|
13
|
+
const part = rawPart;
|
|
14
|
+
const ref = part?.attachment;
|
|
15
|
+
if (part?.type !== 'file' || !ref || typeof ref.attachmentId !== 'string' || !/^sha256:[a-f0-9]{64}$/u.test(ref.attachmentId)
|
|
16
|
+
|| typeof ref.name !== 'string' || !Number.isSafeInteger(ref.bytes) || ref.bytes < 0)
|
|
17
|
+
continue;
|
|
18
|
+
const file = { attachmentId: ref.attachmentId, name: ref.name, bytes: ref.bytes };
|
|
19
|
+
if (store.fileHostPath(file) !== path)
|
|
20
|
+
continue;
|
|
21
|
+
if (file.bytes > FILE_BYTES)
|
|
22
|
+
fail('FILE_LIMIT', '添付入力は 64 MiB 以下のファイルに限ります。');
|
|
23
|
+
const hash = file.attachmentId.slice(7);
|
|
24
|
+
return { source: { path, attachmentId: file.attachmentId, size: file.bytes, hash }, size: file.bytes,
|
|
25
|
+
read: async () => {
|
|
26
|
+
signal?.throwIfAborted();
|
|
27
|
+
const chunks = [], digest = createHash('sha256');
|
|
28
|
+
let size = 0;
|
|
29
|
+
for await (const chunk of store.readFileStream(file, signal)) {
|
|
30
|
+
signal?.throwIfAborted();
|
|
31
|
+
size += chunk.byteLength;
|
|
32
|
+
if (size > file.bytes || size > FILE_BYTES)
|
|
33
|
+
fail('ATTACHMENT_CHANGED', '添付ファイルの容量が記録と一致しません。');
|
|
34
|
+
const copy = Buffer.from(chunk);
|
|
35
|
+
chunks.push(copy);
|
|
36
|
+
digest.update(copy);
|
|
37
|
+
}
|
|
38
|
+
signal?.throwIfAborted();
|
|
39
|
+
if (size !== file.bytes || digest.digest('hex') !== hash)
|
|
40
|
+
fail('ATTACHMENT_CHANGED', '添付ファイルの内容が記録と一致しません。');
|
|
41
|
+
return Buffer.concat(chunks, size);
|
|
42
|
+
} };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
throw new LispError('ATTACHMENT_NOT_IN_SESSION', 'このセッションに添付されたファイルのパスではありません。', 'このセッションの添付パス、または作業フォルダ内の相対パスを inputs に指定してください。');
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=attachment-input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachment-input.js","sourceRoot":"","sources":["../../../src/dsh/lisp/attachment-input.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ export declare const LispConfig: z.ZodObject<{
|
|
|
5
5
|
timeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
6
6
|
startupTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
7
7
|
maxWorkers: z.ZodDefault<z.ZodNumber>;
|
|
8
|
+
idleTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
8
9
|
maxOutputBytes: z.ZodDefault<z.ZodNumber>;
|
|
9
10
|
}, z.core.$strict>;
|
|
10
11
|
export type LispConfiguration = z.infer<typeof LispConfig>;
|
|
@@ -19,7 +20,7 @@ export interface LispOwner {
|
|
|
19
20
|
agentId: string;
|
|
20
21
|
root: string;
|
|
21
22
|
}
|
|
22
|
-
export type LispState = 'DISABLED' | 'PREFLIGHT' | 'READY' | 'EVALUATING' | 'STOPPING' | 'RECOVERY_REQUIRED' | 'STOP_UNCONFIRMED';
|
|
23
|
+
export type LispState = 'DISABLED' | 'PREFLIGHT' | 'READY' | 'SUSPENDED' | 'EVALUATING' | 'STOPPING' | 'RECOVERY_REQUIRED' | 'STOP_UNCONFIRMED';
|
|
23
24
|
export declare class LispError extends Error {
|
|
24
25
|
readonly code: string;
|
|
25
26
|
readonly recovery: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../../src/dsh/lisp/contracts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,eAAO,MAAM,UAAU
|
|
1
|
+
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../../src/dsh/lisp/contracts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,eAAO,MAAM,UAAU;;;;;;;;kBAOZ,CAAA;AACX,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAA;AAC1D,eAAO,MAAM,UAAU,qGAAsG,CAAA;AAC7H,MAAM,MAAM,QAAQ,GAAG,OAAO,UAAU,CAAC,MAAM,CAAC,CAAA;AAChD,eAAO,MAAM,WAAW,UAAY,CAAA;AACpC,eAAO,MAAM,UAAU,QAAmB,CAAA;AAC1C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAC9D,eAAO,MAAM,UAAU,aAA0D,CAAA;AACjF,MAAM,WAAW,SAAS;IAAG,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AAC/E,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,OAAO,GAAG,WAAW,GAAG,YAAY,GAAG,UAAU,GAAG,mBAAmB,GAAG,kBAAkB,CAAA;AAC/I,qBAAa,SAAU,SAAQ,KAAK;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM;IAAmB,QAAQ,CAAC,QAAQ;gBAAhD,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAW,QAAQ,SAAqC;CAC3G;AACD,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAK7C;AACD,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,KAAK,CAAuC;AACjG,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAItG;AACD,eAAO,MAAM,SAAS;;;;kBACyD,CAAA;AAC/E,eAAO,MAAM,eAAe;;;;;;;iCAG1B,CAAA;AACF,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAC3D,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;4BAGtB,CAAA;AACF,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,CAAA"}
|
|
@@ -5,6 +5,7 @@ export const LispConfig = z.object({
|
|
|
5
5
|
timeoutMs: z.number().int().min(100).max(600_000).default(120_000),
|
|
6
6
|
startupTimeoutMs: z.number().int().min(100).max(60_000).default(30_000),
|
|
7
7
|
maxWorkers: z.number().int().min(1).max(32).default(4),
|
|
8
|
+
idleTimeoutMs: z.number().int().min(1000).max(3_600_000).default(300_000),
|
|
8
9
|
maxOutputBytes: z.number().int().min(1024).max(8_388_608).default(8_388_608),
|
|
9
10
|
}).strict();
|
|
10
11
|
export const LISP_TOOLS = ['lisp_eval', 'lisp_describe', 'lisp_inspect', 'lisp_status', 'lisp_cancel', 'lisp_reset'];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../../src/dsh/lisp/contracts.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../../src/dsh/lisp/contracts.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@ import { type LispConfiguration, type LispOwner, type LispTool } from './contrac
|
|
|
3
3
|
import { LispStore } from './store.js';
|
|
4
4
|
import { type LispCiRequest } from './ci.js';
|
|
5
5
|
import type { DshSkillPrompts } from '../skill-prompts.js';
|
|
6
|
+
import type { AttachmentInput } from './attachment-input.js';
|
|
6
7
|
export interface ManagerOptions {
|
|
7
8
|
skillPrompts?: DshSkillPrompts;
|
|
8
9
|
store: LispStore;
|
|
@@ -14,6 +15,7 @@ export interface ManagerOptions {
|
|
|
14
15
|
notify?: (owner: LispOwner, message: string) => void;
|
|
15
16
|
toolCall?: (owner: LispOwner, name: string, args: Record<string, unknown>) => Promise<unknown>;
|
|
16
17
|
ciCall?: (owner: LispOwner, request: LispCiRequest, signal: AbortSignal) => Promise<unknown>;
|
|
18
|
+
attachmentInput?: (owner: LispOwner, path: string, signal: AbortSignal) => AttachmentInput;
|
|
17
19
|
}
|
|
18
20
|
/** Host-owned authority. Worker frames never grant permissions or choose identities. */
|
|
19
21
|
export declare class LispManager {
|
|
@@ -24,8 +26,18 @@ export declare class LispManager {
|
|
|
24
26
|
start(): Promise<void>;
|
|
25
27
|
private entry;
|
|
26
28
|
private protectedRoots;
|
|
27
|
-
enable(owner: LispOwner): Promise<unknown>;
|
|
29
|
+
enable(owner: LispOwner, hostBusy?: boolean, signal?: AbortSignal): Promise<unknown>;
|
|
28
30
|
private startWorker;
|
|
31
|
+
/** Serialize only slot allocation/eviction; compilation remains concurrent. */
|
|
32
|
+
private reserveSlot;
|
|
33
|
+
private canSuspend;
|
|
34
|
+
private scheduleIdle;
|
|
35
|
+
private suspend;
|
|
36
|
+
/** Normal suspension is resumable; crashes and explicit cancellation are not. */
|
|
37
|
+
prepare(owner: LispOwner): Promise<unknown>;
|
|
38
|
+
setAgentBusy(owner: LispOwner, busy: boolean): void;
|
|
39
|
+
/** Disposed sessions retain their fence/journal but cannot admit new work. */
|
|
40
|
+
disposeSession(sessionId: string): Promise<void>;
|
|
29
41
|
private halted;
|
|
30
42
|
private bridge;
|
|
31
43
|
status(owner: LispOwner, offset?: number): Promise<unknown>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/dsh/lisp/manager.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAC9D,OAAO,EAA2D,KAAK,iBAAiB,EAAE,KAAK,SAAS,EAAkB,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAC/J,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAMtC,OAAO,EAAqB,KAAK,aAAa,EAAE,MAAM,SAAS,CAAA;AAI/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/dsh/lisp/manager.ts"],"names":[],"mappings":"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"}
|
package/dist/dsh/lisp/manager.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { mkdir, mkdtemp, open, readFile, realpath, unlink, writeFile } from 'node:fs/promises';
|
|
2
|
-
import { dirname, join } from 'node:path';
|
|
2
|
+
import { dirname, isAbsolute, join } from 'node:path';
|
|
3
3
|
import { randomUUID } from 'node:crypto';
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
5
|
import { z } from 'zod';
|
|
@@ -27,6 +27,7 @@ export class LispManager {
|
|
|
27
27
|
#closed = false;
|
|
28
28
|
#lock = false;
|
|
29
29
|
#artifactReserved = 0;
|
|
30
|
+
#admissionQueue = Promise.resolve();
|
|
30
31
|
#inflight = new Map();
|
|
31
32
|
constructor(options) {
|
|
32
33
|
this.options = options;
|
|
@@ -100,27 +101,33 @@ export class LispManager {
|
|
|
100
101
|
return state;
|
|
101
102
|
}
|
|
102
103
|
protectedRoots() { return [this.options.dataRoot, dirname(this.#library), ...this.options.protectedRoots ?? []]; }
|
|
103
|
-
async enable(owner) {
|
|
104
|
+
async enable(owner, hostBusy = false, signal) {
|
|
105
|
+
signal?.throwIfAborted();
|
|
104
106
|
if (!this.#config.enabled)
|
|
105
107
|
fail('LISP_DISABLED', '設定の lisp.enabled を true にしてプラグインを再読み込みしてください。');
|
|
106
108
|
if (this.#closed)
|
|
107
109
|
fail('HOST_STOPPED', 'プラグインが停止しています。');
|
|
108
|
-
if (this.enabled.has(owner.sessionId))
|
|
109
|
-
|
|
110
|
+
if (this.enabled.has(owner.sessionId)) {
|
|
111
|
+
this.setAgentBusy(owner, hostBusy);
|
|
112
|
+
return this.prepare(owner);
|
|
113
|
+
}
|
|
110
114
|
if (await realpath(owner.root) !== owner.root)
|
|
111
115
|
fail('SCOPE_CONFLICT', '作業ディレクトリを確認できません。');
|
|
112
116
|
// Persist the fence before starting any worker. A failed startup stays protected.
|
|
113
117
|
await this.#store.enable(owner);
|
|
114
118
|
this.enabled.set(owner.sessionId, owner.root);
|
|
119
|
+
signal?.throwIfAborted();
|
|
115
120
|
const state = this.entry(owner);
|
|
121
|
+
state.hostBusy = hostBusy;
|
|
116
122
|
await this.startWorker(state);
|
|
117
123
|
return this.status(owner);
|
|
118
124
|
}
|
|
119
125
|
async startWorker(state) {
|
|
120
126
|
if (state.admission)
|
|
121
127
|
return state.admission;
|
|
122
|
-
if (
|
|
123
|
-
fail('
|
|
128
|
+
if (this.#closed || state.disposed)
|
|
129
|
+
fail('HOST_STOPPED', 'Lisp のセッションが停止しています。');
|
|
130
|
+
clearTimeout(state.idleTimer);
|
|
124
131
|
state.state = 'PREFLIGHT';
|
|
125
132
|
state.compilation = { state: 'checking' };
|
|
126
133
|
const abort = new AbortController();
|
|
@@ -128,6 +135,7 @@ export class LispManager {
|
|
|
128
135
|
const admission = (async () => {
|
|
129
136
|
let worker;
|
|
130
137
|
try {
|
|
138
|
+
await this.reserveSlot(state);
|
|
131
139
|
const compiled = await this.#compiled.ensure(abort.signal, status => { state.compilation = status; });
|
|
132
140
|
if (this.#closed || state.state !== 'PREFLIGHT' || abort.signal.aborted)
|
|
133
141
|
fail('CANCELLED', '起動は取り消されています。');
|
|
@@ -162,8 +170,12 @@ export class LispManager {
|
|
|
162
170
|
catch (stop) {
|
|
163
171
|
error = stop;
|
|
164
172
|
}
|
|
165
|
-
|
|
166
|
-
|
|
173
|
+
if (error instanceof LispError && error.code === 'WORKER_LIMIT') {
|
|
174
|
+
state.state = 'SUSPENDED';
|
|
175
|
+
delete state.error;
|
|
176
|
+
}
|
|
177
|
+
else
|
|
178
|
+
this.halted(state, error);
|
|
167
179
|
throw error;
|
|
168
180
|
}
|
|
169
181
|
})();
|
|
@@ -173,9 +185,131 @@ export class LispManager {
|
|
|
173
185
|
}
|
|
174
186
|
finally {
|
|
175
187
|
delete state.admission;
|
|
188
|
+
delete state.slotReserved;
|
|
176
189
|
state.active.delete(abort);
|
|
190
|
+
this.scheduleIdle(state);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/** Serialize only slot allocation/eviction; compilation remains concurrent. */
|
|
194
|
+
reserveSlot(state) {
|
|
195
|
+
const allocation = this.#admissionQueue.then(async () => {
|
|
196
|
+
if (this.#closed || state.disposed || state.state !== 'PREFLIGHT')
|
|
197
|
+
fail('CANCELLED', 'Lisp の起動を取り消しました。');
|
|
198
|
+
const occupied = () => [...this.#agents.values()].filter(a => a.slotReserved || (a.worker && !a.worker.stopped)).length;
|
|
199
|
+
if (occupied() >= this.#config.maxWorkers) {
|
|
200
|
+
const candidates = [...this.#agents.values()].filter(a => a !== state && this.canSuspend(a)).sort((a, b) => (a.idleSince ?? 0) - (b.idleSince ?? 0));
|
|
201
|
+
for (const candidate of candidates) {
|
|
202
|
+
await this.suspend(candidate);
|
|
203
|
+
if (occupied() < this.#config.maxWorkers)
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (occupied() >= this.#config.maxWorkers)
|
|
208
|
+
throw new LispError('WORKER_LIMIT', 'Lisp の起動枠はすべて使用中です。待機中の Lisp は自動で停止します。', '実行中の処理が終わってから、もう一度依頼してください。');
|
|
209
|
+
if (this.#closed || state.disposed || state.state !== 'PREFLIGHT')
|
|
210
|
+
fail('CANCELLED', 'Lisp の起動を取り消しました。');
|
|
211
|
+
state.slotReserved = true;
|
|
212
|
+
});
|
|
213
|
+
this.#admissionQueue = allocation.catch(() => { });
|
|
214
|
+
return allocation;
|
|
215
|
+
}
|
|
216
|
+
canSuspend(state) {
|
|
217
|
+
return !this.#closed && !state.disposed && state.state === 'READY' && !state.hostBusy && !state.admission && state.active.size === 0
|
|
218
|
+
&& Boolean(state.worker?.healthy) && !state.worker?.hasRunningJobs;
|
|
219
|
+
}
|
|
220
|
+
scheduleIdle(state) {
|
|
221
|
+
clearTimeout(state.idleTimer);
|
|
222
|
+
if (this.#closed || state.disposed || state.state !== 'READY' || state.hostBusy || state.admission || state.active.size)
|
|
223
|
+
return;
|
|
224
|
+
state.idleSince = Date.now();
|
|
225
|
+
state.idleTimer = setTimeout(() => {
|
|
226
|
+
void this.suspend(state).then(() => {
|
|
227
|
+
// A background job can outlive the last evaluation. Recheck after it ends.
|
|
228
|
+
if (state.state === 'READY')
|
|
229
|
+
this.scheduleIdle(state);
|
|
230
|
+
}).catch(error => this.halted(state, error));
|
|
231
|
+
}, this.#config.idleTimeoutMs);
|
|
232
|
+
state.idleTimer.unref();
|
|
233
|
+
}
|
|
234
|
+
async suspend(state) {
|
|
235
|
+
if (!this.canSuspend(state))
|
|
236
|
+
return;
|
|
237
|
+
clearTimeout(state.idleTimer);
|
|
238
|
+
state.state = 'STOPPING'; // claim before awaiting the journal or process exit
|
|
239
|
+
const suspension = (async () => {
|
|
240
|
+
try {
|
|
241
|
+
const pending = (await this.#store.operations(state.owner.sessionId)).some(o => ['RUNNING', 'APPLYING', 'UNKNOWN', 'AWAITING_APPROVAL'].includes(o.state));
|
|
242
|
+
if (pending) {
|
|
243
|
+
state.state = 'READY';
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
await state.worker.stop();
|
|
247
|
+
state.state = 'SUSPENDED';
|
|
248
|
+
delete state.error;
|
|
249
|
+
delete state.worker;
|
|
250
|
+
}
|
|
251
|
+
catch (error) {
|
|
252
|
+
this.halted(state, error);
|
|
253
|
+
throw error;
|
|
254
|
+
}
|
|
255
|
+
})();
|
|
256
|
+
state.suspension = suspension;
|
|
257
|
+
try {
|
|
258
|
+
await suspension;
|
|
259
|
+
}
|
|
260
|
+
finally {
|
|
261
|
+
delete state.suspension;
|
|
177
262
|
}
|
|
178
263
|
}
|
|
264
|
+
/** Normal suspension is resumable; crashes and explicit cancellation are not. */
|
|
265
|
+
async prepare(owner) {
|
|
266
|
+
const state = this.entry(owner);
|
|
267
|
+
if (state.suspension)
|
|
268
|
+
await state.suspension;
|
|
269
|
+
if (state.state === 'SUSPENDED') {
|
|
270
|
+
await this.startWorker(state);
|
|
271
|
+
state.resumed = true;
|
|
272
|
+
}
|
|
273
|
+
else if (state.admission)
|
|
274
|
+
await state.admission;
|
|
275
|
+
return this.status(owner);
|
|
276
|
+
}
|
|
277
|
+
setAgentBusy(owner, busy) {
|
|
278
|
+
if (!this.enabled.has(owner.sessionId))
|
|
279
|
+
return;
|
|
280
|
+
const state = this.entry(owner);
|
|
281
|
+
if (state.hostBusy === busy)
|
|
282
|
+
return;
|
|
283
|
+
state.hostBusy = busy;
|
|
284
|
+
if (busy)
|
|
285
|
+
clearTimeout(state.idleTimer);
|
|
286
|
+
else
|
|
287
|
+
this.scheduleIdle(state);
|
|
288
|
+
}
|
|
289
|
+
/** Disposed sessions retain their fence/journal but cannot admit new work. */
|
|
290
|
+
async disposeSession(sessionId) {
|
|
291
|
+
const states = [...this.#agents.values()].filter(state => state.owner.sessionId === sessionId);
|
|
292
|
+
const resumable = states.filter(state => state.state === 'READY' || state.state === 'SUSPENDED');
|
|
293
|
+
for (const state of states) {
|
|
294
|
+
state.disposed = true;
|
|
295
|
+
clearTimeout(state.idleTimer);
|
|
296
|
+
}
|
|
297
|
+
const stopped = await Promise.allSettled(states.map(state => this.cancel(state)));
|
|
298
|
+
await Promise.allSettled([...this.#executions].filter(([, session]) => session === sessionId).map(([promise]) => promise));
|
|
299
|
+
const pending = (await this.#store.operations(sessionId)).some(o => ['RUNNING', 'APPLYING', 'UNKNOWN', 'AWAITING_APPROVAL'].includes(o.state));
|
|
300
|
+
for (const state of states) {
|
|
301
|
+
state.hostBusy = false;
|
|
302
|
+
state.disposed = false;
|
|
303
|
+
if (!pending && resumable.includes(state) && state.state === 'RECOVERY_REQUIRED' && state.worker?.stopped !== false) {
|
|
304
|
+
state.state = 'SUSPENDED';
|
|
305
|
+
delete state.worker;
|
|
306
|
+
delete state.error;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
const failed = stopped.find(result => result.status === 'rejected');
|
|
310
|
+
if (failed?.status === 'rejected')
|
|
311
|
+
throw failed.reason;
|
|
312
|
+
}
|
|
179
313
|
halted(state, error) {
|
|
180
314
|
state.error = failure(error);
|
|
181
315
|
state.state = state.error.code === 'STOP_UNCONFIRMED' ? 'STOP_UNCONFIRMED' : 'RECOVERY_REQUIRED';
|
|
@@ -251,12 +385,12 @@ export class LispManager {
|
|
|
251
385
|
const pending = operations.filter(o => ['RUNNING', 'UNKNOWN', 'APPLYING', 'AWAITING_APPROVAL'].includes(o.state));
|
|
252
386
|
return { enabled: true, state: state.state, generation: state.worker?.generation ?? null, error: state.error ?? null,
|
|
253
387
|
jobs: state.worker?.jobStatus() ?? [],
|
|
254
|
-
compilation: state.compilation ?? null,
|
|
255
|
-
limits: { timeoutMs: this.#config.timeoutMs, maxOutputBytes: this.#config.maxOutputBytes, maxWorkers: this.#config.maxWorkers,
|
|
388
|
+
compilation: state.compilation ?? null, resumed: state.resumed ?? false,
|
|
389
|
+
limits: { timeoutMs: this.#config.timeoutMs, maxOutputBytes: this.#config.maxOutputBytes, maxWorkers: this.#config.maxWorkers, idleTimeoutMs: this.#config.idleTimeoutMs,
|
|
256
390
|
aggregateMemory: 'unavailable', aggregateCpu: 'unavailable', scratchQuota: 'unavailable', termination: 'supervised', fileBoundary: process.platform === 'darwin' ? 'seatbelt' : 'bubblewrap' },
|
|
257
391
|
operations: offset === undefined ? operations : operations.slice(offset, offset + 10),
|
|
258
392
|
...(offset === undefined ? {} : { operationCount: operations.length, pendingCount: pending.length, pendingStates: Object.fromEntries([...new Set(pending.map(o => o.state))].map(state => [state, pending.filter(o => o.state === state).length])), offset, nextOffset: offset + 10 < operations.length ? offset + 10 : null }),
|
|
259
|
-
recovery: state.state === 'READY' ? null : '停止理由と操作履歴を確認し、/kioku-lisp recover を実行してください。' };
|
|
393
|
+
recovery: state.state === 'SUSPENDED' ? 'Lisp は休止中です。次の利用時に自動起動します。変数・関数定義は保持されません。' : state.state === 'READY' ? null : '停止理由と操作履歴を確認し、/kioku-lisp recover を実行してください。' };
|
|
260
394
|
}
|
|
261
395
|
async diagnostics(owner, id) {
|
|
262
396
|
this.entry(owner);
|
|
@@ -280,8 +414,13 @@ export class LispManager {
|
|
|
280
414
|
this.#inflight.set(key, hash);
|
|
281
415
|
const result = this.dispatch(owner, tool, input, signal);
|
|
282
416
|
this.#executions.set(result, owner.sessionId);
|
|
283
|
-
const finished = () => {
|
|
284
|
-
this.#
|
|
417
|
+
const finished = () => {
|
|
418
|
+
this.#executions.delete(result);
|
|
419
|
+
if (key)
|
|
420
|
+
this.#inflight.delete(key);
|
|
421
|
+
if (tool !== 'lisp_status' && this.enabled.has(owner.sessionId))
|
|
422
|
+
this.scheduleIdle(this.entry(owner));
|
|
423
|
+
};
|
|
285
424
|
void result.then(finished, finished);
|
|
286
425
|
return result;
|
|
287
426
|
}
|
|
@@ -327,8 +466,8 @@ export class LispManager {
|
|
|
327
466
|
await this.cancel(state);
|
|
328
467
|
return { ok: true, state: state.state };
|
|
329
468
|
}
|
|
330
|
-
if (this.#closed)
|
|
331
|
-
fail('HOST_STOPPED', 'Lisp
|
|
469
|
+
if (this.#closed || state.disposed)
|
|
470
|
+
fail('HOST_STOPPED', 'Lisp のホストまたはセッションが停止しています。');
|
|
332
471
|
const id = identifier.parse(input.operationId);
|
|
333
472
|
const hash = digest({ tool, input });
|
|
334
473
|
const old = await this.#store.get(owner, id);
|
|
@@ -337,6 +476,13 @@ export class LispManager {
|
|
|
337
476
|
fail('ID_CONFLICT', '同じ操作 ID の内容を変えることはできません。');
|
|
338
477
|
return await this.replay(owner, old);
|
|
339
478
|
}
|
|
479
|
+
if (state.suspension || state.state === 'SUSPENDED') {
|
|
480
|
+
const prepared = await this.prepare(owner);
|
|
481
|
+
if (prepared.state !== 'READY')
|
|
482
|
+
fail('RECOVERY_REQUIRED', 'Lisp の停止状態を確認してください。');
|
|
483
|
+
return { ok: false, code: 'WORKER_RESUMED', generation: state.worker?.generation, executed: false,
|
|
484
|
+
message: '休止中の Lisp を自動起動しました。以前の変数・関数・参照は失われています。必要な定義を作り直してから実行してください。この要求のコードは実行していません。過去の副作用を再実行しないでください。' };
|
|
485
|
+
}
|
|
340
486
|
if (tool === 'lisp_reset') {
|
|
341
487
|
if (state.state !== 'READY')
|
|
342
488
|
fail('RECOVERY_REQUIRED', '異常停止からの再開には /kioku-lisp recover を使ってください。');
|
|
@@ -373,19 +519,26 @@ export class LispManager {
|
|
|
373
519
|
const snapshots = [];
|
|
374
520
|
const sources = [];
|
|
375
521
|
for (const path of parsed.inputs) {
|
|
522
|
+
if (isAbsolute(path) && this.options.attachmentInput) {
|
|
523
|
+
sources.push(this.options.attachmentInput(owner, path, combined));
|
|
524
|
+
continue;
|
|
525
|
+
}
|
|
376
526
|
const before = await snapshot(owner.root, path, this.protectedRoots());
|
|
377
527
|
if (!before.exists)
|
|
378
528
|
throw new LispError('INPUT_MISSING', `入力ファイルがありません: ${path}`, 'read/glob で対象パスを確認し、inputs を修正してください。Lisp の復旧は不要です。');
|
|
379
|
-
sources.push(before);
|
|
529
|
+
sources.push({ source: before, size: before.size, read: () => checkedBytes(before) });
|
|
380
530
|
}
|
|
381
|
-
if ((state.inputBytes ?? 0) + sources.reduce((sum,
|
|
531
|
+
if ((state.inputBytes ?? 0) + sources.reduce((sum, input) => sum + input.size, 0) > 256 * 1024 ** 2)
|
|
382
532
|
fail('INPUT_LIMIT', 'この Lisp 世代の入力コピーが 256 MiB を超えます。状態を確認して reset してください。');
|
|
383
|
-
for (const
|
|
384
|
-
|
|
533
|
+
for (const source of sources) {
|
|
534
|
+
combined.throwIfAborted();
|
|
535
|
+
const bytes = await source.read();
|
|
536
|
+
combined.throwIfAborted();
|
|
537
|
+
state.inputBytes = (state.inputBytes ?? 0) + source.size;
|
|
385
538
|
const target = join(worker.layout.inputs, randomUUID());
|
|
386
|
-
await writeFile(target,
|
|
539
|
+
await writeFile(target, bytes, { flag: 'wx', mode: 0o400 });
|
|
387
540
|
inputs.push(target);
|
|
388
|
-
snapshots.push({ source:
|
|
541
|
+
snapshots.push({ source: source.source, input: target });
|
|
389
542
|
}
|
|
390
543
|
payload.snapshots = snapshots;
|
|
391
544
|
args = { code: parsed.code, inputs };
|
|
@@ -467,6 +620,9 @@ export class LispManager {
|
|
|
467
620
|
result: await recordedResult(this.#store, owner, old), recovery: ['RUNNING', 'UNKNOWN'].includes(old.state) ? '/kioku-lisp status で確認してください。自動再実行はしません。' : null };
|
|
468
621
|
}
|
|
469
622
|
async cancel(state) {
|
|
623
|
+
clearTimeout(state.idleTimer);
|
|
624
|
+
if (state.suspension)
|
|
625
|
+
await state.suspension;
|
|
470
626
|
state.state = 'STOPPING';
|
|
471
627
|
for (const abort of state.active)
|
|
472
628
|
abort.abort(new LispError('CANCELLED', 'Lisp の処理を取り消しました。'));
|
|
@@ -546,6 +702,9 @@ export class LispManager {
|
|
|
546
702
|
fail('RECOVERY_REQUIRED', '未確定の処理を /kioku-lisp recover で確認してから解除してください。');
|
|
547
703
|
await this.#store.disable(owner.sessionId);
|
|
548
704
|
this.enabled.delete(owner.sessionId);
|
|
705
|
+
for (const [key, state] of this.#agents)
|
|
706
|
+
if (state.owner.sessionId === owner.sessionId)
|
|
707
|
+
this.#agents.delete(key);
|
|
549
708
|
return { ok: true, state: 'DISABLED' };
|
|
550
709
|
}
|
|
551
710
|
async dispose() {
|