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.
Files changed (176) hide show
  1. package/README.md +5 -1
  2. package/dist/backfill/run.d.ts +15 -0
  3. package/dist/backfill/run.d.ts.map +1 -0
  4. package/dist/backfill/run.js +33 -0
  5. package/dist/backfill/run.js.map +1 -0
  6. package/dist/backfill/scanner.d.ts +82 -0
  7. package/dist/backfill/scanner.d.ts.map +1 -0
  8. package/dist/backfill/scanner.js +271 -0
  9. package/dist/backfill/scanner.js.map +1 -0
  10. package/dist/cli/detect.d.ts +2 -0
  11. package/dist/cli/detect.d.ts.map +1 -0
  12. package/dist/cli/detect.js +40 -0
  13. package/dist/cli/detect.js.map +1 -0
  14. package/dist/cli/disable.d.ts +2 -0
  15. package/dist/cli/disable.d.ts.map +1 -0
  16. package/dist/cli/disable.js +44 -0
  17. package/dist/cli/disable.js.map +1 -0
  18. package/dist/cli/enable.d.ts +2 -0
  19. package/dist/cli/enable.d.ts.map +1 -0
  20. package/dist/cli/enable.js +105 -0
  21. package/dist/cli/enable.js.map +1 -0
  22. package/dist/cli/hook.d.ts +2 -0
  23. package/dist/cli/hook.d.ts.map +1 -0
  24. package/dist/cli/hook.js +406 -0
  25. package/dist/cli/hook.js.map +1 -0
  26. package/dist/cli/init.d.ts.map +1 -1
  27. package/dist/cli/init.js +70 -8
  28. package/dist/cli/init.js.map +1 -1
  29. package/dist/cli/install-hooks.d.ts +5 -0
  30. package/dist/cli/install-hooks.d.ts.map +1 -0
  31. package/dist/cli/install-hooks.js +132 -0
  32. package/dist/cli/install-hooks.js.map +1 -0
  33. package/dist/cli/install-task.d.ts +28 -0
  34. package/dist/cli/install-task.d.ts.map +1 -0
  35. package/dist/cli/install-task.js +119 -0
  36. package/dist/cli/install-task.js.map +1 -0
  37. package/dist/cli/mcp.d.ts +2 -0
  38. package/dist/cli/mcp.d.ts.map +1 -0
  39. package/dist/cli/mcp.js +148 -0
  40. package/dist/cli/mcp.js.map +1 -0
  41. package/dist/cli/metrics.d.ts +2 -0
  42. package/dist/cli/metrics.d.ts.map +1 -0
  43. package/dist/cli/metrics.js +103 -0
  44. package/dist/cli/metrics.js.map +1 -0
  45. package/dist/cli/report.d.ts +2 -0
  46. package/dist/cli/report.d.ts.map +1 -0
  47. package/dist/cli/report.js +211 -0
  48. package/dist/cli/report.js.map +1 -0
  49. package/dist/cli/scan.d.ts +2 -0
  50. package/dist/cli/scan.d.ts.map +1 -0
  51. package/dist/cli/scan.js +171 -0
  52. package/dist/cli/scan.js.map +1 -0
  53. package/dist/cli/start.d.ts.map +1 -1
  54. package/dist/cli/start.js +70 -17
  55. package/dist/cli/start.js.map +1 -1
  56. package/dist/cli/status.d.ts.map +1 -1
  57. package/dist/cli/status.js +82 -18
  58. package/dist/cli/status.js.map +1 -1
  59. package/dist/cli/uninstall-task.d.ts +8 -0
  60. package/dist/cli/uninstall-task.d.ts.map +1 -0
  61. package/dist/cli/uninstall-task.js +44 -0
  62. package/dist/cli/uninstall-task.js.map +1 -0
  63. package/dist/config.d.ts +172 -6
  64. package/dist/config.d.ts.map +1 -1
  65. package/dist/config.js +114 -2
  66. package/dist/config.js.map +1 -1
  67. package/dist/console-safe.d.ts +21 -0
  68. package/dist/console-safe.d.ts.map +1 -0
  69. package/dist/console-safe.js +71 -0
  70. package/dist/console-safe.js.map +1 -0
  71. package/dist/detection-secret.d.ts.map +1 -1
  72. package/dist/detection-secret.js +12 -0
  73. package/dist/detection-secret.js.map +1 -1
  74. package/dist/env-detect.d.ts +44 -0
  75. package/dist/env-detect.d.ts.map +1 -0
  76. package/dist/env-detect.js +151 -0
  77. package/dist/env-detect.js.map +1 -0
  78. package/dist/exec/executor.d.ts +42 -0
  79. package/dist/exec/executor.d.ts.map +1 -0
  80. package/dist/exec/executor.js +135 -0
  81. package/dist/exec/executor.js.map +1 -0
  82. package/dist/exec/pk-execute.d.ts +30 -0
  83. package/dist/exec/pk-execute.d.ts.map +1 -0
  84. package/dist/exec/pk-execute.js +174 -0
  85. package/dist/exec/pk-execute.js.map +1 -0
  86. package/dist/exec/policy-fetcher.d.ts +9 -0
  87. package/dist/exec/policy-fetcher.d.ts.map +1 -0
  88. package/dist/exec/policy-fetcher.js +46 -0
  89. package/dist/exec/policy-fetcher.js.map +1 -0
  90. package/dist/exec/policy.d.ts +32 -0
  91. package/dist/exec/policy.d.ts.map +1 -0
  92. package/dist/exec/policy.js +88 -0
  93. package/dist/exec/policy.js.map +1 -0
  94. package/dist/hooks/block-store.d.ts +14 -0
  95. package/dist/hooks/block-store.d.ts.map +1 -0
  96. package/dist/hooks/block-store.js +26 -0
  97. package/dist/hooks/block-store.js.map +1 -0
  98. package/dist/hooks/claude-hook.d.ts +55 -0
  99. package/dist/hooks/claude-hook.d.ts.map +1 -0
  100. package/dist/hooks/claude-hook.js +122 -0
  101. package/dist/hooks/claude-hook.js.map +1 -0
  102. package/dist/hooks/continuity.d.ts +48 -0
  103. package/dist/hooks/continuity.d.ts.map +1 -0
  104. package/dist/hooks/continuity.js +92 -0
  105. package/dist/hooks/continuity.js.map +1 -0
  106. package/dist/hooks/observation.d.ts +27 -0
  107. package/dist/hooks/observation.d.ts.map +1 -0
  108. package/dist/hooks/observation.js +0 -0
  109. package/dist/hooks/observation.js.map +1 -0
  110. package/dist/hooks/platforms.d.ts +24 -0
  111. package/dist/hooks/platforms.d.ts.map +1 -0
  112. package/dist/hooks/platforms.js +57 -0
  113. package/dist/hooks/platforms.js.map +1 -0
  114. package/dist/hooks/read-cache.d.ts +71 -0
  115. package/dist/hooks/read-cache.d.ts.map +1 -0
  116. package/dist/hooks/read-cache.js +166 -0
  117. package/dist/hooks/read-cache.js.map +1 -0
  118. package/dist/hooks/reduction.d.ts +78 -0
  119. package/dist/hooks/reduction.d.ts.map +1 -0
  120. package/dist/hooks/reduction.js +111 -0
  121. package/dist/hooks/reduction.js.map +1 -0
  122. package/dist/hooks/settings-merge.d.ts +32 -0
  123. package/dist/hooks/settings-merge.d.ts.map +1 -0
  124. package/dist/hooks/settings-merge.js +74 -0
  125. package/dist/hooks/settings-merge.js.map +1 -0
  126. package/dist/hooks/snapshot.d.ts +37 -0
  127. package/dist/hooks/snapshot.d.ts.map +1 -0
  128. package/dist/hooks/snapshot.js +180 -0
  129. package/dist/hooks/snapshot.js.map +1 -0
  130. package/dist/index.js +51 -0
  131. package/dist/index.js.map +1 -1
  132. package/dist/mcp/server.d.ts +118 -0
  133. package/dist/mcp/server.d.ts.map +1 -0
  134. package/dist/mcp/server.js +240 -0
  135. package/dist/mcp/server.js.map +1 -0
  136. package/dist/onboarding-report.d.ts +66 -0
  137. package/dist/onboarding-report.d.ts.map +1 -0
  138. package/dist/onboarding-report.js +152 -0
  139. package/dist/onboarding-report.js.map +1 -0
  140. package/dist/onboarding.d.ts +55 -0
  141. package/dist/onboarding.d.ts.map +1 -0
  142. package/dist/onboarding.js +98 -0
  143. package/dist/onboarding.js.map +1 -0
  144. package/dist/pii-masker.d.ts +7 -0
  145. package/dist/pii-masker.d.ts.map +1 -1
  146. package/dist/pii-masker.js +27 -51
  147. package/dist/pii-masker.js.map +1 -1
  148. package/dist/privacy.d.ts +13 -0
  149. package/dist/privacy.d.ts.map +1 -0
  150. package/dist/privacy.js +67 -0
  151. package/dist/privacy.js.map +1 -0
  152. package/dist/residency.d.ts +21 -0
  153. package/dist/residency.d.ts.map +1 -0
  154. package/dist/residency.js +68 -0
  155. package/dist/residency.js.map +1 -0
  156. package/dist/secret-detector.d.ts +19 -0
  157. package/dist/secret-detector.d.ts.map +1 -1
  158. package/dist/secret-detector.js +116 -0
  159. package/dist/secret-detector.js.map +1 -1
  160. package/dist/store/local-store.d.ts +167 -0
  161. package/dist/store/local-store.d.ts.map +1 -0
  162. package/dist/store/local-store.js +538 -0
  163. package/dist/store/local-store.js.map +1 -0
  164. package/dist/store/schema.d.ts +38 -0
  165. package/dist/store/schema.d.ts.map +1 -0
  166. package/dist/store/schema.js +189 -0
  167. package/dist/store/schema.js.map +1 -0
  168. package/dist/types.d.ts +13 -2
  169. package/dist/types.d.ts.map +1 -1
  170. package/dist/version.d.ts +1 -1
  171. package/dist/version.js +1 -1
  172. package/dist/watcher.d.ts +6 -0
  173. package/dist/watcher.d.ts.map +1 -1
  174. package/dist/watcher.js +13 -2
  175. package/dist/watcher.js.map +1 -1
  176. package/package.json +4 -2
@@ -0,0 +1,151 @@
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.detectWSL = detectWSL;
7
+ exports.detectEnvironment = detectEnvironment;
8
+ exports.formatDetectionSummary = formatDetectionSummary;
9
+ const promises_1 = __importDefault(require("fs/promises"));
10
+ const fs_1 = __importDefault(require("fs"));
11
+ const os_1 = __importDefault(require("os"));
12
+ const path_1 = __importDefault(require("path"));
13
+ const TOOL_META = {
14
+ claude_code: { label: 'Claude Code', rel: ['.claude', 'projects'] },
15
+ codex: { label: 'Codex', rel: ['.codex', 'sessions'] },
16
+ };
17
+ /** WSL 上で動いているか (/proc/version に microsoft/WSL を含むか)。 */
18
+ function detectWSL(platform = process.platform) {
19
+ if (platform !== 'linux')
20
+ return false;
21
+ try {
22
+ return /microsoft|wsl/i.test(fs_1.default.readFileSync('/proc/version', 'utf8'));
23
+ }
24
+ catch {
25
+ return false;
26
+ }
27
+ }
28
+ /** /mnt/c/Users 配下の実ユーザーディレクトリ (WSL から Windows 側履歴を拾う)。 */
29
+ function listWindowsUserDirs() {
30
+ const root = '/mnt/c/Users';
31
+ const skip = new Set(['Public', 'Default', 'Default User', 'All Users', 'desktop.ini']);
32
+ try {
33
+ return fs_1.default
34
+ .readdirSync(root, { withFileTypes: true })
35
+ .filter((e) => e.isDirectory() && !skip.has(e.name))
36
+ .map((e) => path_1.default.join(root, e.name));
37
+ }
38
+ catch {
39
+ return [];
40
+ }
41
+ }
42
+ /** base を ~ 圧縮した watch glob を返す。home 配下なら `~/...`、それ以外は絶対パス。 */
43
+ function toWatchGlob(base, home) {
44
+ const norm = base.replace(/\\/g, '/');
45
+ const h = home.replace(/\\/g, '/').replace(/\/+$/, '');
46
+ const rel = norm === h ? '' : norm.startsWith(h + '/') ? norm.slice(h.length + 1) : null;
47
+ const head = rel === null ? norm : rel === '' ? '~' : `~/${rel}`;
48
+ return `${head}/**/*.jsonl`;
49
+ }
50
+ /** base ディレクトリの project 数 (直下のディレクトリ) と *.jsonl セッション数を数える。 */
51
+ async function countDir(base, maxDepth) {
52
+ let exists = false;
53
+ let projects = 0;
54
+ let sessions = 0;
55
+ let top;
56
+ try {
57
+ top = await promises_1.default.readdir(base, { withFileTypes: true });
58
+ exists = true;
59
+ }
60
+ catch {
61
+ return { exists: false, projects: 0, sessions: 0 };
62
+ }
63
+ // 直下のディレクトリ数 = projects (Claude の project 単位)。
64
+ projects = top.filter((e) => e.isDirectory() && !e.isSymbolicLink()).length;
65
+ // *.jsonl を再帰カウント (symlink は辿らない / 深さ上限)。
66
+ const walk = async (dir, entries, depth) => {
67
+ for (const e of entries) {
68
+ if (e.isSymbolicLink())
69
+ continue;
70
+ const full = path_1.default.join(dir, e.name);
71
+ if (e.isFile()) {
72
+ if (e.name.toLowerCase().endsWith('.jsonl'))
73
+ sessions++;
74
+ }
75
+ else if (e.isDirectory() && depth < maxDepth) {
76
+ let sub;
77
+ try {
78
+ sub = await promises_1.default.readdir(full, { withFileTypes: true });
79
+ }
80
+ catch {
81
+ continue;
82
+ }
83
+ await walk(full, sub, depth + 1);
84
+ }
85
+ }
86
+ };
87
+ await walk(base, top, 0);
88
+ return { exists, projects, sessions };
89
+ }
90
+ /**
91
+ * 環境を検出する。各ツールについて候補ベース (ホーム + WSL の Windows ユーザー) を評価し、
92
+ * 「存在する候補のうちセッション数が最大のもの」を採用する。
93
+ */
94
+ async function detectEnvironment(opts = {}) {
95
+ const home = opts.homeDir ?? os_1.default.homedir();
96
+ const platform = opts.platform ?? process.platform;
97
+ const isWSL = opts.isWSL ?? detectWSL(platform);
98
+ const maxDepth = opts.maxDepth ?? 24;
99
+ const windowsUserDirs = opts.windowsUserDirs ?? (isWSL ? listWindowsUserDirs() : []);
100
+ const tools = [];
101
+ for (const tool of Object.keys(TOOL_META)) {
102
+ const { label, rel } = TOOL_META[tool];
103
+ const candidates = [path_1.default.join(home, ...rel), ...windowsUserDirs.map((d) => path_1.default.join(d, ...rel))];
104
+ let chosen = null;
105
+ for (const base of candidates) {
106
+ const counts = await countDir(base, maxDepth);
107
+ if (!counts.exists)
108
+ continue;
109
+ // 存在する候補のうちセッション数が最大のものを採用 (同数なら先勝ち = ホーム優先)。
110
+ if (!chosen || counts.sessions > chosen.counts.sessions)
111
+ chosen = { base, counts };
112
+ }
113
+ tools.push({
114
+ tool,
115
+ label,
116
+ basePath: chosen?.base ?? null,
117
+ present: chosen !== null,
118
+ projects: tool === 'codex' ? 0 : (chosen?.counts.projects ?? 0),
119
+ sessions: chosen?.counts.sessions ?? 0,
120
+ watchGlob: chosen ? toWatchGlob(chosen.base, home) : null,
121
+ });
122
+ }
123
+ const detected = tools.filter((t) => t.present);
124
+ return {
125
+ platform,
126
+ isWSL,
127
+ home,
128
+ tools,
129
+ detected,
130
+ anyDetected: detected.length > 0,
131
+ watchPaths: detected.map((t) => t.watchGlob).filter(Boolean),
132
+ };
133
+ }
134
+ /** 検出結果を人間向けの要約行に整形する (例: `Claude Code : 12 projects / 348 sessions`)。 */
135
+ function formatDetectionSummary(env) {
136
+ const lines = [];
137
+ for (const t of env.tools) {
138
+ if (!t.present) {
139
+ lines.push(` ${t.label.padEnd(12)}: 未検出`);
140
+ continue;
141
+ }
142
+ const count = t.tool === 'codex'
143
+ ? `${t.sessions.toLocaleString()} sessions`
144
+ : `${t.projects.toLocaleString()} projects / ${t.sessions.toLocaleString()} sessions`;
145
+ lines.push(` ${t.label.padEnd(12)}: ${count} (${t.basePath})`);
146
+ }
147
+ if (env.isWSL)
148
+ lines.push(' (WSL を検出: Linux ホーム + /mnt/c/Users を探索)');
149
+ return lines;
150
+ }
151
+ //# sourceMappingURL=env-detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-detect.js","sourceRoot":"","sources":["../src/env-detect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ export declare const SUPPORTED_LANGUAGES: readonly ["bash", "node", "python"];
2
+ export type ExecLanguage = (typeof SUPPORTED_LANGUAGES)[number];
3
+ export declare function isExecLanguage(v: unknown): v is ExecLanguage;
4
+ /**
5
+ * 子プロセスへ伝播する環境変数のホワイトリスト。
6
+ * 秘匿値 (ANTHROPIC_API_KEY / AWS_* / *_TOKEN 等) はリストに無い時点で遮断される
7
+ * (ブラックリストではなくホワイトリスト = 新種のキーも漏れない)。
8
+ * HOME は実ホームを隠すため一時ディレクトリに差し替える。
9
+ */
10
+ export declare const ENV_WHITELIST: readonly ["PATH", "LANG", "LC_ALL", "LC_CTYPE", "TZ", "TERM", "TMPDIR"];
11
+ export interface ExecRequest {
12
+ language: ExecLanguage;
13
+ code: string;
14
+ /** 実行の作業ディレクトリ (プロジェクトルート)。 */
15
+ projectRoot: string;
16
+ /** タイムアウト ms (既定 30_000)。 */
17
+ timeoutMs?: number;
18
+ /** stdout / stderr の取り込み上限 (メモリ保護のハードキャップ)。 */
19
+ maxCaptureBytes?: number;
20
+ }
21
+ export interface ExecResult {
22
+ /** 取り込んだ stdout (maxCaptureBytes でハードキャップ済み・マスク前)。 */
23
+ stdout: string;
24
+ /** stderr の先頭 (診断用に小さく保持)。 */
25
+ stderrHead: string;
26
+ exitCode: number | null;
27
+ /** タイムアウトで SIGKILL したか。 */
28
+ timedOut: boolean;
29
+ /** stdout が maxCaptureBytes を超えて切り捨てられたか。 */
30
+ captureTruncated: boolean;
31
+ durationMs: number;
32
+ }
33
+ /** ホワイトリストで子プロセス環境を構築。HOME は一時ディレクトリに差し替え。 */
34
+ export declare function buildSandboxEnv(parentEnv: NodeJS.ProcessEnv, sandboxHome: string): NodeJS.ProcessEnv;
35
+ /**
36
+ * code を一時ファイル経由で実行する。例外は投げず ExecResult に正規化する
37
+ * (インタープリタ不在等は exitCode null + stderrHead にメッセージ)。
38
+ */
39
+ export declare function executeCode(req: ExecRequest): Promise<ExecResult>;
40
+ /** 実行ログ・参照IDに使う一意 ID。 */
41
+ export declare function generateExecId(): string;
42
+ //# sourceMappingURL=executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/exec/executor.ts"],"names":[],"mappings":"AAkBA,eAAO,MAAM,mBAAmB,qCAAsC,CAAA;AACtE,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAA;AAE/D,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,YAAY,CAE5D;AAED;;;;;GAKG;AACH,eAAO,MAAM,aAAa,yEAA0E,CAAA;AAEpG,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,YAAY,CAAA;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,+BAA+B;IAC/B,WAAW,EAAE,MAAM,CAAA;IACnB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,+CAA+C;IAC/C,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAA;IACd,8BAA8B;IAC9B,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,2BAA2B;IAC3B,QAAQ,EAAE,OAAO,CAAA;IACjB,6CAA6C;IAC7C,gBAAgB,EAAE,OAAO,CAAA;IACzB,UAAU,EAAE,MAAM,CAAA;CACnB;AAcD,8CAA8C;AAC9C,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC,UAAU,CAOpG;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAwEvE;AAED,yBAAyB;AACzB,wBAAgB,cAAc,IAAI,MAAM,CAEvC"}
@@ -0,0 +1,135 @@
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.ENV_WHITELIST = exports.SUPPORTED_LANGUAGES = void 0;
7
+ exports.isExecLanguage = isExecLanguage;
8
+ exports.buildSandboxEnv = buildSandboxEnv;
9
+ exports.executeCode = executeCode;
10
+ exports.generateExecId = generateExecId;
11
+ const child_process_1 = require("child_process");
12
+ const crypto_1 = require("crypto");
13
+ const fs_1 = __importDefault(require("fs"));
14
+ const os_1 = __importDefault(require("os"));
15
+ const path_1 = __importDefault(require("path"));
16
+ // =============================================
17
+ // pk_execute 実行エンジン (Issue #94 / Epic #91 R2)
18
+ // =============================================
19
+ //
20
+ // 生データをコンテキストに入れず、エージェントが書いたコードをローカルで実行して
21
+ // 結果 (stdout) だけを返す。安全制約:
22
+ // - タイムアウト (既定 30s、SIGKILL)
23
+ // - 作業ディレクトリ = プロジェクトルート (cwd 固定)
24
+ // - 環境変数はホワイトリストのみ伝播 (API キー類を子プロセスへ渡さない)
25
+ // - stdout は上限でトリム (超過分は呼び出し側が R1 退避へ回す)
26
+ // ポリシー判定 (policy.ts) は呼び出し側 (mcp/server.ts) が実行前に行う。
27
+ exports.SUPPORTED_LANGUAGES = ['bash', 'node', 'python'];
28
+ function isExecLanguage(v) {
29
+ return typeof v === 'string' && exports.SUPPORTED_LANGUAGES.includes(v);
30
+ }
31
+ /**
32
+ * 子プロセスへ伝播する環境変数のホワイトリスト。
33
+ * 秘匿値 (ANTHROPIC_API_KEY / AWS_* / *_TOKEN 等) はリストに無い時点で遮断される
34
+ * (ブラックリストではなくホワイトリスト = 新種のキーも漏れない)。
35
+ * HOME は実ホームを隠すため一時ディレクトリに差し替える。
36
+ */
37
+ exports.ENV_WHITELIST = ['PATH', 'LANG', 'LC_ALL', 'LC_CTYPE', 'TZ', 'TERM', 'TMPDIR'];
38
+ const DEFAULT_TIMEOUT_MS = 30_000;
39
+ const DEFAULT_MAX_CAPTURE_BYTES = 5 * 1024 * 1024; // 5MB (メモリ保護)
40
+ const STDERR_HEAD_BYTES = 4 * 1024;
41
+ const INTERPRETER = {
42
+ bash: { cmd: 'bash', args: (f) => [f] },
43
+ node: { cmd: 'node', args: (f) => [f] },
44
+ python: { cmd: 'python3', args: (f) => [f] },
45
+ };
46
+ const FILE_EXT = { bash: '.sh', node: '.cjs', python: '.py' };
47
+ /** ホワイトリストで子プロセス環境を構築。HOME は一時ディレクトリに差し替え。 */
48
+ function buildSandboxEnv(parentEnv, sandboxHome) {
49
+ const env = {};
50
+ for (const key of exports.ENV_WHITELIST) {
51
+ if (parentEnv[key] !== undefined)
52
+ env[key] = parentEnv[key];
53
+ }
54
+ env.HOME = sandboxHome;
55
+ return env;
56
+ }
57
+ /**
58
+ * code を一時ファイル経由で実行する。例外は投げず ExecResult に正規化する
59
+ * (インタープリタ不在等は exitCode null + stderrHead にメッセージ)。
60
+ */
61
+ async function executeCode(req) {
62
+ const timeoutMs = req.timeoutMs ?? DEFAULT_TIMEOUT_MS;
63
+ const maxCapture = req.maxCaptureBytes ?? DEFAULT_MAX_CAPTURE_BYTES;
64
+ const started = Date.now();
65
+ // 一時ファイル + サンドボックス HOME (実行ごとに隔離、終了後に削除)
66
+ const workDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'pk-exec-'));
67
+ const codeFile = path_1.default.join(workDir, `code${FILE_EXT[req.language]}`);
68
+ const sandboxHome = path_1.default.join(workDir, 'home');
69
+ fs_1.default.mkdirSync(sandboxHome);
70
+ fs_1.default.writeFileSync(codeFile, req.code, { mode: 0o600 });
71
+ const { cmd, args } = INTERPRETER[req.language];
72
+ try {
73
+ return await new Promise((resolve) => {
74
+ const child = (0, child_process_1.spawn)(cmd, args(codeFile), {
75
+ cwd: req.projectRoot,
76
+ env: buildSandboxEnv(process.env, sandboxHome),
77
+ timeout: timeoutMs,
78
+ killSignal: 'SIGKILL',
79
+ stdio: ['ignore', 'pipe', 'pipe'],
80
+ });
81
+ const out = [];
82
+ let outBytes = 0;
83
+ let captureTruncated = false;
84
+ const err = [];
85
+ let errBytes = 0;
86
+ child.stdout.on('data', (chunk) => {
87
+ if (outBytes >= maxCapture) {
88
+ captureTruncated = true;
89
+ return;
90
+ }
91
+ const room = maxCapture - outBytes;
92
+ const take = chunk.length > room ? chunk.subarray(0, room) : chunk;
93
+ if (take.length < chunk.length)
94
+ captureTruncated = true;
95
+ out.push(take);
96
+ outBytes += take.length;
97
+ });
98
+ child.stderr.on('data', (chunk) => {
99
+ if (errBytes >= STDERR_HEAD_BYTES)
100
+ return;
101
+ const take = chunk.subarray(0, STDERR_HEAD_BYTES - errBytes);
102
+ err.push(take);
103
+ errBytes += take.length;
104
+ });
105
+ child.on('error', (e) => {
106
+ resolve({
107
+ stdout: '',
108
+ stderrHead: `実行に失敗しました: ${e.message}`,
109
+ exitCode: null,
110
+ timedOut: false,
111
+ captureTruncated: false,
112
+ durationMs: Date.now() - started,
113
+ });
114
+ });
115
+ child.on('close', (code, signal) => {
116
+ resolve({
117
+ stdout: Buffer.concat(out).toString('utf8'),
118
+ stderrHead: Buffer.concat(err).toString('utf8'),
119
+ exitCode: code,
120
+ timedOut: signal === 'SIGKILL' && Date.now() - started >= timeoutMs - 50,
121
+ captureTruncated,
122
+ durationMs: Date.now() - started,
123
+ });
124
+ });
125
+ });
126
+ }
127
+ finally {
128
+ fs_1.default.rmSync(workDir, { recursive: true, force: true });
129
+ }
130
+ }
131
+ /** 実行ログ・参照IDに使う一意 ID。 */
132
+ function generateExecId() {
133
+ return `pk-exec-${(0, crypto_1.randomBytes)(6).toString('hex')}`;
134
+ }
135
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/exec/executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { StoredToolOutputRef } from '../store/local-store';
2
+ import type { ParsedEntry } from '../types';
3
+ import { type ExecutionPolicy } from './policy';
4
+ import { executeCode } from './executor';
5
+ export interface PkExecuteDeps {
6
+ /** マスキング前置パイプライン (#68 の不変条件)。 */
7
+ maskText: (text: string) => string;
8
+ /** R1 退避ストアへの保存 (#93)。 */
9
+ storeRef: (ref: StoredToolOutputRef) => void;
10
+ /** 実行ログ entry の記録 + 送信 (best-effort、呼び出し側で実装)。 */
11
+ recordEntry: (entry: ParsedEntry) => Promise<void>;
12
+ /** 組織実行ポリシー (cloud 配信、オフライン時 null)。 */
13
+ getPolicy: () => ExecutionPolicy | null;
14
+ projectRoot: string;
15
+ timeoutMs: number;
16
+ maxReturnBytes: number;
17
+ /** テスト注入用。 */
18
+ now?: () => string;
19
+ execImpl?: typeof executeCode;
20
+ }
21
+ export interface PkExecuteResult {
22
+ content: Array<{
23
+ type: 'text';
24
+ text: string;
25
+ }>;
26
+ isError?: boolean;
27
+ }
28
+ /** pk_execute 本体。例外を投げず PkExecuteResult に正規化する。 */
29
+ export declare function runPkExecute(deps: PkExecuteDeps, args: Record<string, unknown>): Promise<PkExecuteResult>;
30
+ //# sourceMappingURL=pk-execute.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pk-execute.d.ts","sourceRoot":"","sources":["../../src/exec/pk-execute.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAE/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAC3C,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,UAAU,CAAA;AACrE,OAAO,EAAE,WAAW,EAAmD,MAAM,YAAY,CAAA;AAYzF,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;IAClC,0BAA0B;IAC1B,QAAQ,EAAE,CAAC,GAAG,EAAE,mBAAmB,KAAK,IAAI,CAAA;IAC5C,kDAAkD;IAClD,WAAW,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAClD,uCAAuC;IACvC,SAAS,EAAE,MAAM,eAAe,GAAG,IAAI,CAAA;IACvC,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,EAAE,MAAM,CAAA;IACtB,cAAc;IACd,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,OAAO,WAAW,CAAA;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC9C,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAmDD,mDAAmD;AACnD,wBAAsB,YAAY,CAChC,IAAI,EAAE,aAAa,EACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,eAAe,CAAC,CAwI1B"}
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runPkExecute = runPkExecute;
4
+ const crypto_1 = require("crypto");
5
+ const reduction_1 = require("../hooks/reduction");
6
+ const policy_1 = require("./policy");
7
+ const executor_1 = require("./executor");
8
+ function hashPreview(code) {
9
+ return (0, crypto_1.createHash)('sha256').update(code).digest('hex').slice(0, 16);
10
+ }
11
+ /** 実行ログ/拒否ログの観測 entry を組み立てる (本文はマスク済み・先頭のみ)。 */
12
+ function buildExecEntry(p) {
13
+ const maskedCode = p.maskText(p.code).slice(0, 2000);
14
+ const entry = {
15
+ filepath: 'mcp://pk_execute',
16
+ lineNumber: 0,
17
+ parsedAt: p.now,
18
+ source: 'hook',
19
+ raw: {
20
+ type: 'pk_execute',
21
+ sessionId: null, // MCP 経由はセッション文脈を持たない
22
+ timestamp: p.now,
23
+ language: p.language,
24
+ outcome: p.outcome,
25
+ exitCode: p.exitCode ?? null,
26
+ durationMs: p.durationMs ?? null,
27
+ codeMasked: maskedCode,
28
+ },
29
+ };
30
+ if (p.outcome === 'blocked' && p.ruleId) {
31
+ const detection = {
32
+ category: 'custom',
33
+ ruleId: 'pk_execute_blocked',
34
+ severity: 'high',
35
+ count: 1,
36
+ // 拒否理由の識別補助。コードはマスク済み先頭のみ (cloud 上限 200 文字)。
37
+ maskedPreview: `[${p.ruleId}] ${maskedCode}`.slice(0, 200),
38
+ matchHash: hashPreview(p.code),
39
+ };
40
+ entry.detections = [detection];
41
+ }
42
+ if (p.reduction)
43
+ entry.reduction = p.reduction;
44
+ return entry;
45
+ }
46
+ /** pk_execute 本体。例外を投げず PkExecuteResult に正規化する。 */
47
+ async function runPkExecute(deps, args) {
48
+ const now = deps.now ?? (() => new Date().toISOString());
49
+ const language = args.language;
50
+ const code = typeof args.code === 'string' ? args.code : '';
51
+ if (!(0, executor_1.isExecLanguage)(language)) {
52
+ return {
53
+ content: [{ type: 'text', text: 'language は bash / node / python のいずれかを指定してください' }],
54
+ isError: true,
55
+ };
56
+ }
57
+ if (!code.trim()) {
58
+ return { content: [{ type: 'text', text: 'code は必須です' }], isError: true };
59
+ }
60
+ const timeoutArg = typeof args.timeout === 'number' && Number.isFinite(args.timeout) ? args.timeout : null;
61
+ const timeoutMs = timeoutArg ? Math.min(Math.max(timeoutArg * 1000, 1000), 300_000) : deps.timeoutMs;
62
+ // 1. 実行前ポリシー判定 (#44 接続)。拒否は違反イベントとして記録される。
63
+ const verdict = (0, policy_1.checkExecutionPolicy)(code, deps.getPolicy(), deps.projectRoot);
64
+ if (!verdict.allowed) {
65
+ await deps
66
+ .recordEntry(buildExecEntry({
67
+ maskText: deps.maskText,
68
+ now: now(),
69
+ language,
70
+ code,
71
+ outcome: 'blocked',
72
+ ruleId: verdict.ruleId,
73
+ }))
74
+ .catch(() => { });
75
+ return {
76
+ content: [
77
+ {
78
+ type: 'text',
79
+ text: `PromptKaizen のポリシーにより実行をブロックしました: ${verdict.reason}\n` +
80
+ 'コードを修正するか、組織の管理者にポリシー設定を確認してください。',
81
+ },
82
+ ],
83
+ isError: true,
84
+ };
85
+ }
86
+ // 2. 実行 (サンドボックス制約は executor 側)。
87
+ const exec = deps.execImpl ?? executor_1.executeCode;
88
+ const result = await exec({
89
+ language,
90
+ code,
91
+ projectRoot: deps.projectRoot,
92
+ timeoutMs,
93
+ });
94
+ // 3. 返却 stdout のマスク → 上限トリム (超過分は R1 退避 + 削減イベント)。
95
+ const masked = deps.maskText(result.stdout);
96
+ let returned = masked;
97
+ let reduction;
98
+ let overflowNote = '';
99
+ if (Buffer.byteLength(masked, 'utf8') > deps.maxReturnBytes) {
100
+ returned = masked.slice(0, deps.maxReturnBytes);
101
+ const refId = (0, executor_1.generateExecId)();
102
+ try {
103
+ deps.storeRef({
104
+ refId,
105
+ sessionId: null,
106
+ toolName: 'pk_execute',
107
+ cwd: deps.projectRoot,
108
+ createdAt: now(),
109
+ originalBytes: Buffer.byteLength(masked, 'utf8'),
110
+ originalTokens: (0, reduction_1.estimateTokensFromText)(masked),
111
+ replacedTokens: (0, reduction_1.estimateTokensFromText)(returned),
112
+ savedTokens: (0, reduction_1.estimateTokensFromText)(masked) - (0, reduction_1.estimateTokensFromText)(returned),
113
+ body: masked,
114
+ });
115
+ reduction = {
116
+ kind: 'r2_execute',
117
+ refId,
118
+ originalTokens: (0, reduction_1.estimateTokensFromText)(masked),
119
+ replacedTokens: (0, reduction_1.estimateTokensFromText)(returned),
120
+ savedTokens: (0, reduction_1.estimateTokensFromText)(masked) - (0, reduction_1.estimateTokensFromText)(returned),
121
+ };
122
+ overflowNote =
123
+ `\n--- stdout が上限 (${deps.maxReturnBytes.toLocaleString()} bytes) を超えたため切り詰めました。` +
124
+ `全文: pk_fetch(ref_id: "${refId}") / 絞り込み: pk_fetch(ref_id: "${refId}", query: "検索語") ---`;
125
+ }
126
+ catch {
127
+ // 退避失敗時は参照を案内しない (切り詰めのみ)。
128
+ overflowNote = `\n--- stdout が上限 (${deps.maxReturnBytes.toLocaleString()} bytes) を超えたため切り詰めました ---`;
129
+ }
130
+ }
131
+ // 4. 実行ログ (#68) + 削減イベント (#92) を記録 (best-effort)。
132
+ await deps
133
+ .recordEntry(buildExecEntry({
134
+ maskText: deps.maskText,
135
+ now: now(),
136
+ language,
137
+ code,
138
+ outcome: 'executed',
139
+ exitCode: result.exitCode,
140
+ durationMs: result.durationMs,
141
+ reduction,
142
+ }))
143
+ .catch(() => { });
144
+ // 5. 応答の組み立て。
145
+ if (result.timedOut) {
146
+ return {
147
+ content: [
148
+ {
149
+ type: 'text',
150
+ text: `タイムアウト (${Math.round(timeoutMs / 1000)}s) のため実行を中断しました。` + (returned ? `\n--- 中断までの stdout ---\n${returned}${overflowNote}` : ''),
151
+ },
152
+ ],
153
+ isError: true,
154
+ };
155
+ }
156
+ if (result.exitCode !== 0) {
157
+ const stderrMasked = deps.maskText(result.stderrHead);
158
+ return {
159
+ content: [
160
+ {
161
+ type: 'text',
162
+ text: `exit code ${result.exitCode ?? 'null'} (${result.durationMs}ms)\n` +
163
+ (stderrMasked ? `--- stderr (先頭) ---\n${stderrMasked}\n` : '') +
164
+ (returned ? `--- stdout ---\n${returned}${overflowNote}` : ''),
165
+ },
166
+ ],
167
+ isError: true,
168
+ };
169
+ }
170
+ return {
171
+ content: [{ type: 'text', text: (returned || '(stdout なし)') + overflowNote }],
172
+ };
173
+ }
174
+ //# sourceMappingURL=pk-execute.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pk-execute.js","sourceRoot":"","sources":["../../src/exec/pk-execute.ts"],"names":[],"mappings":";;AA2FA,oCA2IC;AAtOD,mCAAmC;AACnC,kDAA2D;AAK3D,qCAAqE;AACrE,yCAAyF;AAkCzF,SAAS,WAAW,CAAC,IAAY;IAC/B,OAAO,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AACrE,CAAC;AAED,iDAAiD;AACjD,SAAS,cAAc,CAAC,CAUvB;IACC,MAAM,UAAU,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;IACpD,MAAM,KAAK,GAAgB;QACzB,QAAQ,EAAE,kBAAkB;QAC5B,UAAU,EAAE,CAAC;QACb,QAAQ,EAAE,CAAC,CAAC,GAAG;QACf,MAAM,EAAE,MAAM;QACd,GAAG,EAAE;YACH,IAAI,EAAE,YAAY;YAClB,SAAS,EAAE,IAAI,EAAE,sBAAsB;YACvC,SAAS,EAAE,CAAC,CAAC,GAAG;YAChB,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,IAAI;YAC5B,UAAU,EAAE,CAAC,CAAC,UAAU,IAAI,IAAI;YAChC,UAAU,EAAE,UAAU;SACvB;KACF,CAAA;IACD,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;QACxC,MAAM,SAAS,GAAkB;YAC/B,QAAQ,EAAE,QAAQ;YAClB,MAAM,EAAE,oBAAoB;YAC5B,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC;YACR,6CAA6C;YAC7C,aAAa,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;YAC1D,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;SAC/B,CAAA;QACD,KAAK,CAAC,UAAU,GAAG,CAAC,SAAS,CAAC,CAAA;IAChC,CAAC;IACD,IAAI,CAAC,CAAC,SAAS;QAAE,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAA;IAC9C,OAAO,KAAK,CAAA;AACd,CAAC;AAED,mDAAmD;AAC5C,KAAK,UAAU,YAAY,CAChC,IAAmB,EACnB,IAA6B;IAE7B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAA;IACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;IAC9B,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA;IAC3D,IAAI,CAAC,IAAA,yBAAc,EAAC,QAAQ,CAAC,EAAE,CAAC;QAC9B,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,gDAAgD,EAAE,CAAC;YACnF,OAAO,EAAE,IAAI;SACd,CAAA;IACH,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QACjB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IAC3E,CAAC;IACD,MAAM,UAAU,GAAG,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA;IAC1G,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,GAAG,IAAI,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAA;IAEpG,2CAA2C;IAC3C,MAAM,OAAO,GAAG,IAAA,6BAAoB,EAAC,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAA;IAC9E,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACrB,MAAM,IAAI;aACP,WAAW,CACV,cAAc,CAAC;YACb,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,GAAG,EAAE,GAAG,EAAE;YACV,QAAQ;YACR,IAAI;YACJ,OAAO,EAAE,SAAS;YAClB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CACH;aACA,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QAClB,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EACF,qCAAqC,OAAO,CAAC,MAAM,IAAI;wBACvD,mCAAmC;iBACtC;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAA;IACH,CAAC;IAED,iCAAiC;IACjC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,IAAI,sBAAW,CAAA;IACzC,MAAM,MAAM,GAAe,MAAM,IAAI,CAAC;QACpC,QAAQ;QACR,IAAI;QACJ,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,SAAS;KACV,CAAC,CAAA;IAEF,mDAAmD;IACnD,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IAC3C,IAAI,QAAQ,GAAG,MAAM,CAAA;IACrB,IAAI,SAAoC,CAAA;IACxC,IAAI,YAAY,GAAG,EAAE,CAAA;IACrB,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QAC5D,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,CAAA;QAC/C,MAAM,KAAK,GAAG,IAAA,yBAAc,GAAE,CAAA;QAC9B,IAAI,CAAC;YACH,IAAI,CAAC,QAAQ,CAAC;gBACZ,KAAK;gBACL,SAAS,EAAE,IAAI;gBACf,QAAQ,EAAE,YAAY;gBACtB,GAAG,EAAE,IAAI,CAAC,WAAW;gBACrB,SAAS,EAAE,GAAG,EAAE;gBAChB,aAAa,EAAE,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC;gBAChD,cAAc,EAAE,IAAA,kCAAsB,EAAC,MAAM,CAAC;gBAC9C,cAAc,EAAE,IAAA,kCAAsB,EAAC,QAAQ,CAAC;gBAChD,WAAW,EAAE,IAAA,kCAAsB,EAAC,MAAM,CAAC,GAAG,IAAA,kCAAsB,EAAC,QAAQ,CAAC;gBAC9E,IAAI,EAAE,MAAM;aACb,CAAC,CAAA;YACF,SAAS,GAAG;gBACV,IAAI,EAAE,YAAY;gBAClB,KAAK;gBACL,cAAc,EAAE,IAAA,kCAAsB,EAAC,MAAM,CAAC;gBAC9C,cAAc,EAAE,IAAA,kCAAsB,EAAC,QAAQ,CAAC;gBAChD,WAAW,EAAE,IAAA,kCAAsB,EAAC,MAAM,CAAC,GAAG,IAAA,kCAAsB,EAAC,QAAQ,CAAC;aAC/E,CAAA;YACD,YAAY;gBACV,qBAAqB,IAAI,CAAC,cAAc,CAAC,cAAc,EAAE,wBAAwB;oBACjF,yBAAyB,KAAK,gCAAgC,KAAK,sBAAsB,CAAA;QAC7F,CAAC;QAAC,MAAM,CAAC;YACP,2BAA2B;YAC3B,YAAY,GAAG,qBAAqB,IAAI,CAAC,cAAc,CAAC,cAAc,EAAE,2BAA2B,CAAA;QACrG,CAAC;IACH,CAAC;IAED,kDAAkD;IAClD,MAAM,IAAI;SACP,WAAW,CACV,cAAc,CAAC;QACb,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,GAAG,EAAE,GAAG,EAAE;QACV,QAAQ;QACR,IAAI;QACJ,OAAO,EAAE,UAAU;QACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,SAAS;KACV,CAAC,CACH;SACA,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;IAElB,cAAc;IACd,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpB,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,WAAW,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,kBAAkB,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,2BAA2B,QAAQ,GAAG,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACzI;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAA;IACH,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;QACrD,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EACF,aAAa,MAAM,CAAC,QAAQ,IAAI,MAAM,KAAK,MAAM,CAAC,UAAU,OAAO;wBACnE,CAAC,YAAY,CAAC,CAAC,CAAC,wBAAwB,YAAY,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;wBAC9D,CAAC,QAAQ,CAAC,CAAC,CAAC,mBAAmB,QAAQ,GAAG,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACjE;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAA;IACH,CAAC;IACD,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,QAAQ,IAAI,aAAa,CAAC,GAAG,YAAY,EAAE,CAAC;KAC9E,CAAA;AACH,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { ExecutionPolicy } from './policy';
2
+ export interface FetchExecutionPolicyOptions {
3
+ apiEndpoint: string;
4
+ apiKey: string;
5
+ fetchImpl?: typeof fetch;
6
+ }
7
+ /** 組織/ユーザーの実行ポリシーを取得する。未設定・通信エラーは null。 */
8
+ export declare function fetchExecutionPolicy(opts: FetchExecutionPolicyOptions): Promise<ExecutionPolicy | null>;
9
+ //# sourceMappingURL=policy-fetcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy-fetcher.d.ts","sourceRoot":"","sources":["../../src/exec/policy-fetcher.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAgB/C,MAAM,WAAW,2BAA2B;IAC1C,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CACzB;AAED,2CAA2C;AAC3C,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,2BAA2B,GAChC,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAuBjC"}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fetchExecutionPolicy = fetchExecutionPolicy;
4
+ const zod_1 = require("zod");
5
+ const logger_1 = require("../logger");
6
+ const mask_rules_fetcher_1 = require("../mask-rules-fetcher");
7
+ // =============================================
8
+ // 組織実行ポリシーの取得 (Issue #94 / #44 接続)
9
+ // =============================================
10
+ //
11
+ // 配信は既存の getAgentMaskRules 応答に同梱される execution フィールドを使う
12
+ // (新エンドポイントを増やさない — functions のデプロイ明示列挙を変えないため)。
13
+ // 取得できない場合は null を返し、ビルトイン禁止リストのみで動作する
14
+ // (緩める方向には倒れない = 安全側)。
15
+ const ExecutionPolicySchema = zod_1.z.object({
16
+ forbiddenCommands: zod_1.z.array(zod_1.z.string().min(1).max(200)).max(50).default([]),
17
+ forbiddenPaths: zod_1.z.array(zod_1.z.string().min(1).max(200)).max(50).default([]),
18
+ });
19
+ /** 組織/ユーザーの実行ポリシーを取得する。未設定・通信エラーは null。 */
20
+ async function fetchExecutionPolicy(opts) {
21
+ const doFetch = opts.fetchImpl ?? fetch;
22
+ try {
23
+ const res = await doFetch((0, mask_rules_fetcher_1.maskRulesUrl)(opts.apiEndpoint), {
24
+ method: 'GET',
25
+ headers: { Authorization: `Bearer ${opts.apiKey}` },
26
+ });
27
+ if (!res.ok) {
28
+ logger_1.logger.warn('fetchExecutionPolicy: non-OK response', { status: res.status });
29
+ return null;
30
+ }
31
+ const body = (await res.json());
32
+ if (!body.success || body.execution == null)
33
+ return null;
34
+ const parsed = ExecutionPolicySchema.safeParse(body.execution);
35
+ if (!parsed.success) {
36
+ logger_1.logger.warn('fetchExecutionPolicy: invalid payload', { error: parsed.error.message });
37
+ return null;
38
+ }
39
+ return parsed.data;
40
+ }
41
+ catch (e) {
42
+ logger_1.logger.warn('fetchExecutionPolicy failed', { error: e.message });
43
+ return null;
44
+ }
45
+ }
46
+ //# sourceMappingURL=policy-fetcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy-fetcher.js","sourceRoot":"","sources":["../../src/exec/policy-fetcher.ts"],"names":[],"mappings":";;AA0BA,oDAyBC;AAnDD,6BAAuB;AACvB,sCAAkC;AAClC,8DAAoD;AAGpD,gDAAgD;AAChD,mCAAmC;AACnC,gDAAgD;AAChD,EAAE;AACF,uDAAuD;AACvD,iDAAiD;AACjD,uCAAuC;AACvC,uBAAuB;AAEvB,MAAM,qBAAqB,GAAG,OAAC,CAAC,MAAM,CAAC;IACrC,iBAAiB,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC1E,cAAc,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CACxE,CAAC,CAAA;AAQF,2CAA2C;AACpC,KAAK,UAAU,oBAAoB,CACxC,IAAiC;IAEjC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,IAAI,KAAK,CAAA;IACvC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAA,iCAAY,EAAC,IAAI,CAAC,WAAW,CAAC,EAAE;YACxD,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE,EAAE;SACpD,CAAC,CAAA;QACF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,eAAM,CAAC,IAAI,CAAC,uCAAuC,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAA;YAC5E,OAAO,IAAI,CAAA;QACb,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA+C,CAAA;QAC7E,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI;YAAE,OAAO,IAAI,CAAA;QACxD,MAAM,MAAM,GAAG,qBAAqB,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAC9D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,eAAM,CAAC,IAAI,CAAC,uCAAuC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;YACrF,OAAO,IAAI,CAAA;QACb,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,CAAA;IACpB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,eAAM,CAAC,IAAI,CAAC,6BAA6B,EAAE,EAAE,KAAK,EAAG,CAAW,CAAC,OAAO,EAAE,CAAC,CAAA;QAC3E,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC"}