promptkaizen-agent 0.2.0 → 0.3.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/README.md +5 -1
- package/dist/backfill/run.d.ts +15 -0
- package/dist/backfill/run.d.ts.map +1 -0
- package/dist/backfill/run.js +33 -0
- package/dist/backfill/run.js.map +1 -0
- package/dist/backfill/scanner.d.ts +82 -0
- package/dist/backfill/scanner.d.ts.map +1 -0
- package/dist/backfill/scanner.js +271 -0
- package/dist/backfill/scanner.js.map +1 -0
- package/dist/cli/detect.d.ts +2 -0
- package/dist/cli/detect.d.ts.map +1 -0
- package/dist/cli/detect.js +40 -0
- package/dist/cli/detect.js.map +1 -0
- package/dist/cli/disable.d.ts +2 -0
- package/dist/cli/disable.d.ts.map +1 -0
- package/dist/cli/disable.js +44 -0
- package/dist/cli/disable.js.map +1 -0
- package/dist/cli/enable.d.ts +2 -0
- package/dist/cli/enable.d.ts.map +1 -0
- package/dist/cli/enable.js +105 -0
- package/dist/cli/enable.js.map +1 -0
- package/dist/cli/hook.d.ts +2 -0
- package/dist/cli/hook.d.ts.map +1 -0
- package/dist/cli/hook.js +406 -0
- package/dist/cli/hook.js.map +1 -0
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +70 -8
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/install-hooks.d.ts +5 -0
- package/dist/cli/install-hooks.d.ts.map +1 -0
- package/dist/cli/install-hooks.js +132 -0
- package/dist/cli/install-hooks.js.map +1 -0
- package/dist/cli/install-task.d.ts +28 -0
- package/dist/cli/install-task.d.ts.map +1 -0
- package/dist/cli/install-task.js +119 -0
- package/dist/cli/install-task.js.map +1 -0
- package/dist/cli/mcp.d.ts +2 -0
- package/dist/cli/mcp.d.ts.map +1 -0
- package/dist/cli/mcp.js +148 -0
- package/dist/cli/mcp.js.map +1 -0
- package/dist/cli/metrics.d.ts +2 -0
- package/dist/cli/metrics.d.ts.map +1 -0
- package/dist/cli/metrics.js +103 -0
- package/dist/cli/metrics.js.map +1 -0
- package/dist/cli/report.d.ts +2 -0
- package/dist/cli/report.d.ts.map +1 -0
- package/dist/cli/report.js +211 -0
- package/dist/cli/report.js.map +1 -0
- package/dist/cli/scan.d.ts +2 -0
- package/dist/cli/scan.d.ts.map +1 -0
- package/dist/cli/scan.js +171 -0
- package/dist/cli/scan.js.map +1 -0
- package/dist/cli/start.d.ts.map +1 -1
- package/dist/cli/start.js +70 -17
- package/dist/cli/start.js.map +1 -1
- package/dist/cli/status.d.ts.map +1 -1
- package/dist/cli/status.js +82 -18
- package/dist/cli/status.js.map +1 -1
- package/dist/cli/uninstall-task.d.ts +8 -0
- package/dist/cli/uninstall-task.d.ts.map +1 -0
- package/dist/cli/uninstall-task.js +44 -0
- package/dist/cli/uninstall-task.js.map +1 -0
- package/dist/config.d.ts +172 -6
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +114 -2
- package/dist/config.js.map +1 -1
- package/dist/console-safe.d.ts +21 -0
- package/dist/console-safe.d.ts.map +1 -0
- package/dist/console-safe.js +71 -0
- package/dist/console-safe.js.map +1 -0
- package/dist/detection-secret.d.ts.map +1 -1
- package/dist/detection-secret.js +12 -0
- package/dist/detection-secret.js.map +1 -1
- package/dist/env-detect.d.ts +44 -0
- package/dist/env-detect.d.ts.map +1 -0
- package/dist/env-detect.js +151 -0
- package/dist/env-detect.js.map +1 -0
- package/dist/exec/executor.d.ts +42 -0
- package/dist/exec/executor.d.ts.map +1 -0
- package/dist/exec/executor.js +135 -0
- package/dist/exec/executor.js.map +1 -0
- package/dist/exec/pk-execute.d.ts +30 -0
- package/dist/exec/pk-execute.d.ts.map +1 -0
- package/dist/exec/pk-execute.js +174 -0
- package/dist/exec/pk-execute.js.map +1 -0
- package/dist/exec/policy-fetcher.d.ts +9 -0
- package/dist/exec/policy-fetcher.d.ts.map +1 -0
- package/dist/exec/policy-fetcher.js +46 -0
- package/dist/exec/policy-fetcher.js.map +1 -0
- package/dist/exec/policy.d.ts +32 -0
- package/dist/exec/policy.d.ts.map +1 -0
- package/dist/exec/policy.js +88 -0
- package/dist/exec/policy.js.map +1 -0
- package/dist/hooks/block-store.d.ts +14 -0
- package/dist/hooks/block-store.d.ts.map +1 -0
- package/dist/hooks/block-store.js +26 -0
- package/dist/hooks/block-store.js.map +1 -0
- package/dist/hooks/claude-hook.d.ts +55 -0
- package/dist/hooks/claude-hook.d.ts.map +1 -0
- package/dist/hooks/claude-hook.js +122 -0
- package/dist/hooks/claude-hook.js.map +1 -0
- package/dist/hooks/continuity.d.ts +48 -0
- package/dist/hooks/continuity.d.ts.map +1 -0
- package/dist/hooks/continuity.js +92 -0
- package/dist/hooks/continuity.js.map +1 -0
- package/dist/hooks/observation.d.ts +27 -0
- package/dist/hooks/observation.d.ts.map +1 -0
- package/dist/hooks/observation.js +0 -0
- package/dist/hooks/observation.js.map +1 -0
- package/dist/hooks/platforms.d.ts +24 -0
- package/dist/hooks/platforms.d.ts.map +1 -0
- package/dist/hooks/platforms.js +57 -0
- package/dist/hooks/platforms.js.map +1 -0
- package/dist/hooks/read-cache.d.ts +71 -0
- package/dist/hooks/read-cache.d.ts.map +1 -0
- package/dist/hooks/read-cache.js +166 -0
- package/dist/hooks/read-cache.js.map +1 -0
- package/dist/hooks/reduction.d.ts +78 -0
- package/dist/hooks/reduction.d.ts.map +1 -0
- package/dist/hooks/reduction.js +111 -0
- package/dist/hooks/reduction.js.map +1 -0
- package/dist/hooks/settings-merge.d.ts +32 -0
- package/dist/hooks/settings-merge.d.ts.map +1 -0
- package/dist/hooks/settings-merge.js +74 -0
- package/dist/hooks/settings-merge.js.map +1 -0
- package/dist/hooks/snapshot.d.ts +37 -0
- package/dist/hooks/snapshot.d.ts.map +1 -0
- package/dist/hooks/snapshot.js +180 -0
- package/dist/hooks/snapshot.js.map +1 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.d.ts +118 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +240 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/onboarding-report.d.ts +66 -0
- package/dist/onboarding-report.d.ts.map +1 -0
- package/dist/onboarding-report.js +152 -0
- package/dist/onboarding-report.js.map +1 -0
- package/dist/onboarding.d.ts +55 -0
- package/dist/onboarding.d.ts.map +1 -0
- package/dist/onboarding.js +98 -0
- package/dist/onboarding.js.map +1 -0
- package/dist/pii-masker.d.ts +7 -0
- package/dist/pii-masker.d.ts.map +1 -1
- package/dist/pii-masker.js +27 -51
- package/dist/pii-masker.js.map +1 -1
- package/dist/privacy.d.ts +13 -0
- package/dist/privacy.d.ts.map +1 -0
- package/dist/privacy.js +67 -0
- package/dist/privacy.js.map +1 -0
- package/dist/residency.d.ts +21 -0
- package/dist/residency.d.ts.map +1 -0
- package/dist/residency.js +68 -0
- package/dist/residency.js.map +1 -0
- package/dist/secret-detector.d.ts +19 -0
- package/dist/secret-detector.d.ts.map +1 -1
- package/dist/secret-detector.js +116 -0
- package/dist/secret-detector.js.map +1 -1
- package/dist/store/local-store.d.ts +167 -0
- package/dist/store/local-store.d.ts.map +1 -0
- package/dist/store/local-store.js +538 -0
- package/dist/store/local-store.js.map +1 -0
- package/dist/store/schema.d.ts +38 -0
- package/dist/store/schema.d.ts.map +1 -0
- package/dist/store/schema.js +189 -0
- package/dist/store/schema.js.map +1 -0
- package/dist/types.d.ts +13 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/watcher.d.ts +6 -0
- package/dist/watcher.d.ts.map +1 -1
- package/dist/watcher.js +13 -2
- package/dist/watcher.js.map +1 -1
- package/package.json +4 -2
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** 組織ポリシー (#44 PolicyConfig.execution) の agent 側表現。 */
|
|
2
|
+
export interface ExecutionPolicy {
|
|
3
|
+
/** 禁止コマンド (正規表現文字列)。 */
|
|
4
|
+
forbiddenCommands: string[];
|
|
5
|
+
/** 禁止パス (前方一致 / ~ 展開対応)。 */
|
|
6
|
+
forbiddenPaths: string[];
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* ビルトイン禁止コマンド (高シグナルのみ。誤検知しやすい汎用語は入れない)。
|
|
10
|
+
* 組織ポリシーは追加方向にのみ働く (緩める方向の上書きは不可 = 安全側)。
|
|
11
|
+
*/
|
|
12
|
+
export declare const BUILTIN_FORBIDDEN_COMMANDS: Array<{
|
|
13
|
+
ruleId: string;
|
|
14
|
+
pattern: string;
|
|
15
|
+
label: string;
|
|
16
|
+
}>;
|
|
17
|
+
/** ビルトイン禁止パス (秘匿情報ディレクトリ)。組織ポリシーで追加可能。 */
|
|
18
|
+
export declare const BUILTIN_FORBIDDEN_PATHS: string[];
|
|
19
|
+
export interface PolicyVerdict {
|
|
20
|
+
allowed: boolean;
|
|
21
|
+
/** 拒否時のみ。detection メタ・拒否メッセージに使う。 */
|
|
22
|
+
ruleId?: string;
|
|
23
|
+
reason?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* code を実行ポリシーに照らす。拒否は最初の該当 1 件を返す。
|
|
27
|
+
* - 禁止コマンド: ビルトイン + 組織ポリシーの正規表現
|
|
28
|
+
* - 禁止パス: ビルトイン + 組織ポリシー (~ 表記と展開後の両方で部分一致)
|
|
29
|
+
* - プロジェクトルート外の絶対パス参照 (ホーム直下・システム領域) を拒否
|
|
30
|
+
*/
|
|
31
|
+
export declare function checkExecutionPolicy(code: string, policy: ExecutionPolicy | null, projectRoot: string): PolicyVerdict;
|
|
32
|
+
//# sourceMappingURL=policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/exec/policy.ts"],"names":[],"mappings":"AAiBA,uDAAuD;AACvD,MAAM,WAAW,eAAe;IAC9B,wBAAwB;IACxB,iBAAiB,EAAE,MAAM,EAAE,CAAA;IAC3B,4BAA4B;IAC5B,cAAc,EAAE,MAAM,EAAE,CAAA;CACzB;AAED;;;GAGG;AACH,eAAO,MAAM,0BAA0B,EAAE,KAAK,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAQhG,CAAA;AAED,0CAA0C;AAC1C,eAAO,MAAM,uBAAuB,UAA0E,CAAA;AAE9G,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAA;IAChB,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAMD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,eAAe,GAAG,IAAI,EAC9B,WAAW,EAAE,MAAM,GAClB,aAAa,CAkDf"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.BUILTIN_FORBIDDEN_PATHS = exports.BUILTIN_FORBIDDEN_COMMANDS = void 0;
|
|
7
|
+
exports.checkExecutionPolicy = checkExecutionPolicy;
|
|
8
|
+
const os_1 = __importDefault(require("os"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
/**
|
|
11
|
+
* ビルトイン禁止コマンド (高シグナルのみ。誤検知しやすい汎用語は入れない)。
|
|
12
|
+
* 組織ポリシーは追加方向にのみ働く (緩める方向の上書きは不可 = 安全側)。
|
|
13
|
+
*/
|
|
14
|
+
exports.BUILTIN_FORBIDDEN_COMMANDS = [
|
|
15
|
+
{ ruleId: 'exec_rm_rf', pattern: 'rm\\s+(-[a-zA-Z]*r[a-zA-Z]*f|-[a-zA-Z]*f[a-zA-Z]*r)\\b', label: 'rm -rf' },
|
|
16
|
+
{ ruleId: 'exec_sudo', pattern: '(^|[\\s;|&])sudo\\s', label: 'sudo' },
|
|
17
|
+
{ ruleId: 'exec_mkfs', pattern: '\\bmkfs(\\.|\\s)', label: 'mkfs' },
|
|
18
|
+
{ ruleId: 'exec_dd_device', pattern: '\\bdd\\s+[^\\n]*of=/dev/', label: 'dd of=/dev/*' },
|
|
19
|
+
{ ruleId: 'exec_fork_bomb', pattern: ':\\(\\)\\s*\\{\\s*:\\s*\\|\\s*:', label: 'fork bomb' },
|
|
20
|
+
{ ruleId: 'exec_shutdown', pattern: '(^|[\\s;|&])(shutdown|reboot|halt)\\s*($|[\\s;|&-])', label: 'shutdown/reboot' },
|
|
21
|
+
{ ruleId: 'exec_curl_pipe_sh', pattern: '(curl|wget)\\s[^\\n|]*\\|\\s*(ba|z)?sh\\b', label: 'curl | sh' },
|
|
22
|
+
];
|
|
23
|
+
/** ビルトイン禁止パス (秘匿情報ディレクトリ)。組織ポリシーで追加可能。 */
|
|
24
|
+
exports.BUILTIN_FORBIDDEN_PATHS = ['~/.ssh', '~/.aws', '~/.gnupg', '~/.config/gcloud', '~/.promptkaizen'];
|
|
25
|
+
function expandHome(p) {
|
|
26
|
+
return p.startsWith('~') ? path_1.default.join(os_1.default.homedir(), p.slice(1)) : p;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* code を実行ポリシーに照らす。拒否は最初の該当 1 件を返す。
|
|
30
|
+
* - 禁止コマンド: ビルトイン + 組織ポリシーの正規表現
|
|
31
|
+
* - 禁止パス: ビルトイン + 組織ポリシー (~ 表記と展開後の両方で部分一致)
|
|
32
|
+
* - プロジェクトルート外の絶対パス参照 (ホーム直下・システム領域) を拒否
|
|
33
|
+
*/
|
|
34
|
+
function checkExecutionPolicy(code, policy, projectRoot) {
|
|
35
|
+
// 1. 禁止コマンド (ビルトイン)
|
|
36
|
+
for (const b of exports.BUILTIN_FORBIDDEN_COMMANDS) {
|
|
37
|
+
if (new RegExp(b.pattern).test(code)) {
|
|
38
|
+
return { allowed: false, ruleId: b.ruleId, reason: `禁止コマンド (${b.label}) を含むため実行できません` };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// 2. 禁止コマンド (組織ポリシー)。不正な正規表現は 1 件で全体を落とさずスキップ。
|
|
42
|
+
for (const pattern of policy?.forbiddenCommands ?? []) {
|
|
43
|
+
try {
|
|
44
|
+
if (new RegExp(pattern).test(code)) {
|
|
45
|
+
return {
|
|
46
|
+
allowed: false,
|
|
47
|
+
ruleId: 'exec_org_forbidden_command',
|
|
48
|
+
reason: '組織ポリシーの禁止コマンドに該当するため実行できません',
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
/* invalid regex → skip */
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// 3. 禁止パス (ビルトイン + 組織)。~ 表記と展開後の両方を見る。
|
|
57
|
+
const forbiddenPaths = [...exports.BUILTIN_FORBIDDEN_PATHS, ...(policy?.forbiddenPaths ?? [])];
|
|
58
|
+
for (const p of forbiddenPaths) {
|
|
59
|
+
const expanded = expandHome(p);
|
|
60
|
+
if (code.includes(p) || (expanded !== p && code.includes(expanded))) {
|
|
61
|
+
return {
|
|
62
|
+
allowed: false,
|
|
63
|
+
ruleId: 'exec_forbidden_path',
|
|
64
|
+
reason: `禁止パス (${p}) への参照を含むため実行できません`,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// 4. プロジェクトルート外の絶対パス参照 (作業ディレクトリ制限)。
|
|
69
|
+
// システム領域・他ユーザー領域を指す絶対パスを高シグナルに検査する。
|
|
70
|
+
// /tmp と projectRoot 配下、および /usr 等の読み取り系ツールパスは許容。
|
|
71
|
+
const rootResolved = path_1.default.resolve(projectRoot);
|
|
72
|
+
const absPattern = /(?:^|[\s"'`=(])(\/(?:Users|home|etc|var|root)\/[^\s"'`);|&]*)/g;
|
|
73
|
+
for (const m of code.matchAll(absPattern)) {
|
|
74
|
+
const ref = m[1];
|
|
75
|
+
const resolved = path_1.default.resolve(ref);
|
|
76
|
+
if (resolved === rootResolved || resolved.startsWith(rootResolved + path_1.default.sep))
|
|
77
|
+
continue;
|
|
78
|
+
if (resolved.startsWith(path_1.default.resolve(os_1.default.tmpdir()) + path_1.default.sep))
|
|
79
|
+
continue;
|
|
80
|
+
return {
|
|
81
|
+
allowed: false,
|
|
82
|
+
ruleId: 'exec_outside_project_root',
|
|
83
|
+
reason: `プロジェクトルート外のパス (${ref}) への参照を含むため実行できません`,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return { allowed: true };
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/exec/policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DetectionMeta } from '../secret-detector';
|
|
2
|
+
declare const BLOCK_LOG_PATH: string;
|
|
3
|
+
export interface BlockEvent {
|
|
4
|
+
recordedAt: string;
|
|
5
|
+
sessionId: string | null;
|
|
6
|
+
cwd: string | null;
|
|
7
|
+
toolName: string | null;
|
|
8
|
+
/** 生機密を含まない検知メタ。 */
|
|
9
|
+
detections: DetectionMeta[];
|
|
10
|
+
}
|
|
11
|
+
/** ブロックイベントを 1 行 append する (best-effort、失敗してもブロック自体は成立)。 */
|
|
12
|
+
export declare function recordBlockEvent(event: BlockEvent, logPath?: string): Promise<void>;
|
|
13
|
+
export { BLOCK_LOG_PATH };
|
|
14
|
+
//# sourceMappingURL=block-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"block-store.d.ts","sourceRoot":"","sources":["../../src/hooks/block-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAWvD,QAAA,MAAM,cAAc,QAAiE,CAAA;AAErF,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,oBAAoB;IACpB,UAAU,EAAE,aAAa,EAAE,CAAA;CAC5B;AAED,4DAA4D;AAC5D,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,UAAU,EACjB,OAAO,GAAE,MAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAGf;AAED,OAAO,EAAE,cAAc,EAAE,CAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.BLOCK_LOG_PATH = void 0;
|
|
7
|
+
exports.recordBlockEvent = recordBlockEvent;
|
|
8
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
|
9
|
+
const os_1 = __importDefault(require("os"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
// =============================================
|
|
12
|
+
// ブロックイベントの記録 (Issue #67)
|
|
13
|
+
// =============================================
|
|
14
|
+
//
|
|
15
|
+
// PreToolUse で deny したイベントをローカルに追記記録する。受け入れ条件は
|
|
16
|
+
// 「ローカル SQLite へ記録」だが、SQLite 導入は Epic #66 P2 (#68) の専用スコープ。
|
|
17
|
+
// 本タスクでは依存を増やさず JSONL に追記し、#68 で SQLite (FTS5) へ移行する。
|
|
18
|
+
// 記録するのは検知メタ (生機密本文を含まない) のみ。
|
|
19
|
+
const BLOCK_LOG_PATH = path_1.default.join(os_1.default.homedir(), '.promptkaizen', 'block-events.jsonl');
|
|
20
|
+
exports.BLOCK_LOG_PATH = BLOCK_LOG_PATH;
|
|
21
|
+
/** ブロックイベントを 1 行 append する (best-effort、失敗してもブロック自体は成立)。 */
|
|
22
|
+
async function recordBlockEvent(event, logPath = BLOCK_LOG_PATH) {
|
|
23
|
+
await promises_1.default.mkdir(path_1.default.dirname(logPath), { recursive: true });
|
|
24
|
+
await promises_1.default.appendFile(logPath, JSON.stringify(event) + '\n', { mode: 0o600 });
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=block-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"block-store.js","sourceRoot":"","sources":["../../src/hooks/block-store.ts"],"names":[],"mappings":";;;;;;AA0BA,4CAMC;AAhCD,2DAA4B;AAC5B,4CAAmB;AACnB,gDAAuB;AAGvB,gDAAgD;AAChD,0BAA0B;AAC1B,gDAAgD;AAChD,EAAE;AACF,+CAA+C;AAC/C,4DAA4D;AAC5D,sDAAsD;AACtD,8BAA8B;AAE9B,MAAM,cAAc,GAAG,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,OAAO,EAAE,EAAE,eAAe,EAAE,oBAAoB,CAAC,CAAA;AAoB5E,wCAAc;AATvB,4DAA4D;AACrD,KAAK,UAAU,gBAAgB,CACpC,KAAiB,EACjB,UAAkB,cAAc;IAEhC,MAAM,kBAAE,CAAC,KAAK,CAAC,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC1D,MAAM,kBAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;AAC7E,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { SecretDetector, type DetectionMeta } from '../secret-detector';
|
|
2
|
+
/**
|
|
3
|
+
* 対応する hook イベント (全プラットフォームの和集合)。
|
|
4
|
+
* プラットフォーム別にどれを登録/受理するかは hooks/platforms.ts が定義する。
|
|
5
|
+
* - PreCompact: Claude Code 固有。
|
|
6
|
+
* - Stop: Codex CLI のターン終了イベント (#70)。観測のみ。
|
|
7
|
+
*/
|
|
8
|
+
export declare const SUPPORTED_EVENTS: readonly ["PreToolUse", "PostToolUse", "UserPromptSubmit", "SessionStart", "PreCompact", "Stop"];
|
|
9
|
+
export type HookEvent = (typeof SUPPORTED_EVENTS)[number];
|
|
10
|
+
export declare function isHookEvent(v: unknown): v is HookEvent;
|
|
11
|
+
/** Claude Code が stdin で渡す共通フィールド (必要な分のみ)。 */
|
|
12
|
+
export interface HookInput {
|
|
13
|
+
hook_event_name?: string;
|
|
14
|
+
session_id?: string;
|
|
15
|
+
cwd?: string;
|
|
16
|
+
transcript_path?: string;
|
|
17
|
+
tool_name?: string;
|
|
18
|
+
tool_input?: unknown;
|
|
19
|
+
prompt?: string;
|
|
20
|
+
[k: string]: unknown;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* PreToolUse の deny は無条件ブロックなので、誤検知の影響が大きい。
|
|
24
|
+
* file_path 等の「パスにキーらしき文字列が紛れる」誤検出を避けるため、
|
|
25
|
+
* 値部分 (コマンド本文・プロンプト) のみを検知対象に集める。
|
|
26
|
+
*/
|
|
27
|
+
export declare function extractRiskText(event: HookEvent, input: HookInput): string;
|
|
28
|
+
/** PreToolUse の出力 (Claude Code hooks の hookSpecificOutput 形式)。 */
|
|
29
|
+
export interface PreToolUseDecision {
|
|
30
|
+
hookSpecificOutput: {
|
|
31
|
+
hookEventName: 'PreToolUse';
|
|
32
|
+
permissionDecision: 'deny' | 'allow' | 'ask';
|
|
33
|
+
permissionDecisionReason: string;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/** 検知メタから日本語の deny 理由を組み立てる (具体的に・生機密は出さない)。 */
|
|
37
|
+
export declare function buildDenyReason(detections: DetectionMeta[]): string;
|
|
38
|
+
/** PreToolUse の判定結果。 */
|
|
39
|
+
export interface HookEvaluation {
|
|
40
|
+
/** PreToolUse で deny したか。 */
|
|
41
|
+
blocked: boolean;
|
|
42
|
+
/** 検知メタ (生機密は含まない)。記録・送信に使う。 */
|
|
43
|
+
detections: DetectionMeta[];
|
|
44
|
+
/** Claude Code に返す stdout JSON。null なら出力なし (= allow)。 */
|
|
45
|
+
output: PreToolUseDecision | null;
|
|
46
|
+
/** 終了コード。PreToolUse の deny は exit 0 + JSON で制御 (exit 2 は非構造化 block)。 */
|
|
47
|
+
exitCode: 0 | 2;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* hook イベントを評価する純粋関数。
|
|
51
|
+
* - PreToolUse: 検知に該当したら deny を返す。
|
|
52
|
+
* - その他: 検知のみ付与 (ブロックはしない)。
|
|
53
|
+
*/
|
|
54
|
+
export declare function evaluateHook(event: HookEvent, input: HookInput, detector: SecretDetector): HookEvaluation;
|
|
55
|
+
//# sourceMappingURL=claude-hook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-hook.d.ts","sourceRoot":"","sources":["../../src/hooks/claude-hook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAkB,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAcvF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,kGAOnB,CAAA;AACV,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEzD,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,SAAS,CAEtD;AAED,+CAA+C;AAC/C,MAAM,WAAW,SAAS;IACxB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACrB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,CAO1E;AAED,kEAAkE;AAClE,MAAM,WAAW,kBAAkB;IACjC,kBAAkB,EAAE;QAClB,aAAa,EAAE,YAAY,CAAA;QAC3B,kBAAkB,EAAE,MAAM,GAAG,OAAO,GAAG,KAAK,CAAA;QAC5C,wBAAwB,EAAE,MAAM,CAAA;KACjC,CAAA;CACF;AAUD,gDAAgD;AAChD,wBAAgB,eAAe,CAAC,UAAU,EAAE,aAAa,EAAE,GAAG,MAAM,CAenE;AA6BD,wBAAwB;AACxB,MAAM,WAAW,cAAc;IAC7B,6BAA6B;IAC7B,OAAO,EAAE,OAAO,CAAA;IAChB,gCAAgC;IAChC,UAAU,EAAE,aAAa,EAAE,CAAA;IAC3B,yDAAyD;IACzD,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAAA;IACjC,wEAAwE;IACxE,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAA;CAChB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,cAAc,GACvB,cAAc,CAwBhB"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SUPPORTED_EVENTS = void 0;
|
|
4
|
+
exports.isHookEvent = isHookEvent;
|
|
5
|
+
exports.extractRiskText = extractRiskText;
|
|
6
|
+
exports.buildDenyReason = buildDenyReason;
|
|
7
|
+
exports.evaluateHook = evaluateHook;
|
|
8
|
+
const secret_detector_1 = require("../secret-detector");
|
|
9
|
+
// =============================================
|
|
10
|
+
// Claude Code hooks アダプタ (Issue #67 / Epic #66 P1) — 純粋ロジック
|
|
11
|
+
// =============================================
|
|
12
|
+
//
|
|
13
|
+
// Claude Code 公式 hooks は JSON を stdin で渡し、stdout の JSON で制御する。
|
|
14
|
+
// 本モジュールは「stdin の event payload を受け取り、返すべき hook 出力 +
|
|
15
|
+
// 送信すべき観測 entry を計算する」純粋部分。I/O (stdin 読み取り・送信・記録) は
|
|
16
|
+
// cli/hook.ts が担う。install-launchd / install-systemd と同じテスト容易性方針。
|
|
17
|
+
//
|
|
18
|
+
// 検知 (#42) を PreToolUse に接続して「事後検知」を「事前ブロック」に格上げする。
|
|
19
|
+
// 既存 chokidar 経路は補完として併存 (hooks 未登録環境・取りこぼし回収)。
|
|
20
|
+
/**
|
|
21
|
+
* 対応する hook イベント (全プラットフォームの和集合)。
|
|
22
|
+
* プラットフォーム別にどれを登録/受理するかは hooks/platforms.ts が定義する。
|
|
23
|
+
* - PreCompact: Claude Code 固有。
|
|
24
|
+
* - Stop: Codex CLI のターン終了イベント (#70)。観測のみ。
|
|
25
|
+
*/
|
|
26
|
+
exports.SUPPORTED_EVENTS = [
|
|
27
|
+
'PreToolUse',
|
|
28
|
+
'PostToolUse',
|
|
29
|
+
'UserPromptSubmit',
|
|
30
|
+
'SessionStart',
|
|
31
|
+
'PreCompact',
|
|
32
|
+
'Stop',
|
|
33
|
+
];
|
|
34
|
+
function isHookEvent(v) {
|
|
35
|
+
return typeof v === 'string' && exports.SUPPORTED_EVENTS.includes(v);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* PreToolUse の deny は無条件ブロックなので、誤検知の影響が大きい。
|
|
39
|
+
* file_path 等の「パスにキーらしき文字列が紛れる」誤検出を避けるため、
|
|
40
|
+
* 値部分 (コマンド本文・プロンプト) のみを検知対象に集める。
|
|
41
|
+
*/
|
|
42
|
+
function extractRiskText(event, input) {
|
|
43
|
+
if (event === 'UserPromptSubmit') {
|
|
44
|
+
return typeof input.prompt === 'string' ? input.prompt : '';
|
|
45
|
+
}
|
|
46
|
+
// PreToolUse / PostToolUse: tool_input 全体の string を集める。
|
|
47
|
+
// Bash の command、Write/Edit の content 等が含まれる。
|
|
48
|
+
return (0, secret_detector_1.collectStrings)(input.tool_input ?? {});
|
|
49
|
+
}
|
|
50
|
+
const SEVERITY_LABEL = { high: '重大', medium: '中', low: '低' };
|
|
51
|
+
const CATEGORY_LABEL = {
|
|
52
|
+
secret: 'シークレット',
|
|
53
|
+
pii: '個人情報',
|
|
54
|
+
pii_jp: '個人情報(日本)',
|
|
55
|
+
custom: '社内機密',
|
|
56
|
+
};
|
|
57
|
+
/** 検知メタから日本語の deny 理由を組み立てる (具体的に・生機密は出さない)。 */
|
|
58
|
+
function buildDenyReason(detections) {
|
|
59
|
+
const top = [...detections].sort((a, b) => severityRank(b.severity) - severityRank(a.severity));
|
|
60
|
+
const lines = top
|
|
61
|
+
.slice(0, 5)
|
|
62
|
+
.map((d) => `・${CATEGORY_LABEL[d.category] ?? d.category} / ${ruleLabel(d.ruleId)} ` +
|
|
63
|
+
`(重大度: ${SEVERITY_LABEL[d.severity] ?? d.severity}, ${d.count} 件, 例: ${d.maskedPreview})`);
|
|
64
|
+
return ('PromptKaizen のポリシーにより、このツール実行をブロックしました。\n' +
|
|
65
|
+
'以下の機密情報が含まれています:\n' +
|
|
66
|
+
lines.join('\n') +
|
|
67
|
+
'\n機密値を削除するか、環境変数・シークレットマネージャ経由に変更してから再実行してください。');
|
|
68
|
+
}
|
|
69
|
+
function severityRank(s) {
|
|
70
|
+
return s === 'high' ? 2 : s === 'medium' ? 1 : 0;
|
|
71
|
+
}
|
|
72
|
+
const RULE_LABEL = {
|
|
73
|
+
anthropic_key: 'Anthropic APIキー',
|
|
74
|
+
openai_key: 'OpenAI APIキー',
|
|
75
|
+
github_token: 'GitHub トークン',
|
|
76
|
+
slack_token: 'Slack トークン',
|
|
77
|
+
aws_access_key: 'AWS アクセスキー',
|
|
78
|
+
gcp_api_key: 'GCP APIキー',
|
|
79
|
+
private_key_block: '秘密鍵ブロック',
|
|
80
|
+
jwt: 'JWT',
|
|
81
|
+
bearer_token: 'Bearer トークン',
|
|
82
|
+
high_entropy: '高エントロピー文字列',
|
|
83
|
+
jp_mynumber: 'マイナンバー',
|
|
84
|
+
jp_corporate_number: '法人番号',
|
|
85
|
+
jp_phone: '電話番号',
|
|
86
|
+
jp_postal: '郵便番号',
|
|
87
|
+
jp_address: '住所',
|
|
88
|
+
credit_card: 'クレジットカード番号',
|
|
89
|
+
email: 'メールアドレス',
|
|
90
|
+
};
|
|
91
|
+
function ruleLabel(id) {
|
|
92
|
+
return RULE_LABEL[id] ?? id;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* hook イベントを評価する純粋関数。
|
|
96
|
+
* - PreToolUse: 検知に該当したら deny を返す。
|
|
97
|
+
* - その他: 検知のみ付与 (ブロックはしない)。
|
|
98
|
+
*/
|
|
99
|
+
function evaluateHook(event, input, detector) {
|
|
100
|
+
const text = extractRiskText(event, input);
|
|
101
|
+
const detections = text ? detector.detect(text) : [];
|
|
102
|
+
// PreToolUse の deny は無条件ブロックなので誤検知の影響が大きい。
|
|
103
|
+
// 重大度 high (重大) のみをブロック対象とし、medium/low は観測のみ
|
|
104
|
+
// (記録・送信は全件残す) に留めて通常の開発作業を妨げない。
|
|
105
|
+
const blocking = detections.filter((d) => d.severity === 'high');
|
|
106
|
+
if (event === 'PreToolUse' && blocking.length > 0) {
|
|
107
|
+
return {
|
|
108
|
+
blocked: true,
|
|
109
|
+
detections,
|
|
110
|
+
output: {
|
|
111
|
+
hookSpecificOutput: {
|
|
112
|
+
hookEventName: 'PreToolUse',
|
|
113
|
+
permissionDecision: 'deny',
|
|
114
|
+
permissionDecisionReason: buildDenyReason(blocking),
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
exitCode: 0,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
return { blocked: false, detections, output: null, exitCode: 0 };
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=claude-hook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-hook.js","sourceRoot":"","sources":["../../src/hooks/claude-hook.ts"],"names":[],"mappings":";;;AA8BA,kCAEC;AAmBD,0CAOC;AAoBD,0CAeC;AA8CD,oCA4BC;AAvKD,wDAAuF;AAEvF,gDAAgD;AAChD,4DAA4D;AAC5D,gDAAgD;AAChD,EAAE;AACF,+DAA+D;AAC/D,qDAAqD;AACrD,oDAAoD;AACpD,iEAAiE;AACjE,EAAE;AACF,oDAAoD;AACpD,gDAAgD;AAEhD;;;;;GAKG;AACU,QAAA,gBAAgB,GAAG;IAC9B,YAAY;IACZ,aAAa;IACb,kBAAkB;IAClB,cAAc;IACd,YAAY;IACZ,MAAM;CACE,CAAA;AAGV,SAAgB,WAAW,CAAC,CAAU;IACpC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAK,wBAAsC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;AACrF,CAAC;AAcD;;;;GAIG;AACH,SAAgB,eAAe,CAAC,KAAgB,EAAE,KAAgB;IAChE,IAAI,KAAK,KAAK,kBAAkB,EAAE,CAAC;QACjC,OAAO,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAA;IAC7D,CAAC;IACD,wDAAwD;IACxD,8CAA8C;IAC9C,OAAO,IAAA,gCAAc,EAAC,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC,CAAA;AAC/C,CAAC;AAWD,MAAM,cAAc,GAA2B,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAA;AACpF,MAAM,cAAc,GAA2B;IAC7C,MAAM,EAAE,QAAQ;IAChB,GAAG,EAAE,MAAM;IACX,MAAM,EAAE,UAAU;IAClB,MAAM,EAAE,MAAM;CACf,CAAA;AAED,gDAAgD;AAChD,SAAgB,eAAe,CAAC,UAA2B;IACzD,MAAM,GAAG,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC/F,MAAM,KAAK,GAAG,GAAG;SACd,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CACJ,IAAI,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,MAAM,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG;QACxE,SAAS,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,aAAa,GAAG,CAC5F,CAAA;IACH,OAAO,CACL,2CAA2C;QAC3C,oBAAoB;QACpB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;QAChB,iDAAiD,CAClD,CAAA;AACH,CAAC;AAED,SAAS,YAAY,CAAC,CAAS;IAC7B,OAAO,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAClD,CAAC;AAED,MAAM,UAAU,GAA2B;IACzC,aAAa,EAAE,iBAAiB;IAChC,UAAU,EAAE,cAAc;IAC1B,YAAY,EAAE,aAAa;IAC3B,WAAW,EAAE,YAAY;IACzB,cAAc,EAAE,YAAY;IAC5B,WAAW,EAAE,WAAW;IACxB,iBAAiB,EAAE,SAAS;IAC5B,GAAG,EAAE,KAAK;IACV,YAAY,EAAE,aAAa;IAC3B,YAAY,EAAE,YAAY;IAC1B,WAAW,EAAE,QAAQ;IACrB,mBAAmB,EAAE,MAAM;IAC3B,QAAQ,EAAE,MAAM;IAChB,SAAS,EAAE,MAAM;IACjB,UAAU,EAAE,IAAI;IAChB,WAAW,EAAE,YAAY;IACzB,KAAK,EAAE,SAAS;CACjB,CAAA;AACD,SAAS,SAAS,CAAC,EAAU;IAC3B,OAAO,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,CAAA;AAC7B,CAAC;AAcD;;;;GAIG;AACH,SAAgB,YAAY,CAC1B,KAAgB,EAChB,KAAgB,EAChB,QAAwB;IAExB,MAAM,IAAI,GAAG,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;IAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAEpD,2CAA2C;IAC3C,6CAA6C;IAC7C,iCAAiC;IACjC,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAA;IAEhE,IAAI,KAAK,KAAK,YAAY,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,UAAU;YACV,MAAM,EAAE;gBACN,kBAAkB,EAAE;oBAClB,aAAa,EAAE,YAAY;oBAC3B,kBAAkB,EAAE,MAAM;oBAC1B,wBAAwB,EAAE,eAAe,CAAC,QAAQ,CAAC;iBACpD;aACF;YACD,QAAQ,EAAE,CAAC;SACZ,CAAA;IACH,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAA;AAClE,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { HookInput } from './claude-hook';
|
|
2
|
+
import { readRecentCommits, readTranscriptTail } from './snapshot';
|
|
3
|
+
import type { StoredSnapshot } from '../store/local-store';
|
|
4
|
+
import type { ParsedEntry } from '../types';
|
|
5
|
+
export interface SaveSnapshotDeps {
|
|
6
|
+
maskText: (text: string) => string;
|
|
7
|
+
recordSnapshot: (s: StoredSnapshot) => void;
|
|
8
|
+
/** テスト注入用。 */
|
|
9
|
+
readTail?: typeof readTranscriptTail;
|
|
10
|
+
readCommits?: typeof readRecentCommits;
|
|
11
|
+
now?: () => string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* transcript 末尾 + git log から状態スナップショットを作り保存する。
|
|
15
|
+
* 抽出できる状態が何も無い場合は保存しない (null)。
|
|
16
|
+
*/
|
|
17
|
+
export declare function saveSnapshot(deps: SaveSnapshotDeps, p: {
|
|
18
|
+
input: HookInput;
|
|
19
|
+
trigger: 'pre_compact' | 'stop';
|
|
20
|
+
}): StoredSnapshot | null;
|
|
21
|
+
/** SessionStart の stdout JSON (Claude Code hooks の hookSpecificOutput 形式)。 */
|
|
22
|
+
export interface SessionStartOutput {
|
|
23
|
+
hookSpecificOutput: {
|
|
24
|
+
hookEventName: 'SessionStart';
|
|
25
|
+
additionalContext: string;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export interface RestoreDeps {
|
|
29
|
+
latestSnapshot: (p: {
|
|
30
|
+
sessionId?: string | null;
|
|
31
|
+
cwd?: string | null;
|
|
32
|
+
maxAgeMs?: number;
|
|
33
|
+
}) => StoredSnapshot | null;
|
|
34
|
+
maxInjectChars: number;
|
|
35
|
+
maxAgeDays: number;
|
|
36
|
+
now?: () => string;
|
|
37
|
+
}
|
|
38
|
+
export interface RestoreResult {
|
|
39
|
+
output: SessionStartOutput;
|
|
40
|
+
/** 復元マーカー観測 entry (#69 の削減計測パターン用)。 */
|
|
41
|
+
markerEntry: ParsedEntry;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* SessionStart で直近スナップショットの要約注入を組み立てる。
|
|
45
|
+
* 対象外 source・スナップショット不在 (期限切れ含む) は null (無介入)。
|
|
46
|
+
*/
|
|
47
|
+
export declare function buildRestore(deps: RestoreDeps, input: HookInput): RestoreResult | null;
|
|
48
|
+
//# sourceMappingURL=continuity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"continuity.d.ts","sourceRoot":"","sources":["../../src/hooks/continuity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAIL,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,YAAY,CAAA;AACnB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAa3C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;IAClC,cAAc,EAAE,CAAC,CAAC,EAAE,cAAc,KAAK,IAAI,CAAA;IAC3C,cAAc;IACd,QAAQ,CAAC,EAAE,OAAO,kBAAkB,CAAA;IACpC,WAAW,CAAC,EAAE,OAAO,iBAAiB,CAAA;IACtC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,gBAAgB,EACtB,CAAC,EAAE;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAAA;CAAE,GACvD,cAAc,GAAG,IAAI,CAuBvB;AAED,8EAA8E;AAC9E,MAAM,WAAW,kBAAkB;IACjC,kBAAkB,EAAE;QAClB,aAAa,EAAE,cAAc,CAAA;QAC7B,iBAAiB,EAAE,MAAM,CAAA;KAC1B,CAAA;CACF;AAED,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE,CAAC,CAAC,EAAE;QAClB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACzB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;KAClB,KAAK,cAAc,GAAG,IAAI,CAAA;IAC3B,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,kBAAkB,CAAA;IAC1B,uCAAuC;IACvC,WAAW,EAAE,WAAW,CAAA;CACzB;AAKD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,GAAG,aAAa,GAAG,IAAI,CA2CtF"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.saveSnapshot = saveSnapshot;
|
|
4
|
+
exports.buildRestore = buildRestore;
|
|
5
|
+
const snapshot_1 = require("./snapshot");
|
|
6
|
+
// =============================================
|
|
7
|
+
// セッション継続オーケストレーション (Issue #95 / R3) — テスト可能層
|
|
8
|
+
// =============================================
|
|
9
|
+
//
|
|
10
|
+
// 保存 (PreCompact / Stop) と復元 (SessionStart) の判断・組み立てを担う。
|
|
11
|
+
// I/O (SQLite open・stdout・送信) は cli/hook.ts が deps として注入する。
|
|
12
|
+
// 不変条件: SQLite に入る summary / detail_json は必ずマスク済み。
|
|
13
|
+
/** 保存時の要約はやや大きめに保持し、注入時に maxInjectChars で切る。 */
|
|
14
|
+
const STORED_SUMMARY_CHARS = 4000;
|
|
15
|
+
/**
|
|
16
|
+
* transcript 末尾 + git log から状態スナップショットを作り保存する。
|
|
17
|
+
* 抽出できる状態が何も無い場合は保存しない (null)。
|
|
18
|
+
*/
|
|
19
|
+
function saveSnapshot(deps, p) {
|
|
20
|
+
const transcriptPath = typeof p.input.transcript_path === 'string' ? p.input.transcript_path : null;
|
|
21
|
+
const cwd = typeof p.input.cwd === 'string' ? p.input.cwd : null;
|
|
22
|
+
if (!transcriptPath)
|
|
23
|
+
return null;
|
|
24
|
+
const tail = (deps.readTail ?? snapshot_1.readTranscriptTail)(transcriptPath);
|
|
25
|
+
const detail = (0, snapshot_1.extractSnapshotDetail)(tail);
|
|
26
|
+
detail.recentCommits = cwd ? (deps.readCommits ?? snapshot_1.readRecentCommits)(cwd) : [];
|
|
27
|
+
const rawSummary = (0, snapshot_1.buildSnapshotSummary)(detail, STORED_SUMMARY_CHARS);
|
|
28
|
+
if (!rawSummary.trim())
|
|
29
|
+
return null; // 抽出ゼロなら保存しない
|
|
30
|
+
const snapshot = {
|
|
31
|
+
sessionId: typeof p.input.session_id === 'string' ? p.input.session_id : null,
|
|
32
|
+
cwd,
|
|
33
|
+
trigger: p.trigger,
|
|
34
|
+
createdAt: (deps.now ?? (() => new Date().toISOString()))(),
|
|
35
|
+
// マスキング前置 (#68 の不変条件): 保存するテキストは必ずマスクを通す。
|
|
36
|
+
summary: deps.maskText(rawSummary),
|
|
37
|
+
detailJson: deps.maskText(JSON.stringify(detail)),
|
|
38
|
+
};
|
|
39
|
+
deps.recordSnapshot(snapshot);
|
|
40
|
+
return snapshot;
|
|
41
|
+
}
|
|
42
|
+
/** SessionStart の source のうち復元を行う対象。startup/clear は古い文脈の混入を避け注入しない。 */
|
|
43
|
+
const RESTORE_SOURCES = new Set(['compact', 'resume']);
|
|
44
|
+
/**
|
|
45
|
+
* SessionStart で直近スナップショットの要約注入を組み立てる。
|
|
46
|
+
* 対象外 source・スナップショット不在 (期限切れ含む) は null (無介入)。
|
|
47
|
+
*/
|
|
48
|
+
function buildRestore(deps, input) {
|
|
49
|
+
const source = typeof input.source === 'string' ? input.source : 'startup';
|
|
50
|
+
if (!RESTORE_SOURCES.has(source))
|
|
51
|
+
return null;
|
|
52
|
+
const sessionId = typeof input.session_id === 'string' ? input.session_id : null;
|
|
53
|
+
const cwd = typeof input.cwd === 'string' ? input.cwd : null;
|
|
54
|
+
const snap = deps.latestSnapshot({
|
|
55
|
+
sessionId,
|
|
56
|
+
cwd,
|
|
57
|
+
maxAgeMs: deps.maxAgeDays * 24 * 3600 * 1000,
|
|
58
|
+
});
|
|
59
|
+
if (!snap)
|
|
60
|
+
return null;
|
|
61
|
+
const additionalContext = (0, snapshot_1.buildRestoreContext)({
|
|
62
|
+
summary: snap.summary,
|
|
63
|
+
createdAt: snap.createdAt,
|
|
64
|
+
trigger: snap.trigger,
|
|
65
|
+
maxChars: deps.maxInjectChars,
|
|
66
|
+
});
|
|
67
|
+
const now = (deps.now ?? (() => new Date().toISOString()))();
|
|
68
|
+
return {
|
|
69
|
+
output: {
|
|
70
|
+
hookSpecificOutput: { hookEventName: 'SessionStart', additionalContext },
|
|
71
|
+
},
|
|
72
|
+
// 復元マーカー: cloud の削減計測パターン (#69 context_restore_savings) が
|
|
73
|
+
// 「復元利用セッション」を識別するための観測 entry。本文は持たない。
|
|
74
|
+
markerEntry: {
|
|
75
|
+
filepath: `hook://claude-code/${sessionId ?? 'unknown'}`,
|
|
76
|
+
lineNumber: 0,
|
|
77
|
+
parsedAt: now,
|
|
78
|
+
source: 'hook',
|
|
79
|
+
raw: {
|
|
80
|
+
type: 'session_restore',
|
|
81
|
+
sessionId,
|
|
82
|
+
cwd,
|
|
83
|
+
timestamp: now,
|
|
84
|
+
hookEvent: 'SessionStart',
|
|
85
|
+
restoreSource: source,
|
|
86
|
+
snapshotCreatedAt: snap.createdAt,
|
|
87
|
+
injectedChars: additionalContext.length,
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=continuity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"continuity.js","sourceRoot":"","sources":["../../src/hooks/continuity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { HookEvent, HookInput } from './claude-hook';
|
|
2
|
+
import type { DetectionMeta } from '../secret-detector';
|
|
3
|
+
import type { MaskStat } from '../pii-masker';
|
|
4
|
+
import type { ParsedEntry } from '../types';
|
|
5
|
+
/** hook イベントから user プロンプト本文を取り出す (UserPromptSubmit のみ)。 */
|
|
6
|
+
export declare function hookPromptText(event: HookEvent, input: HookInput): string | null;
|
|
7
|
+
/** sessionId + 正規化本文から決定論的な重複排除キーを作る。 */
|
|
8
|
+
export declare function dedupeKey(sessionId: string | null, text: string): string;
|
|
9
|
+
export interface BuildObservationInput {
|
|
10
|
+
/** 発生元プラットフォーム (#70)。filepath の経路と raw.hookPlatform に反映。既定 claude-code。 */
|
|
11
|
+
platform?: 'claude-code' | 'codex';
|
|
12
|
+
event: HookEvent;
|
|
13
|
+
input: HookInput;
|
|
14
|
+
maskedText: string;
|
|
15
|
+
detections: DetectionMeta[];
|
|
16
|
+
masks: MaskStat[];
|
|
17
|
+
now?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* hook イベントを観測 entry (ParsedEntry) に整形する。
|
|
21
|
+
* - UserPromptSubmit → type:'user' (Claude Code 互換、cloud の normalize が user 集計に乗せる)
|
|
22
|
+
* - PostToolUse → type:'hook_tool_result' (集計対象外の補助 entry)
|
|
23
|
+
* - PreToolUse/SessionStart/PreCompact → 観測 entry は作らない (null)
|
|
24
|
+
* 本文は呼び出し側でマスク済み (maskedText) を渡す。生プロンプトは送らない。
|
|
25
|
+
*/
|
|
26
|
+
export declare function buildHookObservation(p: BuildObservationInput): ParsedEntry | null;
|
|
27
|
+
//# sourceMappingURL=observation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observation.d.ts","sourceRoot":"","sources":["../../src/hooks/observation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAe3C,2DAA2D;AAC3D,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAKhF;AAED,yCAAyC;AACzC,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAGxE;AAED,MAAM,WAAW,qBAAqB;IACpC,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,aAAa,GAAG,OAAO,CAAA;IAClC,KAAK,EAAE,SAAS,CAAA;IAChB,KAAK,EAAE,SAAS,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,aAAa,EAAE,CAAA;IAC3B,KAAK,EAAE,QAAQ,EAAE,CAAA;IACjB,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,qBAAqB,GAAG,WAAW,GAAG,IAAI,CA4CjF"}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observation.js","sourceRoot":"","sources":["../../src/hooks/observation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { HookEvent } from './claude-hook';
|
|
2
|
+
export type HookPlatform = 'claude-code' | 'codex';
|
|
3
|
+
export interface HookRegistration {
|
|
4
|
+
event: HookEvent;
|
|
5
|
+
matcher?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface PlatformConfig {
|
|
8
|
+
id: HookPlatform;
|
|
9
|
+
/** このプラットフォームが受理する hook イベント。 */
|
|
10
|
+
events: HookEvent[];
|
|
11
|
+
/** PreToolUse が deny のみ対応か (Codex は true: 詳細制御不可)。 */
|
|
12
|
+
denyOnly: boolean;
|
|
13
|
+
/** 設定ファイル (hooks 登録先) の絶対パス。 */
|
|
14
|
+
settingsFile: string;
|
|
15
|
+
/** command 識別マーカー (`promptkaizen-agent hook <platform>`)。 */
|
|
16
|
+
commandMarker: string;
|
|
17
|
+
/** install-hooks で登録するイベントと matcher。 */
|
|
18
|
+
registrations: HookRegistration[];
|
|
19
|
+
}
|
|
20
|
+
export declare function isHookPlatform(v: unknown): v is HookPlatform;
|
|
21
|
+
export declare function getPlatformConfig(platform: HookPlatform): PlatformConfig;
|
|
22
|
+
/** プラットフォームがそのイベントを受理するか。 */
|
|
23
|
+
export declare function platformAcceptsEvent(platform: HookPlatform, event: HookEvent): boolean;
|
|
24
|
+
//# sourceMappingURL=platforms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platforms.d.ts","sourceRoot":"","sources":["../../src/hooks/platforms.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAgB9C,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,OAAO,CAAA;AAElD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,SAAS,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,YAAY,CAAA;IAChB,iCAAiC;IACjC,MAAM,EAAE,SAAS,EAAE,CAAA;IACnB,sDAAsD;IACtD,QAAQ,EAAE,OAAO,CAAA;IACjB,gCAAgC;IAChC,YAAY,EAAE,MAAM,CAAA;IACpB,6DAA6D;IAC7D,aAAa,EAAE,MAAM,CAAA;IACrB,wCAAwC;IACxC,aAAa,EAAE,gBAAgB,EAAE,CAAA;CAClC;AA0CD,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,YAAY,CAE5D;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,YAAY,GAAG,cAAc,CAExE;AAED,6BAA6B;AAC7B,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAEtF"}
|