my-pi 0.3.4 → 0.3.6
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/dist/api.d.ts +0 -22
- package/dist/api.js +9 -16
- package/dist/api.js.map +1 -1
- package/dist/{builtin-registry-D0mQ10up.js → builtin-registry-C0CQdd45.js} +11 -12
- package/dist/{builtin-registry-D0mQ10up.js.map → builtin-registry-C0CQdd45.js.map} +1 -1
- package/dist/footer-BAZIMVSb.js +1 -0
- package/dist/{handoff-C6wR2mSG.js → handoff-B2wpybTf.js} +2 -3
- package/dist/{handoff-C6wR2mSG.js.map → handoff-B2wpybTf.js.map} +1 -1
- package/dist/{hooks-resolution-qlhPfMFJ.js → hooks-resolution-kzoVsQAX.js} +8 -15
- package/dist/{hooks-resolution-qlhPfMFJ.js.map → hooks-resolution-kzoVsQAX.js.map} +1 -1
- package/dist/index.js +5 -9
- package/dist/index.js.map +1 -1
- package/dist/{openrouter-fusion-config-BWsHBPQv.js → openrouter-fusion-config-CPXLfmCA.js} +3 -4
- package/dist/{openrouter-fusion-config-BWsHBPQv.js.map → openrouter-fusion-config-CPXLfmCA.js.map} +1 -1
- package/dist/{prompt-presets-XraV03Ed.js → prompt-presets-DOn1oZFJ.js} +11 -21
- package/dist/{prompt-presets-XraV03Ed.js.map → prompt-presets-DOn1oZFJ.js.map} +1 -1
- package/dist/{session-name-CD6TVRnh.js → session-name-qyrX-OES.js} +2 -3
- package/dist/{session-name-CD6TVRnh.js.map → session-name-qyrX-OES.js.map} +1 -1
- package/dist/{settings-BCn3P9qH.js → settings-UYlhEo3S.js} +6 -11
- package/dist/{settings-BCn3P9qH.js.map → settings-UYlhEo3S.js.map} +1 -1
- package/dist/{startup-screen-DUeBWuAc.js → startup-screen-D5YGuwge.js} +2 -3
- package/dist/{startup-screen-DUeBWuAc.js.map → startup-screen-D5YGuwge.js.map} +1 -1
- package/dist/{turn-timer-CoyDI4gQ.js → turn-timer-mowT6nwv.js} +2 -3
- package/dist/{turn-timer-CoyDI4gQ.js.map → turn-timer-mowT6nwv.js.map} +1 -1
- package/dist/{umans-provider-C2UJ4qkO.js → umans-provider-DIupQTRK.js} +2 -3
- package/dist/{umans-provider-C2UJ4qkO.js.map → umans-provider-DIupQTRK.js.map} +1 -1
- package/package.json +10 -10
- package/dist/footer-Dt5eBLRN.js +0 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handoff-
|
|
1
|
+
{"version":3,"file":"handoff-B2wpybTf.js","names":[],"sources":["../src/extensions/handoff/index.ts"],"sourcesContent":["// Handoff extension — zero-context help for Pi continuation primitives.\n\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\n\nexport const HANDOFF_GUIDE = `Handoff in Pi\n\nUse built-ins first:\n- /fork: exact-context branch for experiments or continuing in a fresh session\n- /tree: inspect/navigate conversation branches\n- /export and /import: move session data between Pi instances\n- /share: create a shareable session artifact\n\nUse a markdown handoff only when the recipient is outside Pi or needs a compact task/return brief.\nReturn brief: changed files, validation, risks, next action.`;\n\nexport function handoff_command_output(args: string): string {\n\tconst trimmed = args.trim();\n\tif (!trimmed) return HANDOFF_GUIDE;\n\treturn `${HANDOFF_GUIDE}\\n\\nIntent noted: ${trimmed}`;\n}\n\nexport default function handoff(pi: ExtensionAPI): void {\n\tpi.registerCommand('handoff', {\n\t\tdescription:\n\t\t\t'Show when to use /fork, /tree, /export, /import, /share, or a portable handoff',\n\t\thandler: async (args, ctx) => {\n\t\t\tctx.ui.notify(handoff_command_output(args), 'info');\n\t\t},\n\t});\n}\n"],"mappings":";AAIA,MAAa,gBAAgB;;;;;;;;;;AAW7B,SAAgB,uBAAuB,MAAsB;CAC5D,MAAM,UAAU,KAAK,KAAK;CAC1B,IAAI,CAAC,SAAS,OAAO;CACrB,OAAO,GAAG,cAAc,oBAAoB;AAC7C;AAEA,SAAwB,QAAQ,IAAwB;CACvD,GAAG,gBAAgB,WAAW;EAC7B,aACC;EACD,SAAS,OAAO,MAAM,QAAQ;GAC7B,IAAI,GAAG,OAAO,uBAAuB,IAAI,GAAG,MAAM;EACnD;CACD,CAAC;AACF"}
|
|
@@ -4,7 +4,7 @@ import { create_project_trust_wrapper, resolve_project_trust } from "@spences10/
|
|
|
4
4
|
import { createHash } from "node:crypto";
|
|
5
5
|
import { create_child_process_env, create_pi_session_env } from "@spences10/pi-child-env";
|
|
6
6
|
import { spawn } from "node:child_process";
|
|
7
|
-
|
|
7
|
+
// src/extensions/hooks-resolution/config.ts
|
|
8
8
|
function is_file(path) {
|
|
9
9
|
try {
|
|
10
10
|
return statSync(path).isFile();
|
|
@@ -173,8 +173,7 @@ function get_hooks_config_info(cwd) {
|
|
|
173
173
|
hooks
|
|
174
174
|
};
|
|
175
175
|
}
|
|
176
|
-
|
|
177
|
-
//#region src/extensions/hooks-resolution/env.ts
|
|
176
|
+
// src/extensions/hooks-resolution/env.ts
|
|
178
177
|
function create_hook_session_env(ctx) {
|
|
179
178
|
return create_pi_session_env({
|
|
180
179
|
session_id: ctx.sessionManager.getSessionId(),
|
|
@@ -191,8 +190,7 @@ function create_child_process_env$1(explicit_env = {}, source_env = process.env)
|
|
|
191
190
|
source_env
|
|
192
191
|
});
|
|
193
192
|
}
|
|
194
|
-
|
|
195
|
-
//#region src/extensions/hooks-resolution/payload.ts
|
|
193
|
+
// src/extensions/hooks-resolution/payload.ts
|
|
196
194
|
function to_claude_tool_name(tool_name) {
|
|
197
195
|
if (tool_name === "ls") return "LS";
|
|
198
196
|
if (tool_name.length === 0) return tool_name;
|
|
@@ -254,8 +252,7 @@ function build_hook_payload(event, event_name, ctx, project_dir) {
|
|
|
254
252
|
if ("content" in event) payload.tool_response = build_tool_response(event, normalized_input);
|
|
255
253
|
return payload;
|
|
256
254
|
}
|
|
257
|
-
|
|
258
|
-
//#region src/extensions/hooks-resolution/runner.ts
|
|
255
|
+
// src/extensions/hooks-resolution/runner.ts
|
|
259
256
|
const HOOK_TIMEOUT_MS = 6e5;
|
|
260
257
|
async function run_command_hook(command, cwd, payload, pi_session_env = {}) {
|
|
261
258
|
return await new Promise((resolve) => {
|
|
@@ -345,8 +342,7 @@ function hook_name(command) {
|
|
|
345
342
|
const first_token = command.trim().split(/\s+/)[0] ?? "hook";
|
|
346
343
|
return basename(first_token);
|
|
347
344
|
}
|
|
348
|
-
|
|
349
|
-
//#region src/extensions/hooks-resolution/trust.ts
|
|
345
|
+
// src/extensions/hooks-resolution/trust.ts
|
|
350
346
|
const HOOKS_CONFIG_ENV$1 = "MY_PI_HOOKS_CONFIG";
|
|
351
347
|
const hooks_config_trust = create_project_trust_wrapper({
|
|
352
348
|
store_filename: "trusted-hooks.json",
|
|
@@ -371,8 +367,7 @@ function create_hooks_config_trust_subject(project_dir, hash) {
|
|
|
371
367
|
function is_hooks_config_trusted(project_dir, hash, trust_store_path = default_hooks_trust_store_path()) {
|
|
372
368
|
return hooks_config_trust.is_trusted(create_hooks_config_trust_subject(project_dir, hash), trust_store_path);
|
|
373
369
|
}
|
|
374
|
-
|
|
375
|
-
//#region src/extensions/hooks-resolution/trust-gate.ts
|
|
370
|
+
// src/extensions/hooks-resolution/trust-gate.ts
|
|
376
371
|
const HOOKS_CONFIG_ENV = "MY_PI_HOOKS_CONFIG";
|
|
377
372
|
function create_hooks_trust_subject(info) {
|
|
378
373
|
const source_lines = info.sources.map((source) => `- ${source}`);
|
|
@@ -415,8 +410,7 @@ async function should_load_hooks_config(cwd, ctx) {
|
|
|
415
410
|
});
|
|
416
411
|
return decision.action === "allow-once" || decision.action === "trust-persisted";
|
|
417
412
|
}
|
|
418
|
-
|
|
419
|
-
//#region src/extensions/hooks-resolution/index.ts
|
|
413
|
+
// src/extensions/hooks-resolution/index.ts
|
|
420
414
|
function create_hooks_resolution_extension(options = {}) {
|
|
421
415
|
const load_hooks_impl = options.load_hooks ?? load_hooks;
|
|
422
416
|
const run_command_hook_impl = options.run_command_hook ?? run_command_hook;
|
|
@@ -479,7 +473,6 @@ function create_hooks_resolution_extension(options = {}) {
|
|
|
479
473
|
};
|
|
480
474
|
}
|
|
481
475
|
var hooks_resolution_default = create_hooks_resolution_extension();
|
|
482
|
-
//#endregion
|
|
483
476
|
export { hooks_resolution_default as default };
|
|
484
477
|
|
|
485
|
-
//# sourceMappingURL=hooks-resolution-
|
|
478
|
+
//# sourceMappingURL=hooks-resolution-kzoVsQAX.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks-resolution-qlhPfMFJ.js","names":["create_child_process_env","create_shared_child_process_env","create_child_process_env","HOOKS_CONFIG_ENV"],"sources":["../src/extensions/hooks-resolution/config.ts","../src/extensions/hooks-resolution/env.ts","../src/extensions/hooks-resolution/payload.ts","../src/extensions/hooks-resolution/runner.ts","../src/extensions/hooks-resolution/trust.ts","../src/extensions/hooks-resolution/trust-gate.ts","../src/extensions/hooks-resolution/index.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport { existsSync, readFileSync, statSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport type {\n\tHookEventName,\n\tHooksConfigInfo,\n\tHookState,\n\tJsonValue,\n\tResolvedCommandHook,\n} from './types.js';\n\nexport function is_file(path: string): boolean {\n\ttry {\n\t\treturn statSync(path).isFile();\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport function as_record(\n\tvalue: unknown,\n): Record<string, unknown> | undefined {\n\tif (typeof value !== 'object' || value === null) return undefined;\n\treturn value as Record<string, unknown>;\n}\n\nexport function walk_up_directories(\n\tstart_dir: string,\n\tstop_dir?: string,\n): string[] {\n\tconst directories: string[] = [];\n\tconst has_stop_dir = stop_dir !== undefined;\n\tlet current = resolve(start_dir);\n\tlet parent = dirname(current);\n\tlet reached_stop_dir = has_stop_dir && current === stop_dir;\n\tlet reached_filesystem_root = parent === current;\n\n\tdirectories.push(current);\n\twhile (!reached_stop_dir && !reached_filesystem_root) {\n\t\tcurrent = parent;\n\t\tparent = dirname(current);\n\t\treached_stop_dir = has_stop_dir && current === stop_dir;\n\t\treached_filesystem_root = parent === current;\n\t\tdirectories.push(current);\n\t}\n\n\treturn directories;\n}\n\nexport function find_nearest_git_root(\n\tstart_dir: string,\n): string | undefined {\n\tfor (const directory of walk_up_directories(start_dir)) {\n\t\tif (existsSync(join(directory, '.git'))) {\n\t\t\treturn directory;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nexport function has_hooks_config(directory: string): boolean {\n\treturn (\n\t\tis_file(join(directory, '.claude', 'settings.json')) ||\n\t\tis_file(join(directory, '.rulesync', 'hooks.json')) ||\n\t\tis_file(join(directory, '.pi', 'hooks.json'))\n\t);\n}\n\nexport function find_project_dir(cwd: string): string {\n\tconst git_root = find_nearest_git_root(cwd);\n\tfor (const directory of walk_up_directories(cwd, git_root)) {\n\t\tif (has_hooks_config(directory)) {\n\t\t\treturn directory;\n\t\t}\n\t}\n\treturn git_root ?? resolve(cwd);\n}\n\nexport function read_json_file(path: string): JsonValue | undefined {\n\tif (!is_file(path)) return undefined;\n\ttry {\n\t\treturn JSON.parse(readFileSync(path, 'utf8')) as JsonValue;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function resolve_hook_command(\n\tcommand: string,\n\tproject_dir: string,\n): string {\n\treturn command.replace(/\\$CLAUDE_PROJECT_DIR\\b/g, project_dir);\n}\n\nexport function compile_matcher(\n\tmatcher_text: string | undefined,\n): RegExp | undefined {\n\tif (matcher_text === undefined) return undefined;\n\ttry {\n\t\treturn new RegExp(matcher_text);\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function create_hook(\n\tevent_name: HookEventName,\n\tmatcher_text: string | undefined,\n\tcommand: string,\n\tsource: string,\n\tproject_dir: string,\n): ResolvedCommandHook | undefined {\n\tconst matcher = compile_matcher(matcher_text);\n\tif (matcher_text !== undefined && matcher === undefined)\n\t\treturn undefined;\n\treturn {\n\t\tevent_name,\n\t\tmatcher,\n\t\tmatcher_text,\n\t\tcommand: resolve_hook_command(command, project_dir),\n\t\tsource,\n\t};\n}\n\nexport function get_hook_entries(\n\thooks_record: Record<string, unknown>,\n\tevent_name: HookEventName,\n): unknown[] {\n\tconst keys =\n\t\tevent_name === 'PreToolUse'\n\t\t\t? ['PreToolUse', 'preToolUse']\n\t\t\t: event_name === 'PostToolUse'\n\t\t\t\t? ['PostToolUse', 'postToolUse']\n\t\t\t\t: ['PostToolUseFailure', 'postToolUseFailure'];\n\n\tfor (const key of keys) {\n\t\tconst value = hooks_record[key];\n\t\tif (Array.isArray(value)) return value;\n\t}\n\treturn [];\n}\n\nexport function parse_claude_settings_hooks(\n\tconfig: unknown,\n\tsource: string,\n\tproject_dir: string,\n): ResolvedCommandHook[] {\n\tconst root = as_record(config);\n\tconst hooks_root = root ? as_record(root.hooks) : undefined;\n\tif (!hooks_root) return [];\n\n\tconst hooks: ResolvedCommandHook[] = [];\n\tconst events: HookEventName[] = [\n\t\t'PreToolUse',\n\t\t'PostToolUse',\n\t\t'PostToolUseFailure',\n\t];\n\n\tfor (const event_name of events) {\n\t\tconst entries = get_hook_entries(hooks_root, event_name);\n\t\tfor (const entry of entries) {\n\t\t\tconst entry_record = as_record(entry);\n\t\t\tif (!entry_record || !Array.isArray(entry_record.hooks))\n\t\t\t\tcontinue;\n\n\t\t\tconst matcher_text =\n\t\t\t\ttypeof entry_record.matcher === 'string'\n\t\t\t\t\t? entry_record.matcher\n\t\t\t\t\t: undefined;\n\t\t\tfor (const nested_hook of entry_record.hooks) {\n\t\t\t\tconst nested_record = as_record(nested_hook);\n\t\t\t\tif (!nested_record) continue;\n\t\t\t\tif (nested_record.type !== 'command') continue;\n\t\t\t\tif (typeof nested_record.command !== 'string') continue;\n\n\t\t\t\tconst hook = create_hook(\n\t\t\t\t\tevent_name,\n\t\t\t\t\tmatcher_text,\n\t\t\t\t\tnested_record.command,\n\t\t\t\t\tsource,\n\t\t\t\t\tproject_dir,\n\t\t\t\t);\n\t\t\t\tif (hook) hooks.push(hook);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn hooks;\n}\n\nexport function parse_simple_hooks_file(\n\tconfig: unknown,\n\tsource: string,\n\tproject_dir: string,\n): ResolvedCommandHook[] {\n\tconst root = as_record(config);\n\tconst hooks_root = root ? as_record(root.hooks) : undefined;\n\tif (!hooks_root) return [];\n\n\tconst hooks: ResolvedCommandHook[] = [];\n\tconst events: HookEventName[] = [\n\t\t'PreToolUse',\n\t\t'PostToolUse',\n\t\t'PostToolUseFailure',\n\t];\n\n\tfor (const event_name of events) {\n\t\tconst entries = get_hook_entries(hooks_root, event_name);\n\t\tfor (const entry of entries) {\n\t\t\tconst entry_record = as_record(entry);\n\t\t\tif (!entry_record || typeof entry_record.command !== 'string') {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst matcher_text =\n\t\t\t\ttypeof entry_record.matcher === 'string'\n\t\t\t\t\t? entry_record.matcher\n\t\t\t\t\t: undefined;\n\t\t\tconst hook = create_hook(\n\t\t\t\tevent_name,\n\t\t\t\tmatcher_text,\n\t\t\t\tentry_record.command,\n\t\t\t\tsource,\n\t\t\t\tproject_dir,\n\t\t\t);\n\t\t\tif (hook) hooks.push(hook);\n\t\t}\n\t}\n\n\treturn hooks;\n}\n\nfunction hook_config_paths(project_dir: string): string[] {\n\treturn [\n\t\tjoin(project_dir, '.claude', 'settings.json'),\n\t\tjoin(project_dir, '.rulesync', 'hooks.json'),\n\t\tjoin(project_dir, '.pi', 'hooks.json'),\n\t];\n}\n\nfunction parse_hooks_config_file(\n\tpath: string,\n\tproject_dir: string,\n): ResolvedCommandHook[] {\n\tconst config = read_json_file(path);\n\tif (config === undefined) return [];\n\tif (path.endsWith(join('.claude', 'settings.json'))) {\n\t\treturn parse_claude_settings_hooks(config, path, project_dir);\n\t}\n\treturn parse_simple_hooks_file(config, path, project_dir);\n}\n\nexport function load_hooks(cwd: string): HookState {\n\tconst project_dir = find_project_dir(cwd);\n\tconst hooks = hook_config_paths(project_dir).flatMap((path) =>\n\t\tparse_hooks_config_file(path, project_dir),\n\t);\n\n\treturn { project_dir, hooks };\n}\n\nexport function get_hooks_config_info(\n\tcwd: string,\n): HooksConfigInfo | undefined {\n\tconst project_dir = find_project_dir(cwd);\n\tconst sources = hook_config_paths(project_dir).filter(is_file);\n\tif (sources.length === 0) return undefined;\n\n\tconst hash = createHash('sha256');\n\tfor (const source of sources) {\n\t\thash.update(source);\n\t\thash.update('\\0');\n\t\thash.update(readFileSync(source, 'utf8'));\n\t\thash.update('\\0');\n\t}\n\n\tconst hooks = sources\n\t\t.flatMap((source) => parse_hooks_config_file(source, project_dir))\n\t\t.map((hook) => ({\n\t\t\tevent_name: hook.event_name,\n\t\t\tmatcher_text: hook.matcher_text,\n\t\t\tcommand: hook.command,\n\t\t\tsource: hook.source,\n\t\t}));\n\n\treturn {\n\t\tproject_dir,\n\t\thash: hash.digest('hex'),\n\t\tsources,\n\t\thooks,\n\t};\n}\n","import type { ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport {\n\tcreate_pi_session_env,\n\tcreate_child_process_env as create_shared_child_process_env,\n} from '@spences10/pi-child-env';\n\nexport function create_hook_session_env(\n\tctx: ExtensionContext,\n): Record<string, string> {\n\treturn create_pi_session_env({\n\t\tsession_id: ctx.sessionManager.getSessionId(),\n\t\tsession_file: ctx.sessionManager.getSessionFile(),\n\t\tprovider: ctx.model?.provider,\n\t\tmodel: ctx.model?.id,\n\t\treasoning_level: ctx.thinkingLevel,\n\t});\n}\n\nexport function create_child_process_env(\n\texplicit_env: Record<string, string> = {},\n\tsource_env: NodeJS.ProcessEnv = process.env,\n): NodeJS.ProcessEnv {\n\treturn create_shared_child_process_env({\n\t\tprofile: 'hooks',\n\t\texplicit_env,\n\t\tsource_env,\n\t});\n}\n","import type {\n\tExtensionContext,\n\tToolCallEvent,\n\tToolResultEvent,\n} from '@earendil-works/pi-coding-agent';\nimport type { HookEventName, ResolvedCommandHook } from './types.js';\n\nexport function to_claude_tool_name(tool_name: string): string {\n\tif (tool_name === 'ls') return 'LS';\n\tif (tool_name.length === 0) return tool_name;\n\treturn tool_name[0].toUpperCase() + tool_name.slice(1);\n}\n\nexport function matches_hook(\n\thook: ResolvedCommandHook,\n\ttool_name: string,\n): boolean {\n\tif (!hook.matcher) return true;\n\n\tconst claude_tool_name = to_claude_tool_name(tool_name);\n\thook.matcher.lastIndex = 0;\n\tif (hook.matcher.test(tool_name)) return true;\n\n\thook.matcher.lastIndex = 0;\n\treturn hook.matcher.test(claude_tool_name);\n}\n\nexport function extract_text_content(content: unknown): string {\n\tif (!Array.isArray(content)) return '';\n\n\tconst parts: string[] = [];\n\tfor (const item of content) {\n\t\tif (!item || typeof item !== 'object') continue;\n\t\tconst item_record = item as Record<string, unknown>;\n\t\tif (\n\t\t\titem_record.type === 'text' &&\n\t\t\ttypeof item_record.text === 'string'\n\t\t) {\n\t\t\tparts.push(item_record.text);\n\t\t}\n\t}\n\n\treturn parts.join('\\n');\n}\n\nexport function normalize_tool_input(\n\tinput: Record<string, unknown>,\n): Record<string, unknown> {\n\tconst normalized: Record<string, unknown> = { ...input };\n\tconst path_value =\n\t\ttypeof input.path === 'string' ? input.path : undefined;\n\tif (path_value !== undefined) {\n\t\tnormalized.file_path = path_value;\n\t\tnormalized.filePath = path_value;\n\t}\n\treturn normalized;\n}\n\nexport function build_tool_response(\n\tevent: ToolResultEvent,\n\tnormalized_input: Record<string, unknown>,\n): Record<string, unknown> {\n\tconst response: Record<string, unknown> = {\n\t\tis_error: event.isError,\n\t\tisError: event.isError,\n\t\tcontent: event.content,\n\t\ttext: extract_text_content(event.content),\n\t\tdetails: event.details ?? null,\n\t};\n\n\tconst file_path =\n\t\ttypeof normalized_input.file_path === 'string'\n\t\t\t? normalized_input.file_path\n\t\t\t: undefined;\n\tif (file_path !== undefined) {\n\t\tresponse.file_path = file_path;\n\t\tresponse.filePath = file_path;\n\t}\n\n\treturn response;\n}\n\nexport function build_hook_payload(\n\tevent: ToolCallEvent | ToolResultEvent,\n\tevent_name: HookEventName,\n\tctx: ExtensionContext,\n\tproject_dir: string,\n): Record<string, unknown> {\n\tconst normalized_input = normalize_tool_input(\n\t\tevent.input as Record<string, unknown>,\n\t);\n\tconst session_id =\n\t\tctx.sessionManager.getSessionFile() ?? 'ephemeral';\n\tconst payload: Record<string, unknown> = {\n\t\tsession_id,\n\t\tcwd: ctx.cwd,\n\t\tclaude_project_dir: project_dir,\n\t\thook_event_name: event_name,\n\t\ttool_name: to_claude_tool_name(event.toolName),\n\t\ttool_call_id: event.toolCallId,\n\t\ttool_input: normalized_input,\n\t};\n\n\tif ('content' in event) {\n\t\tpayload.tool_response = build_tool_response(\n\t\t\tevent,\n\t\t\tnormalized_input,\n\t\t);\n\t}\n\n\treturn payload;\n}\n","import type { ToolResultEvent } from '@earendil-works/pi-coding-agent';\nimport { spawn } from 'node:child_process';\nimport { basename } from 'node:path';\nimport { as_record } from './config.js';\nimport { create_child_process_env } from './env.js';\nimport type { CommandRunResult, HookEventName } from './types.js';\n\nconst HOOK_TIMEOUT_MS = 10 * 60 * 1000;\n\nexport async function run_command_hook(\n\tcommand: string,\n\tcwd: string,\n\tpayload: Record<string, unknown>,\n\tpi_session_env: Record<string, string> = {},\n): Promise<CommandRunResult> {\n\treturn await new Promise((resolve) => {\n\t\tconst started_at = Date.now();\n\t\tconst child = spawn('bash', ['-lc', command], {\n\t\t\tcwd,\n\t\t\tenv: create_child_process_env({\n\t\t\t\tCLAUDE_PROJECT_DIR: cwd,\n\t\t\t\t...pi_session_env,\n\t\t\t}),\n\t\t\tstdio: ['pipe', 'pipe', 'pipe'],\n\t\t});\n\n\t\tlet stdout = '';\n\t\tlet stderr = '';\n\t\tlet timed_out = false;\n\t\tlet resolved = false;\n\n\t\tconst finish = (code: number) => {\n\t\t\tif (resolved) return;\n\t\t\tresolved = true;\n\t\t\tresolve({\n\t\t\t\tcode,\n\t\t\t\tstdout,\n\t\t\t\tstderr,\n\t\t\t\telapsed_ms: Date.now() - started_at,\n\t\t\t\ttimed_out,\n\t\t\t});\n\t\t};\n\n\t\tconst timeout = setTimeout(() => {\n\t\t\ttimed_out = true;\n\t\t\tchild.kill('SIGTERM');\n\t\t\tconst kill_timer = setTimeout(() => {\n\t\t\t\tchild.kill('SIGKILL');\n\t\t\t}, 1000);\n\t\t\t(\n\t\t\t\tkill_timer as NodeJS.Timeout & { unref?: () => void }\n\t\t\t).unref?.();\n\t\t}, HOOK_TIMEOUT_MS);\n\t\t(timeout as NodeJS.Timeout & { unref?: () => void }).unref?.();\n\n\t\tchild.stdout.on('data', (chunk: Buffer) => {\n\t\t\tstdout += chunk.toString('utf8');\n\t\t});\n\t\tchild.stderr.on('data', (chunk: Buffer) => {\n\t\t\tstderr += chunk.toString('utf8');\n\t\t});\n\n\t\tchild.on('error', (error) => {\n\t\t\tclearTimeout(timeout);\n\t\t\tstderr += `${error.message}\\n`;\n\t\t\tfinish(-1);\n\t\t});\n\n\t\tchild.on('close', (code) => {\n\t\t\tclearTimeout(timeout);\n\t\t\tfinish(code ?? -1);\n\t\t});\n\n\t\ttry {\n\t\t\tchild.stdin.write(JSON.stringify(payload));\n\t\t\tchild.stdin.end();\n\t\t} catch (error) {\n\t\t\tstderr += `${error instanceof Error ? error.message : String(error)}\\n`;\n\t\t}\n\t});\n}\n\nexport function hook_event_name_for_result(\n\tevent: ToolResultEvent,\n): HookEventName {\n\treturn event.isError ? 'PostToolUseFailure' : 'PostToolUse';\n}\n\nexport function hook_block_reason(\n\tresult: CommandRunResult,\n): string | undefined {\n\tconst parse_json = (\n\t\ttext: string,\n\t): Record<string, unknown> | undefined => {\n\t\tconst trimmed = text.trim();\n\t\tif (!trimmed) return undefined;\n\t\ttry {\n\t\t\treturn as_record(JSON.parse(trimmed));\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t};\n\n\tconst json = parse_json(result.stdout) ?? parse_json(result.stderr);\n\tif (json?.decision === 'block') {\n\t\treturn typeof json.reason === 'string'\n\t\t\t? json.reason\n\t\t\t: 'Blocked by hook';\n\t}\n\tif (result.code === 2) {\n\t\treturn (\n\t\t\tresult.stderr.trim() ||\n\t\t\tresult.stdout.trim() ||\n\t\t\t'Blocked by hook'\n\t\t);\n\t}\n\treturn undefined;\n}\n\nexport function format_duration(elapsed_ms: number): string {\n\tif (elapsed_ms < 1000) return `${elapsed_ms}ms`;\n\treturn `${(elapsed_ms / 1000).toFixed(1)}s`;\n}\n\nexport function hook_name(command: string): string {\n\tconst sh_path_match = command.match(/[^\\s|;&]+\\.sh\\b/);\n\tif (sh_path_match) return basename(sh_path_match[0]);\n\tconst first_token = command.trim().split(/\\s+/)[0] ?? 'hook';\n\treturn basename(first_token);\n}\n","import {\n\tcreate_project_trust_wrapper,\n\ttype ProjectTrustSubject,\n} from '@spences10/pi-project-trust';\n\nconst HOOKS_CONFIG_ENV = 'MY_PI_HOOKS_CONFIG';\n\nconst hooks_config_trust = create_project_trust_wrapper({\n\tstore_filename: 'trusted-hooks.json',\n\tlegacy_matcher: (entry, subject) => {\n\t\tconst legacy_entry = entry as\n\t\t\t| { project_dir?: unknown; hash?: unknown }\n\t\t\t| undefined;\n\t\treturn (\n\t\t\tlegacy_entry?.project_dir === subject.id &&\n\t\t\tlegacy_entry.hash === subject.hash\n\t\t);\n\t},\n});\n\nexport function default_hooks_trust_store_path(): string {\n\treturn hooks_config_trust.default_trust_store_path();\n}\n\nexport function create_hooks_config_trust_subject(\n\tproject_dir: string,\n\thash: string,\n): ProjectTrustSubject {\n\treturn {\n\t\tkind: 'hooks-config',\n\t\tid: project_dir,\n\t\tstore_key: project_dir,\n\t\thash,\n\t\tenv_key: HOOKS_CONFIG_ENV,\n\t\tprompt_title:\n\t\t\t'Project hook config can execute shell commands after tool use. Trust these hooks?',\n\t};\n}\n\nexport function is_hooks_config_trusted(\n\tproject_dir: string,\n\thash: string,\n\ttrust_store_path = default_hooks_trust_store_path(),\n): boolean {\n\treturn hooks_config_trust.is_trusted(\n\t\tcreate_hooks_config_trust_subject(project_dir, hash),\n\t\ttrust_store_path,\n\t);\n}\n\nexport function trust_hooks_config(\n\tproject_dir: string,\n\thash: string,\n\ttrust_store_path = default_hooks_trust_store_path(),\n): void {\n\thooks_config_trust.trust(\n\t\tcreate_hooks_config_trust_subject(project_dir, hash),\n\t\ttrust_store_path,\n\t);\n}\n","import type { ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport {\n\tresolve_project_trust,\n\ttype ProjectTrustSubject,\n} from '@spences10/pi-project-trust';\nimport { get_hooks_config_info } from './config.js';\nimport {\n\tdefault_hooks_trust_store_path,\n\tis_hooks_config_trusted,\n} from './trust.js';\nimport type { HooksConfigInfo } from './types.js';\n\nconst HOOKS_CONFIG_ENV = 'MY_PI_HOOKS_CONFIG';\n\nexport function create_hooks_trust_subject(\n\tinfo: HooksConfigInfo,\n): ProjectTrustSubject {\n\tconst source_lines = info.sources.map((source) => `- ${source}`);\n\tconst hook_lines =\n\t\tinfo.hooks.length === 0\n\t\t\t? ['- no valid command hooks detected']\n\t\t\t: info.hooks.map((hook) => {\n\t\t\t\t\tconst matcher = hook.matcher_text\n\t\t\t\t\t\t? ` matcher=${hook.matcher_text}`\n\t\t\t\t\t\t: '';\n\t\t\t\t\treturn `- ${hook.event_name}${matcher}: ${hook.command}`;\n\t\t\t\t});\n\treturn {\n\t\tkind: 'hooks-config',\n\t\tid: info.project_dir,\n\t\tstore_key: info.project_dir,\n\t\thash: info.hash,\n\t\tenv_key: HOOKS_CONFIG_ENV,\n\t\tprompt_title:\n\t\t\t'Project hook config can execute shell commands after tool use. Trust these hooks?',\n\t\tsummary_lines: [\n\t\t\t'Sources:',\n\t\t\t...source_lines,\n\t\t\t'Commands:',\n\t\t\t...hook_lines,\n\t\t],\n\t\tchoices: {\n\t\t\tallow_once: 'Allow once for this session',\n\t\t\ttrust: 'Trust this repo until hook config changes',\n\t\t\tskip: 'Skip project hooks',\n\t\t},\n\t\theadless_warning: `Skipping untrusted hook config in ${info.project_dir}. Set ${HOOKS_CONFIG_ENV}=allow to enable hooks for this run.`,\n\t};\n}\n\nexport async function should_load_hooks_config(\n\tcwd: string,\n\tctx?: ExtensionContext,\n): Promise<boolean> {\n\tconst info = get_hooks_config_info(cwd);\n\tif (!info) return true;\n\tif (is_hooks_config_trusted(info.project_dir, info.hash))\n\t\treturn true;\n\n\tconst decision = await resolve_project_trust(\n\t\tcreate_hooks_trust_subject(info),\n\t\t{\n\t\t\thas_ui: ctx?.hasUI,\n\t\t\tselect: ctx?.hasUI\n\t\t\t\t? async (\n\t\t\t\t\t\tmessage: string,\n\t\t\t\t\t\tchoices: string[],\n\t\t\t\t\t): Promise<string> => {\n\t\t\t\t\t\tconst selected = await ctx.ui.select(message, choices);\n\t\t\t\t\t\treturn selected ?? '';\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t\tenv: process.env,\n\t\t\ttrust_store_path: default_hooks_trust_store_path(),\n\t\t},\n\t);\n\treturn (\n\t\tdecision.action === 'allow-once' ||\n\t\tdecision.action === 'trust-persisted'\n\t);\n}\n","// Hooks resolution — Claude Code style hook compatibility\n\nimport type {\n\tExtensionAPI,\n\tExtensionContext,\n\tExtensionFactory,\n\tToolCallEventResult,\n} from '@earendil-works/pi-coding-agent';\nimport { load_hooks } from './config.js';\nimport { create_hook_session_env } from './env.js';\nimport { build_hook_payload, matches_hook } from './payload.js';\nimport {\n\tformat_duration,\n\thook_block_reason,\n\thook_event_name_for_result,\n\thook_name,\n\trun_command_hook,\n} from './runner.js';\nimport { should_load_hooks_config } from './trust-gate.js';\nimport type { CommandRunResult, HookState } from './types.js';\n\nexport {\n\tas_record,\n\tcompile_matcher,\n\tcreate_hook,\n\tfind_nearest_git_root,\n\tfind_project_dir,\n\tget_hook_entries,\n\tget_hooks_config_info,\n\thas_hooks_config,\n\tis_file,\n\tload_hooks,\n\tparse_claude_settings_hooks,\n\tparse_simple_hooks_file,\n\tread_json_file,\n\tresolve_hook_command,\n\twalk_up_directories,\n} from './config.js';\nexport {\n\tbuild_hook_payload,\n\tbuild_tool_response,\n\textract_text_content,\n\tmatches_hook,\n\tnormalize_tool_input,\n\tto_claude_tool_name,\n} from './payload.js';\nexport {\n\tformat_duration,\n\thook_block_reason,\n\thook_event_name_for_result,\n\thook_name,\n\trun_command_hook,\n} from './runner.js';\nexport type {\n\tCommandRunResult,\n\tHookEventName,\n\tHooksConfigInfo,\n\tHookState,\n\tResolvedCommandHook,\n} from './types.js';\nexport interface HooksResolutionOptions {\n\tload_hooks?: (cwd: string) => HookState;\n\trun_command_hook?: (\n\t\tcommand: string,\n\t\tcwd: string,\n\t\tpayload: Record<string, unknown>,\n\t\tpi_session_env?: Record<string, string>,\n\t) => Promise<CommandRunResult>;\n}\n\nexport function create_hooks_resolution_extension(\n\toptions: HooksResolutionOptions = {},\n): ExtensionFactory {\n\tconst load_hooks_impl = options.load_hooks ?? load_hooks;\n\tconst run_command_hook_impl =\n\t\toptions.run_command_hook ?? run_command_hook;\n\n\treturn async function hooks_resolution(pi: ExtensionAPI) {\n\t\tlet state: HookState = {\n\t\t\tproject_dir: process.cwd(),\n\t\t\thooks: [],\n\t\t};\n\n\t\tconst refresh_hooks = async (\n\t\t\tcwd: string,\n\t\t\tctx?: ExtensionContext,\n\t\t) => {\n\t\t\tif (!(await should_load_hooks_config(cwd, ctx))) {\n\t\t\t\tstate = { project_dir: cwd, hooks: [] };\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tstate = load_hooks_impl(cwd);\n\t\t};\n\n\t\tpi.on('session_start', async (_event, ctx) => {\n\t\t\tawait refresh_hooks(ctx.cwd, ctx);\n\t\t});\n\n\t\tpi.on(\n\t\t\t'tool_call',\n\t\t\tasync (\n\t\t\t\tevent,\n\t\t\t\tctx,\n\t\t\t): Promise<ToolCallEventResult | undefined> => {\n\t\t\t\tif (state.hooks.length === 0) return;\n\n\t\t\t\tconst matching_hooks = state.hooks.filter(\n\t\t\t\t\t(hook) =>\n\t\t\t\t\t\thook.event_name === 'PreToolUse' &&\n\t\t\t\t\t\tmatches_hook(hook, event.toolName),\n\t\t\t\t);\n\t\t\t\tif (matching_hooks.length === 0) return;\n\n\t\t\t\tconst payload = build_hook_payload(\n\t\t\t\t\tevent,\n\t\t\t\t\t'PreToolUse',\n\t\t\t\t\tctx,\n\t\t\t\t\tstate.project_dir,\n\t\t\t\t);\n\t\t\t\tconst executed_commands = new Set<string>();\n\n\t\t\t\tfor (const hook of matching_hooks) {\n\t\t\t\t\tif (executed_commands.has(hook.command)) continue;\n\t\t\t\t\texecuted_commands.add(hook.command);\n\n\t\t\t\t\tconst result = await run_command_hook_impl(\n\t\t\t\t\t\thook.command,\n\t\t\t\t\t\tstate.project_dir,\n\t\t\t\t\t\tpayload,\n\t\t\t\t\t\tcreate_hook_session_env(ctx),\n\t\t\t\t\t);\n\t\t\t\t\tconst reason = hook_block_reason(result);\n\t\t\t\t\tif (reason) return { block: true, reason };\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\n\t\tpi.on('tool_result', async (event, ctx) => {\n\t\t\tif (state.hooks.length === 0) return;\n\n\t\t\tconst event_name = hook_event_name_for_result(event);\n\t\t\tconst matching_hooks = state.hooks.filter(\n\t\t\t\t(hook) =>\n\t\t\t\t\thook.event_name === event_name &&\n\t\t\t\t\tmatches_hook(hook, event.toolName),\n\t\t\t);\n\t\t\tif (matching_hooks.length === 0) return;\n\n\t\t\tconst payload = build_hook_payload(\n\t\t\t\tevent,\n\t\t\t\tevent_name,\n\t\t\t\tctx,\n\t\t\t\tstate.project_dir,\n\t\t\t);\n\t\t\tconst executed_commands = new Set<string>();\n\n\t\t\tfor (const hook of matching_hooks) {\n\t\t\t\tif (executed_commands.has(hook.command)) continue;\n\t\t\t\texecuted_commands.add(hook.command);\n\n\t\t\t\tconst result = await run_command_hook_impl(\n\t\t\t\t\thook.command,\n\t\t\t\t\tstate.project_dir,\n\t\t\t\t\tpayload,\n\t\t\t\t\tcreate_hook_session_env(ctx),\n\t\t\t\t);\n\t\t\t\tconst name = hook_name(hook.command);\n\t\t\t\tconst duration = format_duration(result.elapsed_ms);\n\n\t\t\t\tif (ctx.hasUI) {\n\t\t\t\t\tif (result.code === 0) {\n\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\t`Hook \\`${name}\\` ran (${duration})`,\n\t\t\t\t\t\t\t'info',\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst error_line =\n\t\t\t\t\t\t\tresult.stderr.trim() ||\n\t\t\t\t\t\t\tresult.stdout.trim() ||\n\t\t\t\t\t\t\t`exit code ${result.code}`;\n\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\t`Hook \\`${name}\\` failed (${duration}): ${error_line}`,\n\t\t\t\t\t\t\t'warning',\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t};\n}\n\nexport default create_hooks_resolution_extension();\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"hooks-resolution-kzoVsQAX.js","names":["create_child_process_env","create_shared_child_process_env","create_child_process_env","HOOKS_CONFIG_ENV"],"sources":["../src/extensions/hooks-resolution/config.ts","../src/extensions/hooks-resolution/env.ts","../src/extensions/hooks-resolution/payload.ts","../src/extensions/hooks-resolution/runner.ts","../src/extensions/hooks-resolution/trust.ts","../src/extensions/hooks-resolution/trust-gate.ts","../src/extensions/hooks-resolution/index.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport { existsSync, readFileSync, statSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport type {\n\tHookEventName,\n\tHooksConfigInfo,\n\tHookState,\n\tJsonValue,\n\tResolvedCommandHook,\n} from './types.js';\n\nexport function is_file(path: string): boolean {\n\ttry {\n\t\treturn statSync(path).isFile();\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport function as_record(\n\tvalue: unknown,\n): Record<string, unknown> | undefined {\n\tif (typeof value !== 'object' || value === null) return undefined;\n\treturn value as Record<string, unknown>;\n}\n\nexport function walk_up_directories(\n\tstart_dir: string,\n\tstop_dir?: string,\n): string[] {\n\tconst directories: string[] = [];\n\tconst has_stop_dir = stop_dir !== undefined;\n\tlet current = resolve(start_dir);\n\tlet parent = dirname(current);\n\tlet reached_stop_dir = has_stop_dir && current === stop_dir;\n\tlet reached_filesystem_root = parent === current;\n\n\tdirectories.push(current);\n\twhile (!reached_stop_dir && !reached_filesystem_root) {\n\t\tcurrent = parent;\n\t\tparent = dirname(current);\n\t\treached_stop_dir = has_stop_dir && current === stop_dir;\n\t\treached_filesystem_root = parent === current;\n\t\tdirectories.push(current);\n\t}\n\n\treturn directories;\n}\n\nexport function find_nearest_git_root(\n\tstart_dir: string,\n): string | undefined {\n\tfor (const directory of walk_up_directories(start_dir)) {\n\t\tif (existsSync(join(directory, '.git'))) {\n\t\t\treturn directory;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nexport function has_hooks_config(directory: string): boolean {\n\treturn (\n\t\tis_file(join(directory, '.claude', 'settings.json')) ||\n\t\tis_file(join(directory, '.rulesync', 'hooks.json')) ||\n\t\tis_file(join(directory, '.pi', 'hooks.json'))\n\t);\n}\n\nexport function find_project_dir(cwd: string): string {\n\tconst git_root = find_nearest_git_root(cwd);\n\tfor (const directory of walk_up_directories(cwd, git_root)) {\n\t\tif (has_hooks_config(directory)) {\n\t\t\treturn directory;\n\t\t}\n\t}\n\treturn git_root ?? resolve(cwd);\n}\n\nexport function read_json_file(path: string): JsonValue | undefined {\n\tif (!is_file(path)) return undefined;\n\ttry {\n\t\treturn JSON.parse(readFileSync(path, 'utf8')) as JsonValue;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function resolve_hook_command(\n\tcommand: string,\n\tproject_dir: string,\n): string {\n\treturn command.replace(/\\$CLAUDE_PROJECT_DIR\\b/g, project_dir);\n}\n\nexport function compile_matcher(\n\tmatcher_text: string | undefined,\n): RegExp | undefined {\n\tif (matcher_text === undefined) return undefined;\n\ttry {\n\t\treturn new RegExp(matcher_text);\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function create_hook(\n\tevent_name: HookEventName,\n\tmatcher_text: string | undefined,\n\tcommand: string,\n\tsource: string,\n\tproject_dir: string,\n): ResolvedCommandHook | undefined {\n\tconst matcher = compile_matcher(matcher_text);\n\tif (matcher_text !== undefined && matcher === undefined)\n\t\treturn undefined;\n\treturn {\n\t\tevent_name,\n\t\tmatcher,\n\t\tmatcher_text,\n\t\tcommand: resolve_hook_command(command, project_dir),\n\t\tsource,\n\t};\n}\n\nexport function get_hook_entries(\n\thooks_record: Record<string, unknown>,\n\tevent_name: HookEventName,\n): unknown[] {\n\tconst keys =\n\t\tevent_name === 'PreToolUse'\n\t\t\t? ['PreToolUse', 'preToolUse']\n\t\t\t: event_name === 'PostToolUse'\n\t\t\t\t? ['PostToolUse', 'postToolUse']\n\t\t\t\t: ['PostToolUseFailure', 'postToolUseFailure'];\n\n\tfor (const key of keys) {\n\t\tconst value = hooks_record[key];\n\t\tif (Array.isArray(value)) return value;\n\t}\n\treturn [];\n}\n\nexport function parse_claude_settings_hooks(\n\tconfig: unknown,\n\tsource: string,\n\tproject_dir: string,\n): ResolvedCommandHook[] {\n\tconst root = as_record(config);\n\tconst hooks_root = root ? as_record(root.hooks) : undefined;\n\tif (!hooks_root) return [];\n\n\tconst hooks: ResolvedCommandHook[] = [];\n\tconst events: HookEventName[] = [\n\t\t'PreToolUse',\n\t\t'PostToolUse',\n\t\t'PostToolUseFailure',\n\t];\n\n\tfor (const event_name of events) {\n\t\tconst entries = get_hook_entries(hooks_root, event_name);\n\t\tfor (const entry of entries) {\n\t\t\tconst entry_record = as_record(entry);\n\t\t\tif (!entry_record || !Array.isArray(entry_record.hooks))\n\t\t\t\tcontinue;\n\n\t\t\tconst matcher_text =\n\t\t\t\ttypeof entry_record.matcher === 'string'\n\t\t\t\t\t? entry_record.matcher\n\t\t\t\t\t: undefined;\n\t\t\tfor (const nested_hook of entry_record.hooks) {\n\t\t\t\tconst nested_record = as_record(nested_hook);\n\t\t\t\tif (!nested_record) continue;\n\t\t\t\tif (nested_record.type !== 'command') continue;\n\t\t\t\tif (typeof nested_record.command !== 'string') continue;\n\n\t\t\t\tconst hook = create_hook(\n\t\t\t\t\tevent_name,\n\t\t\t\t\tmatcher_text,\n\t\t\t\t\tnested_record.command,\n\t\t\t\t\tsource,\n\t\t\t\t\tproject_dir,\n\t\t\t\t);\n\t\t\t\tif (hook) hooks.push(hook);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn hooks;\n}\n\nexport function parse_simple_hooks_file(\n\tconfig: unknown,\n\tsource: string,\n\tproject_dir: string,\n): ResolvedCommandHook[] {\n\tconst root = as_record(config);\n\tconst hooks_root = root ? as_record(root.hooks) : undefined;\n\tif (!hooks_root) return [];\n\n\tconst hooks: ResolvedCommandHook[] = [];\n\tconst events: HookEventName[] = [\n\t\t'PreToolUse',\n\t\t'PostToolUse',\n\t\t'PostToolUseFailure',\n\t];\n\n\tfor (const event_name of events) {\n\t\tconst entries = get_hook_entries(hooks_root, event_name);\n\t\tfor (const entry of entries) {\n\t\t\tconst entry_record = as_record(entry);\n\t\t\tif (!entry_record || typeof entry_record.command !== 'string') {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst matcher_text =\n\t\t\t\ttypeof entry_record.matcher === 'string'\n\t\t\t\t\t? entry_record.matcher\n\t\t\t\t\t: undefined;\n\t\t\tconst hook = create_hook(\n\t\t\t\tevent_name,\n\t\t\t\tmatcher_text,\n\t\t\t\tentry_record.command,\n\t\t\t\tsource,\n\t\t\t\tproject_dir,\n\t\t\t);\n\t\t\tif (hook) hooks.push(hook);\n\t\t}\n\t}\n\n\treturn hooks;\n}\n\nfunction hook_config_paths(project_dir: string): string[] {\n\treturn [\n\t\tjoin(project_dir, '.claude', 'settings.json'),\n\t\tjoin(project_dir, '.rulesync', 'hooks.json'),\n\t\tjoin(project_dir, '.pi', 'hooks.json'),\n\t];\n}\n\nfunction parse_hooks_config_file(\n\tpath: string,\n\tproject_dir: string,\n): ResolvedCommandHook[] {\n\tconst config = read_json_file(path);\n\tif (config === undefined) return [];\n\tif (path.endsWith(join('.claude', 'settings.json'))) {\n\t\treturn parse_claude_settings_hooks(config, path, project_dir);\n\t}\n\treturn parse_simple_hooks_file(config, path, project_dir);\n}\n\nexport function load_hooks(cwd: string): HookState {\n\tconst project_dir = find_project_dir(cwd);\n\tconst hooks = hook_config_paths(project_dir).flatMap((path) =>\n\t\tparse_hooks_config_file(path, project_dir),\n\t);\n\n\treturn { project_dir, hooks };\n}\n\nexport function get_hooks_config_info(\n\tcwd: string,\n): HooksConfigInfo | undefined {\n\tconst project_dir = find_project_dir(cwd);\n\tconst sources = hook_config_paths(project_dir).filter(is_file);\n\tif (sources.length === 0) return undefined;\n\n\tconst hash = createHash('sha256');\n\tfor (const source of sources) {\n\t\thash.update(source);\n\t\thash.update('\\0');\n\t\thash.update(readFileSync(source, 'utf8'));\n\t\thash.update('\\0');\n\t}\n\n\tconst hooks = sources\n\t\t.flatMap((source) => parse_hooks_config_file(source, project_dir))\n\t\t.map((hook) => ({\n\t\t\tevent_name: hook.event_name,\n\t\t\tmatcher_text: hook.matcher_text,\n\t\t\tcommand: hook.command,\n\t\t\tsource: hook.source,\n\t\t}));\n\n\treturn {\n\t\tproject_dir,\n\t\thash: hash.digest('hex'),\n\t\tsources,\n\t\thooks,\n\t};\n}\n","import type { ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport {\n\tcreate_pi_session_env,\n\tcreate_child_process_env as create_shared_child_process_env,\n} from '@spences10/pi-child-env';\n\nexport function create_hook_session_env(\n\tctx: ExtensionContext,\n): Record<string, string> {\n\treturn create_pi_session_env({\n\t\tsession_id: ctx.sessionManager.getSessionId(),\n\t\tsession_file: ctx.sessionManager.getSessionFile(),\n\t\tprovider: ctx.model?.provider,\n\t\tmodel: ctx.model?.id,\n\t\treasoning_level: ctx.thinkingLevel,\n\t});\n}\n\nexport function create_child_process_env(\n\texplicit_env: Record<string, string> = {},\n\tsource_env: NodeJS.ProcessEnv = process.env,\n): NodeJS.ProcessEnv {\n\treturn create_shared_child_process_env({\n\t\tprofile: 'hooks',\n\t\texplicit_env,\n\t\tsource_env,\n\t});\n}\n","import type {\n\tExtensionContext,\n\tToolCallEvent,\n\tToolResultEvent,\n} from '@earendil-works/pi-coding-agent';\nimport type { HookEventName, ResolvedCommandHook } from './types.js';\n\nexport function to_claude_tool_name(tool_name: string): string {\n\tif (tool_name === 'ls') return 'LS';\n\tif (tool_name.length === 0) return tool_name;\n\treturn tool_name[0].toUpperCase() + tool_name.slice(1);\n}\n\nexport function matches_hook(\n\thook: ResolvedCommandHook,\n\ttool_name: string,\n): boolean {\n\tif (!hook.matcher) return true;\n\n\tconst claude_tool_name = to_claude_tool_name(tool_name);\n\thook.matcher.lastIndex = 0;\n\tif (hook.matcher.test(tool_name)) return true;\n\n\thook.matcher.lastIndex = 0;\n\treturn hook.matcher.test(claude_tool_name);\n}\n\nexport function extract_text_content(content: unknown): string {\n\tif (!Array.isArray(content)) return '';\n\n\tconst parts: string[] = [];\n\tfor (const item of content) {\n\t\tif (!item || typeof item !== 'object') continue;\n\t\tconst item_record = item as Record<string, unknown>;\n\t\tif (\n\t\t\titem_record.type === 'text' &&\n\t\t\ttypeof item_record.text === 'string'\n\t\t) {\n\t\t\tparts.push(item_record.text);\n\t\t}\n\t}\n\n\treturn parts.join('\\n');\n}\n\nexport function normalize_tool_input(\n\tinput: Record<string, unknown>,\n): Record<string, unknown> {\n\tconst normalized: Record<string, unknown> = { ...input };\n\tconst path_value =\n\t\ttypeof input.path === 'string' ? input.path : undefined;\n\tif (path_value !== undefined) {\n\t\tnormalized.file_path = path_value;\n\t\tnormalized.filePath = path_value;\n\t}\n\treturn normalized;\n}\n\nexport function build_tool_response(\n\tevent: ToolResultEvent,\n\tnormalized_input: Record<string, unknown>,\n): Record<string, unknown> {\n\tconst response: Record<string, unknown> = {\n\t\tis_error: event.isError,\n\t\tisError: event.isError,\n\t\tcontent: event.content,\n\t\ttext: extract_text_content(event.content),\n\t\tdetails: event.details ?? null,\n\t};\n\n\tconst file_path =\n\t\ttypeof normalized_input.file_path === 'string'\n\t\t\t? normalized_input.file_path\n\t\t\t: undefined;\n\tif (file_path !== undefined) {\n\t\tresponse.file_path = file_path;\n\t\tresponse.filePath = file_path;\n\t}\n\n\treturn response;\n}\n\nexport function build_hook_payload(\n\tevent: ToolCallEvent | ToolResultEvent,\n\tevent_name: HookEventName,\n\tctx: ExtensionContext,\n\tproject_dir: string,\n): Record<string, unknown> {\n\tconst normalized_input = normalize_tool_input(\n\t\tevent.input as Record<string, unknown>,\n\t);\n\tconst session_id =\n\t\tctx.sessionManager.getSessionFile() ?? 'ephemeral';\n\tconst payload: Record<string, unknown> = {\n\t\tsession_id,\n\t\tcwd: ctx.cwd,\n\t\tclaude_project_dir: project_dir,\n\t\thook_event_name: event_name,\n\t\ttool_name: to_claude_tool_name(event.toolName),\n\t\ttool_call_id: event.toolCallId,\n\t\ttool_input: normalized_input,\n\t};\n\n\tif ('content' in event) {\n\t\tpayload.tool_response = build_tool_response(\n\t\t\tevent,\n\t\t\tnormalized_input,\n\t\t);\n\t}\n\n\treturn payload;\n}\n","import type { ToolResultEvent } from '@earendil-works/pi-coding-agent';\nimport { spawn } from 'node:child_process';\nimport { basename } from 'node:path';\nimport { as_record } from './config.js';\nimport { create_child_process_env } from './env.js';\nimport type { CommandRunResult, HookEventName } from './types.js';\n\nconst HOOK_TIMEOUT_MS = 10 * 60 * 1000;\n\nexport async function run_command_hook(\n\tcommand: string,\n\tcwd: string,\n\tpayload: Record<string, unknown>,\n\tpi_session_env: Record<string, string> = {},\n): Promise<CommandRunResult> {\n\treturn await new Promise((resolve) => {\n\t\tconst started_at = Date.now();\n\t\tconst child = spawn('bash', ['-lc', command], {\n\t\t\tcwd,\n\t\t\tenv: create_child_process_env({\n\t\t\t\tCLAUDE_PROJECT_DIR: cwd,\n\t\t\t\t...pi_session_env,\n\t\t\t}),\n\t\t\tstdio: ['pipe', 'pipe', 'pipe'],\n\t\t});\n\n\t\tlet stdout = '';\n\t\tlet stderr = '';\n\t\tlet timed_out = false;\n\t\tlet resolved = false;\n\n\t\tconst finish = (code: number) => {\n\t\t\tif (resolved) return;\n\t\t\tresolved = true;\n\t\t\tresolve({\n\t\t\t\tcode,\n\t\t\t\tstdout,\n\t\t\t\tstderr,\n\t\t\t\telapsed_ms: Date.now() - started_at,\n\t\t\t\ttimed_out,\n\t\t\t});\n\t\t};\n\n\t\tconst timeout = setTimeout(() => {\n\t\t\ttimed_out = true;\n\t\t\tchild.kill('SIGTERM');\n\t\t\tconst kill_timer = setTimeout(() => {\n\t\t\t\tchild.kill('SIGKILL');\n\t\t\t}, 1000);\n\t\t\t(\n\t\t\t\tkill_timer as NodeJS.Timeout & { unref?: () => void }\n\t\t\t).unref?.();\n\t\t}, HOOK_TIMEOUT_MS);\n\t\t(timeout as NodeJS.Timeout & { unref?: () => void }).unref?.();\n\n\t\tchild.stdout.on('data', (chunk: Buffer) => {\n\t\t\tstdout += chunk.toString('utf8');\n\t\t});\n\t\tchild.stderr.on('data', (chunk: Buffer) => {\n\t\t\tstderr += chunk.toString('utf8');\n\t\t});\n\n\t\tchild.on('error', (error) => {\n\t\t\tclearTimeout(timeout);\n\t\t\tstderr += `${error.message}\\n`;\n\t\t\tfinish(-1);\n\t\t});\n\n\t\tchild.on('close', (code) => {\n\t\t\tclearTimeout(timeout);\n\t\t\tfinish(code ?? -1);\n\t\t});\n\n\t\ttry {\n\t\t\tchild.stdin.write(JSON.stringify(payload));\n\t\t\tchild.stdin.end();\n\t\t} catch (error) {\n\t\t\tstderr += `${error instanceof Error ? error.message : String(error)}\\n`;\n\t\t}\n\t});\n}\n\nexport function hook_event_name_for_result(\n\tevent: ToolResultEvent,\n): HookEventName {\n\treturn event.isError ? 'PostToolUseFailure' : 'PostToolUse';\n}\n\nexport function hook_block_reason(\n\tresult: CommandRunResult,\n): string | undefined {\n\tconst parse_json = (\n\t\ttext: string,\n\t): Record<string, unknown> | undefined => {\n\t\tconst trimmed = text.trim();\n\t\tif (!trimmed) return undefined;\n\t\ttry {\n\t\t\treturn as_record(JSON.parse(trimmed));\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t};\n\n\tconst json = parse_json(result.stdout) ?? parse_json(result.stderr);\n\tif (json?.decision === 'block') {\n\t\treturn typeof json.reason === 'string'\n\t\t\t? json.reason\n\t\t\t: 'Blocked by hook';\n\t}\n\tif (result.code === 2) {\n\t\treturn (\n\t\t\tresult.stderr.trim() ||\n\t\t\tresult.stdout.trim() ||\n\t\t\t'Blocked by hook'\n\t\t);\n\t}\n\treturn undefined;\n}\n\nexport function format_duration(elapsed_ms: number): string {\n\tif (elapsed_ms < 1000) return `${elapsed_ms}ms`;\n\treturn `${(elapsed_ms / 1000).toFixed(1)}s`;\n}\n\nexport function hook_name(command: string): string {\n\tconst sh_path_match = command.match(/[^\\s|;&]+\\.sh\\b/);\n\tif (sh_path_match) return basename(sh_path_match[0]);\n\tconst first_token = command.trim().split(/\\s+/)[0] ?? 'hook';\n\treturn basename(first_token);\n}\n","import {\n\tcreate_project_trust_wrapper,\n\ttype ProjectTrustSubject,\n} from '@spences10/pi-project-trust';\n\nconst HOOKS_CONFIG_ENV = 'MY_PI_HOOKS_CONFIG';\n\nconst hooks_config_trust = create_project_trust_wrapper({\n\tstore_filename: 'trusted-hooks.json',\n\tlegacy_matcher: (entry, subject) => {\n\t\tconst legacy_entry = entry as\n\t\t\t| { project_dir?: unknown; hash?: unknown }\n\t\t\t| undefined;\n\t\treturn (\n\t\t\tlegacy_entry?.project_dir === subject.id &&\n\t\t\tlegacy_entry.hash === subject.hash\n\t\t);\n\t},\n});\n\nexport function default_hooks_trust_store_path(): string {\n\treturn hooks_config_trust.default_trust_store_path();\n}\n\nexport function create_hooks_config_trust_subject(\n\tproject_dir: string,\n\thash: string,\n): ProjectTrustSubject {\n\treturn {\n\t\tkind: 'hooks-config',\n\t\tid: project_dir,\n\t\tstore_key: project_dir,\n\t\thash,\n\t\tenv_key: HOOKS_CONFIG_ENV,\n\t\tprompt_title:\n\t\t\t'Project hook config can execute shell commands after tool use. Trust these hooks?',\n\t};\n}\n\nexport function is_hooks_config_trusted(\n\tproject_dir: string,\n\thash: string,\n\ttrust_store_path = default_hooks_trust_store_path(),\n): boolean {\n\treturn hooks_config_trust.is_trusted(\n\t\tcreate_hooks_config_trust_subject(project_dir, hash),\n\t\ttrust_store_path,\n\t);\n}\n\nexport function trust_hooks_config(\n\tproject_dir: string,\n\thash: string,\n\ttrust_store_path = default_hooks_trust_store_path(),\n): void {\n\thooks_config_trust.trust(\n\t\tcreate_hooks_config_trust_subject(project_dir, hash),\n\t\ttrust_store_path,\n\t);\n}\n","import type { ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport {\n\tresolve_project_trust,\n\ttype ProjectTrustSubject,\n} from '@spences10/pi-project-trust';\nimport { get_hooks_config_info } from './config.js';\nimport {\n\tdefault_hooks_trust_store_path,\n\tis_hooks_config_trusted,\n} from './trust.js';\nimport type { HooksConfigInfo } from './types.js';\n\nconst HOOKS_CONFIG_ENV = 'MY_PI_HOOKS_CONFIG';\n\nexport function create_hooks_trust_subject(\n\tinfo: HooksConfigInfo,\n): ProjectTrustSubject {\n\tconst source_lines = info.sources.map((source) => `- ${source}`);\n\tconst hook_lines =\n\t\tinfo.hooks.length === 0\n\t\t\t? ['- no valid command hooks detected']\n\t\t\t: info.hooks.map((hook) => {\n\t\t\t\t\tconst matcher = hook.matcher_text\n\t\t\t\t\t\t? ` matcher=${hook.matcher_text}`\n\t\t\t\t\t\t: '';\n\t\t\t\t\treturn `- ${hook.event_name}${matcher}: ${hook.command}`;\n\t\t\t\t});\n\treturn {\n\t\tkind: 'hooks-config',\n\t\tid: info.project_dir,\n\t\tstore_key: info.project_dir,\n\t\thash: info.hash,\n\t\tenv_key: HOOKS_CONFIG_ENV,\n\t\tprompt_title:\n\t\t\t'Project hook config can execute shell commands after tool use. Trust these hooks?',\n\t\tsummary_lines: [\n\t\t\t'Sources:',\n\t\t\t...source_lines,\n\t\t\t'Commands:',\n\t\t\t...hook_lines,\n\t\t],\n\t\tchoices: {\n\t\t\tallow_once: 'Allow once for this session',\n\t\t\ttrust: 'Trust this repo until hook config changes',\n\t\t\tskip: 'Skip project hooks',\n\t\t},\n\t\theadless_warning: `Skipping untrusted hook config in ${info.project_dir}. Set ${HOOKS_CONFIG_ENV}=allow to enable hooks for this run.`,\n\t};\n}\n\nexport async function should_load_hooks_config(\n\tcwd: string,\n\tctx?: ExtensionContext,\n): Promise<boolean> {\n\tconst info = get_hooks_config_info(cwd);\n\tif (!info) return true;\n\tif (is_hooks_config_trusted(info.project_dir, info.hash))\n\t\treturn true;\n\n\tconst decision = await resolve_project_trust(\n\t\tcreate_hooks_trust_subject(info),\n\t\t{\n\t\t\thas_ui: ctx?.hasUI,\n\t\t\tselect: ctx?.hasUI\n\t\t\t\t? async (\n\t\t\t\t\t\tmessage: string,\n\t\t\t\t\t\tchoices: string[],\n\t\t\t\t\t): Promise<string> => {\n\t\t\t\t\t\tconst selected = await ctx.ui.select(message, choices);\n\t\t\t\t\t\treturn selected ?? '';\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t\tenv: process.env,\n\t\t\ttrust_store_path: default_hooks_trust_store_path(),\n\t\t},\n\t);\n\treturn (\n\t\tdecision.action === 'allow-once' ||\n\t\tdecision.action === 'trust-persisted'\n\t);\n}\n","// Hooks resolution — Claude Code style hook compatibility\n\nimport type {\n\tExtensionAPI,\n\tExtensionContext,\n\tExtensionFactory,\n\tToolCallEventResult,\n} from '@earendil-works/pi-coding-agent';\nimport { load_hooks } from './config.js';\nimport { create_hook_session_env } from './env.js';\nimport { build_hook_payload, matches_hook } from './payload.js';\nimport {\n\tformat_duration,\n\thook_block_reason,\n\thook_event_name_for_result,\n\thook_name,\n\trun_command_hook,\n} from './runner.js';\nimport { should_load_hooks_config } from './trust-gate.js';\nimport type { CommandRunResult, HookState } from './types.js';\n\nexport {\n\tas_record,\n\tcompile_matcher,\n\tcreate_hook,\n\tfind_nearest_git_root,\n\tfind_project_dir,\n\tget_hook_entries,\n\tget_hooks_config_info,\n\thas_hooks_config,\n\tis_file,\n\tload_hooks,\n\tparse_claude_settings_hooks,\n\tparse_simple_hooks_file,\n\tread_json_file,\n\tresolve_hook_command,\n\twalk_up_directories,\n} from './config.js';\nexport {\n\tbuild_hook_payload,\n\tbuild_tool_response,\n\textract_text_content,\n\tmatches_hook,\n\tnormalize_tool_input,\n\tto_claude_tool_name,\n} from './payload.js';\nexport {\n\tformat_duration,\n\thook_block_reason,\n\thook_event_name_for_result,\n\thook_name,\n\trun_command_hook,\n} from './runner.js';\nexport type {\n\tCommandRunResult,\n\tHookEventName,\n\tHooksConfigInfo,\n\tHookState,\n\tResolvedCommandHook,\n} from './types.js';\nexport interface HooksResolutionOptions {\n\tload_hooks?: (cwd: string) => HookState;\n\trun_command_hook?: (\n\t\tcommand: string,\n\t\tcwd: string,\n\t\tpayload: Record<string, unknown>,\n\t\tpi_session_env?: Record<string, string>,\n\t) => Promise<CommandRunResult>;\n}\n\nexport function create_hooks_resolution_extension(\n\toptions: HooksResolutionOptions = {},\n): ExtensionFactory {\n\tconst load_hooks_impl = options.load_hooks ?? load_hooks;\n\tconst run_command_hook_impl =\n\t\toptions.run_command_hook ?? run_command_hook;\n\n\treturn async function hooks_resolution(pi: ExtensionAPI) {\n\t\tlet state: HookState = {\n\t\t\tproject_dir: process.cwd(),\n\t\t\thooks: [],\n\t\t};\n\n\t\tconst refresh_hooks = async (\n\t\t\tcwd: string,\n\t\t\tctx?: ExtensionContext,\n\t\t) => {\n\t\t\tif (!(await should_load_hooks_config(cwd, ctx))) {\n\t\t\t\tstate = { project_dir: cwd, hooks: [] };\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tstate = load_hooks_impl(cwd);\n\t\t};\n\n\t\tpi.on('session_start', async (_event, ctx) => {\n\t\t\tawait refresh_hooks(ctx.cwd, ctx);\n\t\t});\n\n\t\tpi.on(\n\t\t\t'tool_call',\n\t\t\tasync (\n\t\t\t\tevent,\n\t\t\t\tctx,\n\t\t\t): Promise<ToolCallEventResult | undefined> => {\n\t\t\t\tif (state.hooks.length === 0) return;\n\n\t\t\t\tconst matching_hooks = state.hooks.filter(\n\t\t\t\t\t(hook) =>\n\t\t\t\t\t\thook.event_name === 'PreToolUse' &&\n\t\t\t\t\t\tmatches_hook(hook, event.toolName),\n\t\t\t\t);\n\t\t\t\tif (matching_hooks.length === 0) return;\n\n\t\t\t\tconst payload = build_hook_payload(\n\t\t\t\t\tevent,\n\t\t\t\t\t'PreToolUse',\n\t\t\t\t\tctx,\n\t\t\t\t\tstate.project_dir,\n\t\t\t\t);\n\t\t\t\tconst executed_commands = new Set<string>();\n\n\t\t\t\tfor (const hook of matching_hooks) {\n\t\t\t\t\tif (executed_commands.has(hook.command)) continue;\n\t\t\t\t\texecuted_commands.add(hook.command);\n\n\t\t\t\t\tconst result = await run_command_hook_impl(\n\t\t\t\t\t\thook.command,\n\t\t\t\t\t\tstate.project_dir,\n\t\t\t\t\t\tpayload,\n\t\t\t\t\t\tcreate_hook_session_env(ctx),\n\t\t\t\t\t);\n\t\t\t\t\tconst reason = hook_block_reason(result);\n\t\t\t\t\tif (reason) return { block: true, reason };\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\n\t\tpi.on('tool_result', async (event, ctx) => {\n\t\t\tif (state.hooks.length === 0) return;\n\n\t\t\tconst event_name = hook_event_name_for_result(event);\n\t\t\tconst matching_hooks = state.hooks.filter(\n\t\t\t\t(hook) =>\n\t\t\t\t\thook.event_name === event_name &&\n\t\t\t\t\tmatches_hook(hook, event.toolName),\n\t\t\t);\n\t\t\tif (matching_hooks.length === 0) return;\n\n\t\t\tconst payload = build_hook_payload(\n\t\t\t\tevent,\n\t\t\t\tevent_name,\n\t\t\t\tctx,\n\t\t\t\tstate.project_dir,\n\t\t\t);\n\t\t\tconst executed_commands = new Set<string>();\n\n\t\t\tfor (const hook of matching_hooks) {\n\t\t\t\tif (executed_commands.has(hook.command)) continue;\n\t\t\t\texecuted_commands.add(hook.command);\n\n\t\t\t\tconst result = await run_command_hook_impl(\n\t\t\t\t\thook.command,\n\t\t\t\t\tstate.project_dir,\n\t\t\t\t\tpayload,\n\t\t\t\t\tcreate_hook_session_env(ctx),\n\t\t\t\t);\n\t\t\t\tconst name = hook_name(hook.command);\n\t\t\t\tconst duration = format_duration(result.elapsed_ms);\n\n\t\t\t\tif (ctx.hasUI) {\n\t\t\t\t\tif (result.code === 0) {\n\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\t`Hook \\`${name}\\` ran (${duration})`,\n\t\t\t\t\t\t\t'info',\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst error_line =\n\t\t\t\t\t\t\tresult.stderr.trim() ||\n\t\t\t\t\t\t\tresult.stdout.trim() ||\n\t\t\t\t\t\t\t`exit code ${result.code}`;\n\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\t`Hook \\`${name}\\` failed (${duration}): ${error_line}`,\n\t\t\t\t\t\t\t'warning',\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t};\n}\n\nexport default create_hooks_resolution_extension();\n"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { t as BUILTIN_EXTENSIONS } from "./builtin-registry-
|
|
2
|
+
import { t as BUILTIN_EXTENSIONS } from "./builtin-registry-C0CQdd45.js";
|
|
3
3
|
import { defineCommand, renderUsage, runMain } from "citty";
|
|
4
4
|
import { existsSync, readFileSync } from "node:fs";
|
|
5
5
|
import { dirname, join, resolve } from "node:path";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
|
-
|
|
7
|
+
// src/cli-args.ts
|
|
8
8
|
const THINKING_LEVELS = /* @__PURE__ */ new Set([
|
|
9
9
|
"off",
|
|
10
10
|
"minimal",
|
|
@@ -127,8 +127,7 @@ function parse_thinking_level(value) {
|
|
|
127
127
|
if (!THINKING_LEVELS.has(normalized)) throw new Error("--thinking must be one of: off, minimal, low, medium, high, xhigh.");
|
|
128
128
|
return normalized;
|
|
129
129
|
}
|
|
130
|
-
|
|
131
|
-
//#region src/runtime-preflight.ts
|
|
130
|
+
// src/runtime-preflight.ts
|
|
132
131
|
const MINIMUM_NODE_VERSION = "24.15.0";
|
|
133
132
|
function parse_node_version(version) {
|
|
134
133
|
const match = /^v?(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/.exec(version);
|
|
@@ -153,8 +152,7 @@ function get_node_preflight_error(current_version = process.versions.node) {
|
|
|
153
152
|
if (is_supported_node_version(current_version)) return void 0;
|
|
154
153
|
return `my-pi requires Node >=${MINIMUM_NODE_VERSION}; current version is ${current_version}. Upgrade Node and retry.`;
|
|
155
154
|
}
|
|
156
|
-
|
|
157
|
-
//#region src/warnings.ts
|
|
155
|
+
// src/warnings.ts
|
|
158
156
|
const SQLITE_EXPERIMENTAL_WARNING = "SQLite is an experimental feature";
|
|
159
157
|
const FILTER_INSTALLED = Symbol.for("my-pi.sqlite-warning-filter-installed");
|
|
160
158
|
const ORIGINAL_EMIT_WARNING = Symbol.for("my-pi.original-emit-warning");
|
|
@@ -176,8 +174,7 @@ function install_sqlite_warning_filter(process_like = process) {
|
|
|
176
174
|
return original_emit_warning.apply(this, args);
|
|
177
175
|
};
|
|
178
176
|
}
|
|
179
|
-
|
|
180
|
-
//#region src/index.ts
|
|
177
|
+
// src/index.ts
|
|
181
178
|
const node_preflight_error = get_node_preflight_error();
|
|
182
179
|
if (node_preflight_error) {
|
|
183
180
|
console.error(node_preflight_error);
|
|
@@ -521,7 +518,6 @@ const main = defineCommand({
|
|
|
521
518
|
runMain(main, { showUsage: async (cmd, parent) => {
|
|
522
519
|
await print_usage(cmd, parent);
|
|
523
520
|
} });
|
|
524
|
-
//#endregion
|
|
525
521
|
export {};
|
|
526
522
|
|
|
527
523
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/cli-args.ts","../src/runtime-preflight.ts","../src/warnings.ts","../src/index.ts"],"sourcesContent":["import { resolve } from 'node:path';\nimport {\n\tBUILTIN_EXTENSIONS,\n\ttype BuiltinExtensionOptionName,\n} from './extensions/builtin-registry.js';\n\nconst THINKING_LEVELS = new Set([\n\t'off',\n\t'minimal',\n\t'low',\n\t'medium',\n\t'high',\n\t'xhigh',\n]);\n\nexport type CliThinkingLevel =\n\t| 'off'\n\t| 'minimal'\n\t| 'low'\n\t| 'medium'\n\t| 'high'\n\t| 'xhigh';\n\nexport type BuiltinDisableCliArgs = Record<\n\tstring,\n\t{\n\t\ttype: 'boolean';\n\t\tdescription: string;\n\t\tdefault: false;\n\t}\n>;\n\nexport interface CliArgDefinition {\n\ttype: 'boolean' | 'string' | 'enum' | 'positional';\n\talias?: string | readonly string[];\n}\n\nexport type CliArgDefinitions = Record<string, CliArgDefinition>;\n\nexport interface ParsedExtensionCliArgs {\n\textension_flag_values: Map<string, boolean | string>;\n\tpositionals: string[];\n\tdiagnostics: string[];\n}\n\nexport function create_builtin_disable_cli_args(): BuiltinDisableCliArgs {\n\treturn Object.fromEntries(\n\t\tBUILTIN_EXTENSIONS.map((extension) => [\n\t\t\textension.cli_arg,\n\t\t\t{\n\t\t\t\ttype: 'boolean' as const,\n\t\t\t\tdescription: extension.cli_description,\n\t\t\t\tdefault: false as const,\n\t\t\t},\n\t\t]),\n\t);\n}\n\nfunction is_citty_no_flag_set(\n\targs: Record<string, unknown>,\n\tcli_arg: string,\n): boolean {\n\tif (args[cli_arg]) return true;\n\n\tconst positive_kebab = cli_arg.replace(/^no-/, '');\n\tconst positive_camel = positive_kebab.replace(\n\t\t/-([a-z])/g,\n\t\t(_, char) => String(char).toUpperCase(),\n\t);\n\treturn (\n\t\targs[positive_kebab] === false || args[positive_camel] === false\n\t);\n}\n\nexport function resolve_builtin_extension_options(\n\targs: Record<string, unknown>,\n): Partial<Record<BuiltinExtensionOptionName, boolean>> {\n\tconst no_builtin = is_citty_no_flag_set(args, 'no-builtin');\n\treturn Object.fromEntries(\n\t\tBUILTIN_EXTENSIONS.map((extension) => [\n\t\t\textension.option_name,\n\t\t\t!no_builtin &&\n\t\t\t\t!is_citty_no_flag_set(args, extension.cli_arg) &&\n\t\t\t\textension.default_enabled,\n\t\t]),\n\t) as Partial<Record<BuiltinExtensionOptionName, boolean>>;\n}\n\nexport function parse_extension_cli_args(\n\targv: string[],\n\tknown_args: CliArgDefinitions,\n): ParsedExtensionCliArgs {\n\tconst known_flags = new Map<string, CliArgDefinition['type']>();\n\tfor (const [name, definition] of Object.entries(known_args)) {\n\t\tknown_flags.set(`--${name}`, definition.type);\n\t\tconst camel_name = name.replace(/-([a-z])/g, (_, char) =>\n\t\t\tString(char).toUpperCase(),\n\t\t);\n\t\tknown_flags.set(`--${camel_name}`, definition.type);\n\t\tif (definition.type === 'boolean')\n\t\t\tknown_flags.set(`--no-${name}`, definition.type);\n\t\tconst aliases = Array.isArray(definition.alias)\n\t\t\t? definition.alias\n\t\t\t: definition.alias\n\t\t\t\t? [definition.alias]\n\t\t\t\t: [];\n\t\tfor (const alias of aliases)\n\t\t\tknown_flags.set(`-${alias}`, definition.type);\n\t}\n\n\tconst extension_flag_values = new Map<string, boolean | string>();\n\tconst positionals: string[] = [];\n\tconst diagnostics: string[] = [];\n\n\tfor (let i = 0; i < argv.length; i++) {\n\t\tconst arg = argv[i];\n\t\tif (!arg) continue;\n\t\tif (arg === '--') {\n\t\t\tpositionals.push(...argv.slice(i + 1));\n\t\t\tbreak;\n\t\t}\n\n\t\tconst equals_index = arg.indexOf('=');\n\t\tconst flag_token =\n\t\t\tequals_index === -1 ? arg : arg.slice(0, equals_index);\n\t\tconst known_type = known_flags.get(flag_token);\n\t\tif (known_type) {\n\t\t\tif (\n\t\t\t\tequals_index === -1 &&\n\t\t\t\t(known_type === 'string' || known_type === 'enum') &&\n\t\t\t\ti + 1 < argv.length &&\n\t\t\t\targv[i + 1] !== '--'\n\t\t\t) {\n\t\t\t\ti += 1;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (arg.startsWith('--')) {\n\t\t\tif (equals_index !== -1) {\n\t\t\t\textension_flag_values.set(\n\t\t\t\t\targ.slice(2, equals_index),\n\t\t\t\t\targ.slice(equals_index + 1),\n\t\t\t\t);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst name = arg.slice(2);\n\t\t\tconst next = argv[i + 1];\n\t\t\tif (\n\t\t\t\tnext !== undefined &&\n\t\t\t\t!next.startsWith('-') &&\n\t\t\t\t!next.startsWith('@')\n\t\t\t) {\n\t\t\t\textension_flag_values.set(name, next);\n\t\t\t\ti += 1;\n\t\t\t} else {\n\t\t\t\textension_flag_values.set(name, true);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (arg.startsWith('-')) {\n\t\t\tdiagnostics.push(`Unknown option: ${arg}`);\n\t\t\tcontinue;\n\t\t}\n\t\tpositionals.push(arg);\n\t}\n\n\treturn { extension_flag_values, positionals, diagnostics };\n}\n\nexport function collect_flag_values(\n\targv: string[],\n\tflags: readonly string[],\n): string[] {\n\tconst values: string[] = [];\n\tconst flag_set = new Set(flags);\n\n\tfor (let i = 0; i < argv.length; i++) {\n\t\tconst arg = argv[i];\n\t\tif (arg === '--') break;\n\t\tif (!arg) continue;\n\n\t\tconst equals_index = arg.indexOf('=');\n\t\tif (equals_index !== -1) {\n\t\t\tconst name = arg.slice(0, equals_index);\n\t\t\tif (flag_set.has(name)) {\n\t\t\t\tvalues.push(arg.slice(equals_index + 1));\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (flag_set.has(arg) && i + 1 < argv.length) {\n\t\t\tconst next = argv[i + 1];\n\t\t\tif (next !== undefined && next !== '--') {\n\t\t\t\tvalues.push(next);\n\t\t\t\ti += 1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn values;\n}\n\nexport function parse_extension_paths(\n\targv: string[],\n\tcwd = process.cwd(),\n): string[] {\n\treturn collect_flag_values(argv, ['-e', '--extension'])\n\t\t.map((path) => path.trim())\n\t\t.filter(Boolean)\n\t\t.map((path) => resolve(cwd, path));\n}\n\nfunction parse_comma_list_flags(\n\targv: string[],\n\tflags: readonly string[],\n): string[] | undefined {\n\tconst values = collect_flag_values(argv, flags)\n\t\t.flatMap((value) => value.split(','))\n\t\t.map((value) => value.trim())\n\t\t.filter(Boolean);\n\treturn values.length ? [...new Set(values)] : undefined;\n}\n\nexport function parse_tool_allowlist(\n\targv: string[],\n): string[] | undefined {\n\treturn parse_comma_list_flags(argv, ['--tools', '-t']);\n}\n\nexport function parse_tool_excludelist(\n\targv: string[],\n): string[] | undefined {\n\treturn parse_comma_list_flags(argv, ['--exclude-tools', '-xt']);\n}\n\nexport function parse_skill_allowlist(\n\targv: string[],\n): string[] | undefined {\n\treturn parse_comma_list_flags(argv, ['--skill']);\n}\n\nexport function parse_thinking_level(\n\tvalue: string | undefined,\n): CliThinkingLevel | undefined {\n\tconst normalized = value?.trim().toLowerCase();\n\tif (!normalized) return undefined;\n\tif (!THINKING_LEVELS.has(normalized)) {\n\t\tthrow new Error(\n\t\t\t'--thinking must be one of: off, minimal, low, medium, high, xhigh.',\n\t\t);\n\t}\n\treturn normalized as CliThinkingLevel;\n}\n","export const MINIMUM_NODE_VERSION = '24.15.0';\n\nfunction parse_node_version(\n\tversion: string,\n): [number, number, number] | undefined {\n\tconst match = /^v?(\\d+)\\.(\\d+)\\.(\\d+)(?:[-+].*)?$/.exec(version);\n\tif (!match) return undefined;\n\treturn [Number(match[1]), Number(match[2]), Number(match[3])];\n}\n\nexport function is_supported_node_version(version: string): boolean {\n\tconst current = parse_node_version(version);\n\tconst minimum = parse_node_version(MINIMUM_NODE_VERSION);\n\tif (!current || !minimum) return false;\n\n\tfor (let index = 0; index < current.length; index++) {\n\t\tif (current[index] > minimum[index]) return true;\n\t\tif (current[index] < minimum[index]) return false;\n\t}\n\treturn true;\n}\n\nexport function get_node_preflight_error(\n\tcurrent_version = process.versions.node,\n): string | undefined {\n\tif (is_supported_node_version(current_version)) return undefined;\n\treturn `my-pi requires Node >=${MINIMUM_NODE_VERSION}; current version is ${current_version}. Upgrade Node and retry.`;\n}\n","const SQLITE_EXPERIMENTAL_WARNING =\n\t'SQLite is an experimental feature';\nconst FILTER_INSTALLED = Symbol.for(\n\t'my-pi.sqlite-warning-filter-installed',\n);\nconst ORIGINAL_EMIT_WARNING = Symbol.for(\n\t'my-pi.original-emit-warning',\n);\n\ntype WarningEmitter = Pick<typeof process, 'emitWarning'> & {\n\t[FILTER_INSTALLED]?: boolean;\n\t[ORIGINAL_EMIT_WARNING]?: typeof process.emitWarning;\n};\n\nexport function should_suppress_warning(warning: Error): boolean {\n\treturn (\n\t\twarning.name === 'ExperimentalWarning' &&\n\t\twarning.message.includes(SQLITE_EXPERIMENTAL_WARNING)\n\t);\n}\n\nfunction should_suppress_emit_warning_args(args: unknown[]): boolean {\n\tconst [warning, options_or_type] = args;\n\tif (warning instanceof Error)\n\t\treturn should_suppress_warning(warning);\n\tconst warning_type =\n\t\ttypeof options_or_type === 'string'\n\t\t\t? options_or_type\n\t\t\t: options_or_type && typeof options_or_type === 'object'\n\t\t\t\t? (options_or_type as { type?: unknown }).type\n\t\t\t\t: undefined;\n\treturn (\n\t\twarning_type === 'ExperimentalWarning' &&\n\t\tString(warning).includes(SQLITE_EXPERIMENTAL_WARNING)\n\t);\n}\n\nexport function install_sqlite_warning_filter(\n\tprocess_like: WarningEmitter = process,\n): void {\n\tif (process_like[FILTER_INSTALLED]) return;\n\tprocess_like[FILTER_INSTALLED] = true;\n\n\tconst original_emit_warning =\n\t\tprocess_like[ORIGINAL_EMIT_WARNING] ?? process_like.emitWarning;\n\tprocess_like[ORIGINAL_EMIT_WARNING] = original_emit_warning;\n\n\tprocess_like.emitWarning = function emit_filtered_warning(\n\t\tthis: WarningEmitter,\n\t\t...args: unknown[]\n\t) {\n\t\tif (should_suppress_emit_warning_args(args)) return;\n\t\treturn (\n\t\t\toriginal_emit_warning as (...args: unknown[]) => void\n\t\t).apply(this, args);\n\t} as typeof process.emitWarning;\n}\n","#!/usr/bin/env node\n\nimport {\n\tdefineCommand,\n\trenderUsage,\n\trunMain,\n\ttype ArgsDef,\n\ttype CommandDef,\n} from 'citty';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport {\n\tcreate_builtin_disable_cli_args,\n\tparse_extension_cli_args,\n\tparse_extension_paths,\n\tparse_skill_allowlist,\n\tparse_thinking_level,\n\tparse_tool_allowlist,\n\tparse_tool_excludelist,\n\tresolve_builtin_extension_options,\n\ttype CliArgDefinitions,\n} from './cli-args.js';\nimport { get_node_preflight_error } from './runtime-preflight.js';\nimport { install_sqlite_warning_filter } from './warnings.js';\n\nconst node_preflight_error = get_node_preflight_error();\nif (node_preflight_error) {\n\tconsole.error(node_preflight_error);\n\tprocess.exit(1);\n}\n\ninstall_sqlite_warning_filter();\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst package_root = join(__dirname, '..');\nconst pkg = JSON.parse(\n\treadFileSync(join(package_root, 'package.json'), 'utf-8'),\n);\n\n// my-pi is a wrapper around Pi; upstream Pi update banners are useful in\n// this repo, but confusing for installed wrapper users.\nif (!existsSync(join(package_root, '.git'))) {\n\tprocess.env.PI_SKIP_VERSION_CHECK ??= '1';\n}\n\nasync function read_stdin(): Promise<string> {\n\tconst chunks: Buffer[] = [];\n\tfor await (const chunk of process.stdin) {\n\t\tchunks.push(chunk as Buffer);\n\t}\n\treturn Buffer.concat(chunks).toString('utf-8').trim();\n}\n\ntype MyPiRuntime = Awaited<\n\tReturnType<(typeof import('./api.js'))['create_my_pi']>\n>;\ntype InteractiveModeConstructor =\n\t(typeof import('@earendil-works/pi-coding-agent'))['InteractiveMode'];\n\nasync function run_interactive_mode(\n\truntime: MyPiRuntime,\n\tInteractiveModeClass: InteractiveModeConstructor,\n): Promise<void> {\n\tconst original_write = process.stdout.write.bind(process.stdout);\n\tprocess.stdout.write = ((\n\t\tchunk: string | Uint8Array,\n\t\t...args: Parameters<typeof original_write>\n\t) => {\n\t\tif (typeof chunk === 'string') {\n\t\t\tconst escape = String.fromCharCode(27);\n\t\t\tconst styled_hint = new RegExp(\n\t\t\t\t`(To resume this session:${escape}\\\\[[\\\\d;]*m )pi( --session )`,\n\t\t\t\t'g',\n\t\t\t);\n\t\t\tchunk = chunk.replace(styled_hint, '$1my-pi$2');\n\t\t\tchunk = chunk.replace(\n\t\t\t\t/(To resume this session: )pi( --session )/g,\n\t\t\t\t'$1my-pi$2',\n\t\t\t);\n\t\t}\n\t\treturn Reflect.apply(original_write, process.stdout, [\n\t\t\tchunk,\n\t\t\t...args,\n\t\t]);\n\t}) as typeof process.stdout.write;\n\ttry {\n\t\tconst mode = new InteractiveModeClass(runtime, {\n\t\t\tmigratedProviders: [],\n\t\t\tmodelFallbackMessage: undefined,\n\t\t\tinitialMessage: undefined,\n\t\t\tinitialImages: [],\n\t\t\tinitialMessages: [],\n\t\t});\n\t\tawait mode.run();\n\t} finally {\n\t\tprocess.stdout.write =\n\t\t\toriginal_write as typeof process.stdout.write;\n\t}\n}\n\nconst HELP_APPENDIX = `\nMODES\n\n my-pi\n Interactive TUI with slash commands, editor, and session UI.\n\n my-pi \"prompt\"\n my-pi -P \"prompt\"\n One-shot print mode with plain text output.\n\n my-pi --json \"prompt\"\n Non-interactive NDJSON mode for scripts, evals, and other agents.\n\n my-pi --mode rpc\n RPC mode over stdin/stdout JSONL for orchestrators and teammate sessions.\n\nNOTES\n\n - In non-interactive modes, my-pi keeps headless-capable built-ins like\n MCP, LSP, prompt presets, recall, nopeek, Omnisearch, SQLite tools, hooks, and secret redaction.\n - UI-only built-ins like session auto-naming are skipped.\n - Repeat -e / --extension to compose multiple extensions.\n - Positional prompt arguments are joined with a single space.\n - Everything after -- is prompt text, not options.\n - --prompt takes precedence over positional prompt text and stdin.\n\nNESTED RUNS\n\n - Child runs inherit cwd and environment unless you isolate them explicitly.\n - Use --agent-dir to isolate auth, config, sessions, and telemetry state.\n - For safer evals or unknown repos, use --untrusted plus an explicit\n --system-prompt.\n\nEXAMPLES\n\n my-pi\n my-pi \"fix the failing test\"\n my-pi -P \"summarize this repo\"\n my-pi --json \"list all TODO comments\"\n echo \"plan a login page\" | my-pi --json\n my-pi --telemetry --json \"run eval case\"\n my-pi --telemetry --telemetry-db ./tmp/evals.db --json \"run case\"\n my-pi observability\n my-pi --untrusted --agent-dir /tmp/pi-agent --json \"run case\"\n my-pi -e ./my-ext.ts -e ./other-ext.ts \"hello\"\n my-pi -m claude-haiku-4-5-20241022 \"explain this file\"\n XIAOMI_API_KEY=... my-pi -m xiaomi/mimo-v2.5-pro \"summarize this repo\"\n my-pi -m cloudflare-workers-ai/@cf/meta/llama-3.3-70b-instruct-fp8-fast \"explain this file\"\n my-pi --preset terse,no-purple-prose \"summarize this repo\"\n my-pi --system-prompt \"You are a JSON classifier. Return only JSON.\" --json \"classify this\"\n\nPROMPT PRESETS\n\n Interactive commands:\n /prompt-preset help\n /prompt-preset export-defaults\n /prompt-preset edit-global terse\n /prompt-preset base detailed\n /prompt-preset enable bullets\n\n Short alias: /preset\n\n Editable preset files:\n ~/.pi/agent/presets/*.md\n .pi/presets/*.md\n`;\n\nasync function render_rich_usage<T extends ArgsDef>(\n\tcmd: CommandDef<T>,\n\tparent?: CommandDef<T>,\n): Promise<string> {\n\treturn `${await renderUsage(cmd, parent)}\\n${HELP_APPENDIX}`;\n}\n\nasync function print_usage<T extends ArgsDef>(\n\tcmd: CommandDef<T>,\n\tparent?: CommandDef<T>,\n): Promise<void> {\n\tconsole.log(await render_rich_usage(cmd, parent));\n}\n\nconst main = defineCommand({\n\tmeta: {\n\t\tname: 'my-pi',\n\t\tversion: pkg.version,\n\t\tdescription:\n\t\t\t'Composable pi coding agent with MCP, LSP, presets, and local eval telemetry',\n\t},\n\targs: {\n\t\tprint: {\n\t\t\ttype: 'boolean',\n\t\t\talias: 'P',\n\t\t\tdescription: 'Print mode (non-interactive, one-shot)',\n\t\t\tdefault: false,\n\t\t},\n\t\t'agent-dir': {\n\t\t\ttype: 'string',\n\t\t\tdescription:\n\t\t\t\t'Override Pi auth/config/session directory for this process',\n\t\t\trequired: false,\n\t\t},\n\t\t'session-dir': {\n\t\t\ttype: 'string',\n\t\t\tdescription:\n\t\t\t\t'Override Pi session storage directory for this process',\n\t\t\trequired: false,\n\t\t},\n\t\tjson: {\n\t\t\ttype: 'boolean',\n\t\t\talias: 'j',\n\t\t\tdescription: 'Output NDJSON events (for agent consumption)',\n\t\t\tdefault: false,\n\t\t},\n\t\tmode: {\n\t\t\ttype: 'string',\n\t\t\tdescription: 'Runtime mode: interactive, print, json, or rpc',\n\t\t\trequired: false,\n\t\t},\n\t\textension: {\n\t\t\ttype: 'string',\n\t\t\talias: 'e',\n\t\t\tdescription:\n\t\t\t\t'Extension path to load; repeatable via argv parsing',\n\t\t\trequired: false,\n\t\t},\n\t\t'no-builtin': {\n\t\t\ttype: 'boolean',\n\t\t\tdescription: 'Disable all built-in extensions',\n\t\t\tdefault: false,\n\t\t},\n\t\tuntrusted: {\n\t\t\ttype: 'boolean',\n\t\t\tdescription:\n\t\t\t\t'Safe mode for unknown repos: skip project MCP, hooks, project prompt presets, project skills, and project LSP binaries unless explicitly re-enabled',\n\t\t\tdefault: false,\n\t\t},\n\t\t...create_builtin_disable_cli_args(),\n\t\ttelemetry: {\n\t\t\ttype: 'boolean',\n\t\t\tdescription: 'Enable local SQLite telemetry for this process',\n\t\t\tdefault: false,\n\t\t},\n\t\t'no-telemetry': {\n\t\t\ttype: 'boolean',\n\t\t\tdescription: 'Disable local SQLite telemetry for this process',\n\t\t\tdefault: false,\n\t\t},\n\t\t'telemetry-db': {\n\t\t\ttype: 'string',\n\t\t\tdescription:\n\t\t\t\t'Override telemetry database path for this process',\n\t\t\trequired: false,\n\t\t},\n\t\tmodel: {\n\t\t\ttype: 'string',\n\t\t\talias: 'm',\n\t\t\tdescription:\n\t\t\t\t'Model to use (e.g. claude-sonnet-4-5-20241022, gpt-5.4, cloudflare-workers-ai/@cf/meta/llama-3.3-70b-instruct-fp8-fast)',\n\t\t},\n\t\tthinking: {\n\t\t\ttype: 'string',\n\t\t\tdescription:\n\t\t\t\t'Thinking level: off, minimal, low, medium, high, or xhigh',\n\t\t\trequired: false,\n\t\t},\n\t\ttools: {\n\t\t\ttype: 'string',\n\t\t\talias: 't',\n\t\t\tdescription:\n\t\t\t\t'Comma-separated allowlist of tool names to enable',\n\t\t\trequired: false,\n\t\t},\n\t\t'exclude-tools': {\n\t\t\ttype: 'string',\n\t\t\talias: 'xt',\n\t\t\tdescription: 'Comma-separated list of tool names to disable',\n\t\t\trequired: false,\n\t\t},\n\t\tsession: {\n\t\t\ttype: 'string',\n\t\t\tdescription: 'Resume a specific session file or session ID',\n\t\t\trequired: false,\n\t\t},\n\t\t'session-id': {\n\t\t\ttype: 'string',\n\t\t\tdescription:\n\t\t\t\t'Create or resume an exact project-local session ID',\n\t\t\trequired: false,\n\t\t},\n\t\tname: {\n\t\t\ttype: 'string',\n\t\t\talias: 'n',\n\t\t\tdescription: 'Set the session display name at startup',\n\t\t\trequired: false,\n\t\t},\n\t\tskill: {\n\t\t\ttype: 'string',\n\t\t\tdescription: 'Skill name to allow; repeatable in argv parsing',\n\t\t\trequired: false,\n\t\t},\n\t\t'system-prompt': {\n\t\t\ttype: 'string',\n\t\t\tdescription: 'Replace the base system prompt',\n\t\t\trequired: false,\n\t\t},\n\t\t'append-system-prompt': {\n\t\t\ttype: 'string',\n\t\t\tdescription: 'Append one-off instructions to the system prompt',\n\t\t\trequired: false,\n\t\t},\n\t\tprompt: {\n\t\t\ttype: 'string',\n\t\t\talias: 'p',\n\t\t\tdescription: 'Prompt text (alternative to positional argument)',\n\t\t\trequired: false,\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst cwd = process.cwd();\n\t\tconst cli_argv = process.argv.slice(2);\n\t\tconst parsed_extension_cli = parse_extension_cli_args(\n\t\t\tcli_argv,\n\t\t\tmain.args as CliArgDefinitions,\n\t\t);\n\t\tif (parsed_extension_cli.diagnostics.length) {\n\t\t\tfor (const message of parsed_extension_cli.diagnostics)\n\t\t\t\tconsole.error(`Error: ${message}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tconst extension_paths = parse_extension_paths(cli_argv, cwd);\n\t\tconst selected_tools = parse_tool_allowlist(cli_argv);\n\t\tconst excluded_tools = parse_tool_excludelist(cli_argv);\n\t\tconst selected_skills = parse_skill_allowlist(cli_argv);\n\t\tlet selected_thinking;\n\t\ttry {\n\t\t\tselected_thinking = parse_thinking_level(args.thinking);\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\terror instanceof Error ? error.message : String(error),\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tlet runtime_mode: 'interactive' | 'print' | 'json' | 'rpc' =\n\t\t\t'interactive';\n\t\tif (args.mode) {\n\t\t\tconst requested = String(args.mode).trim().toLowerCase();\n\t\t\tif (\n\t\t\t\t!['interactive', 'print', 'json', 'rpc'].includes(requested)\n\t\t\t) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t'Error: --mode must be one of interactive, print, json, rpc.',\n\t\t\t\t);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\truntime_mode = requested as\n\t\t\t\t| 'interactive'\n\t\t\t\t| 'print'\n\t\t\t\t| 'json'\n\t\t\t\t| 'rpc';\n\t\t}\n\t\tif (args.json) runtime_mode = 'json';\n\t\telse if (args.print) runtime_mode = 'print';\n\n\t\tconst positionals = parsed_extension_cli.positionals;\n\t\tif (positionals?.[0] === 'observability') {\n\t\t\tconst { start_observability_server } =\n\t\t\t\tawait import('@spences10/pi-observability/server');\n\t\t\tstart_observability_server();\n\t\t\treturn;\n\t\t}\n\n\t\t// Resolve prompt: named --prompt flag > positional > stdin\n\t\tlet prompt = args.prompt;\n\t\tif (!prompt && positionals && positionals.length > 0) {\n\t\t\tprompt = positionals.join(' ');\n\t\t}\n\t\tif (!prompt && !process.stdin.isTTY && runtime_mode !== 'rpc') {\n\t\t\tprompt = await read_stdin();\n\t\t}\n\t\tif (prompt && runtime_mode === 'interactive')\n\t\t\truntime_mode = 'print';\n\n\t\tif (\n\t\t\truntime_mode === 'interactive' &&\n\t\t\t!prompt &&\n\t\t\t!process.stdout.isTTY\n\t\t) {\n\t\t\tawait print_usage(main);\n\t\t\treturn;\n\t\t}\n\n\t\t// Startup feedback so silence = broken (issue #3)\n\t\tif (runtime_mode !== 'interactive') {\n\t\t\tprocess.stderr.write(\n\t\t\t\t`my-pi: connecting to ${args.model || 'default model'}...\\n`,\n\t\t\t);\n\t\t}\n\n\t\tif (args.telemetry && args['no-telemetry']) {\n\t\t\tconsole.error(\n\t\t\t\t'Error: --telemetry and --no-telemetry cannot be used together.',\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tif (args.session && args['session-id']) {\n\t\t\tconsole.error(\n\t\t\t\t'Error: --session and --session-id cannot be used together.',\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tlet telemetry_override: boolean | undefined;\n\t\tif (args.telemetry) {\n\t\t\ttelemetry_override = true;\n\t\t} else if (args['no-telemetry']) {\n\t\t\ttelemetry_override = false;\n\t\t}\n\n\t\tconst [\n\t\t\t{ create_my_pi },\n\t\t\t{ InteractiveMode, runPrintMode, runRpcMode },\n\t\t] = await Promise.all([\n\t\t\timport('./api.js'),\n\t\t\timport('@earendil-works/pi-coding-agent'),\n\t\t]);\n\n\t\tconst runtime = await create_my_pi({\n\t\t\tcwd,\n\t\t\tagent_dir: args['agent-dir'],\n\t\t\tsession_dir: args['session-dir'],\n\t\t\textensions: extension_paths,\n\t\t\textension_flag_values:\n\t\t\t\tparsed_extension_cli.extension_flag_values,\n\t\t\truntime_mode,\n\t\t\t...resolve_builtin_extension_options(args),\n\t\t\ttelemetry: telemetry_override,\n\t\t\ttelemetry_db_path: args['telemetry-db'],\n\t\t\tmodel: args.model,\n\t\t\tthinking: selected_thinking,\n\t\t\tselected_tools,\n\t\t\texcluded_tools,\n\t\t\tselected_skills,\n\t\t\tsession: args.session,\n\t\t\tsession_id: args['session-id'],\n\t\t\tstartup_session_name: args.name,\n\t\t\tsystem_prompt: args['system-prompt'],\n\t\t\tappend_system_prompt: args['append-system-prompt'],\n\t\t\tuntrusted_repo: args.untrusted,\n\t\t});\n\n\t\tfor (const diagnostic of runtime.diagnostics) {\n\t\t\tconst prefix =\n\t\t\t\tdiagnostic.type === 'error'\n\t\t\t\t\t? 'Error: '\n\t\t\t\t\t: diagnostic.type === 'warning'\n\t\t\t\t\t\t? 'Warning: '\n\t\t\t\t\t\t: '';\n\t\t\tconsole.error(`${prefix}${diagnostic.message}`);\n\t\t}\n\t\tif (\n\t\t\truntime.diagnostics.some(\n\t\t\t\t(diagnostic) => diagnostic.type === 'error',\n\t\t\t)\n\t\t) {\n\t\t\tawait runtime.dispose();\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tif (runtime_mode === 'rpc') {\n\t\t\tawait runRpcMode(runtime);\n\t\t} else if (runtime_mode === 'print' || runtime_mode === 'json') {\n\t\t\tconst code = await runPrintMode(runtime, {\n\t\t\t\tmode: runtime_mode === 'json' ? 'json' : 'text',\n\t\t\t\tinitialMessage: prompt || '',\n\t\t\t\tinitialImages: [],\n\t\t\t\tmessages: [],\n\t\t\t});\n\t\t\tprocess.exit(code);\n\t\t} else if (!process.stdout.isTTY) {\n\t\t\tawait print_usage(main);\n\t\t} else {\n\t\t\tawait run_interactive_mode(runtime, InteractiveMode);\n\t\t}\n\t},\n});\n\nvoid runMain(main, {\n\tshowUsage: async (cmd, parent) => {\n\t\tawait print_usage(cmd, parent);\n\t},\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/cli-args.ts","../src/runtime-preflight.ts","../src/warnings.ts","../src/index.ts"],"sourcesContent":["import { resolve } from 'node:path';\nimport {\n\tBUILTIN_EXTENSIONS,\n\ttype BuiltinExtensionOptionName,\n} from './extensions/builtin-registry.js';\n\nconst THINKING_LEVELS = new Set([\n\t'off',\n\t'minimal',\n\t'low',\n\t'medium',\n\t'high',\n\t'xhigh',\n]);\n\nexport type CliThinkingLevel =\n\t| 'off'\n\t| 'minimal'\n\t| 'low'\n\t| 'medium'\n\t| 'high'\n\t| 'xhigh';\n\nexport type BuiltinDisableCliArgs = Record<\n\tstring,\n\t{\n\t\ttype: 'boolean';\n\t\tdescription: string;\n\t\tdefault: false;\n\t}\n>;\n\nexport interface CliArgDefinition {\n\ttype: 'boolean' | 'string' | 'enum' | 'positional';\n\talias?: string | readonly string[];\n}\n\nexport type CliArgDefinitions = Record<string, CliArgDefinition>;\n\nexport interface ParsedExtensionCliArgs {\n\textension_flag_values: Map<string, boolean | string>;\n\tpositionals: string[];\n\tdiagnostics: string[];\n}\n\nexport function create_builtin_disable_cli_args(): BuiltinDisableCliArgs {\n\treturn Object.fromEntries(\n\t\tBUILTIN_EXTENSIONS.map((extension) => [\n\t\t\textension.cli_arg,\n\t\t\t{\n\t\t\t\ttype: 'boolean' as const,\n\t\t\t\tdescription: extension.cli_description,\n\t\t\t\tdefault: false as const,\n\t\t\t},\n\t\t]),\n\t);\n}\n\nfunction is_citty_no_flag_set(\n\targs: Record<string, unknown>,\n\tcli_arg: string,\n): boolean {\n\tif (args[cli_arg]) return true;\n\n\tconst positive_kebab = cli_arg.replace(/^no-/, '');\n\tconst positive_camel = positive_kebab.replace(\n\t\t/-([a-z])/g,\n\t\t(_, char) => String(char).toUpperCase(),\n\t);\n\treturn (\n\t\targs[positive_kebab] === false || args[positive_camel] === false\n\t);\n}\n\nexport function resolve_builtin_extension_options(\n\targs: Record<string, unknown>,\n): Partial<Record<BuiltinExtensionOptionName, boolean>> {\n\tconst no_builtin = is_citty_no_flag_set(args, 'no-builtin');\n\treturn Object.fromEntries(\n\t\tBUILTIN_EXTENSIONS.map((extension) => [\n\t\t\textension.option_name,\n\t\t\t!no_builtin &&\n\t\t\t\t!is_citty_no_flag_set(args, extension.cli_arg) &&\n\t\t\t\textension.default_enabled,\n\t\t]),\n\t) as Partial<Record<BuiltinExtensionOptionName, boolean>>;\n}\n\nexport function parse_extension_cli_args(\n\targv: string[],\n\tknown_args: CliArgDefinitions,\n): ParsedExtensionCliArgs {\n\tconst known_flags = new Map<string, CliArgDefinition['type']>();\n\tfor (const [name, definition] of Object.entries(known_args)) {\n\t\tknown_flags.set(`--${name}`, definition.type);\n\t\tconst camel_name = name.replace(/-([a-z])/g, (_, char) =>\n\t\t\tString(char).toUpperCase(),\n\t\t);\n\t\tknown_flags.set(`--${camel_name}`, definition.type);\n\t\tif (definition.type === 'boolean')\n\t\t\tknown_flags.set(`--no-${name}`, definition.type);\n\t\tconst aliases = Array.isArray(definition.alias)\n\t\t\t? definition.alias\n\t\t\t: definition.alias\n\t\t\t\t? [definition.alias]\n\t\t\t\t: [];\n\t\tfor (const alias of aliases)\n\t\t\tknown_flags.set(`-${alias}`, definition.type);\n\t}\n\n\tconst extension_flag_values = new Map<string, boolean | string>();\n\tconst positionals: string[] = [];\n\tconst diagnostics: string[] = [];\n\n\tfor (let i = 0; i < argv.length; i++) {\n\t\tconst arg = argv[i];\n\t\tif (!arg) continue;\n\t\tif (arg === '--') {\n\t\t\tpositionals.push(...argv.slice(i + 1));\n\t\t\tbreak;\n\t\t}\n\n\t\tconst equals_index = arg.indexOf('=');\n\t\tconst flag_token =\n\t\t\tequals_index === -1 ? arg : arg.slice(0, equals_index);\n\t\tconst known_type = known_flags.get(flag_token);\n\t\tif (known_type) {\n\t\t\tif (\n\t\t\t\tequals_index === -1 &&\n\t\t\t\t(known_type === 'string' || known_type === 'enum') &&\n\t\t\t\ti + 1 < argv.length &&\n\t\t\t\targv[i + 1] !== '--'\n\t\t\t) {\n\t\t\t\ti += 1;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (arg.startsWith('--')) {\n\t\t\tif (equals_index !== -1) {\n\t\t\t\textension_flag_values.set(\n\t\t\t\t\targ.slice(2, equals_index),\n\t\t\t\t\targ.slice(equals_index + 1),\n\t\t\t\t);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst name = arg.slice(2);\n\t\t\tconst next = argv[i + 1];\n\t\t\tif (\n\t\t\t\tnext !== undefined &&\n\t\t\t\t!next.startsWith('-') &&\n\t\t\t\t!next.startsWith('@')\n\t\t\t) {\n\t\t\t\textension_flag_values.set(name, next);\n\t\t\t\ti += 1;\n\t\t\t} else {\n\t\t\t\textension_flag_values.set(name, true);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (arg.startsWith('-')) {\n\t\t\tdiagnostics.push(`Unknown option: ${arg}`);\n\t\t\tcontinue;\n\t\t}\n\t\tpositionals.push(arg);\n\t}\n\n\treturn { extension_flag_values, positionals, diagnostics };\n}\n\nexport function collect_flag_values(\n\targv: string[],\n\tflags: readonly string[],\n): string[] {\n\tconst values: string[] = [];\n\tconst flag_set = new Set(flags);\n\n\tfor (let i = 0; i < argv.length; i++) {\n\t\tconst arg = argv[i];\n\t\tif (arg === '--') break;\n\t\tif (!arg) continue;\n\n\t\tconst equals_index = arg.indexOf('=');\n\t\tif (equals_index !== -1) {\n\t\t\tconst name = arg.slice(0, equals_index);\n\t\t\tif (flag_set.has(name)) {\n\t\t\t\tvalues.push(arg.slice(equals_index + 1));\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (flag_set.has(arg) && i + 1 < argv.length) {\n\t\t\tconst next = argv[i + 1];\n\t\t\tif (next !== undefined && next !== '--') {\n\t\t\t\tvalues.push(next);\n\t\t\t\ti += 1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn values;\n}\n\nexport function parse_extension_paths(\n\targv: string[],\n\tcwd = process.cwd(),\n): string[] {\n\treturn collect_flag_values(argv, ['-e', '--extension'])\n\t\t.map((path) => path.trim())\n\t\t.filter(Boolean)\n\t\t.map((path) => resolve(cwd, path));\n}\n\nfunction parse_comma_list_flags(\n\targv: string[],\n\tflags: readonly string[],\n): string[] | undefined {\n\tconst values = collect_flag_values(argv, flags)\n\t\t.flatMap((value) => value.split(','))\n\t\t.map((value) => value.trim())\n\t\t.filter(Boolean);\n\treturn values.length ? [...new Set(values)] : undefined;\n}\n\nexport function parse_tool_allowlist(\n\targv: string[],\n): string[] | undefined {\n\treturn parse_comma_list_flags(argv, ['--tools', '-t']);\n}\n\nexport function parse_tool_excludelist(\n\targv: string[],\n): string[] | undefined {\n\treturn parse_comma_list_flags(argv, ['--exclude-tools', '-xt']);\n}\n\nexport function parse_skill_allowlist(\n\targv: string[],\n): string[] | undefined {\n\treturn parse_comma_list_flags(argv, ['--skill']);\n}\n\nexport function parse_thinking_level(\n\tvalue: string | undefined,\n): CliThinkingLevel | undefined {\n\tconst normalized = value?.trim().toLowerCase();\n\tif (!normalized) return undefined;\n\tif (!THINKING_LEVELS.has(normalized)) {\n\t\tthrow new Error(\n\t\t\t'--thinking must be one of: off, minimal, low, medium, high, xhigh.',\n\t\t);\n\t}\n\treturn normalized as CliThinkingLevel;\n}\n","export const MINIMUM_NODE_VERSION = '24.15.0';\n\nfunction parse_node_version(\n\tversion: string,\n): [number, number, number] | undefined {\n\tconst match = /^v?(\\d+)\\.(\\d+)\\.(\\d+)(?:[-+].*)?$/.exec(version);\n\tif (!match) return undefined;\n\treturn [Number(match[1]), Number(match[2]), Number(match[3])];\n}\n\nexport function is_supported_node_version(version: string): boolean {\n\tconst current = parse_node_version(version);\n\tconst minimum = parse_node_version(MINIMUM_NODE_VERSION);\n\tif (!current || !minimum) return false;\n\n\tfor (let index = 0; index < current.length; index++) {\n\t\tif (current[index] > minimum[index]) return true;\n\t\tif (current[index] < minimum[index]) return false;\n\t}\n\treturn true;\n}\n\nexport function get_node_preflight_error(\n\tcurrent_version = process.versions.node,\n): string | undefined {\n\tif (is_supported_node_version(current_version)) return undefined;\n\treturn `my-pi requires Node >=${MINIMUM_NODE_VERSION}; current version is ${current_version}. Upgrade Node and retry.`;\n}\n","const SQLITE_EXPERIMENTAL_WARNING =\n\t'SQLite is an experimental feature';\nconst FILTER_INSTALLED = Symbol.for(\n\t'my-pi.sqlite-warning-filter-installed',\n);\nconst ORIGINAL_EMIT_WARNING = Symbol.for(\n\t'my-pi.original-emit-warning',\n);\n\ntype WarningEmitter = Pick<typeof process, 'emitWarning'> & {\n\t[FILTER_INSTALLED]?: boolean;\n\t[ORIGINAL_EMIT_WARNING]?: typeof process.emitWarning;\n};\n\nexport function should_suppress_warning(warning: Error): boolean {\n\treturn (\n\t\twarning.name === 'ExperimentalWarning' &&\n\t\twarning.message.includes(SQLITE_EXPERIMENTAL_WARNING)\n\t);\n}\n\nfunction should_suppress_emit_warning_args(args: unknown[]): boolean {\n\tconst [warning, options_or_type] = args;\n\tif (warning instanceof Error)\n\t\treturn should_suppress_warning(warning);\n\tconst warning_type =\n\t\ttypeof options_or_type === 'string'\n\t\t\t? options_or_type\n\t\t\t: options_or_type && typeof options_or_type === 'object'\n\t\t\t\t? (options_or_type as { type?: unknown }).type\n\t\t\t\t: undefined;\n\treturn (\n\t\twarning_type === 'ExperimentalWarning' &&\n\t\tString(warning).includes(SQLITE_EXPERIMENTAL_WARNING)\n\t);\n}\n\nexport function install_sqlite_warning_filter(\n\tprocess_like: WarningEmitter = process,\n): void {\n\tif (process_like[FILTER_INSTALLED]) return;\n\tprocess_like[FILTER_INSTALLED] = true;\n\n\tconst original_emit_warning =\n\t\tprocess_like[ORIGINAL_EMIT_WARNING] ?? process_like.emitWarning;\n\tprocess_like[ORIGINAL_EMIT_WARNING] = original_emit_warning;\n\n\tprocess_like.emitWarning = function emit_filtered_warning(\n\t\tthis: WarningEmitter,\n\t\t...args: unknown[]\n\t) {\n\t\tif (should_suppress_emit_warning_args(args)) return;\n\t\treturn (\n\t\t\toriginal_emit_warning as (...args: unknown[]) => void\n\t\t).apply(this, args);\n\t} as typeof process.emitWarning;\n}\n","#!/usr/bin/env node\n\nimport {\n\tdefineCommand,\n\trenderUsage,\n\trunMain,\n\ttype ArgsDef,\n\ttype CommandDef,\n} from 'citty';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport {\n\tcreate_builtin_disable_cli_args,\n\tparse_extension_cli_args,\n\tparse_extension_paths,\n\tparse_skill_allowlist,\n\tparse_thinking_level,\n\tparse_tool_allowlist,\n\tparse_tool_excludelist,\n\tresolve_builtin_extension_options,\n\ttype CliArgDefinitions,\n} from './cli-args.js';\nimport { get_node_preflight_error } from './runtime-preflight.js';\nimport { install_sqlite_warning_filter } from './warnings.js';\n\nconst node_preflight_error = get_node_preflight_error();\nif (node_preflight_error) {\n\tconsole.error(node_preflight_error);\n\tprocess.exit(1);\n}\n\ninstall_sqlite_warning_filter();\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst package_root = join(__dirname, '..');\nconst pkg = JSON.parse(\n\treadFileSync(join(package_root, 'package.json'), 'utf-8'),\n);\n\n// my-pi is a wrapper around Pi; upstream Pi update banners are useful in\n// this repo, but confusing for installed wrapper users.\nif (!existsSync(join(package_root, '.git'))) {\n\tprocess.env.PI_SKIP_VERSION_CHECK ??= '1';\n}\n\nasync function read_stdin(): Promise<string> {\n\tconst chunks: Buffer[] = [];\n\tfor await (const chunk of process.stdin) {\n\t\tchunks.push(chunk as Buffer);\n\t}\n\treturn Buffer.concat(chunks).toString('utf-8').trim();\n}\n\ntype MyPiRuntime = Awaited<\n\tReturnType<(typeof import('./api.js'))['create_my_pi']>\n>;\ntype InteractiveModeConstructor =\n\t(typeof import('@earendil-works/pi-coding-agent'))['InteractiveMode'];\n\nasync function run_interactive_mode(\n\truntime: MyPiRuntime,\n\tInteractiveModeClass: InteractiveModeConstructor,\n): Promise<void> {\n\tconst original_write = process.stdout.write.bind(process.stdout);\n\tprocess.stdout.write = ((\n\t\tchunk: string | Uint8Array,\n\t\t...args: Parameters<typeof original_write>\n\t) => {\n\t\tif (typeof chunk === 'string') {\n\t\t\tconst escape = String.fromCharCode(27);\n\t\t\tconst styled_hint = new RegExp(\n\t\t\t\t`(To resume this session:${escape}\\\\[[\\\\d;]*m )pi( --session )`,\n\t\t\t\t'g',\n\t\t\t);\n\t\t\tchunk = chunk.replace(styled_hint, '$1my-pi$2');\n\t\t\tchunk = chunk.replace(\n\t\t\t\t/(To resume this session: )pi( --session )/g,\n\t\t\t\t'$1my-pi$2',\n\t\t\t);\n\t\t}\n\t\treturn Reflect.apply(original_write, process.stdout, [\n\t\t\tchunk,\n\t\t\t...args,\n\t\t]);\n\t}) as typeof process.stdout.write;\n\ttry {\n\t\tconst mode = new InteractiveModeClass(runtime, {\n\t\t\tmigratedProviders: [],\n\t\t\tmodelFallbackMessage: undefined,\n\t\t\tinitialMessage: undefined,\n\t\t\tinitialImages: [],\n\t\t\tinitialMessages: [],\n\t\t});\n\t\tawait mode.run();\n\t} finally {\n\t\tprocess.stdout.write =\n\t\t\toriginal_write as typeof process.stdout.write;\n\t}\n}\n\nconst HELP_APPENDIX = `\nMODES\n\n my-pi\n Interactive TUI with slash commands, editor, and session UI.\n\n my-pi \"prompt\"\n my-pi -P \"prompt\"\n One-shot print mode with plain text output.\n\n my-pi --json \"prompt\"\n Non-interactive NDJSON mode for scripts, evals, and other agents.\n\n my-pi --mode rpc\n RPC mode over stdin/stdout JSONL for orchestrators and teammate sessions.\n\nNOTES\n\n - In non-interactive modes, my-pi keeps headless-capable built-ins like\n MCP, LSP, prompt presets, recall, nopeek, Omnisearch, SQLite tools, hooks, and secret redaction.\n - UI-only built-ins like session auto-naming are skipped.\n - Repeat -e / --extension to compose multiple extensions.\n - Positional prompt arguments are joined with a single space.\n - Everything after -- is prompt text, not options.\n - --prompt takes precedence over positional prompt text and stdin.\n\nNESTED RUNS\n\n - Child runs inherit cwd and environment unless you isolate them explicitly.\n - Use --agent-dir to isolate auth, config, sessions, and telemetry state.\n - For safer evals or unknown repos, use --untrusted plus an explicit\n --system-prompt.\n\nEXAMPLES\n\n my-pi\n my-pi \"fix the failing test\"\n my-pi -P \"summarize this repo\"\n my-pi --json \"list all TODO comments\"\n echo \"plan a login page\" | my-pi --json\n my-pi --telemetry --json \"run eval case\"\n my-pi --telemetry --telemetry-db ./tmp/evals.db --json \"run case\"\n my-pi observability\n my-pi --untrusted --agent-dir /tmp/pi-agent --json \"run case\"\n my-pi -e ./my-ext.ts -e ./other-ext.ts \"hello\"\n my-pi -m claude-haiku-4-5-20241022 \"explain this file\"\n XIAOMI_API_KEY=... my-pi -m xiaomi/mimo-v2.5-pro \"summarize this repo\"\n my-pi -m cloudflare-workers-ai/@cf/meta/llama-3.3-70b-instruct-fp8-fast \"explain this file\"\n my-pi --preset terse,no-purple-prose \"summarize this repo\"\n my-pi --system-prompt \"You are a JSON classifier. Return only JSON.\" --json \"classify this\"\n\nPROMPT PRESETS\n\n Interactive commands:\n /prompt-preset help\n /prompt-preset export-defaults\n /prompt-preset edit-global terse\n /prompt-preset base detailed\n /prompt-preset enable bullets\n\n Short alias: /preset\n\n Editable preset files:\n ~/.pi/agent/presets/*.md\n .pi/presets/*.md\n`;\n\nasync function render_rich_usage<T extends ArgsDef>(\n\tcmd: CommandDef<T>,\n\tparent?: CommandDef<T>,\n): Promise<string> {\n\treturn `${await renderUsage(cmd, parent)}\\n${HELP_APPENDIX}`;\n}\n\nasync function print_usage<T extends ArgsDef>(\n\tcmd: CommandDef<T>,\n\tparent?: CommandDef<T>,\n): Promise<void> {\n\tconsole.log(await render_rich_usage(cmd, parent));\n}\n\nconst main = defineCommand({\n\tmeta: {\n\t\tname: 'my-pi',\n\t\tversion: pkg.version,\n\t\tdescription:\n\t\t\t'Composable pi coding agent with MCP, LSP, presets, and local eval telemetry',\n\t},\n\targs: {\n\t\tprint: {\n\t\t\ttype: 'boolean',\n\t\t\talias: 'P',\n\t\t\tdescription: 'Print mode (non-interactive, one-shot)',\n\t\t\tdefault: false,\n\t\t},\n\t\t'agent-dir': {\n\t\t\ttype: 'string',\n\t\t\tdescription:\n\t\t\t\t'Override Pi auth/config/session directory for this process',\n\t\t\trequired: false,\n\t\t},\n\t\t'session-dir': {\n\t\t\ttype: 'string',\n\t\t\tdescription:\n\t\t\t\t'Override Pi session storage directory for this process',\n\t\t\trequired: false,\n\t\t},\n\t\tjson: {\n\t\t\ttype: 'boolean',\n\t\t\talias: 'j',\n\t\t\tdescription: 'Output NDJSON events (for agent consumption)',\n\t\t\tdefault: false,\n\t\t},\n\t\tmode: {\n\t\t\ttype: 'string',\n\t\t\tdescription: 'Runtime mode: interactive, print, json, or rpc',\n\t\t\trequired: false,\n\t\t},\n\t\textension: {\n\t\t\ttype: 'string',\n\t\t\talias: 'e',\n\t\t\tdescription:\n\t\t\t\t'Extension path to load; repeatable via argv parsing',\n\t\t\trequired: false,\n\t\t},\n\t\t'no-builtin': {\n\t\t\ttype: 'boolean',\n\t\t\tdescription: 'Disable all built-in extensions',\n\t\t\tdefault: false,\n\t\t},\n\t\tuntrusted: {\n\t\t\ttype: 'boolean',\n\t\t\tdescription:\n\t\t\t\t'Safe mode for unknown repos: skip project MCP, hooks, project prompt presets, project skills, and project LSP binaries unless explicitly re-enabled',\n\t\t\tdefault: false,\n\t\t},\n\t\t...create_builtin_disable_cli_args(),\n\t\ttelemetry: {\n\t\t\ttype: 'boolean',\n\t\t\tdescription: 'Enable local SQLite telemetry for this process',\n\t\t\tdefault: false,\n\t\t},\n\t\t'no-telemetry': {\n\t\t\ttype: 'boolean',\n\t\t\tdescription: 'Disable local SQLite telemetry for this process',\n\t\t\tdefault: false,\n\t\t},\n\t\t'telemetry-db': {\n\t\t\ttype: 'string',\n\t\t\tdescription:\n\t\t\t\t'Override telemetry database path for this process',\n\t\t\trequired: false,\n\t\t},\n\t\tmodel: {\n\t\t\ttype: 'string',\n\t\t\talias: 'm',\n\t\t\tdescription:\n\t\t\t\t'Model to use (e.g. claude-sonnet-4-5-20241022, gpt-5.4, cloudflare-workers-ai/@cf/meta/llama-3.3-70b-instruct-fp8-fast)',\n\t\t},\n\t\tthinking: {\n\t\t\ttype: 'string',\n\t\t\tdescription:\n\t\t\t\t'Thinking level: off, minimal, low, medium, high, or xhigh',\n\t\t\trequired: false,\n\t\t},\n\t\ttools: {\n\t\t\ttype: 'string',\n\t\t\talias: 't',\n\t\t\tdescription:\n\t\t\t\t'Comma-separated allowlist of tool names to enable',\n\t\t\trequired: false,\n\t\t},\n\t\t'exclude-tools': {\n\t\t\ttype: 'string',\n\t\t\talias: 'xt',\n\t\t\tdescription: 'Comma-separated list of tool names to disable',\n\t\t\trequired: false,\n\t\t},\n\t\tsession: {\n\t\t\ttype: 'string',\n\t\t\tdescription: 'Resume a specific session file or session ID',\n\t\t\trequired: false,\n\t\t},\n\t\t'session-id': {\n\t\t\ttype: 'string',\n\t\t\tdescription:\n\t\t\t\t'Create or resume an exact project-local session ID',\n\t\t\trequired: false,\n\t\t},\n\t\tname: {\n\t\t\ttype: 'string',\n\t\t\talias: 'n',\n\t\t\tdescription: 'Set the session display name at startup',\n\t\t\trequired: false,\n\t\t},\n\t\tskill: {\n\t\t\ttype: 'string',\n\t\t\tdescription: 'Skill name to allow; repeatable in argv parsing',\n\t\t\trequired: false,\n\t\t},\n\t\t'system-prompt': {\n\t\t\ttype: 'string',\n\t\t\tdescription: 'Replace the base system prompt',\n\t\t\trequired: false,\n\t\t},\n\t\t'append-system-prompt': {\n\t\t\ttype: 'string',\n\t\t\tdescription: 'Append one-off instructions to the system prompt',\n\t\t\trequired: false,\n\t\t},\n\t\tprompt: {\n\t\t\ttype: 'string',\n\t\t\talias: 'p',\n\t\t\tdescription: 'Prompt text (alternative to positional argument)',\n\t\t\trequired: false,\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst cwd = process.cwd();\n\t\tconst cli_argv = process.argv.slice(2);\n\t\tconst parsed_extension_cli = parse_extension_cli_args(\n\t\t\tcli_argv,\n\t\t\tmain.args as CliArgDefinitions,\n\t\t);\n\t\tif (parsed_extension_cli.diagnostics.length) {\n\t\t\tfor (const message of parsed_extension_cli.diagnostics)\n\t\t\t\tconsole.error(`Error: ${message}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tconst extension_paths = parse_extension_paths(cli_argv, cwd);\n\t\tconst selected_tools = parse_tool_allowlist(cli_argv);\n\t\tconst excluded_tools = parse_tool_excludelist(cli_argv);\n\t\tconst selected_skills = parse_skill_allowlist(cli_argv);\n\t\tlet selected_thinking;\n\t\ttry {\n\t\t\tselected_thinking = parse_thinking_level(args.thinking);\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\terror instanceof Error ? error.message : String(error),\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tlet runtime_mode: 'interactive' | 'print' | 'json' | 'rpc' =\n\t\t\t'interactive';\n\t\tif (args.mode) {\n\t\t\tconst requested = String(args.mode).trim().toLowerCase();\n\t\t\tif (\n\t\t\t\t!['interactive', 'print', 'json', 'rpc'].includes(requested)\n\t\t\t) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t'Error: --mode must be one of interactive, print, json, rpc.',\n\t\t\t\t);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\truntime_mode = requested as\n\t\t\t\t| 'interactive'\n\t\t\t\t| 'print'\n\t\t\t\t| 'json'\n\t\t\t\t| 'rpc';\n\t\t}\n\t\tif (args.json) runtime_mode = 'json';\n\t\telse if (args.print) runtime_mode = 'print';\n\n\t\tconst positionals = parsed_extension_cli.positionals;\n\t\tif (positionals?.[0] === 'observability') {\n\t\t\tconst { start_observability_server } =\n\t\t\t\tawait import('@spences10/pi-observability/server');\n\t\t\tstart_observability_server();\n\t\t\treturn;\n\t\t}\n\n\t\t// Resolve prompt: named --prompt flag > positional > stdin\n\t\tlet prompt = args.prompt;\n\t\tif (!prompt && positionals && positionals.length > 0) {\n\t\t\tprompt = positionals.join(' ');\n\t\t}\n\t\tif (!prompt && !process.stdin.isTTY && runtime_mode !== 'rpc') {\n\t\t\tprompt = await read_stdin();\n\t\t}\n\t\tif (prompt && runtime_mode === 'interactive')\n\t\t\truntime_mode = 'print';\n\n\t\tif (\n\t\t\truntime_mode === 'interactive' &&\n\t\t\t!prompt &&\n\t\t\t!process.stdout.isTTY\n\t\t) {\n\t\t\tawait print_usage(main);\n\t\t\treturn;\n\t\t}\n\n\t\t// Startup feedback so silence = broken (issue #3)\n\t\tif (runtime_mode !== 'interactive') {\n\t\t\tprocess.stderr.write(\n\t\t\t\t`my-pi: connecting to ${args.model || 'default model'}...\\n`,\n\t\t\t);\n\t\t}\n\n\t\tif (args.telemetry && args['no-telemetry']) {\n\t\t\tconsole.error(\n\t\t\t\t'Error: --telemetry and --no-telemetry cannot be used together.',\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tif (args.session && args['session-id']) {\n\t\t\tconsole.error(\n\t\t\t\t'Error: --session and --session-id cannot be used together.',\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tlet telemetry_override: boolean | undefined;\n\t\tif (args.telemetry) {\n\t\t\ttelemetry_override = true;\n\t\t} else if (args['no-telemetry']) {\n\t\t\ttelemetry_override = false;\n\t\t}\n\n\t\tconst [\n\t\t\t{ create_my_pi },\n\t\t\t{ InteractiveMode, runPrintMode, runRpcMode },\n\t\t] = await Promise.all([\n\t\t\timport('./api.js'),\n\t\t\timport('@earendil-works/pi-coding-agent'),\n\t\t]);\n\n\t\tconst runtime = await create_my_pi({\n\t\t\tcwd,\n\t\t\tagent_dir: args['agent-dir'],\n\t\t\tsession_dir: args['session-dir'],\n\t\t\textensions: extension_paths,\n\t\t\textension_flag_values:\n\t\t\t\tparsed_extension_cli.extension_flag_values,\n\t\t\truntime_mode,\n\t\t\t...resolve_builtin_extension_options(args),\n\t\t\ttelemetry: telemetry_override,\n\t\t\ttelemetry_db_path: args['telemetry-db'],\n\t\t\tmodel: args.model,\n\t\t\tthinking: selected_thinking,\n\t\t\tselected_tools,\n\t\t\texcluded_tools,\n\t\t\tselected_skills,\n\t\t\tsession: args.session,\n\t\t\tsession_id: args['session-id'],\n\t\t\tstartup_session_name: args.name,\n\t\t\tsystem_prompt: args['system-prompt'],\n\t\t\tappend_system_prompt: args['append-system-prompt'],\n\t\t\tuntrusted_repo: args.untrusted,\n\t\t});\n\n\t\tfor (const diagnostic of runtime.diagnostics) {\n\t\t\tconst prefix =\n\t\t\t\tdiagnostic.type === 'error'\n\t\t\t\t\t? 'Error: '\n\t\t\t\t\t: diagnostic.type === 'warning'\n\t\t\t\t\t\t? 'Warning: '\n\t\t\t\t\t\t: '';\n\t\t\tconsole.error(`${prefix}${diagnostic.message}`);\n\t\t}\n\t\tif (\n\t\t\truntime.diagnostics.some(\n\t\t\t\t(diagnostic) => diagnostic.type === 'error',\n\t\t\t)\n\t\t) {\n\t\t\tawait runtime.dispose();\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tif (runtime_mode === 'rpc') {\n\t\t\tawait runRpcMode(runtime);\n\t\t} else if (runtime_mode === 'print' || runtime_mode === 'json') {\n\t\t\tconst code = await runPrintMode(runtime, {\n\t\t\t\tmode: runtime_mode === 'json' ? 'json' : 'text',\n\t\t\t\tinitialMessage: prompt || '',\n\t\t\t\tinitialImages: [],\n\t\t\t\tmessages: [],\n\t\t\t});\n\t\t\tprocess.exit(code);\n\t\t} else if (!process.stdout.isTTY) {\n\t\t\tawait print_usage(main);\n\t\t} else {\n\t\t\tawait run_interactive_mode(runtime, InteractiveMode);\n\t\t}\n\t},\n});\n\nvoid runMain(main, {\n\tshowUsage: async (cmd, parent) => {\n\t\tawait print_usage(cmd, parent);\n\t},\n});\n"],"mappings":";;;;;;;AAMA,MAAM,kCAAkB,IAAI,IAAI;CAC/B;CACA;CACA;CACA;CACA;CACA;AACD,CAAC;AAgCD,SAAgB,kCAAyD;CACxE,OAAO,OAAO,YACb,mBAAmB,KAAK,cAAc,CACrC,UAAU,SACV;EACC,MAAM;EACN,aAAa,UAAU;EACvB,SAAS;CACV,CACD,CAAC,CACF;AACD;AAEA,SAAS,qBACR,MACA,SACU;CACV,IAAI,KAAK,UAAU,OAAO;CAE1B,MAAM,iBAAiB,QAAQ,QAAQ,QAAQ,EAAE;CACjD,MAAM,iBAAiB,eAAe,QACrC,cACC,GAAG,SAAS,OAAO,IAAI,CAAC,CAAC,YAAY,CACvC;CACA,OACC,KAAK,oBAAoB,SAAS,KAAK,oBAAoB;AAE7D;AAEA,SAAgB,kCACf,MACuD;CACvD,MAAM,aAAa,qBAAqB,MAAM,YAAY;CAC1D,OAAO,OAAO,YACb,mBAAmB,KAAK,cAAc,CACrC,UAAU,aACV,CAAC,cACA,CAAC,qBAAqB,MAAM,UAAU,OAAO,KAC7C,UAAU,eACZ,CAAC,CACF;AACD;AAEA,SAAgB,yBACf,MACA,YACyB;CACzB,MAAM,8BAAc,IAAI,IAAsC;CAC9D,KAAK,MAAM,CAAC,MAAM,eAAe,OAAO,QAAQ,UAAU,GAAG;EAC5D,YAAY,IAAI,KAAK,QAAQ,WAAW,IAAI;EAC5C,MAAM,aAAa,KAAK,QAAQ,cAAc,GAAG,SAChD,OAAO,IAAI,CAAC,CAAC,YAAY,CAC1B;EACA,YAAY,IAAI,KAAK,cAAc,WAAW,IAAI;EAClD,IAAI,WAAW,SAAS,WACvB,YAAY,IAAI,QAAQ,QAAQ,WAAW,IAAI;EAChD,MAAM,UAAU,MAAM,QAAQ,WAAW,KAAK,IAC3C,WAAW,QACX,WAAW,QACV,CAAC,WAAW,KAAK,IACjB,CAAC;EACL,KAAK,MAAM,SAAS,SACnB,YAAY,IAAI,IAAI,SAAS,WAAW,IAAI;CAC9C;CAEA,MAAM,wCAAwB,IAAI,IAA8B;CAChE,MAAM,cAAwB,CAAC;CAC/B,MAAM,cAAwB,CAAC;CAE/B,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;EACrC,MAAM,MAAM,KAAK;EACjB,IAAI,CAAC,KAAK;EACV,IAAI,QAAQ,MAAM;GACjB,YAAY,KAAK,GAAG,KAAK,MAAM,IAAI,CAAC,CAAC;GACrC;EACD;EAEA,MAAM,eAAe,IAAI,QAAQ,GAAG;EACpC,MAAM,aACL,iBAAiB,KAAK,MAAM,IAAI,MAAM,GAAG,YAAY;EACtD,MAAM,aAAa,YAAY,IAAI,UAAU;EAC7C,IAAI,YAAY;GACf,IACC,iBAAiB,OAChB,eAAe,YAAY,eAAe,WAC3C,IAAI,IAAI,KAAK,UACb,KAAK,IAAI,OAAO,MAEhB,KAAK;GAEN;EACD;EAEA,IAAI,IAAI,WAAW,IAAI,GAAG;GACzB,IAAI,iBAAiB,IAAI;IACxB,sBAAsB,IACrB,IAAI,MAAM,GAAG,YAAY,GACzB,IAAI,MAAM,eAAe,CAAC,CAC3B;IACA;GACD;GACA,MAAM,OAAO,IAAI,MAAM,CAAC;GACxB,MAAM,OAAO,KAAK,IAAI;GACtB,IACC,SAAS,KAAA,KACT,CAAC,KAAK,WAAW,GAAG,KACpB,CAAC,KAAK,WAAW,GAAG,GACnB;IACD,sBAAsB,IAAI,MAAM,IAAI;IACpC,KAAK;GACN,OACC,sBAAsB,IAAI,MAAM,IAAI;GAErC;EACD;EAEA,IAAI,IAAI,WAAW,GAAG,GAAG;GACxB,YAAY,KAAK,mBAAmB,KAAK;GACzC;EACD;EACA,YAAY,KAAK,GAAG;CACrB;CAEA,OAAO;EAAE;EAAuB;EAAa;CAAY;AAC1D;AAEA,SAAgB,oBACf,MACA,OACW;CACX,MAAM,SAAmB,CAAC;CAC1B,MAAM,WAAW,IAAI,IAAI,KAAK;CAE9B,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;EACrC,MAAM,MAAM,KAAK;EACjB,IAAI,QAAQ,MAAM;EAClB,IAAI,CAAC,KAAK;EAEV,MAAM,eAAe,IAAI,QAAQ,GAAG;EACpC,IAAI,iBAAiB,IAAI;GACxB,MAAM,OAAO,IAAI,MAAM,GAAG,YAAY;GACtC,IAAI,SAAS,IAAI,IAAI,GACpB,OAAO,KAAK,IAAI,MAAM,eAAe,CAAC,CAAC;GAExC;EACD;EAEA,IAAI,SAAS,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,QAAQ;GAC7C,MAAM,OAAO,KAAK,IAAI;GACtB,IAAI,SAAS,KAAA,KAAa,SAAS,MAAM;IACxC,OAAO,KAAK,IAAI;IAChB,KAAK;GACN;EACD;CACD;CAEA,OAAO;AACR;AAEA,SAAgB,sBACf,MACA,MAAM,QAAQ,IAAI,GACP;CACX,OAAO,oBAAoB,MAAM,CAAC,MAAM,aAAa,CAAC,CAAC,CACrD,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAC1B,OAAO,OAAO,CAAC,CACf,KAAK,SAAS,QAAQ,KAAK,IAAI,CAAC;AACnC;AAEA,SAAS,uBACR,MACA,OACuB;CACvB,MAAM,SAAS,oBAAoB,MAAM,KAAK,CAAC,CAC7C,SAAS,UAAU,MAAM,MAAM,GAAG,CAAC,CAAC,CACpC,KAAK,UAAU,MAAM,KAAK,CAAC,CAAC,CAC5B,OAAO,OAAO;CAChB,OAAO,OAAO,SAAS,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC,IAAI,KAAA;AAC/C;AAEA,SAAgB,qBACf,MACuB;CACvB,OAAO,uBAAuB,MAAM,CAAC,WAAW,IAAI,CAAC;AACtD;AAEA,SAAgB,uBACf,MACuB;CACvB,OAAO,uBAAuB,MAAM,CAAC,mBAAmB,KAAK,CAAC;AAC/D;AAEA,SAAgB,sBACf,MACuB;CACvB,OAAO,uBAAuB,MAAM,CAAC,SAAS,CAAC;AAChD;AAEA,SAAgB,qBACf,OAC+B;CAC/B,MAAM,aAAa,OAAO,KAAK,CAAC,CAAC,YAAY;CAC7C,IAAI,CAAC,YAAY,OAAO,KAAA;CACxB,IAAI,CAAC,gBAAgB,IAAI,UAAU,GAClC,MAAM,IAAI,MACT,oEACD;CAED,OAAO;AACR;;AC9PA,MAAa,uBAAuB;AAEpC,SAAS,mBACR,SACuC;CACvC,MAAM,QAAQ,qCAAqC,KAAK,OAAO;CAC/D,IAAI,CAAC,OAAO,OAAO,KAAA;CACnB,OAAO;EAAC,OAAO,MAAM,EAAE;EAAG,OAAO,MAAM,EAAE;EAAG,OAAO,MAAM,EAAE;CAAC;AAC7D;AAEA,SAAgB,0BAA0B,SAA0B;CACnE,MAAM,UAAU,mBAAmB,OAAO;CAC1C,MAAM,UAAU,mBAAmB,oBAAoB;CACvD,IAAI,CAAC,WAAW,CAAC,SAAS,OAAO;CAEjC,KAAK,IAAI,QAAQ,GAAG,QAAQ,QAAQ,QAAQ,SAAS;EACpD,IAAI,QAAQ,SAAS,QAAQ,QAAQ,OAAO;EAC5C,IAAI,QAAQ,SAAS,QAAQ,QAAQ,OAAO;CAC7C;CACA,OAAO;AACR;AAEA,SAAgB,yBACf,kBAAkB,QAAQ,SAAS,MACd;CACrB,IAAI,0BAA0B,eAAe,GAAG,OAAO,KAAA;CACvD,OAAO,yBAAyB,qBAAqB,uBAAuB,gBAAgB;AAC7F;;AC3BA,MAAM,8BACL;AACD,MAAM,mBAAmB,OAAO,IAC/B,uCACD;AACA,MAAM,wBAAwB,OAAO,IACpC,6BACD;AAOA,SAAgB,wBAAwB,SAAyB;CAChE,OACC,QAAQ,SAAS,yBACjB,QAAQ,QAAQ,SAAS,2BAA2B;AAEtD;AAEA,SAAS,kCAAkC,MAA0B;CACpE,MAAM,CAAC,SAAS,mBAAmB;CACnC,IAAI,mBAAmB,OACtB,OAAO,wBAAwB,OAAO;CAOvC,QALC,OAAO,oBAAoB,WACxB,kBACA,mBAAmB,OAAO,oBAAoB,WAC5C,gBAAuC,OACxC,KAAA,OAEa,yBACjB,OAAO,OAAO,CAAC,CAAC,SAAS,2BAA2B;AAEtD;AAEA,SAAgB,8BACf,eAA+B,SACxB;CACP,IAAI,aAAa,mBAAmB;CACpC,aAAa,oBAAoB;CAEjC,MAAM,wBACL,aAAa,0BAA0B,aAAa;CACrD,aAAa,yBAAyB;CAEtC,aAAa,cAAc,SAAS,sBAEnC,GAAG,MACF;EACD,IAAI,kCAAkC,IAAI,GAAG;EAC7C,OACC,sBACC,MAAM,MAAM,IAAI;CACnB;AACD;;AC9BA,MAAM,uBAAuB,yBAAyB;AACtD,IAAI,sBAAsB;CACzB,QAAQ,MAAM,oBAAoB;CAClC,QAAQ,KAAK,CAAC;AACf;AAEA,8BAA8B;AAE9B,MAAM,YAAY,QAAQ,cAAc,YAAY,GAAG,CAAC;AACxD,MAAM,eAAe,KAAK,WAAW,IAAI;AACzC,MAAM,MAAM,KAAK,MAChB,aAAa,KAAK,cAAc,cAAc,GAAG,OAAO,CACzD;AAIA,IAAI,CAAC,WAAW,KAAK,cAAc,MAAM,CAAC,GACzC,QAAQ,IAAI,0BAA0B;AAGvC,eAAe,aAA8B;CAC5C,MAAM,SAAmB,CAAC;CAC1B,WAAW,MAAM,SAAS,QAAQ,OACjC,OAAO,KAAK,KAAe;CAE5B,OAAO,OAAO,OAAO,MAAM,CAAC,CAAC,SAAS,OAAO,CAAC,CAAC,KAAK;AACrD;AAQA,eAAe,qBACd,SACA,sBACgB;CAChB,MAAM,iBAAiB,QAAQ,OAAO,MAAM,KAAK,QAAQ,MAAM;CAC/D,QAAQ,OAAO,UACd,OACA,GAAG,SACC;EACJ,IAAI,OAAO,UAAU,UAAU;GAE9B,MAAM,cAAc,IAAI,OACvB,2BAFc,OAAO,aAAa,EAEF,EAAE,+BAClC,GACD;GACA,QAAQ,MAAM,QAAQ,aAAa,WAAW;GAC9C,QAAQ,MAAM,QACb,8CACA,WACD;EACD;EACA,OAAO,QAAQ,MAAM,gBAAgB,QAAQ,QAAQ,CACpD,OACA,GAAG,IACJ,CAAC;CACF;CACA,IAAI;EAQH,MAAM,IAPW,qBAAqB,SAAS;GAC9C,mBAAmB,CAAC;GACpB,sBAAsB,KAAA;GACtB,gBAAgB,KAAA;GAChB,eAAe,CAAC;GAChB,iBAAiB,CAAC;EACnB,CACS,CAAC,CAAC,IAAI;CAChB,UAAU;EACT,QAAQ,OAAO,QACd;CACF;AACD;AAEA,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmEtB,eAAe,kBACd,KACA,QACkB;CAClB,OAAO,GAAG,MAAM,YAAY,KAAK,MAAM,EAAE,IAAI;AAC9C;AAEA,eAAe,YACd,KACA,QACgB;CAChB,QAAQ,IAAI,MAAM,kBAAkB,KAAK,MAAM,CAAC;AACjD;AAEA,MAAM,OAAO,cAAc;CAC1B,MAAM;EACL,MAAM;EACN,SAAS,IAAI;EACb,aACC;CACF;CACA,MAAM;EACL,OAAO;GACN,MAAM;GACN,OAAO;GACP,aAAa;GACb,SAAS;EACV;EACA,aAAa;GACZ,MAAM;GACN,aACC;GACD,UAAU;EACX;EACA,eAAe;GACd,MAAM;GACN,aACC;GACD,UAAU;EACX;EACA,MAAM;GACL,MAAM;GACN,OAAO;GACP,aAAa;GACb,SAAS;EACV;EACA,MAAM;GACL,MAAM;GACN,aAAa;GACb,UAAU;EACX;EACA,WAAW;GACV,MAAM;GACN,OAAO;GACP,aACC;GACD,UAAU;EACX;EACA,cAAc;GACb,MAAM;GACN,aAAa;GACb,SAAS;EACV;EACA,WAAW;GACV,MAAM;GACN,aACC;GACD,SAAS;EACV;EACA,GAAG,gCAAgC;EACnC,WAAW;GACV,MAAM;GACN,aAAa;GACb,SAAS;EACV;EACA,gBAAgB;GACf,MAAM;GACN,aAAa;GACb,SAAS;EACV;EACA,gBAAgB;GACf,MAAM;GACN,aACC;GACD,UAAU;EACX;EACA,OAAO;GACN,MAAM;GACN,OAAO;GACP,aACC;EACF;EACA,UAAU;GACT,MAAM;GACN,aACC;GACD,UAAU;EACX;EACA,OAAO;GACN,MAAM;GACN,OAAO;GACP,aACC;GACD,UAAU;EACX;EACA,iBAAiB;GAChB,MAAM;GACN,OAAO;GACP,aAAa;GACb,UAAU;EACX;EACA,SAAS;GACR,MAAM;GACN,aAAa;GACb,UAAU;EACX;EACA,cAAc;GACb,MAAM;GACN,aACC;GACD,UAAU;EACX;EACA,MAAM;GACL,MAAM;GACN,OAAO;GACP,aAAa;GACb,UAAU;EACX;EACA,OAAO;GACN,MAAM;GACN,aAAa;GACb,UAAU;EACX;EACA,iBAAiB;GAChB,MAAM;GACN,aAAa;GACb,UAAU;EACX;EACA,wBAAwB;GACvB,MAAM;GACN,aAAa;GACb,UAAU;EACX;EACA,QAAQ;GACP,MAAM;GACN,OAAO;GACP,aAAa;GACb,UAAU;EACX;CACD;CACA,MAAM,IAAI,EAAE,QAAQ;EACnB,MAAM,MAAM,QAAQ,IAAI;EACxB,MAAM,WAAW,QAAQ,KAAK,MAAM,CAAC;EACrC,MAAM,uBAAuB,yBAC5B,UACA,KAAK,IACN;EACA,IAAI,qBAAqB,YAAY,QAAQ;GAC5C,KAAK,MAAM,WAAW,qBAAqB,aAC1C,QAAQ,MAAM,UAAU,SAAS;GAClC,QAAQ,KAAK,CAAC;EACf;EACA,MAAM,kBAAkB,sBAAsB,UAAU,GAAG;EAC3D,MAAM,iBAAiB,qBAAqB,QAAQ;EACpD,MAAM,iBAAiB,uBAAuB,QAAQ;EACtD,MAAM,kBAAkB,sBAAsB,QAAQ;EACtD,IAAI;EACJ,IAAI;GACH,oBAAoB,qBAAqB,KAAK,QAAQ;EACvD,SAAS,OAAO;GACf,QAAQ,MACP,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CACtD;GACA,QAAQ,KAAK,CAAC;EACf;EAEA,IAAI,eACH;EACD,IAAI,KAAK,MAAM;GACd,MAAM,YAAY,OAAO,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,YAAY;GACvD,IACC,CAAC;IAAC;IAAe;IAAS;IAAQ;GAAK,CAAC,CAAC,SAAS,SAAS,GAC1D;IACD,QAAQ,MACP,6DACD;IACA,QAAQ,KAAK,CAAC;GACf;GACA,eAAe;EAKhB;EACA,IAAI,KAAK,MAAM,eAAe;OACzB,IAAI,KAAK,OAAO,eAAe;EAEpC,MAAM,cAAc,qBAAqB;EACzC,IAAI,cAAc,OAAO,iBAAiB;GACzC,MAAM,EAAE,+BACP,MAAM,OAAO;GACd,2BAA2B;GAC3B;EACD;EAGA,IAAI,SAAS,KAAK;EAClB,IAAI,CAAC,UAAU,eAAe,YAAY,SAAS,GAClD,SAAS,YAAY,KAAK,GAAG;EAE9B,IAAI,CAAC,UAAU,CAAC,QAAQ,MAAM,SAAS,iBAAiB,OACvD,SAAS,MAAM,WAAW;EAE3B,IAAI,UAAU,iBAAiB,eAC9B,eAAe;EAEhB,IACC,iBAAiB,iBACjB,CAAC,UACD,CAAC,QAAQ,OAAO,OACf;GACD,MAAM,YAAY,IAAI;GACtB;EACD;EAGA,IAAI,iBAAiB,eACpB,QAAQ,OAAO,MACd,wBAAwB,KAAK,SAAS,gBAAgB,MACvD;EAGD,IAAI,KAAK,aAAa,KAAK,iBAAiB;GAC3C,QAAQ,MACP,gEACD;GACA,QAAQ,KAAK,CAAC;EACf;EACA,IAAI,KAAK,WAAW,KAAK,eAAe;GACvC,QAAQ,MACP,4DACD;GACA,QAAQ,KAAK,CAAC;EACf;EAEA,IAAI;EACJ,IAAI,KAAK,WACR,qBAAqB;OACf,IAAI,KAAK,iBACf,qBAAqB;EAGtB,MAAM,CACL,EAAE,gBACF,EAAE,iBAAiB,cAAc,gBAC9B,MAAM,QAAQ,IAAI,CACrB,OAAO,aACP,OAAO,kCACR,CAAC;EAED,MAAM,UAAU,MAAM,aAAa;GAClC;GACA,WAAW,KAAK;GAChB,aAAa,KAAK;GAClB,YAAY;GACZ,uBACC,qBAAqB;GACtB;GACA,GAAG,kCAAkC,IAAI;GACzC,WAAW;GACX,mBAAmB,KAAK;GACxB,OAAO,KAAK;GACZ,UAAU;GACV;GACA;GACA;GACA,SAAS,KAAK;GACd,YAAY,KAAK;GACjB,sBAAsB,KAAK;GAC3B,eAAe,KAAK;GACpB,sBAAsB,KAAK;GAC3B,gBAAgB,KAAK;EACtB,CAAC;EAED,KAAK,MAAM,cAAc,QAAQ,aAAa;GAC7C,MAAM,SACL,WAAW,SAAS,UACjB,YACA,WAAW,SAAS,YACnB,cACA;GACL,QAAQ,MAAM,GAAG,SAAS,WAAW,SAAS;EAC/C;EACA,IACC,QAAQ,YAAY,MAClB,eAAe,WAAW,SAAS,OACrC,GACC;GACD,MAAM,QAAQ,QAAQ;GACtB,QAAQ,KAAK,CAAC;EACf;EAEA,IAAI,iBAAiB,OACpB,MAAM,WAAW,OAAO;OAClB,IAAI,iBAAiB,WAAW,iBAAiB,QAAQ;GAC/D,MAAM,OAAO,MAAM,aAAa,SAAS;IACxC,MAAM,iBAAiB,SAAS,SAAS;IACzC,gBAAgB,UAAU;IAC1B,eAAe,CAAC;IAChB,UAAU,CAAC;GACZ,CAAC;GACD,QAAQ,KAAK,IAAI;EAClB,OAAO,IAAI,CAAC,QAAQ,OAAO,OAC1B,MAAM,YAAY,IAAI;OAEtB,MAAM,qBAAqB,SAAS,eAAe;CAErD;AACD,CAAC;AAEI,QAAQ,MAAM,EAClB,WAAW,OAAO,KAAK,WAAW;CACjC,MAAM,YAAY,KAAK,MAAM;AAC9B,EACD,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as load_settings } from "./settings-
|
|
2
|
-
|
|
1
|
+
import { t as load_settings } from "./settings-UYlhEo3S.js";
|
|
2
|
+
// src/extensions/openrouter-fusion-config/index.ts
|
|
3
3
|
const DEFAULT_FUSION_ANALYSIS_MODELS = [
|
|
4
4
|
"~openai/gpt-latest",
|
|
5
5
|
"~google/gemini-pro-latest",
|
|
@@ -59,7 +59,6 @@ function apply_fusion_config_plugin(payload, config) {
|
|
|
59
59
|
const extension = (pi) => {
|
|
60
60
|
pi.on("before_provider_request", (event) => apply_fusion_config_plugin(event.payload, get_fusion_request_config()));
|
|
61
61
|
};
|
|
62
|
-
//#endregion
|
|
63
62
|
export { extension as default };
|
|
64
63
|
|
|
65
|
-
//# sourceMappingURL=openrouter-fusion-config-
|
|
64
|
+
//# sourceMappingURL=openrouter-fusion-config-CPXLfmCA.js.map
|
package/dist/{openrouter-fusion-config-BWsHBPQv.js.map → openrouter-fusion-config-CPXLfmCA.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openrouter-fusion-config-
|
|
1
|
+
{"version":3,"file":"openrouter-fusion-config-CPXLfmCA.js","names":[],"sources":["../src/extensions/openrouter-fusion-config/index.ts"],"sourcesContent":["import type { ExtensionFactory } from '@earendil-works/pi-coding-agent';\n\nimport { load_settings } from '../../settings/index.js';\n\nexport const DEFAULT_FUSION_ANALYSIS_MODELS = [\n\t'~openai/gpt-latest',\n\t'~google/gemini-pro-latest',\n\t'deepseek/deepseek-v3.2',\n\t'~moonshotai/kimi-latest',\n] as const;\n\nexport const DEFAULT_FUSION_JUDGE_MODEL = '~openai/gpt-latest';\n\nconst FUSION_MODEL_ID = 'openrouter/fusion';\nconst FUSION_PLUGIN_ID = 'fusion';\n\nexport interface FusionPluginConfig {\n\tid: 'fusion';\n\tanalysis_models: string[];\n\tmodel: string;\n}\n\nexport interface OpenRouterFusionSettings {\n\tanalysisModels?: string[];\n\tjudgeModel?: string;\n\tforce?: boolean;\n}\n\nexport interface FusionRequestConfig {\n\tplugin: FusionPluginConfig;\n\tforce: boolean;\n}\n\nfunction split_models(value: string | undefined): string[] {\n\treturn (value ?? '')\n\t\t.split(',')\n\t\t.map((model) => model.trim())\n\t\t.filter(Boolean);\n}\n\nfunction string_array(value: unknown): string[] | undefined {\n\tif (!Array.isArray(value)) return undefined;\n\tconst values = value\n\t\t.map((item) => (typeof item === 'string' ? item.trim() : ''))\n\t\t.filter(Boolean);\n\treturn values.length > 0 ? values : undefined;\n}\n\nfunction env_flag(value: string | undefined): boolean | undefined {\n\tif (!value) return undefined;\n\tconst normalized = value.trim().toLowerCase();\n\tif (['1', 'true', 'yes', 'on'].includes(normalized)) return true;\n\tif (['0', 'false', 'no', 'off'].includes(normalized)) return false;\n\treturn undefined;\n}\n\nexport function get_fusion_request_config(\n\toptions: {\n\t\tsettings?: OpenRouterFusionSettings;\n\t\tenv?: NodeJS.ProcessEnv;\n\t} = {},\n): FusionRequestConfig {\n\tconst env = options.env ?? process.env;\n\tconst settings =\n\t\toptions.settings ?? load_settings().openRouterFusion ?? {};\n\tconst env_models = split_models(env.MY_PI_FUSION_ANALYSIS_MODELS);\n\n\treturn {\n\t\tplugin: {\n\t\t\tid: FUSION_PLUGIN_ID,\n\t\t\tanalysis_models:\n\t\t\t\tenv_models.length > 0\n\t\t\t\t\t? env_models\n\t\t\t\t\t: (string_array(settings.analysisModels) ?? [\n\t\t\t\t\t\t\t...DEFAULT_FUSION_ANALYSIS_MODELS,\n\t\t\t\t\t\t]),\n\t\t\tmodel:\n\t\t\t\tenv.MY_PI_FUSION_JUDGE_MODEL?.trim() ||\n\t\t\t\tsettings.judgeModel?.trim() ||\n\t\t\t\tDEFAULT_FUSION_JUDGE_MODEL,\n\t\t},\n\t\tforce: env_flag(env.MY_PI_FUSION_FORCE) ?? settings.force ?? true,\n\t};\n}\n\nexport function get_fusion_plugin_config(\n\toptions: {\n\t\tsettings?: OpenRouterFusionSettings;\n\t\tenv?: NodeJS.ProcessEnv;\n\t} = {},\n): FusionPluginConfig {\n\treturn get_fusion_request_config(options).plugin;\n}\n\nexport function apply_fusion_config_plugin(\n\tpayload: unknown,\n\tconfig: FusionRequestConfig,\n): unknown {\n\tif (!payload || typeof payload !== 'object') return undefined;\n\n\tconst request = payload as Record<string, unknown>;\n\tif (request.model !== FUSION_MODEL_ID) return undefined;\n\n\tconst plugins = Array.isArray(request.plugins)\n\t\t? request.plugins\n\t\t: [];\n\tconst next_plugins = [\n\t\t...plugins.filter(\n\t\t\t(plugin) =>\n\t\t\t\t!plugin ||\n\t\t\t\ttypeof plugin !== 'object' ||\n\t\t\t\t(plugin as Record<string, unknown>).id !== FUSION_PLUGIN_ID,\n\t\t),\n\t\tconfig.plugin,\n\t];\n\n\treturn {\n\t\t...request,\n\t\tplugins: next_plugins,\n\t\t...(config.force ? { tool_choice: 'required' } : {}),\n\t};\n}\n\nconst extension: ExtensionFactory = (pi) => {\n\tpi.on('before_provider_request', (event) =>\n\t\tapply_fusion_config_plugin(\n\t\t\tevent.payload,\n\t\t\tget_fusion_request_config(),\n\t\t),\n\t);\n};\n\nexport default extension;\n"],"mappings":";;AAIA,MAAa,iCAAiC;CAC7C;CACA;CACA;CACA;AACD;AAIA,MAAM,kBAAkB;AACxB,MAAM,mBAAmB;AAmBzB,SAAS,aAAa,OAAqC;CAC1D,QAAQ,SAAS,GAAA,CACf,MAAM,GAAG,CAAC,CACV,KAAK,UAAU,MAAM,KAAK,CAAC,CAAC,CAC5B,OAAO,OAAO;AACjB;AAEA,SAAS,aAAa,OAAsC;CAC3D,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,OAAO,KAAA;CAClC,MAAM,SAAS,MACb,KAAK,SAAU,OAAO,SAAS,WAAW,KAAK,KAAK,IAAI,EAAG,CAAC,CAC5D,OAAO,OAAO;CAChB,OAAO,OAAO,SAAS,IAAI,SAAS,KAAA;AACrC;AAEA,SAAS,SAAS,OAAgD;CACjE,IAAI,CAAC,OAAO,OAAO,KAAA;CACnB,MAAM,aAAa,MAAM,KAAK,CAAC,CAAC,YAAY;CAC5C,IAAI;EAAC;EAAK;EAAQ;EAAO;CAAI,CAAC,CAAC,SAAS,UAAU,GAAG,OAAO;CAC5D,IAAI;EAAC;EAAK;EAAS;EAAM;CAAK,CAAC,CAAC,SAAS,UAAU,GAAG,OAAO;AAE9D;AAEA,SAAgB,0BACf,UAGI,CAAC,GACiB;CACtB,MAAM,MAAM,QAAQ,OAAO,QAAQ;CACnC,MAAM,WACL,QAAQ,YAAY,cAAc,CAAC,CAAC,oBAAoB,CAAC;CAC1D,MAAM,aAAa,aAAa,IAAI,4BAA4B;CAEhE,OAAO;EACN,QAAQ;GACP,IAAI;GACJ,iBACC,WAAW,SAAS,IACjB,aACC,aAAa,SAAS,cAAc,KAAK,CAC1C,GAAG,8BACJ;GACH,OACC,IAAI,0BAA0B,KAAK,KACnC,SAAS,YAAY,KAAK,KAAA;EAE5B;EACA,OAAO,SAAS,IAAI,kBAAkB,KAAK,SAAS,SAAS;CAC9D;AACD;AAWA,SAAgB,2BACf,SACA,QACU;CACV,IAAI,CAAC,WAAW,OAAO,YAAY,UAAU,OAAO,KAAA;CAEpD,MAAM,UAAU;CAChB,IAAI,QAAQ,UAAU,iBAAiB,OAAO,KAAA;CAK9C,MAAM,eAAe,CACpB,IAJe,MAAM,QAAQ,QAAQ,OAAO,IAC1C,QAAQ,UACR,CAAC,EAAA,CAEQ,QACT,WACA,CAAC,UACD,OAAO,WAAW,YACjB,OAAmC,OAAO,gBAC7C,GACA,OAAO,MACR;CAEA,OAAO;EACN,GAAG;EACH,SAAS;EACT,GAAI,OAAO,QAAQ,EAAE,aAAa,WAAW,IAAI,CAAC;CACnD;AACD;AAEA,MAAM,aAA+B,OAAO;CAC3C,GAAG,GAAG,4BAA4B,UACjC,2BACC,MAAM,SACN,0BAA0B,CAC3B,CACD;AACD"}
|