@oh-my-pi/pi-coding-agent 16.0.5 → 16.0.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.
Files changed (223) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/dist/cli.js +1927 -1376
  3. package/dist/types/advisor/advise-tool.d.ts +22 -19
  4. package/dist/types/autoresearch/tools/init-experiment.d.ts +13 -17
  5. package/dist/types/autoresearch/tools/log-experiment.d.ts +17 -19
  6. package/dist/types/autoresearch/tools/run-experiment.d.ts +3 -4
  7. package/dist/types/autoresearch/tools/update-notes.d.ts +4 -5
  8. package/dist/types/cli/ttsr-cli.d.ts +39 -0
  9. package/dist/types/commands/ttsr.d.ts +57 -0
  10. package/dist/types/commit/agentic/tools/analyze-file.d.ts +4 -5
  11. package/dist/types/commit/agentic/tools/git-file-diff.d.ts +4 -5
  12. package/dist/types/commit/agentic/tools/git-hunk.d.ts +5 -6
  13. package/dist/types/commit/agentic/tools/git-overview.d.ts +4 -5
  14. package/dist/types/commit/agentic/tools/propose-changelog.d.ts +23 -24
  15. package/dist/types/commit/agentic/tools/propose-commit.d.ts +11 -32
  16. package/dist/types/commit/agentic/tools/recent-commits.d.ts +3 -4
  17. package/dist/types/commit/agentic/tools/schemas.d.ts +6 -27
  18. package/dist/types/commit/agentic/tools/split-commit.d.ts +28 -49
  19. package/dist/types/commit/changelog/generate.d.ts +12 -13
  20. package/dist/types/commit/shared-llm.d.ts +10 -37
  21. package/dist/types/config/config-file.d.ts +4 -4
  22. package/dist/types/config/keybindings.d.ts +5 -0
  23. package/dist/types/config/models-config-schema.d.ts +625 -990
  24. package/dist/types/config/models-config.d.ts +229 -217
  25. package/dist/types/config/settings-schema.d.ts +53 -23
  26. package/dist/types/edit/hashline/params.d.ts +7 -11
  27. package/dist/types/edit/index.d.ts +2 -1
  28. package/dist/types/edit/modes/apply-patch.d.ts +4 -5
  29. package/dist/types/edit/modes/patch.d.ts +15 -24
  30. package/dist/types/edit/modes/replace.d.ts +16 -17
  31. package/dist/types/eval/js/index.d.ts +1 -0
  32. package/dist/types/extensibility/custom-commands/types.d.ts +6 -3
  33. package/dist/types/extensibility/custom-tools/types.d.ts +8 -5
  34. package/dist/types/extensibility/extensions/types.d.ts +6 -3
  35. package/dist/types/extensibility/hooks/types.d.ts +7 -4
  36. package/dist/types/extensibility/legacy-pi-ai-shim.d.ts +13 -5
  37. package/dist/types/extensibility/legacy-pi-coding-agent-shim.d.ts +17 -0
  38. package/dist/types/extensibility/typebox.d.ts +80 -58
  39. package/dist/types/goals/tools/goal-tool.d.ts +11 -24
  40. package/dist/types/index.d.ts +2 -0
  41. package/dist/types/lsp/index.d.ts +11 -26
  42. package/dist/types/lsp/types.d.ts +12 -28
  43. package/dist/types/mcp/client.d.ts +8 -0
  44. package/dist/types/modes/components/btw-panel.d.ts +1 -0
  45. package/dist/types/modes/components/custom-editor.d.ts +3 -1
  46. package/dist/types/modes/controllers/btw-controller.d.ts +2 -0
  47. package/dist/types/modes/controllers/input-controller.d.ts +1 -0
  48. package/dist/types/modes/interactive-mode.d.ts +3 -0
  49. package/dist/types/modes/setup-wizard/index.d.ts +1 -0
  50. package/dist/types/modes/setup-wizard/startup-splash.d.ts +7 -0
  51. package/dist/types/modes/theme/theme.d.ts +1 -1
  52. package/dist/types/modes/types.d.ts +3 -0
  53. package/dist/types/sdk.d.ts +5 -0
  54. package/dist/types/session/agent-session.d.ts +4 -0
  55. package/dist/types/startup-splash.d.ts +12 -0
  56. package/dist/types/task/types.d.ts +47 -48
  57. package/dist/types/tools/ask.d.ts +26 -27
  58. package/dist/types/tools/ast-edit.d.ts +17 -17
  59. package/dist/types/tools/ast-grep.d.ts +12 -13
  60. package/dist/types/tools/bash.d.ts +20 -17
  61. package/dist/types/tools/browser.d.ts +46 -71
  62. package/dist/types/tools/checkpoint.d.ts +14 -15
  63. package/dist/types/tools/debug.d.ts +82 -145
  64. package/dist/types/tools/eval.d.ts +30 -40
  65. package/dist/types/tools/find.d.ts +17 -18
  66. package/dist/types/tools/gh.d.ts +49 -78
  67. package/dist/types/tools/image-gen.d.ts +20 -36
  68. package/dist/types/tools/inspect-image.d.ts +10 -11
  69. package/dist/types/tools/irc.d.ts +22 -33
  70. package/dist/types/tools/job.d.ts +11 -12
  71. package/dist/types/tools/learn.d.ts +21 -28
  72. package/dist/types/tools/manage-skill.d.ts +13 -22
  73. package/dist/types/tools/memory-edit.d.ts +15 -24
  74. package/dist/types/tools/memory-recall.d.ts +7 -8
  75. package/dist/types/tools/memory-reflect.d.ts +9 -10
  76. package/dist/types/tools/memory-retain.d.ts +13 -14
  77. package/dist/types/tools/read.d.ts +7 -8
  78. package/dist/types/tools/resolve.d.ts +11 -18
  79. package/dist/types/tools/review.d.ts +9 -15
  80. package/dist/types/tools/search-tool-bm25.d.ts +9 -10
  81. package/dist/types/tools/search.d.ts +16 -17
  82. package/dist/types/tools/ssh.d.ts +14 -15
  83. package/dist/types/tools/todo.d.ts +27 -43
  84. package/dist/types/tools/tts.d.ts +8 -9
  85. package/dist/types/tools/write.d.ts +9 -10
  86. package/dist/types/tui/index.d.ts +1 -0
  87. package/dist/types/tui/width-aware-text.d.ts +23 -0
  88. package/dist/types/utils/markit.d.ts +10 -1
  89. package/dist/types/web/search/index.d.ts +17 -28
  90. package/dist/types/web/search/providers/perplexity.d.ts +0 -2
  91. package/dist/types/web/search/types.d.ts +32 -26
  92. package/package.json +14 -13
  93. package/scripts/omp +1 -1
  94. package/src/advisor/__tests__/advisor.test.ts +44 -1
  95. package/src/advisor/advise-tool.ts +34 -11
  96. package/src/autoresearch/tools/init-experiment.ts +13 -16
  97. package/src/autoresearch/tools/log-experiment.ts +15 -18
  98. package/src/autoresearch/tools/run-experiment.ts +3 -3
  99. package/src/autoresearch/tools/update-notes.ts +4 -4
  100. package/src/cli/ttsr-cli.ts +995 -0
  101. package/src/cli-commands.ts +1 -0
  102. package/src/cli.ts +7 -1
  103. package/src/commands/ttsr.ts +125 -0
  104. package/src/commit/agentic/tools/analyze-file.ts +4 -4
  105. package/src/commit/agentic/tools/git-file-diff.ts +4 -4
  106. package/src/commit/agentic/tools/git-hunk.ts +7 -5
  107. package/src/commit/agentic/tools/git-overview.ts +4 -4
  108. package/src/commit/agentic/tools/propose-changelog.ts +18 -15
  109. package/src/commit/agentic/tools/propose-commit.ts +6 -6
  110. package/src/commit/agentic/tools/recent-commits.ts +3 -3
  111. package/src/commit/agentic/tools/schemas.ts +8 -20
  112. package/src/commit/agentic/tools/split-commit.ts +19 -23
  113. package/src/commit/analysis/summary.ts +7 -5
  114. package/src/commit/changelog/generate.ts +15 -11
  115. package/src/commit/shared-llm.ts +17 -24
  116. package/src/config/config-file.ts +13 -15
  117. package/src/config/keybindings.ts +6 -0
  118. package/src/config/models-config-schema.ts +206 -179
  119. package/src/config/settings-schema.ts +34 -0
  120. package/src/discovery/builtin-rules/index.ts +2 -0
  121. package/src/discovery/builtin-rules/ts-import-type.md +2 -2
  122. package/src/discovery/builtin-rules/ts-no-any.md +11 -2
  123. package/src/discovery/builtin-rules/ts-no-inline-cast-access.md +55 -0
  124. package/src/edit/hashline/params.ts +12 -11
  125. package/src/edit/index.ts +5 -4
  126. package/src/edit/modes/apply-patch.ts +4 -4
  127. package/src/edit/modes/patch.ts +15 -18
  128. package/src/edit/modes/replace.ts +13 -17
  129. package/src/edit/renderer.ts +0 -1
  130. package/src/eval/agent-bridge.ts +11 -13
  131. package/src/eval/completion-bridge.ts +25 -17
  132. package/src/eval/js/context-manager.ts +17 -2
  133. package/src/eval/js/index.ts +1 -1
  134. package/src/eval/py/executor.ts +2 -2
  135. package/src/extensibility/custom-commands/loader.ts +5 -3
  136. package/src/extensibility/custom-commands/types.ts +6 -3
  137. package/src/extensibility/custom-tools/loader.ts +4 -2
  138. package/src/extensibility/custom-tools/types.ts +8 -5
  139. package/src/extensibility/extensions/loader.ts +4 -2
  140. package/src/extensibility/extensions/types.ts +6 -3
  141. package/src/extensibility/hooks/loader.ts +5 -2
  142. package/src/extensibility/hooks/types.ts +7 -4
  143. package/src/extensibility/legacy-pi-ai-shim.ts +42 -5
  144. package/src/extensibility/legacy-pi-coding-agent-shim.ts +113 -0
  145. package/src/extensibility/plugins/legacy-pi-compat.ts +13 -13
  146. package/src/extensibility/tool-proxy.ts +4 -1
  147. package/src/extensibility/typebox.ts +778 -251
  148. package/src/goals/guided-setup.ts +12 -3
  149. package/src/goals/tools/goal-tool.ts +6 -6
  150. package/src/index.ts +2 -0
  151. package/src/internal-urls/docs-index.generated.ts +11 -9
  152. package/src/lsp/types.ts +13 -27
  153. package/src/main.ts +19 -18
  154. package/src/mcp/client.ts +38 -13
  155. package/src/mcp/render.ts +102 -89
  156. package/src/modes/components/agent-hub.ts +11 -4
  157. package/src/modes/components/btw-panel.ts +5 -1
  158. package/src/modes/components/custom-editor.ts +18 -0
  159. package/src/modes/components/status-line/component.ts +8 -1
  160. package/src/modes/components/tool-execution.ts +17 -10
  161. package/src/modes/controllers/btw-controller.ts +69 -1
  162. package/src/modes/controllers/input-controller.ts +29 -0
  163. package/src/modes/interactive-mode.ts +38 -8
  164. package/src/modes/setup-wizard/index.ts +1 -0
  165. package/src/modes/setup-wizard/scenes/sign-in.ts +77 -5
  166. package/src/modes/setup-wizard/startup-splash.ts +107 -0
  167. package/src/modes/theme/theme.ts +133 -143
  168. package/src/modes/types.ts +3 -0
  169. package/src/modes/utils/context-usage.ts +9 -5
  170. package/src/modes/utils/hotkeys-markdown.ts +1 -0
  171. package/src/prompts/system/system-prompt.md +1 -0
  172. package/src/sdk.ts +21 -4
  173. package/src/session/agent-session.ts +160 -33
  174. package/src/session/session-history-format.ts +11 -2
  175. package/src/session/snapcompact-inline.ts +1 -1
  176. package/src/slash-commands/builtin-registry.ts +4 -11
  177. package/src/startup-splash.ts +19 -0
  178. package/src/task/executor.ts +11 -6
  179. package/src/task/types.ts +44 -41
  180. package/src/tool-discovery/tool-index.ts +17 -4
  181. package/src/tools/ask.ts +14 -14
  182. package/src/tools/ast-edit.ts +17 -14
  183. package/src/tools/ast-grep.ts +10 -9
  184. package/src/tools/bash.ts +15 -10
  185. package/src/tools/browser/launch.ts +13 -0
  186. package/src/tools/browser.ts +26 -32
  187. package/src/tools/checkpoint.ts +7 -7
  188. package/src/tools/debug.ts +72 -69
  189. package/src/tools/eval.ts +18 -19
  190. package/src/tools/find.ts +20 -13
  191. package/src/tools/gh.ts +29 -49
  192. package/src/tools/image-gen.ts +27 -32
  193. package/src/tools/inspect-image.ts +8 -9
  194. package/src/tools/irc.ts +12 -12
  195. package/src/tools/job.ts +6 -6
  196. package/src/tools/learn.ts +11 -14
  197. package/src/tools/manage-skill.ts +19 -23
  198. package/src/tools/memory-edit.ts +8 -8
  199. package/src/tools/memory-recall.ts +4 -4
  200. package/src/tools/memory-reflect.ts +5 -5
  201. package/src/tools/memory-retain.ts +9 -11
  202. package/src/tools/puppeteer/02_stealth_hairline.txt +1 -1
  203. package/src/tools/puppeteer/04_stealth_iframe.txt +4 -4
  204. package/src/tools/puppeteer/05_stealth_webgl.txt +1 -1
  205. package/src/tools/puppeteer/10_stealth_plugins.txt +6 -4
  206. package/src/tools/puppeteer/12_stealth_codecs.txt +2 -2
  207. package/src/tools/puppeteer/13_stealth_worker.txt +1 -1
  208. package/src/tools/read.ts +169 -13
  209. package/src/tools/report-tool-issue.ts +6 -6
  210. package/src/tools/resolve.ts +6 -6
  211. package/src/tools/review.ts +10 -12
  212. package/src/tools/search-tool-bm25.ts +5 -5
  213. package/src/tools/search.ts +20 -29
  214. package/src/tools/ssh.ts +8 -8
  215. package/src/tools/todo.ts +16 -19
  216. package/src/tools/tts.ts +16 -15
  217. package/src/tools/write.ts +5 -5
  218. package/src/tui/index.ts +1 -0
  219. package/src/tui/width-aware-text.ts +58 -0
  220. package/src/utils/markit.ts +17 -2
  221. package/src/web/search/index.ts +9 -9
  222. package/src/web/search/providers/perplexity.ts +373 -126
  223. package/src/web/search/types.ts +28 -48
package/src/tools/gh.ts CHANGED
@@ -11,7 +11,7 @@ import type {
11
11
  } from "@oh-my-pi/pi-agent-core";
12
12
 
13
13
  import { getWorktreeDir, hashPath, isEnoent, prompt, untilAborted } from "@oh-my-pi/pi-utils";
14
- import { z } from "zod/v4";
14
+ import { type } from "arktype";
15
15
  import type { Settings } from "../config/settings";
16
16
  import githubDescription from "../prompts/tools/github.md" with { type: "text" };
17
17
  import * as git from "../utils/git";
@@ -255,54 +255,34 @@ const GITHUB_READONLY_OPS: ReadonlySet<string> = new Set([
255
255
  "run_watch",
256
256
  ]);
257
257
 
258
- const githubSchema = z
259
- .object({
260
- op: z
261
- .enum([
262
- "repo_view",
263
- "pr_create",
264
- "pr_checkout",
265
- "pr_push",
266
- "search_issues",
267
- "search_prs",
268
- "search_code",
269
- "search_commits",
270
- "search_repos",
271
- "run_watch",
272
- ] as const)
273
- .describe("github operation"),
274
- repo: z.string().describe("owner/repo").optional(),
275
- branch: z.string().describe("branch").optional(),
276
- pr: z
277
- .union([z.string(), z.array(z.string())])
278
- .describe("pr number, url, or branch")
279
- .optional(),
280
- force: z.boolean().describe("reset existing local branch").optional(),
281
- forceWithLease: z.boolean().describe("force-with-lease push").optional(),
282
- title: z.string().describe("pr title").optional(),
283
- body: z.string().describe("pr body markdown").optional(),
284
- base: z.string().describe("pr base branch").optional(),
285
- head: z.string().describe("pr head branch").optional(),
286
- draft: z.boolean().describe("open pr as draft").optional(),
287
- fill: z.boolean().describe("auto-fill pr title/body from commits").optional(),
288
- reviewer: z.array(z.string()).describe("reviewers").optional(),
289
- assignee: z.array(z.string()).describe("assignees").optional(),
290
- label: z.array(z.string()).describe("labels").optional(),
291
- query: z.string().describe("search query").optional(),
292
- since: z.string().describe("lower-bound date filter").optional(),
293
- until: z.string().describe("upper-bound date filter").optional(),
294
- dateField: z
295
- .enum(["created", "updated"] as const)
296
- .describe("date field")
297
- .default("created")
298
- .optional(),
299
- limit: z.number().default(10).describe("max results").optional(),
300
- run: z.string().describe("actions run id or url").optional(),
301
- tail: z.number().default(15).describe("log lines per failed job").optional(),
302
- })
303
- .strict();
304
-
305
- type GithubInput = z.infer<typeof githubSchema>;
258
+ const githubSchema = type({
259
+ op: type(
260
+ "'repo_view' | 'pr_create' | 'pr_checkout' | 'pr_push' | 'search_issues' | 'search_prs' | 'search_code' | 'search_commits' | 'search_repos' | 'run_watch'",
261
+ ).describe("github operation"),
262
+ "repo?": type("string").describe("owner/repo"),
263
+ "branch?": type("string").describe("branch"),
264
+ "pr?": type("string | string[]").describe("pr number, url, or branch"),
265
+ "force?": type("boolean").describe("reset existing local branch"),
266
+ "forceWithLease?": type("boolean").describe("force-with-lease push"),
267
+ "title?": type("string").describe("pr title"),
268
+ "body?": type("string").describe("pr body markdown"),
269
+ "base?": type("string").describe("pr base branch"),
270
+ "head?": type("string").describe("pr head branch"),
271
+ "draft?": type("boolean").describe("open pr as draft"),
272
+ "fill?": type("boolean").describe("auto-fill pr title/body from commits"),
273
+ "reviewer?": type("string[]").describe("reviewers"),
274
+ "assignee?": type("string[]").describe("assignees"),
275
+ "label?": type("string[]").describe("labels"),
276
+ "query?": type("string").describe("search query"),
277
+ "since?": type("string").describe("lower-bound date filter"),
278
+ "until?": type("string").describe("upper-bound date filter"),
279
+ "dateField?": type("'created' | 'updated'").describe("date field"),
280
+ "limit?": type("number").describe("max results"),
281
+ "run?": type("string").describe("actions run id or url"),
282
+ "tail?": type("number").describe("log lines per failed job"),
283
+ });
284
+
285
+ type GithubInput = typeof githubSchema.infer;
306
286
 
307
287
  export interface GhToolDetails {
308
288
  meta?: OutputMeta;
@@ -19,7 +19,7 @@ import {
19
19
  Snowflake,
20
20
  untilAborted,
21
21
  } from "@oh-my-pi/pi-utils";
22
- import { z } from "zod/v4";
22
+ import { type } from "arktype";
23
23
  import packageJson from "../../package.json" with { type: "json" };
24
24
  import { isAuthenticated, type ModelRegistry } from "../config/model-registry";
25
25
  import { settings } from "../config/settings";
@@ -58,37 +58,32 @@ const XAI_IMAGE_ASPECT_RATIOS = [...COMMON_IMAGE_ASPECT_RATIOS, "3:2", "2:3"] as
58
58
  const COMMON_IMAGE_ASPECT_RATIO_SET = new Set<string>(COMMON_IMAGE_ASPECT_RATIOS);
59
59
  const IMAGE_PROVIDER_PREFERENCES = new Set<string>(["auto", "antigravity", "gemini", "openai", "openrouter", "xai"]);
60
60
 
61
- const responseModalitySchema = z.enum(["IMAGE", "TEXT"] as const);
62
- const aspectRatioSchema = z.enum(XAI_IMAGE_ASPECT_RATIOS).describe("aspect ratio");
63
- const imageSizeSchema = z.enum(["1024x1024", "1536x1024", "1024x1536"] as const).describe("image size");
64
-
65
- const inputImageSchema = z
66
- .object({
67
- path: z.string().describe("input image path").optional(),
68
- data: z.string().describe("base64 image data").optional(),
69
- mime_type: z.string().describe("mime type").optional(),
70
- })
71
- .strict();
72
-
73
- const baseImageSchema = z
74
- .object({
75
- subject: z.string().describe("main subject"),
76
- action: z.string().describe("what subject is doing").optional(),
77
- scene: z.string().describe("location or environment").optional(),
78
- composition: z.string().describe("camera angle and framing").optional(),
79
- lighting: z.string().describe("lighting setup").optional(),
80
- style: z.string().describe("artistic style").optional(),
81
- text: z.string().describe("text to render").optional(),
82
- changes: z.array(z.string()).describe("edits to make").optional(),
83
- aspect_ratio: aspectRatioSchema.optional(),
84
- image_size: imageSizeSchema.optional(),
85
- input: z.array(inputImageSchema).describe("input images").optional(),
86
- })
87
- .strict();
88
-
89
- export const imageGenSchema = baseImageSchema;
90
- export type ImageGenParams = z.infer<typeof imageGenSchema>;
91
- export type GeminiResponseModality = z.infer<typeof responseModalitySchema>;
61
+ const responseModalitySchema = type('"IMAGE" | "TEXT"');
62
+
63
+ const aspectRatioSchema = type.enumerated(...XAI_IMAGE_ASPECT_RATIOS).describe("aspect ratio");
64
+ const imageSizeSchema = type('"1024x1024" | "1536x1024" | "1024x1536"').describe("image size");
65
+
66
+ const inputImageSchema = type({
67
+ "path?": type("string").describe("input image path"),
68
+ "data?": type("string").describe("base64 image data"),
69
+ "mime_type?": type("string").describe("mime type"),
70
+ });
71
+
72
+ export const imageGenSchema = type({
73
+ subject: type("string").describe("main subject"),
74
+ "action?": type("string").describe("what subject is doing"),
75
+ "scene?": type("string").describe("location or environment"),
76
+ "composition?": type("string").describe("camera angle and framing"),
77
+ "lighting?": type("string").describe("lighting setup"),
78
+ "style?": type("string").describe("artistic style"),
79
+ "text?": type("string").describe("text to render"),
80
+ "changes?": type("string[]").describe("edits to make"),
81
+ "aspect_ratio?": aspectRatioSchema,
82
+ "image_size?": imageSizeSchema,
83
+ "input?": inputImageSchema.array().describe("input images"),
84
+ });
85
+ export type ImageGenParams = typeof imageGenSchema.infer;
86
+ export type GeminiResponseModality = typeof responseModalitySchema.infer;
92
87
 
93
88
  /**
94
89
  * Assembles a structured prompt from the provided parameters.
@@ -2,7 +2,7 @@ import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallb
2
2
  import { instrumentedCompleteSimple, resolveTelemetry } from "@oh-my-pi/pi-agent-core";
3
3
  import { type Api, completeSimple, type Model, type ToolExample } from "@oh-my-pi/pi-ai";
4
4
  import { prompt } from "@oh-my-pi/pi-utils";
5
- import { z } from "zod/v4";
5
+ import { type } from "arktype";
6
6
  import { extractTextContent } from "../commit/utils";
7
7
 
8
8
  import { expandRoleAlias, getModelMatchPreferences, resolveModelFromString } from "../config/model-resolver";
@@ -18,14 +18,13 @@ import {
18
18
  import type { ToolSession } from "./index";
19
19
  import { ToolError } from "./tool-errors";
20
20
 
21
- const inspectImageSchema = z
22
- .object({
23
- path: z.string().describe("image path"),
24
- question: z.string().describe("question about image"),
25
- })
26
- .strict();
21
+ const inspectImageSchema = type({
22
+ path: type("string").describe("image path"),
23
+ question: type("string").describe("question about image"),
24
+ "+": "reject",
25
+ });
27
26
 
28
- export type InspectImageParams = z.infer<typeof inspectImageSchema>;
27
+ export type InspectImageParams = typeof inspectImageSchema.infer;
29
28
 
30
29
  export interface InspectImageToolDetails {
31
30
  model: string;
@@ -43,7 +42,7 @@ export class InspectImageTool implements AgentTool<typeof inspectImageSchema, In
43
42
  readonly parameters = inspectImageSchema;
44
43
  readonly strict = false;
45
44
 
46
- readonly examples: readonly ToolExample<z.input<typeof inspectImageSchema>>[] = [
45
+ readonly examples: readonly ToolExample<typeof inspectImageSchema.infer>[] = [
47
46
  {
48
47
  caption: "OCR with strict formatting",
49
48
  call: {
package/src/tools/irc.ts CHANGED
@@ -13,7 +13,7 @@ import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallb
13
13
  import type { ToolExample } from "@oh-my-pi/pi-ai";
14
14
  import { type Component, Text } from "@oh-my-pi/pi-tui";
15
15
  import { formatAge, formatDuration, prompt } from "@oh-my-pi/pi-utils";
16
- import { z } from "zod/v4";
16
+ import { type } from "arktype";
17
17
  import type { Settings } from "../config/settings";
18
18
  import type { RenderResultOptions } from "../extensibility/custom-tools/types";
19
19
  import { IrcBus, type IrcDeliveryReceipt, type IrcMessage } from "../irc/bus";
@@ -49,18 +49,18 @@ export function isIrcEnabled(settings: Settings, taskDepth: number): boolean {
49
49
  return canSpawnAtDepth(maxDepth, taskDepth);
50
50
  }
51
51
 
52
- const ircSchema = z.object({
53
- op: z.enum(["send", "wait", "inbox", "list"]).describe("irc operation"),
54
- to: z.string().optional().describe('send: recipient agent id or "all"'),
55
- message: z.string().optional().describe("send: message body"),
56
- replyTo: z.string().optional().describe("send: message id being answered"),
57
- await: z.boolean().optional().describe('send: wait for the recipient\'s reply (invalid with to:"all")'),
58
- from: z.string().optional().describe("wait: only accept a message from this agent id"),
59
- timeoutMs: z.number().optional().describe("wait: timeout in milliseconds (0 waits indefinitely)"),
60
- peek: z.boolean().optional().describe("inbox: list messages without consuming them"),
52
+ const ircSchema = type({
53
+ op: type("'send' | 'wait' | 'inbox' | 'list'").describe("irc operation"),
54
+ "to?": type("string").describe('send: recipient agent id or "all"'),
55
+ "message?": type("string").describe("send: message body"),
56
+ "replyTo?": type("string").describe("send: message id being answered"),
57
+ "await?": type("boolean").describe('send: wait for the recipient\'s reply (invalid with to:"all")'),
58
+ "from?": type("string").describe("wait: only accept a message from this agent id"),
59
+ "timeoutMs?": type("number").describe("wait: timeout in milliseconds (0 waits indefinitely)"),
60
+ "peek?": type("boolean").describe("inbox: list messages without consuming them"),
61
61
  });
62
62
 
63
- type IrcParams = z.infer<typeof ircSchema>;
63
+ type IrcParams = typeof ircSchema.infer;
64
64
 
65
65
  interface IrcPeerInfo {
66
66
  id: string;
@@ -98,7 +98,7 @@ export class IrcTool implements AgentTool<typeof ircSchema, IrcDetails> {
98
98
  readonly parameters = ircSchema;
99
99
  readonly strict = true;
100
100
 
101
- readonly examples: readonly ToolExample<z.input<typeof ircSchema>>[] = [
101
+ readonly examples: readonly ToolExample<typeof ircSchema.infer>[] = [
102
102
  {
103
103
  caption: "List peers",
104
104
  call: { op: "list" },
package/src/tools/job.ts CHANGED
@@ -2,7 +2,7 @@ import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallb
2
2
  import type { Component } from "@oh-my-pi/pi-tui";
3
3
  import { Text } from "@oh-my-pi/pi-tui";
4
4
  import { prompt } from "@oh-my-pi/pi-utils";
5
- import { z } from "zod/v4";
5
+ import { type } from "arktype";
6
6
  import type { AsyncJob, AsyncJobManager } from "../async";
7
7
  import type { RenderResultOptions } from "../extensibility/custom-tools/types";
8
8
  import { shimmerEnabled, shimmerText } from "../modes/theme/shimmer";
@@ -23,13 +23,13 @@ import {
23
23
  } from "./render-utils";
24
24
  import { ToolError } from "./tool-errors";
25
25
 
26
- const jobSchema = z.object({
27
- poll: z.array(z.string()).optional().describe("job ids to wait for; omit to wait on all running jobs"),
28
- cancel: z.array(z.string()).optional().describe("job ids to cancel"),
29
- list: z.boolean().optional().describe("snapshot all jobs"),
26
+ const jobSchema = type({
27
+ "poll?": type("string[]").describe("job ids to wait for; omit to wait on all running jobs"),
28
+ "cancel?": type("string[]").describe("job ids to cancel"),
29
+ "list?": type("boolean").describe("snapshot all jobs"),
30
30
  });
31
31
 
32
- type JobParams = z.infer<typeof jobSchema>;
32
+ type JobParams = typeof jobSchema.infer;
33
33
 
34
34
  const WAIT_DURATION_MS: Record<string, number> = {
35
35
  "5s": 5_000,
@@ -1,26 +1,23 @@
1
1
  import type { AgentTool, AgentToolResult } from "@oh-my-pi/pi-agent-core";
2
- import { z } from "zod/v4";
2
+ import { type } from "arktype";
3
3
  import { sanitizeSkillName, writeManagedSkill } from "../autolearn/managed-skills";
4
4
  import { isNameClaimedByAuthoredSkill } from "../extensibility/skills";
5
5
  import { localBackend } from "../memory-backend/local-backend";
6
6
  import learnDescription from "../prompts/tools/learn.md" with { type: "text" };
7
7
  import type { ToolSession } from ".";
8
8
 
9
- const learnSchema = z.object({
10
- memory: z.string().describe("the durable, self-contained lesson to remember (what, when, why)"),
11
- context: z.string().describe("optional source context for the lesson").optional(),
12
- skill: z
13
- .object({
14
- action: z.enum(["create", "update"]),
15
- name: z.string().describe("kebab-case skill name"),
16
- description: z.string().describe("one-line description of when to use the skill"),
17
- body: z.string().describe("the SKILL.md body in markdown (no frontmatter)"),
18
- })
19
- .describe("also create or enhance a managed skill in the same call")
20
- .optional(),
9
+ const learnSchema = type({
10
+ memory: type("string").describe("the durable, self-contained lesson to remember (what, when, why)"),
11
+ "context?": type("string").describe("optional source context for the lesson"),
12
+ "skill?": type({
13
+ action: "'create' | 'update'",
14
+ name: type("string").describe("kebab-case skill name"),
15
+ description: type("string").describe("one-line description of when to use the skill"),
16
+ body: type("string").describe("the SKILL.md body in markdown (no frontmatter)"),
17
+ }).describe("also create or enhance a managed skill in the same call"),
21
18
  });
22
19
 
23
- export type LearnParams = z.infer<typeof learnSchema>;
20
+ export type LearnParams = typeof learnSchema.infer;
24
21
 
25
22
  /**
26
23
  * Orchestrating "learn" tool: persists a lesson to long-term memory and,
@@ -1,6 +1,6 @@
1
1
  import * as path from "node:path";
2
2
  import type { AgentTool, AgentToolResult } from "@oh-my-pi/pi-agent-core";
3
- import { z } from "zod/v4";
3
+ import { type } from "arktype";
4
4
  import {
5
5
  deleteManagedSkill,
6
6
  getManagedSkillsDir,
@@ -11,29 +11,25 @@ import { isNameClaimedByAuthoredSkill } from "../extensibility/skills";
11
11
  import manageSkillDescription from "../prompts/tools/manage-skill.md" with { type: "text" };
12
12
  import type { ToolSession } from ".";
13
13
 
14
- const manageSkillSchema = z
15
- .object({
16
- action: z.enum(["create", "update", "delete"]),
17
- name: z.string().describe("kebab-case skill name"),
18
- description: z
19
- .string()
20
- .describe("one-line description of when to use the skill (required for create/update)")
21
- .optional(),
22
- body: z
23
- .string()
24
- .describe("the SKILL.md body in markdown, no frontmatter (required for create/update)")
25
- .optional(),
26
- })
27
- // Enforce the action/field contract at validation time rather than only in
28
- // execute. Kept as a cross-field refine (not a discriminated union) so the
29
- // wire schema stays a single root object strict structured-output mode and
30
- // the Anthropic tool-schema builder both require that.
31
- .refine(p => p.action === "delete" || (p.description !== undefined && p.body !== undefined), {
32
- message: '"create" and "update" require both "description" and "body".',
33
- path: ["description"],
34
- });
14
+ const manageSkillSchema = type({
15
+ action: "'create' | 'update' | 'delete'",
16
+ name: type("string").describe("kebab-case skill name"),
17
+ "description?": type("string").describe(
18
+ "one-line description of when to use the skill (required for create/update)",
19
+ ),
20
+ "body?": type("string").describe("the SKILL.md body in markdown, no frontmatter (required for create/update)"),
21
+ }).narrow(
22
+ (p, ctx) =>
23
+ p.action === "delete" ||
24
+ (p.description !== undefined && p.body !== undefined) ||
25
+ // Enforce the action/field contract at validation time rather than only in
26
+ // execute. Kept as a cross-field narrow (not a discriminated union) so the
27
+ // wire schema stays a single root object strict structured-output mode and
28
+ // the Anthropic tool-schema builder both require that.
29
+ ctx.mustBe('used with both "description" and "body" for "create" and "update"'),
30
+ );
35
31
 
36
- export type ManageSkillParams = z.infer<typeof manageSkillSchema>;
32
+ export type ManageSkillParams = typeof manageSkillSchema.infer;
37
33
 
38
34
  /**
39
35
  * Direct create/update/delete of isolated managed skills. Gated behind
@@ -1,17 +1,17 @@
1
1
  import type { AgentTool, AgentToolResult } from "@oh-my-pi/pi-agent-core";
2
- import { z } from "zod/v4";
2
+ import { type } from "arktype";
3
3
  import memoryEditDescription from "../prompts/tools/memory-edit.md" with { type: "text" };
4
4
  import type { ToolSession } from ".";
5
5
 
6
- const memoryEditSchema = z.object({
7
- op: z.enum(["update", "forget", "invalidate"]).describe("memory edit operation"),
8
- id: z.string().describe("memory id from recall output"),
9
- content: z.string().optional().describe("replacement content for update"),
10
- importance: z.number().optional().describe("replacement importance for update, clamped to [0, 1]"),
11
- replacement_id: z.string().optional().describe("replacement memory id for invalidate"),
6
+ const memoryEditSchema = type({
7
+ op: type("'update' | 'forget' | 'invalidate'").describe("memory edit operation"),
8
+ id: type("string").describe("memory id from recall output"),
9
+ "content?": type("string").describe("replacement content for update"),
10
+ "importance?": type("number").describe("replacement importance for update, clamped to [0, 1]"),
11
+ "replacement_id?": type("string").describe("replacement memory id for invalidate"),
12
12
  });
13
13
 
14
- export type MemoryEditParams = z.infer<typeof memoryEditSchema>;
14
+ export type MemoryEditParams = typeof memoryEditSchema.infer;
15
15
 
16
16
  export class MemoryEditTool implements AgentTool<typeof memoryEditSchema> {
17
17
  readonly name = "memory_edit";
@@ -1,15 +1,15 @@
1
1
  import type { AgentTool, AgentToolResult } from "@oh-my-pi/pi-agent-core";
2
2
  import { logger, untilAborted } from "@oh-my-pi/pi-utils";
3
- import { z } from "zod/v4";
3
+ import { type } from "arktype";
4
4
  import { formatCurrentTime, formatMemories } from "../hindsight/content";
5
5
  import recallDescription from "../prompts/tools/recall.md" with { type: "text" };
6
6
  import type { ToolSession } from ".";
7
7
 
8
- const memoryRecallSchema = z.object({
9
- query: z.string().describe("natural language search query"),
8
+ const memoryRecallSchema = type({
9
+ query: type("string").describe("natural language search query"),
10
10
  });
11
11
 
12
- export type MemoryRecallParams = z.infer<typeof memoryRecallSchema>;
12
+ export type MemoryRecallParams = typeof memoryRecallSchema.infer;
13
13
 
14
14
  export class MemoryRecallTool implements AgentTool<typeof memoryRecallSchema> {
15
15
  readonly name = "recall";
@@ -1,16 +1,16 @@
1
1
  import type { AgentTool, AgentToolResult } from "@oh-my-pi/pi-agent-core";
2
2
  import { logger, untilAborted } from "@oh-my-pi/pi-utils";
3
- import { z } from "zod/v4";
3
+ import { type } from "arktype";
4
4
  import { ensureBankExists } from "../hindsight/bank";
5
5
  import reflectDescription from "../prompts/tools/reflect.md" with { type: "text" };
6
6
  import type { ToolSession } from ".";
7
7
 
8
- const memoryReflectSchema = z.object({
9
- query: z.string().describe("question to answer"),
10
- context: z.string().describe("optional context").optional(),
8
+ const memoryReflectSchema = type({
9
+ query: type("string").describe("question to answer"),
10
+ "context?": type("string").describe("optional context"),
11
11
  });
12
12
 
13
- export type MemoryReflectParams = z.infer<typeof memoryReflectSchema>;
13
+ export type MemoryReflectParams = typeof memoryReflectSchema.infer;
14
14
 
15
15
  export class MemoryReflectTool implements AgentTool<typeof memoryReflectSchema> {
16
16
  readonly name = "reflect";
@@ -1,21 +1,19 @@
1
1
  import type { AgentTool, AgentToolResult } from "@oh-my-pi/pi-agent-core";
2
- import { z } from "zod/v4";
2
+ import { type } from "arktype";
3
3
  import retainDescription from "../prompts/tools/retain.md" with { type: "text" };
4
4
  import type { ToolSession } from ".";
5
5
 
6
- const memoryRetainSchema = z.object({
7
- items: z
8
- .array(
9
- z.object({
10
- content: z.string().describe("information to remember"),
11
- context: z.string().describe("source context").optional(),
12
- }),
13
- )
14
- .min(1)
6
+ const memoryRetainSchema = type({
7
+ items: type({
8
+ content: type("string").describe("information to remember"),
9
+ "context?": type("string").describe("source context"),
10
+ })
11
+ .array()
12
+ .atLeastLength(1)
15
13
  .describe("memories to retain"),
16
14
  });
17
15
 
18
- export type MemoryRetainParams = z.infer<typeof memoryRetainSchema>;
16
+ export type MemoryRetainParams = typeof memoryRetainSchema.infer;
19
17
  export class MemoryRetainTool implements AgentTool<typeof memoryRetainSchema> {
20
18
  readonly name = "retain";
21
19
  readonly approval = "read" as const;
@@ -6,6 +6,6 @@ Object_defineProperty(HTMLDivElement.prototype, "offsetHeight", {
6
6
  ...elementDescriptor,
7
7
  get: function () {
8
8
  if (this.id === "modernizr") return 1;
9
- return elementDescriptor.get.apply(this);
9
+ return Reflect_apply(elementDescriptor.get, this, []);
10
10
  },
11
11
  });
@@ -4,7 +4,7 @@ const addContentWindowProxy = (iframe) => {
4
4
  if (key === "self") return this;
5
5
  if (key === "frameElement") return iframe;
6
6
  if (key === "0") return undefined;
7
- return Reflect.get(target, key);
7
+ return Reflect_get(target, key);
8
8
  },
9
9
  };
10
10
 
@@ -24,7 +24,7 @@ const addContentWindowProxy = (iframe) => {
24
24
  };
25
25
 
26
26
  const handleIframeCreation = (target, thisArg, args) => {
27
- const iframe = target.apply(thisArg, args);
27
+ const iframe = Reflect_apply(target, thisArg, args);
28
28
  const originalIframe = iframe;
29
29
  const originalSrcdoc = originalIframe.srcdoc;
30
30
 
@@ -53,12 +53,12 @@ const addIframeCreationSniffer = () => {
53
53
  apply(target, thisArg, args) {
54
54
  const isIframe = args && args.length && `${args[0]}`.toLowerCase() === "iframe";
55
55
  if (!isIframe) {
56
- return target.apply(thisArg, args);
56
+ return Reflect_apply(target, thisArg, args);
57
57
  }
58
58
  return handleIframeCreation(target, thisArg, args);
59
59
  },
60
60
  get(target, key) {
61
- return Reflect.get(target, key);
61
+ return Reflect_get(target, key);
62
62
  },
63
63
  };
64
64
 
@@ -22,7 +22,7 @@ const getParameterProxyHandler = {
22
22
  if (param === 0x9245) return vendor;
23
23
  // UNMASKED_RENDERER_WEBGL = 0x9246
24
24
  if (param === 0x9246) return renderer;
25
- return target.apply(thisArg, args);
25
+ return Reflect_apply(target, thisArg, args);
26
26
  },
27
27
  };
28
28
 
@@ -113,11 +113,13 @@ const generateMagicArray = (dataArray, proto, itemProto, itemMainProp) => {
113
113
  const blacklist = [...Object_keys(data), "length", "enabledPlugin"];
114
114
  return new Window_Proxy(obj, {
115
115
  ownKeys(target) {
116
- return Reflect.ownKeys(target).filter(key => !blacklist.includes(key));
116
+ return [...Object_getOwnPropertyNames(target), ...Object.getOwnPropertySymbols(target)].filter(
117
+ key => !blacklist.includes(key),
118
+ );
117
119
  },
118
120
  getOwnPropertyDescriptor(target, prop) {
119
121
  if (blacklist.includes(prop)) return undefined;
120
- return Reflect.getOwnPropertyDescriptor(target, prop);
122
+ return Object_getOwnPropertyDescriptor(target, prop);
121
123
  },
122
124
  });
123
125
  };
@@ -148,7 +150,7 @@ const generateMagicArray = (dataArray, proto, itemProto, itemMainProp) => {
148
150
  if (key === "item") return functionMocks.item;
149
151
  if (key === "namedItem") return functionMocks.namedItem;
150
152
  if (proto === PluginArray.prototype && key === "refresh") return functionMocks.refresh;
151
- return Reflect.get(target, key);
153
+ return Reflect_get(target, key);
152
154
  },
153
155
  ownKeys(target) {
154
156
  const keys = [];
@@ -159,7 +161,7 @@ const generateMagicArray = (dataArray, proto, itemProto, itemMainProp) => {
159
161
  },
160
162
  getOwnPropertyDescriptor(target, prop) {
161
163
  if (prop === "length") return undefined;
162
- return Reflect.getOwnPropertyDescriptor(target, prop);
164
+ return Object_getOwnPropertyDescriptor(target, prop);
163
165
  },
164
166
  });
165
167
  };
@@ -19,7 +19,7 @@ Object_defineProperty(HTMLMediaElement.prototype, "canPlayType", {
19
19
  value: new Window_Proxy(originalCanPlayType, {
20
20
  apply(target, ctx, args) {
21
21
  if (!args || !args.length) {
22
- return target.apply(ctx, args);
22
+ return Reflect_apply(target, ctx, args);
23
23
  }
24
24
  const { mime, codecs } = parseInput(args[0]);
25
25
  if (mime === "video/mp4" && codecs.includes("avc1.42E01E")) {
@@ -31,7 +31,7 @@ Object_defineProperty(HTMLMediaElement.prototype, "canPlayType", {
31
31
  if (mime === "audio/aac" && !codecs.length) {
32
32
  return "probably";
33
33
  }
34
- return target.apply(ctx, args);
34
+ return Reflect_apply(target, ctx, args);
35
35
  },
36
36
  }),
37
37
  writable: true,
@@ -50,7 +50,7 @@ const patchWorkerConstructor = (name, OriginalWorker) => {
50
50
  }
51
51
  },
52
52
  apply(target, thisArg, args) {
53
- return Reflect.apply(target, thisArg, args || []);
53
+ return Reflect_apply(target, thisArg, args || []);
54
54
  },
55
55
  };
56
56