@oh-my-pi/pi-coding-agent 15.8.3 → 15.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/CHANGELOG.md +74 -31
  2. package/dist/types/capability/skill.d.ts +7 -0
  3. package/dist/types/config/settings-schema.d.ts +36 -22
  4. package/dist/types/debug/protocol-probe.d.ts +38 -0
  5. package/dist/types/debug/terminal-info.d.ts +34 -0
  6. package/dist/types/export/html/template.generated.d.ts +1 -1
  7. package/dist/types/extensibility/custom-tools/types.d.ts +1 -1
  8. package/dist/types/extensibility/extensions/types.d.ts +11 -0
  9. package/dist/types/extensibility/shared-events.d.ts +1 -1
  10. package/dist/types/index.d.ts +1 -0
  11. package/dist/types/mcp/transports/stdio.d.ts +16 -7
  12. package/dist/types/modes/components/assistant-message.d.ts +3 -2
  13. package/dist/types/modes/components/hook-selector.d.ts +11 -0
  14. package/dist/types/modes/components/todo-reminder.d.ts +1 -1
  15. package/dist/types/modes/components/transcript-container.d.ts +36 -0
  16. package/dist/types/modes/interactive-mode.d.ts +2 -1
  17. package/dist/types/modes/rpc/rpc-types.d.ts +1 -1
  18. package/dist/types/modes/theme/theme.d.ts +20 -1
  19. package/dist/types/plan-mode/plan-handoff.d.ts +20 -0
  20. package/dist/types/session/agent-session.d.ts +1 -1
  21. package/dist/types/session/indexed-session-storage.d.ts +59 -0
  22. package/dist/types/session/redis-session-storage.d.ts +12 -85
  23. package/dist/types/session/session-manager.d.ts +20 -0
  24. package/dist/types/session/session-storage.d.ts +5 -7
  25. package/dist/types/session/sql-session-storage.d.ts +16 -85
  26. package/dist/types/task/executor.d.ts +9 -0
  27. package/dist/types/task/index.d.ts +3 -1
  28. package/dist/types/telemetry-export.d.ts +19 -0
  29. package/dist/types/tiny/compiled-runtime.d.ts +35 -0
  30. package/dist/types/tools/ask.d.ts +1 -0
  31. package/dist/types/tools/index.d.ts +4 -2
  32. package/dist/types/tools/path-utils.d.ts +1 -1
  33. package/dist/types/tools/search.d.ts +2 -2
  34. package/dist/types/tools/{todo-write.d.ts → todo.d.ts} +18 -18
  35. package/dist/types/utils/session-color.d.ts +7 -2
  36. package/dist/types/web/search/index.d.ts +1 -1
  37. package/dist/types/web/search/provider.d.ts +2 -2
  38. package/dist/types/web/search/types.d.ts +65 -1
  39. package/package.json +15 -9
  40. package/scripts/build-binary.ts +12 -0
  41. package/src/capability/skill.ts +7 -0
  42. package/src/cli/args.ts +1 -1
  43. package/src/config/settings-schema.ts +22 -55
  44. package/src/debug/index.ts +67 -1
  45. package/src/debug/protocol-probe.ts +267 -0
  46. package/src/debug/terminal-info.ts +127 -0
  47. package/src/export/html/template.generated.ts +1 -1
  48. package/src/export/html/template.js +3 -3
  49. package/src/extensibility/custom-tools/types.ts +1 -1
  50. package/src/extensibility/extensions/types.ts +11 -0
  51. package/src/extensibility/shared-events.ts +1 -1
  52. package/src/extensibility/skills.ts +3 -3
  53. package/src/index.ts +1 -0
  54. package/src/internal-urls/docs-index.generated.ts +7 -7
  55. package/src/main.ts +12 -0
  56. package/src/mcp/transports/stdio.ts +37 -12
  57. package/src/modes/acp/acp-event-mapper.ts +7 -7
  58. package/src/modes/components/assistant-message.ts +3 -2
  59. package/src/modes/components/hook-selector.ts +149 -14
  60. package/src/modes/components/session-selector.ts +36 -5
  61. package/src/modes/components/status-line/segments.ts +2 -1
  62. package/src/modes/components/status-line.ts +1 -1
  63. package/src/modes/components/tips.txt +1 -1
  64. package/src/modes/components/todo-reminder.ts +1 -1
  65. package/src/modes/components/tool-execution.ts +9 -4
  66. package/src/modes/components/transcript-container.ts +91 -0
  67. package/src/modes/controllers/event-controller.ts +12 -7
  68. package/src/modes/controllers/extension-ui-controller.ts +3 -0
  69. package/src/modes/controllers/todo-command-controller.ts +1 -1
  70. package/src/modes/interactive-mode.ts +18 -6
  71. package/src/modes/print-mode.ts +5 -0
  72. package/src/modes/rpc/rpc-types.ts +1 -1
  73. package/src/modes/theme/theme.ts +48 -8
  74. package/src/modes/utils/ui-helpers.ts +1 -0
  75. package/src/plan-mode/plan-handoff.ts +37 -0
  76. package/src/priority.json +4 -0
  77. package/src/prompts/goals/goal-continuation.md +1 -1
  78. package/src/prompts/system/eager-todo.md +3 -3
  79. package/src/prompts/system/orchestrate-notice.md +5 -5
  80. package/src/prompts/system/plan-mode-approved.md +14 -17
  81. package/src/prompts/system/plan-mode-reference.md +3 -6
  82. package/src/prompts/system/subagent-system-prompt.md +11 -0
  83. package/src/prompts/system/workflow-notice.md +1 -1
  84. package/src/prompts/tools/browser.md +5 -2
  85. package/src/prompts/tools/search.md +1 -1
  86. package/src/prompts/tools/task.md +3 -1
  87. package/src/prompts/tools/{todo-write.md → todo.md} +5 -5
  88. package/src/sdk.ts +1 -0
  89. package/src/session/agent-session.ts +14 -14
  90. package/src/session/indexed-session-storage.ts +430 -0
  91. package/src/session/redis-session-storage.ts +66 -377
  92. package/src/session/session-manager.ts +102 -22
  93. package/src/session/session-storage.ts +148 -68
  94. package/src/session/sql-session-storage.ts +131 -382
  95. package/src/slash-commands/helpers/todo.ts +2 -2
  96. package/src/task/executor.ts +9 -1
  97. package/src/task/index.ts +51 -1
  98. package/src/telemetry-export.ts +126 -0
  99. package/src/tiny/compiled-runtime.ts +179 -0
  100. package/src/tiny/worker.ts +24 -2
  101. package/src/tools/ask.ts +133 -87
  102. package/src/tools/fetch.ts +17 -4
  103. package/src/tools/find.ts +2 -2
  104. package/src/tools/index.ts +6 -4
  105. package/src/tools/path-utils.ts +16 -7
  106. package/src/tools/renderers.ts +2 -2
  107. package/src/tools/search.ts +6 -3
  108. package/src/tools/{todo-write.ts → todo.ts} +32 -35
  109. package/src/utils/session-color.ts +39 -14
  110. package/src/web/search/index.ts +1 -1
  111. package/src/web/search/provider.ts +18 -34
  112. package/src/web/search/types.ts +73 -32
@@ -1,16 +1,16 @@
1
- import type { SessionStorage, SessionStorageStat, SessionStorageWriter } from "./session-storage";
1
+ import { IndexedSessionStorage, type SessionStorageBackend } from "./indexed-session-storage";
2
2
  /**
3
3
  * Supported `bun:sql` adapter dialects. `Bun.SQL` reports this string on
4
4
  * `client.options.adapter`; we detect it once at construction and pick the
5
- * correct DDL / upsert / concat syntax for the underlying engine.
5
+ * correct DDL / upsert / concat / byte-slice syntax for the underlying engine.
6
6
  */
7
7
  export type SqlSessionStorageAdapter = "postgres" | "mysql" | "sqlite";
8
8
  /**
9
9
  * Minimal subset of the `Bun.SQL` instance surface used by
10
- * {@link SqlSessionStorage}. The real client exposes a callable
11
- * tagged-template too; we only ever call `unsafe()` so the contract here is
12
- * narrow making it trivial to swap in a test double or wrap a pooled
13
- * client.
10
+ * {@link SqlSessionStorage}. Bun's SQL client exposes a tagged-template API too,
11
+ * but this implementation intentionally uses `unsafe(query, values)` because
12
+ * the table identifier is validated and then inlined while values remain bound
13
+ * parameters.
14
14
  */
15
15
  export interface SqlSessionStorageClient {
16
16
  unsafe(query: string, values?: unknown[]): Promise<unknown[]>;
@@ -50,92 +50,23 @@ export interface SqlSessionStorageOptions {
50
50
  }
51
51
  /**
52
52
  * SQL-backed implementation of {@link SessionStorage} using `bun:sql`. Each
53
- * session JSONL file maps to a row keyed by `path`; one table stores
54
- * everything.
53
+ * session JSONL file maps to a row keyed by `path`; one table stores the file
54
+ * contents while this process keeps only a metadata index (`size`, `mtimeMs`) in
55
+ * memory for synchronous `existsSync` / `statSync` / `listFilesSync` calls.
55
56
  *
56
57
  * Works against PostgreSQL, MySQL/MariaDB, and SQLite by selecting the
57
- * dialect-correct DDL, upsert, and string-concat syntax at construction.
58
- *
59
- * Trade-offs vs `FileSessionStorage`:
60
- * - An in-memory mirror is loaded on construction so the interface's
61
- * synchronous methods (`existsSync`, `statSync`, `listFilesSync`, …) keep
62
- * their contracts; `bun:sql` is async only. Mirror state is process-local,
63
- * matching `FileSessionStorage`'s existing single-writer assumption — peer
64
- * processes need {@link refresh} to pick up out-of-band writes.
65
- * - `writeLineSync` updates the mirror synchronously and queues an async
66
- * upsert that appends the line to the existing row (or inserts it as the
67
- * first chunk). The promise is awaited by `flush()` / `close()` /
68
- * {@link drain}. A SIGKILL between the sync mirror update and the network
69
- * round-trip loses the last line.
70
- * - Blobs (image data) and tool artifact files still live on disk via
71
- * `BlobStore` / `ArtifactManager`. Those are out of scope for this storage.
58
+ * dialect-correct DDL, upsert, string-concat, byte-length, and byte-slice syntax
59
+ * at construction.
72
60
  */
73
- export declare class SqlSessionStorage implements SessionStorage {
61
+ export declare class SqlSessionStorage extends IndexedSessionStorage {
74
62
  #private;
75
- private constructor();
63
+ constructor(backend: SessionStorageBackend, adapter: SqlSessionStorageAdapter, table: string);
76
64
  /**
77
- * Apply the dialect-correct DDL (unless `createTable: false` is set) and
78
- * warm the in-memory mirror with every existing row. Must be awaited
79
- * before passing the storage into `SessionManager.create()`.
65
+ * Apply the dialect-correct DDL (unless `createTable: false` is set) and warm
66
+ * the metadata index with every existing row. Must be awaited before passing
67
+ * the storage into `SessionManager.create()`.
80
68
  */
81
69
  static create(options: SqlSessionStorageOptions): Promise<SqlSessionStorage>;
82
70
  get adapter(): SqlSessionStorageAdapter;
83
71
  get table(): string;
84
- /**
85
- * Re-load the mirror from the database. Call this from a different
86
- * process that took over the table, or after an out-of-band write made
87
- * by another agent.
88
- */
89
- refresh(): Promise<void>;
90
- /**
91
- * Resolve once every pending background write (issued via `writeTextSync`
92
- * or `writer.writeLineSync`) has been acknowledged by the database.
93
- * Throws if any background write failed since the last drain. Call on
94
- * graceful shutdown to avoid losing the last unflushed line.
95
- */
96
- drain(): Promise<void>;
97
- ensureDirSync(_dir: string): void;
98
- existsSync(path: string): boolean;
99
- writeTextSync(path: string, content: string): void;
100
- readTextSync(path: string): string;
101
- statSync(path: string): SessionStorageStat;
102
- listFilesSync(dir: string, pattern: string): string[];
103
- exists(path: string): Promise<boolean>;
104
- readText(path: string): Promise<string>;
105
- readTextPrefix(path: string, maxBytes: number): Promise<string>;
106
- writeText(path: string, content: string): Promise<void>;
107
- rename(src: string, dst: string): Promise<void>;
108
- unlink(path: string): Promise<void>;
109
- deleteSessionWithArtifacts(sessionPath: string): Promise<void>;
110
- openWriter(path: string, options?: {
111
- flags?: "a" | "w";
112
- onError?: (err: Error) => void;
113
- }): SessionStorageWriter;
114
- _writerClosed(writer: SqlSessionStorageWriter): void;
115
- _mirrorAppend(path: string, line: string): {
116
- content: string;
117
- mtimeMs: number;
118
- };
119
- _mirrorTruncate(path: string): void;
120
- _remoteTruncate(path: string): Promise<void>;
121
- /**
122
- * Append a chunk to the row at `path`, inserting if the row doesn't
123
- * exist yet. Single round-trip via the dialect-specific `upsertAppend`.
124
- */
125
- _remoteAppend(path: string, line: string, mtimeMs: number): Promise<void>;
126
- _attachPending(promise: Promise<void>): void;
127
- }
128
- declare class SqlSessionStorageWriter implements SessionStorageWriter {
129
- #private;
130
- constructor(storage: SqlSessionStorage, path: string, options?: {
131
- flags?: "a" | "w";
132
- onError?: (err: Error) => void;
133
- });
134
- writeLineSync(line: string): void;
135
- writeLine(line: string): Promise<void>;
136
- flush(): Promise<void>;
137
- fsync(): Promise<void>;
138
- close(): Promise<void>;
139
- getError(): Error | undefined;
140
72
  }
141
- export {};
@@ -26,6 +26,15 @@ export interface ExecutorOptions {
26
26
  task: string;
27
27
  assignment?: string;
28
28
  context?: string;
29
+ /**
30
+ * The session's active overall plan, handed off so subagents spawned during
31
+ * plan execution share the same plan context as the main agent. Omitted when
32
+ * the session did not start with a plan (or while plan mode is still active).
33
+ */
34
+ planReference?: {
35
+ path: string;
36
+ content: string;
37
+ };
29
38
  description?: string;
30
39
  index: number;
31
40
  id: string;
@@ -1,7 +1,7 @@
1
1
  import type { AgentTool, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
2
2
  import type { ToolSession } from "..";
3
3
  import type { Theme } from "../modes/theme/theme";
4
- import { type TaskToolDetails, type TaskToolSchemaInstance } from "./types";
4
+ import { type AgentDefinition, type TaskToolDetails, type TaskToolSchemaInstance } from "./types";
5
5
  import "../tools/review";
6
6
  import { renderResult, renderCall as renderTaskCall } from "./render";
7
7
  export { loadBundledAgents as BUNDLED_AGENTS } from "./agents";
@@ -10,6 +10,8 @@ export { discoverAgents, getAgent } from "./discovery";
10
10
  export { AgentOutputManager } from "./output-manager";
11
11
  export type { AgentDefinition, AgentProgress, SingleResult, SubagentLifecyclePayload, SubagentProgressPayload, TaskParams, TaskToolDetails, } from "./types";
12
12
  export { TASK_SUBAGENT_EVENT_CHANNEL, TASK_SUBAGENT_LIFECYCLE_CHANNEL, TASK_SUBAGENT_PROGRESS_CHANNEL, taskSchema, } from "./types";
13
+ export declare const READ_ONLY_TOOL_NAMES: ReadonlySet<string>;
14
+ export declare function isReadOnlyAgent(agent: AgentDefinition): boolean;
13
15
  /**
14
16
  * Task tool - Delegate tasks to specialized agents.
15
17
  *
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Whether {@link initTelemetryExport} registered a real provider. The CLI uses
3
+ * this to decide whether to switch on the agent loop's telemetry config — there
4
+ * is no point emitting spans into a no-op tracer.
5
+ */
6
+ export declare function isTelemetryExportEnabled(): boolean;
7
+ /**
8
+ * Register the global TracerProvider + OTLP exporter when an OTLP endpoint is
9
+ * configured via env. Idempotent, and a no-op when no endpoint is set (or when
10
+ * the OTEL kill-switches are engaged), so it is safe to call unconditionally at
11
+ * startup.
12
+ */
13
+ export declare function initTelemetryExport(): void;
14
+ /**
15
+ * Flush any buffered spans to the exporter. No-op when export is disabled.
16
+ * Hosts embedding the agent can call this at natural boundaries (e.g. the end
17
+ * of a turn) so traces surface promptly rather than on the batch interval.
18
+ */
19
+ export declare function flushTelemetryExport(): Promise<void>;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Walk a conditional `exports` target (string, array of fallbacks, or a
3
+ * condition object) and return the first relative path that matches a runtime
4
+ * condition in declaration order. Returns `null` when nothing applies (e.g.
5
+ * `import`-only targets).
6
+ */
7
+ export declare function selectConditionalTarget(target: unknown): string | null;
8
+ /**
9
+ * Split a bare specifier into its package name and optional subpath, handling
10
+ * scoped packages (`@scope/name/sub` → `@scope/name` + `sub`).
11
+ */
12
+ export declare function splitBareSpecifier(specifier: string): {
13
+ packageName: string;
14
+ subpath: string | undefined;
15
+ };
16
+ /**
17
+ * Resolve a bare specifier against an installed `node_modules` directory,
18
+ * honoring `exports` (CommonJS conditions), then `main`, then `index.js`.
19
+ * Returns an absolute file path, or `null` when the package/entry is absent.
20
+ */
21
+ export declare function resolveRuntimeModule(runtimeNodeModules: string, specifier: string): string | null;
22
+ interface ResolverOptions {
23
+ /** Absolute path to the runtime cache's `node_modules`. */
24
+ runtimeNodeModules: string;
25
+ /** Bare specifier → absolute file path overrides (e.g. `sharp` → no-op stub). */
26
+ stubs?: Record<string, string>;
27
+ }
28
+ /**
29
+ * Patch `node:module`'s resolver (idempotently) so bare specifiers that the
30
+ * stock compiled-binary resolver cannot find fall back to the runtime cache.
31
+ * Stock resolution is tried first, so this never changes behavior for modules
32
+ * that already resolve (the worker's own bundled imports, node builtins).
33
+ */
34
+ export declare function installRuntimeModuleResolver({ runtimeNodeModules, stubs }: ResolverOptions): void;
35
+ export {};
@@ -100,6 +100,7 @@ interface AskRenderArgs {
100
100
  }>;
101
101
  }
102
102
  export declare const askToolRenderer: {
103
+ mergeCallAndResult: boolean;
103
104
  renderCall(args: AskRenderArgs, _options: RenderResultOptions, uiTheme: Theme): Component;
104
105
  renderResult(result: {
105
106
  content: Array<{
@@ -20,7 +20,7 @@ import type { DiscoverableTool, DiscoverableToolSearchIndex } from "../tool-disc
20
20
  import type { EventBus } from "../utils/event-bus";
21
21
  import type { WorkspaceTree } from "../workspace-tree";
22
22
  import { type CheckpointState } from "./checkpoint";
23
- import { type TodoPhase } from "./todo-write";
23
+ import { type TodoPhase } from "./todo";
24
24
  export * from "../edit";
25
25
  export * from "../exa";
26
26
  export type * from "../exa/types";
@@ -56,7 +56,7 @@ export * from "./review";
56
56
  export * from "./search";
57
57
  export * from "./search-tool-bm25";
58
58
  export * from "./ssh";
59
- export * from "./todo-write";
59
+ export * from "./todo";
60
60
  export * from "./tts";
61
61
  export * from "./write";
62
62
  export * from "./yield";
@@ -147,6 +147,8 @@ export interface ToolSession {
147
147
  settings: Settings;
148
148
  /** Plan mode state (if active) */
149
149
  getPlanModeState?: () => PlanModeState | undefined;
150
+ /** Path of the session's active plan reference (e.g. `local://<title>.md`); defaults to `local://PLAN.md`. */
151
+ getPlanReferencePath?: () => string;
150
152
  /** Goal mode state (if active or paused) */
151
153
  getGoalModeState?: () => GoalModeState | undefined;
152
154
  /** Goal runtime for the active agent session. */
@@ -9,7 +9,7 @@ export interface LineRange {
9
9
  startLine: number;
10
10
  endLine: number | undefined;
11
11
  }
12
- /** Parse a single `N`, `N-M`, `N-`, or `N+K` chunk. Throws via {@link ToolError} on invalid bounds. */
12
+ /** Parse a single `N`, `N-M`, `N-`, `N+K`, or `..`-aliased (`N..M`, `N..`) chunk. Throws via {@link ToolError} on invalid bounds. */
13
13
  export declare function parseLineRangeChunk(sel: string): LineRange | null;
14
14
  /**
15
15
  * Parse a comma-separated list of line ranges (e.g. `5-16,960-973`). Returns
@@ -8,7 +8,7 @@ import type { ToolSession } from ".";
8
8
  import { type OutputMeta } from "./output-meta";
9
9
  declare const searchSchema: z.ZodObject<{
10
10
  pattern: z.ZodString;
11
- paths: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>;
11
+ paths: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
12
12
  i: z.ZodOptional<z.ZodBoolean>;
13
13
  gitignore: z.ZodOptional<z.ZodBoolean>;
14
14
  skip: z.ZodOptional<z.ZodNumber>;
@@ -63,7 +63,7 @@ export declare class SearchTool implements AgentTool<typeof searchSchema, Search
63
63
  readonly description: string;
64
64
  readonly parameters: z.ZodObject<{
65
65
  pattern: z.ZodString;
66
- paths: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>;
66
+ paths: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
67
67
  i: z.ZodOptional<z.ZodBoolean>;
68
68
  gitignore: z.ZodOptional<z.ZodBoolean>;
69
69
  skip: z.ZodOptional<z.ZodNumber>;
@@ -25,12 +25,12 @@ export interface TodoCompletionTransition {
25
25
  phase: string;
26
26
  content: string;
27
27
  }
28
- export interface TodoWriteToolDetails {
28
+ export interface TodoToolDetails {
29
29
  phases: TodoPhase[];
30
30
  storage: "session" | "memory";
31
31
  completedTasks?: TodoCompletionTransition[];
32
32
  }
33
- declare const todoWriteSchema: z.ZodObject<{
33
+ declare const todoSchema: z.ZodObject<{
34
34
  ops: z.ZodArray<z.ZodObject<{
35
35
  op: z.ZodEnum<{
36
36
  append: "append";
@@ -51,7 +51,7 @@ declare const todoWriteSchema: z.ZodObject<{
51
51
  text: z.ZodOptional<z.ZodString>;
52
52
  }, z.core.$strip>>;
53
53
  }, z.core.$strip>;
54
- type TodoWriteParams = z.infer<typeof todoWriteSchema>;
54
+ type TodoParams = z.infer<typeof todoSchema>;
55
55
  export declare const USER_TODO_EDIT_CUSTOM_TYPE = "user_todo_edit";
56
56
  export declare function getLatestTodoPhasesFromEntries(entries: SessionEntry[]): TodoPhase[];
57
57
  /**
@@ -62,7 +62,7 @@ export declare function getLatestTodoPhasesFromEntries(entries: SessionEntry[]):
62
62
  * the caller can render a `+N more` hint. When every task in `tasks` is
63
63
  * closed (completed or abandoned), returns the trailing `maxVisible` tasks
64
64
  * with `hiddenOpenCount = 0`, so the panel keeps useful context until the
65
- * active-phase pointer advances on the next `todo_write`.
65
+ * active-phase pointer advances on the next `todo`.
66
66
  *
67
67
  * Task identity and order are preserved — this is a slice, never a sort.
68
68
  */
@@ -84,8 +84,8 @@ export declare function selectStickyTodoWindow(tasks: TodoItem[], maxVisible?: n
84
84
  * the contained side.
85
85
  */
86
86
  export declare function todoMatchesAnyDescription(content: string, descriptions: readonly string[]): boolean;
87
- /** Apply an array of `todo_write`-style ops to existing phases. Used by /todo slash command. */
88
- export declare function applyOpsToPhases(currentPhases: TodoPhase[], ops: TodoWriteParams["ops"]): {
87
+ /** Apply an array of `todo`-style ops to existing phases. Used by /todo slash command. */
88
+ export declare function applyOpsToPhases(currentPhases: TodoPhase[], ops: TodoParams["ops"]): {
89
89
  phases: TodoPhase[];
90
90
  errors: string[];
91
91
  };
@@ -96,11 +96,11 @@ export declare function markdownToPhases(md: string): {
96
96
  phases: TodoPhase[];
97
97
  errors: string[];
98
98
  };
99
- export declare class TodoWriteTool implements AgentTool<typeof todoWriteSchema, TodoWriteToolDetails> {
99
+ export declare class TodoTool implements AgentTool<typeof todoSchema, TodoToolDetails> {
100
100
  private readonly session;
101
- readonly name = "todo_write";
101
+ readonly name = "todo";
102
102
  readonly approval: "read";
103
- readonly label = "Todo Write";
103
+ readonly label = "Todo";
104
104
  readonly summary = "Write a structured todo list to track progress within a session";
105
105
  readonly description: string;
106
106
  readonly parameters: z.ZodObject<{
@@ -128,9 +128,9 @@ export declare class TodoWriteTool implements AgentTool<typeof todoWriteSchema,
128
128
  readonly strict = true;
129
129
  readonly loadMode = "discoverable";
130
130
  constructor(session: ToolSession);
131
- execute(_toolCallId: string, params: TodoWriteParams, _signal?: AbortSignal, _onUpdate?: AgentToolUpdateCallback<TodoWriteToolDetails>, _context?: AgentToolContext): Promise<AgentToolResult<TodoWriteToolDetails>>;
131
+ execute(_toolCallId: string, params: TodoParams, _signal?: AbortSignal, _onUpdate?: AgentToolUpdateCallback<TodoToolDetails>, _context?: AgentToolContext): Promise<AgentToolResult<TodoToolDetails>>;
132
132
  }
133
- type TodoWriteRenderArgs = {
133
+ type TodoRenderArgs = {
134
134
  ops?: Array<{
135
135
  op?: string;
136
136
  task?: string;
@@ -142,18 +142,18 @@ type TodoWriteRenderArgs = {
142
142
  export declare function phaseRomanNumeral(oneBasedIndex: number): string;
143
143
  /** Display-only phase header: `I. Foundation`. State and prompts never see this. */
144
144
  export declare function formatPhaseDisplayName(name: string, oneBasedIndex: number): string;
145
- export declare const TODO_WRITE_STRIKE_HOLD_FRAMES = 2;
146
- export declare const TODO_WRITE_STRIKE_REVEAL_FRAMES = 12;
147
- export declare const TODO_WRITE_STRIKE_TOTAL_FRAMES: number;
148
- export declare const todoWriteToolRenderer: {
149
- renderCall(args: TodoWriteRenderArgs, _options: RenderResultOptions, uiTheme: Theme): Component;
145
+ export declare const TODO_STRIKE_HOLD_FRAMES = 2;
146
+ export declare const TODO_STRIKE_REVEAL_FRAMES = 12;
147
+ export declare const TODO_STRIKE_TOTAL_FRAMES: number;
148
+ export declare const todoToolRenderer: {
149
+ renderCall(args: TodoRenderArgs, _options: RenderResultOptions, uiTheme: Theme): Component;
150
150
  renderResult(result: {
151
151
  content: Array<{
152
152
  type: string;
153
153
  text?: string;
154
154
  }>;
155
- details?: TodoWriteToolDetails;
156
- }, options: RenderResultOptions, uiTheme: Theme, _args?: TodoWriteRenderArgs): Component;
155
+ details?: TodoToolDetails;
156
+ }, options: RenderResultOptions, uiTheme: Theme, _args?: TodoRenderArgs): Component;
157
157
  mergeCallAndResult: boolean;
158
158
  };
159
159
  export {};
@@ -1,8 +1,13 @@
1
1
  /**
2
2
  * Derive a stable CSS hex accent color from a session name.
3
- * High saturation, vivid — suitable for both status bar text and border coloring.
3
+ *
4
+ * On dark themes (`surfaceLuminance` undefined) the accent is vivid (high
5
+ * saturation, high lightness). On light themes the lightness is reduced until the
6
+ * accent's perceived luminance clears {@link ACCENT_MIN_CONTRAST} against the
7
+ * actual surface it renders on — so it stays legible on near-white *and* mid-light
8
+ * backgrounds — while keeping the same per-session hue.
4
9
  */
5
- export declare function getSessionAccentHex(name: string): string;
10
+ export declare function getSessionAccentHex(name: string, surfaceLuminance?: number): string;
6
11
  /**
7
12
  * Convert a hex accent color to an ANSI-16m foreground escape sequence.
8
13
  * Returns `undefined` if `hex` is nullish or Bun.color conversion fails.
@@ -50,7 +50,7 @@ export declare function runSearchQuery(params: SearchQueryParams, options?: {
50
50
  /**
51
51
  * Web search tool implementation.
52
52
  *
53
- * Supports Anthropic, Perplexity, Exa, Brave, Jina, Kimi, Gemini, Codex, Z.AI, SearXNG, and Synthetic providers with automatic fallback.
53
+ * Supports the configured web-search provider chain with automatic fallback.
54
54
  */
55
55
  export declare class WebSearchTool implements AgentTool<typeof webSearchSchema, SearchRenderDetails> {
56
56
  #private;
@@ -1,8 +1,9 @@
1
1
  import type { AuthStorage } from "@oh-my-pi/pi-ai";
2
2
  import type { SearchProvider } from "./providers/base";
3
- import type { SearchProviderId } from "./types";
3
+ import { type SearchProviderId } from "./types";
4
4
  export type { SearchParams } from "./providers/base";
5
5
  export { SearchProvider } from "./providers/base";
6
+ export { SEARCH_PROVIDER_ORDER } from "./types";
6
7
  /** Cheap, sync metadata accessor — never triggers a provider load. */
7
8
  export declare function getSearchProviderLabel(id: SearchProviderId): string;
8
9
  /**
@@ -10,7 +11,6 @@ export declare function getSearchProviderLabel(id: SearchProviderId): string;
10
11
  * underlying module; subsequent calls return the cached singleton.
11
12
  */
12
13
  export declare function getSearchProvider(id: SearchProviderId): Promise<SearchProvider>;
13
- export declare const SEARCH_PROVIDER_ORDER: SearchProviderId[];
14
14
  /** Set the preferred web search provider from settings */
15
15
  export declare function setPreferredSearchProvider(provider: SearchProviderId | "auto"): void;
16
16
  /**
@@ -3,8 +3,72 @@
3
3
  *
4
4
  * Unified types for web search responses across supported providers.
5
5
  */
6
+ export declare const SEARCH_PROVIDER_ORDER: readonly ["tavily", "perplexity", "brave", "jina", "kimi", "anthropic", "gemini", "codex", "zai", "exa", "parallel", "kagi", "synthetic", "searxng"];
6
7
  /** Supported web search providers */
7
- export type SearchProviderId = "exa" | "brave" | "jina" | "kimi" | "zai" | "anthropic" | "perplexity" | "gemini" | "codex" | "tavily" | "parallel" | "kagi" | "synthetic" | "searxng";
8
+ export type SearchProviderId = (typeof SEARCH_PROVIDER_ORDER)[number];
9
+ export declare const SEARCH_PROVIDER_PREFERENCES: readonly ["auto", "tavily", "perplexity", "brave", "jina", "kimi", "anthropic", "gemini", "codex", "zai", "exa", "parallel", "kagi", "synthetic", "searxng"];
10
+ export declare const SEARCH_PROVIDER_OPTIONS: readonly [{
11
+ readonly value: "auto";
12
+ readonly label: "Auto";
13
+ readonly description: "Automatically uses the first configured web-search provider";
14
+ }, {
15
+ readonly value: "tavily";
16
+ readonly label: "Tavily";
17
+ readonly description: "Requires TAVILY_API_KEY";
18
+ }, {
19
+ readonly value: "perplexity";
20
+ readonly label: "Perplexity";
21
+ readonly description: "Requires PERPLEXITY_COOKIES or PERPLEXITY_API_KEY";
22
+ }, {
23
+ readonly value: "brave";
24
+ readonly label: "Brave";
25
+ readonly description: "Requires BRAVE_API_KEY";
26
+ }, {
27
+ readonly value: "jina";
28
+ readonly label: "Jina";
29
+ readonly description: "Requires JINA_API_KEY";
30
+ }, {
31
+ readonly value: "kimi";
32
+ readonly label: "Kimi";
33
+ readonly description: "Requires MOONSHOT_SEARCH_API_KEY or MOONSHOT_API_KEY";
34
+ }, {
35
+ readonly value: "anthropic";
36
+ readonly label: "Anthropic";
37
+ readonly description: "Claude's native web_search tool (uses Anthropic OAuth or ANTHROPIC_API_KEY)";
38
+ }, {
39
+ readonly value: "gemini";
40
+ readonly label: "Gemini";
41
+ readonly description: "Google Search grounding via Gemini (uses google-gemini-cli or google-antigravity OAuth)";
42
+ }, {
43
+ readonly value: "codex";
44
+ readonly label: "OpenAI";
45
+ readonly description: "OpenAI's native web_search (uses ChatGPT OAuth via /login openai-codex)";
46
+ }, {
47
+ readonly value: "zai";
48
+ readonly label: "Z.AI";
49
+ readonly description: "Calls Z.AI webSearchPrime MCP";
50
+ }, {
51
+ readonly value: "exa";
52
+ readonly label: "Exa";
53
+ readonly description: "Requires EXA_API_KEY";
54
+ }, {
55
+ readonly value: "parallel";
56
+ readonly label: "Parallel";
57
+ readonly description: "Requires PARALLEL_API_KEY";
58
+ }, {
59
+ readonly value: "kagi";
60
+ readonly label: "Kagi";
61
+ readonly description: "Requires KAGI_API_KEY and Kagi Search API beta access";
62
+ }, {
63
+ readonly value: "synthetic";
64
+ readonly label: "Synthetic";
65
+ readonly description: "Requires SYNTHETIC_API_KEY";
66
+ }, {
67
+ readonly value: "searxng";
68
+ readonly label: "SearXNG";
69
+ readonly description: "Requires SEARXNG_ENDPOINT or searxng.endpoint";
70
+ }];
71
+ export declare const SEARCH_PROVIDER_LABELS: Record<SearchProviderId, string>;
8
72
  export declare function isSearchProviderId(value: string): value is SearchProviderId;
9
73
  export declare function isSearchProviderPreference(value: string): value is SearchProviderId | "auto";
10
74
  /** Source returned by search (all providers) */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/pi-coding-agent",
4
- "version": "15.8.3",
4
+ "version": "15.9.0",
5
5
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
6
6
  "homepage": "https://omp.sh",
7
7
  "author": "Can Boluk",
@@ -47,14 +47,20 @@
47
47
  "@agentclientprotocol/sdk": "0.22.1",
48
48
  "@babel/parser": "^7.29.7",
49
49
  "@mozilla/readability": "^0.6.0",
50
- "@oh-my-pi/hashline": "15.8.3",
51
- "@oh-my-pi/omp-stats": "15.8.3",
52
- "@oh-my-pi/pi-agent-core": "15.8.3",
53
- "@oh-my-pi/pi-ai": "15.8.3",
54
- "@oh-my-pi/pi-mnemopi": "15.8.3",
55
- "@oh-my-pi/pi-natives": "15.8.3",
56
- "@oh-my-pi/pi-tui": "15.8.3",
57
- "@oh-my-pi/pi-utils": "15.8.3",
50
+ "@oh-my-pi/hashline": "15.9.0",
51
+ "@oh-my-pi/omp-stats": "15.9.0",
52
+ "@oh-my-pi/pi-agent-core": "15.9.0",
53
+ "@oh-my-pi/pi-ai": "15.9.0",
54
+ "@oh-my-pi/pi-mnemopi": "15.9.0",
55
+ "@oh-my-pi/pi-natives": "15.9.0",
56
+ "@oh-my-pi/pi-tui": "15.9.0",
57
+ "@oh-my-pi/pi-utils": "15.9.0",
58
+ "@opentelemetry/api": "^1.9.1",
59
+ "@opentelemetry/context-async-hooks": "^2.7.1",
60
+ "@opentelemetry/exporter-trace-otlp-proto": "^0.218.0",
61
+ "@opentelemetry/resources": "^2.7.1",
62
+ "@opentelemetry/sdk-trace-base": "^2.7.1",
63
+ "@opentelemetry/sdk-trace-node": "^2.7.1",
58
64
  "@puppeteer/browsers": "^3.0.4",
59
65
  "@types/turndown": "5.0.6",
60
66
  "@xterm/headless": "^6.0.0",
@@ -1,10 +1,20 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
+ import { createRequire } from "node:module";
3
4
  import * as path from "node:path";
4
5
 
5
6
  const packageDir = path.join(import.meta.dir, "..");
6
7
  const outputPath = path.join(packageDir, "dist", "omp");
7
8
 
9
+ // Transformers.js is an optional, native-heavy dependency that is never bundled
10
+ // into the binary; the tiny-model worker `bun install`s it into a runtime cache
11
+ // on first use. The `catalog:` spec cannot be resolved from inside the compiled
12
+ // bunfs (issue #1763), so embed the concrete installed version here for the
13
+ // worker to pin its runtime install against.
14
+ const transformersVersion = (
15
+ createRequire(import.meta.url)("@huggingface/transformers/package.json") as { version: string }
16
+ ).version;
17
+
8
18
  function shouldAdhocSignDarwinBinary(): boolean {
9
19
  return process.platform === "darwin";
10
20
  }
@@ -40,6 +50,8 @@ async function main(): Promise<void> {
40
50
  "--keep-names",
41
51
  "--define",
42
52
  'process.env.PI_COMPILED="true"',
53
+ "--define",
54
+ `process.env.PI_TINY_TRANSFORMERS_VERSION=${JSON.stringify(transformersVersion)}`,
43
55
  "--external",
44
56
  "mupdf",
45
57
  "--root",
@@ -21,6 +21,13 @@ export interface SkillFrontmatter {
21
21
  * rather than ones the model should auto-discover.
22
22
  */
23
23
  hide?: boolean;
24
+ /**
25
+ * Agent Skills standard equivalent of `hide`.
26
+ * When `true`, the skill is excluded from the system prompt listing.
27
+ * Normalized from kebab-case `disable-model-invocation` in YAML frontmatter.
28
+ * @see https://agentskills.io/specification
29
+ */
30
+ disableModelInvocation?: boolean;
24
31
  [key: string]: unknown;
25
32
  }
26
33
 
package/src/cli/args.ts CHANGED
@@ -313,7 +313,7 @@ ${chalk.bold("Available Tools (default-enabled unless noted):")}
313
313
  inspect_image - Analyze images with a vision model
314
314
  browser - Browser automation (Puppeteer)
315
315
  task - Launch sub-agents for parallel tasks
316
- todo_write - Manage todo/task lists
316
+ todo - Manage todo/task lists
317
317
  web_search - Search the web
318
318
  ask - Ask user questions (interactive mode only)
319
319