@oh-my-pi/pi-coding-agent 1.337.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 (224) hide show
  1. package/CHANGELOG.md +1228 -0
  2. package/README.md +1041 -0
  3. package/docs/compaction.md +403 -0
  4. package/docs/custom-tools.md +541 -0
  5. package/docs/extension-loading.md +1004 -0
  6. package/docs/hooks.md +867 -0
  7. package/docs/rpc.md +1040 -0
  8. package/docs/sdk.md +994 -0
  9. package/docs/session-tree-plan.md +441 -0
  10. package/docs/session.md +240 -0
  11. package/docs/skills.md +290 -0
  12. package/docs/theme.md +637 -0
  13. package/docs/tree.md +197 -0
  14. package/docs/tui.md +341 -0
  15. package/examples/README.md +21 -0
  16. package/examples/custom-tools/README.md +124 -0
  17. package/examples/custom-tools/hello/index.ts +20 -0
  18. package/examples/custom-tools/question/index.ts +84 -0
  19. package/examples/custom-tools/subagent/README.md +172 -0
  20. package/examples/custom-tools/subagent/agents/planner.md +37 -0
  21. package/examples/custom-tools/subagent/agents/reviewer.md +35 -0
  22. package/examples/custom-tools/subagent/agents/scout.md +50 -0
  23. package/examples/custom-tools/subagent/agents/worker.md +24 -0
  24. package/examples/custom-tools/subagent/agents.ts +156 -0
  25. package/examples/custom-tools/subagent/commands/implement-and-review.md +10 -0
  26. package/examples/custom-tools/subagent/commands/implement.md +10 -0
  27. package/examples/custom-tools/subagent/commands/scout-and-plan.md +9 -0
  28. package/examples/custom-tools/subagent/index.ts +1002 -0
  29. package/examples/custom-tools/todo/index.ts +212 -0
  30. package/examples/hooks/README.md +56 -0
  31. package/examples/hooks/auto-commit-on-exit.ts +49 -0
  32. package/examples/hooks/confirm-destructive.ts +59 -0
  33. package/examples/hooks/custom-compaction.ts +116 -0
  34. package/examples/hooks/dirty-repo-guard.ts +52 -0
  35. package/examples/hooks/file-trigger.ts +41 -0
  36. package/examples/hooks/git-checkpoint.ts +53 -0
  37. package/examples/hooks/handoff.ts +150 -0
  38. package/examples/hooks/permission-gate.ts +34 -0
  39. package/examples/hooks/protected-paths.ts +30 -0
  40. package/examples/hooks/qna.ts +119 -0
  41. package/examples/hooks/snake.ts +343 -0
  42. package/examples/hooks/status-line.ts +40 -0
  43. package/examples/sdk/01-minimal.ts +22 -0
  44. package/examples/sdk/02-custom-model.ts +49 -0
  45. package/examples/sdk/03-custom-prompt.ts +44 -0
  46. package/examples/sdk/04-skills.ts +44 -0
  47. package/examples/sdk/05-tools.ts +90 -0
  48. package/examples/sdk/06-hooks.ts +61 -0
  49. package/examples/sdk/07-context-files.ts +36 -0
  50. package/examples/sdk/08-slash-commands.ts +42 -0
  51. package/examples/sdk/09-api-keys-and-oauth.ts +55 -0
  52. package/examples/sdk/10-settings.ts +38 -0
  53. package/examples/sdk/11-sessions.ts +48 -0
  54. package/examples/sdk/12-full-control.ts +95 -0
  55. package/examples/sdk/README.md +154 -0
  56. package/package.json +81 -0
  57. package/src/cli/args.ts +246 -0
  58. package/src/cli/file-processor.ts +72 -0
  59. package/src/cli/list-models.ts +104 -0
  60. package/src/cli/plugin-cli.ts +650 -0
  61. package/src/cli/session-picker.ts +41 -0
  62. package/src/cli.ts +10 -0
  63. package/src/commands/init.md +20 -0
  64. package/src/config.ts +159 -0
  65. package/src/core/agent-session.ts +1900 -0
  66. package/src/core/auth-storage.ts +236 -0
  67. package/src/core/bash-executor.ts +196 -0
  68. package/src/core/compaction/branch-summarization.ts +343 -0
  69. package/src/core/compaction/compaction.ts +742 -0
  70. package/src/core/compaction/index.ts +7 -0
  71. package/src/core/compaction/utils.ts +154 -0
  72. package/src/core/custom-tools/index.ts +21 -0
  73. package/src/core/custom-tools/loader.ts +248 -0
  74. package/src/core/custom-tools/types.ts +169 -0
  75. package/src/core/custom-tools/wrapper.ts +28 -0
  76. package/src/core/exec.ts +129 -0
  77. package/src/core/export-html/index.ts +211 -0
  78. package/src/core/export-html/template.css +781 -0
  79. package/src/core/export-html/template.html +54 -0
  80. package/src/core/export-html/template.js +1185 -0
  81. package/src/core/export-html/vendor/highlight.min.js +1213 -0
  82. package/src/core/export-html/vendor/marked.min.js +6 -0
  83. package/src/core/hooks/index.ts +16 -0
  84. package/src/core/hooks/loader.ts +312 -0
  85. package/src/core/hooks/runner.ts +434 -0
  86. package/src/core/hooks/tool-wrapper.ts +99 -0
  87. package/src/core/hooks/types.ts +773 -0
  88. package/src/core/index.ts +52 -0
  89. package/src/core/mcp/client.ts +158 -0
  90. package/src/core/mcp/config.ts +154 -0
  91. package/src/core/mcp/index.ts +45 -0
  92. package/src/core/mcp/loader.ts +68 -0
  93. package/src/core/mcp/manager.ts +181 -0
  94. package/src/core/mcp/tool-bridge.ts +148 -0
  95. package/src/core/mcp/transports/http.ts +316 -0
  96. package/src/core/mcp/transports/index.ts +6 -0
  97. package/src/core/mcp/transports/stdio.ts +252 -0
  98. package/src/core/mcp/types.ts +220 -0
  99. package/src/core/messages.ts +189 -0
  100. package/src/core/model-registry.ts +317 -0
  101. package/src/core/model-resolver.ts +393 -0
  102. package/src/core/plugins/doctor.ts +59 -0
  103. package/src/core/plugins/index.ts +38 -0
  104. package/src/core/plugins/installer.ts +189 -0
  105. package/src/core/plugins/loader.ts +338 -0
  106. package/src/core/plugins/manager.ts +672 -0
  107. package/src/core/plugins/parser.ts +105 -0
  108. package/src/core/plugins/paths.ts +32 -0
  109. package/src/core/plugins/types.ts +190 -0
  110. package/src/core/sdk.ts +760 -0
  111. package/src/core/session-manager.ts +1128 -0
  112. package/src/core/settings-manager.ts +443 -0
  113. package/src/core/skills.ts +437 -0
  114. package/src/core/slash-commands.ts +248 -0
  115. package/src/core/system-prompt.ts +439 -0
  116. package/src/core/timings.ts +25 -0
  117. package/src/core/tools/ask.ts +211 -0
  118. package/src/core/tools/bash-interceptor.ts +120 -0
  119. package/src/core/tools/bash.ts +250 -0
  120. package/src/core/tools/context.ts +32 -0
  121. package/src/core/tools/edit-diff.ts +475 -0
  122. package/src/core/tools/edit.ts +208 -0
  123. package/src/core/tools/exa/company.ts +59 -0
  124. package/src/core/tools/exa/index.ts +64 -0
  125. package/src/core/tools/exa/linkedin.ts +59 -0
  126. package/src/core/tools/exa/logger.ts +56 -0
  127. package/src/core/tools/exa/mcp-client.ts +368 -0
  128. package/src/core/tools/exa/render.ts +196 -0
  129. package/src/core/tools/exa/researcher.ts +90 -0
  130. package/src/core/tools/exa/search.ts +337 -0
  131. package/src/core/tools/exa/types.ts +168 -0
  132. package/src/core/tools/exa/websets.ts +248 -0
  133. package/src/core/tools/find.ts +261 -0
  134. package/src/core/tools/grep.ts +555 -0
  135. package/src/core/tools/index.ts +202 -0
  136. package/src/core/tools/ls.ts +140 -0
  137. package/src/core/tools/lsp/client.ts +605 -0
  138. package/src/core/tools/lsp/config.ts +147 -0
  139. package/src/core/tools/lsp/edits.ts +101 -0
  140. package/src/core/tools/lsp/index.ts +804 -0
  141. package/src/core/tools/lsp/render.ts +447 -0
  142. package/src/core/tools/lsp/rust-analyzer.ts +145 -0
  143. package/src/core/tools/lsp/types.ts +463 -0
  144. package/src/core/tools/lsp/utils.ts +486 -0
  145. package/src/core/tools/notebook.ts +229 -0
  146. package/src/core/tools/path-utils.ts +61 -0
  147. package/src/core/tools/read.ts +240 -0
  148. package/src/core/tools/renderers.ts +540 -0
  149. package/src/core/tools/task/agents.ts +153 -0
  150. package/src/core/tools/task/artifacts.ts +114 -0
  151. package/src/core/tools/task/bundled-agents/browser.md +71 -0
  152. package/src/core/tools/task/bundled-agents/explore.md +82 -0
  153. package/src/core/tools/task/bundled-agents/plan.md +54 -0
  154. package/src/core/tools/task/bundled-agents/reviewer.md +59 -0
  155. package/src/core/tools/task/bundled-agents/task.md +53 -0
  156. package/src/core/tools/task/bundled-commands/architect-plan.md +10 -0
  157. package/src/core/tools/task/bundled-commands/implement-with-critic.md +11 -0
  158. package/src/core/tools/task/bundled-commands/implement.md +11 -0
  159. package/src/core/tools/task/commands.ts +213 -0
  160. package/src/core/tools/task/discovery.ts +208 -0
  161. package/src/core/tools/task/executor.ts +367 -0
  162. package/src/core/tools/task/index.ts +388 -0
  163. package/src/core/tools/task/model-resolver.ts +115 -0
  164. package/src/core/tools/task/parallel.ts +38 -0
  165. package/src/core/tools/task/render.ts +232 -0
  166. package/src/core/tools/task/types.ts +99 -0
  167. package/src/core/tools/truncate.ts +265 -0
  168. package/src/core/tools/web-fetch.ts +2370 -0
  169. package/src/core/tools/web-search/auth.ts +193 -0
  170. package/src/core/tools/web-search/index.ts +537 -0
  171. package/src/core/tools/web-search/providers/anthropic.ts +198 -0
  172. package/src/core/tools/web-search/providers/exa.ts +302 -0
  173. package/src/core/tools/web-search/providers/perplexity.ts +195 -0
  174. package/src/core/tools/web-search/render.ts +182 -0
  175. package/src/core/tools/web-search/types.ts +180 -0
  176. package/src/core/tools/write.ts +99 -0
  177. package/src/index.ts +176 -0
  178. package/src/main.ts +464 -0
  179. package/src/migrations.ts +135 -0
  180. package/src/modes/index.ts +43 -0
  181. package/src/modes/interactive/components/armin.ts +382 -0
  182. package/src/modes/interactive/components/assistant-message.ts +86 -0
  183. package/src/modes/interactive/components/bash-execution.ts +196 -0
  184. package/src/modes/interactive/components/bordered-loader.ts +41 -0
  185. package/src/modes/interactive/components/branch-summary-message.ts +42 -0
  186. package/src/modes/interactive/components/compaction-summary-message.ts +45 -0
  187. package/src/modes/interactive/components/custom-editor.ts +122 -0
  188. package/src/modes/interactive/components/diff.ts +147 -0
  189. package/src/modes/interactive/components/dynamic-border.ts +25 -0
  190. package/src/modes/interactive/components/footer.ts +381 -0
  191. package/src/modes/interactive/components/hook-editor.ts +117 -0
  192. package/src/modes/interactive/components/hook-input.ts +64 -0
  193. package/src/modes/interactive/components/hook-message.ts +96 -0
  194. package/src/modes/interactive/components/hook-selector.ts +91 -0
  195. package/src/modes/interactive/components/model-selector.ts +247 -0
  196. package/src/modes/interactive/components/oauth-selector.ts +120 -0
  197. package/src/modes/interactive/components/plugin-settings.ts +479 -0
  198. package/src/modes/interactive/components/queue-mode-selector.ts +56 -0
  199. package/src/modes/interactive/components/session-selector.ts +204 -0
  200. package/src/modes/interactive/components/settings-selector.ts +453 -0
  201. package/src/modes/interactive/components/show-images-selector.ts +45 -0
  202. package/src/modes/interactive/components/theme-selector.ts +62 -0
  203. package/src/modes/interactive/components/thinking-selector.ts +64 -0
  204. package/src/modes/interactive/components/tool-execution.ts +675 -0
  205. package/src/modes/interactive/components/tree-selector.ts +866 -0
  206. package/src/modes/interactive/components/user-message-selector.ts +159 -0
  207. package/src/modes/interactive/components/user-message.ts +18 -0
  208. package/src/modes/interactive/components/visual-truncate.ts +50 -0
  209. package/src/modes/interactive/components/welcome.ts +183 -0
  210. package/src/modes/interactive/interactive-mode.ts +2516 -0
  211. package/src/modes/interactive/theme/dark.json +101 -0
  212. package/src/modes/interactive/theme/light.json +98 -0
  213. package/src/modes/interactive/theme/theme-schema.json +308 -0
  214. package/src/modes/interactive/theme/theme.ts +998 -0
  215. package/src/modes/print-mode.ts +128 -0
  216. package/src/modes/rpc/rpc-client.ts +527 -0
  217. package/src/modes/rpc/rpc-mode.ts +483 -0
  218. package/src/modes/rpc/rpc-types.ts +203 -0
  219. package/src/utils/changelog.ts +99 -0
  220. package/src/utils/clipboard.ts +265 -0
  221. package/src/utils/fuzzy.ts +108 -0
  222. package/src/utils/mime.ts +30 -0
  223. package/src/utils/shell.ts +276 -0
  224. package/src/utils/tools-manager.ts +274 -0
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Feature bracket parser for plugin specifiers.
3
+ *
4
+ * Supports syntax like:
5
+ * - "my-plugin" -> base features (null)
6
+ * - "my-plugin[search,web]" -> specific features
7
+ * - "my-plugin[*]" -> all features
8
+ * - "my-plugin[]" -> no optional features
9
+ * - "@scope/plugin@1.2.3[feat]" -> scoped with version and features
10
+ */
11
+
12
+ export interface ParsedPluginSpec {
13
+ /** Package name (may include version specifier like @1.0.0) */
14
+ packageName: string;
15
+ /**
16
+ * Feature selection:
17
+ * - null: use defaults (base features on first install, preserve on reinstall)
18
+ * - "*": all features
19
+ * - string[]: specific features (empty array = no optional features)
20
+ */
21
+ features: string[] | null | "*";
22
+ }
23
+
24
+ /**
25
+ * Parse plugin specifier with feature bracket syntax.
26
+ *
27
+ * @example
28
+ * parsePluginSpec("my-plugin") // { packageName: "my-plugin", features: null }
29
+ * parsePluginSpec("my-plugin[search,web]") // { packageName: "my-plugin", features: ["search", "web"] }
30
+ * parsePluginSpec("my-plugin[*]") // { packageName: "my-plugin", features: "*" }
31
+ * parsePluginSpec("my-plugin[]") // { packageName: "my-plugin", features: [] }
32
+ * parsePluginSpec("@scope/pkg@1.2.3[feat]") // { packageName: "@scope/pkg@1.2.3", features: ["feat"] }
33
+ */
34
+ export function parsePluginSpec(spec: string): ParsedPluginSpec {
35
+ // Find the last bracket pair (to handle version specifiers like @1.0.0)
36
+ const bracketStart = spec.lastIndexOf("[");
37
+ const bracketEnd = spec.lastIndexOf("]");
38
+
39
+ // No brackets or malformed -> base features
40
+ if (bracketStart === -1 || bracketEnd === -1 || bracketEnd < bracketStart) {
41
+ return { packageName: spec, features: null };
42
+ }
43
+
44
+ const packageName = spec.slice(0, bracketStart);
45
+ const featureStr = spec.slice(bracketStart + 1, bracketEnd).trim();
46
+
47
+ // All features
48
+ if (featureStr === "*") {
49
+ return { packageName, features: "*" };
50
+ }
51
+
52
+ // No optional features
53
+ if (featureStr === "") {
54
+ return { packageName, features: [] };
55
+ }
56
+
57
+ // Specific features (comma-separated)
58
+ const features = featureStr
59
+ .split(",")
60
+ .map((f) => f.trim())
61
+ .filter(Boolean);
62
+
63
+ return { packageName, features };
64
+ }
65
+
66
+ /**
67
+ * Format a parsed plugin spec back to string form.
68
+ *
69
+ * @example
70
+ * formatPluginSpec({ packageName: "pkg", features: null }) // "pkg"
71
+ * formatPluginSpec({ packageName: "pkg", features: "*" }) // "pkg[*]"
72
+ * formatPluginSpec({ packageName: "pkg", features: [] }) // "pkg[]"
73
+ * formatPluginSpec({ packageName: "pkg", features: ["a", "b"] }) // "pkg[a,b]"
74
+ */
75
+ export function formatPluginSpec(spec: ParsedPluginSpec): string {
76
+ if (spec.features === null) {
77
+ return spec.packageName;
78
+ }
79
+ if (spec.features === "*") {
80
+ return `${spec.packageName}[*]`;
81
+ }
82
+ if (spec.features.length === 0) {
83
+ return `${spec.packageName}[]`;
84
+ }
85
+ return `${spec.packageName}[${spec.features.join(",")}]`;
86
+ }
87
+
88
+ /**
89
+ * Extract the base package name without version specifier.
90
+ * Used for path lookups after npm install.
91
+ *
92
+ * @example
93
+ * extractPackageName("lodash@4.17.21") // "lodash"
94
+ * extractPackageName("@scope/pkg@1.0.0") // "@scope/pkg"
95
+ * extractPackageName("@scope/pkg") // "@scope/pkg"
96
+ */
97
+ export function extractPackageName(specifier: string): string {
98
+ // Handle scoped packages: @scope/name@version -> @scope/name
99
+ if (specifier.startsWith("@")) {
100
+ const match = specifier.match(/^(@[^/]+\/[^@]+)/);
101
+ return match ? match[1] : specifier;
102
+ }
103
+ // Unscoped: name@version -> name
104
+ return specifier.replace(/@[^@]+$/, "");
105
+ }
@@ -0,0 +1,32 @@
1
+ import { homedir } from "os";
2
+ import { join } from "path";
3
+ import { CONFIG_DIR_NAME } from "../../config.js";
4
+
5
+ // =============================================================================
6
+ // Plugin Directory Paths
7
+ // =============================================================================
8
+
9
+ /** Root plugin directory: ~/.pi/plugins (not under agent/) */
10
+ export function getPluginsDir(): string {
11
+ return join(homedir(), CONFIG_DIR_NAME, "plugins");
12
+ }
13
+
14
+ /** Where npm installs packages: ~/.pi/plugins/node_modules */
15
+ export function getPluginsNodeModules(): string {
16
+ return join(getPluginsDir(), "node_modules");
17
+ }
18
+
19
+ /** Plugin manifest: ~/.pi/plugins/package.json */
20
+ export function getPluginsPackageJson(): string {
21
+ return join(getPluginsDir(), "package.json");
22
+ }
23
+
24
+ /** Plugin lock file: ~/.pi/plugins/pi-plugins.lock.json */
25
+ export function getPluginsLockfile(): string {
26
+ return join(getPluginsDir(), "pi-plugins.lock.json");
27
+ }
28
+
29
+ /** Project-local plugin overrides: .pi/plugin-overrides.json */
30
+ export function getProjectPluginOverrides(cwd: string): string {
31
+ return join(cwd, CONFIG_DIR_NAME, "plugin-overrides.json");
32
+ }
@@ -0,0 +1,190 @@
1
+ // =============================================================================
2
+ // Plugin Manifest Types (from package.json omp/pi field)
3
+ // =============================================================================
4
+
5
+ /**
6
+ * Feature definition for selective plugin installation.
7
+ * Features allow plugins to expose optional functionality.
8
+ */
9
+ export interface PluginFeature {
10
+ /** Human-readable description */
11
+ description?: string;
12
+ /** Whether this feature is enabled by default */
13
+ default?: boolean;
14
+ /** Additional tool entry points provided by this feature */
15
+ tools?: string[];
16
+ /** Additional hook entry points provided by this feature */
17
+ hooks?: string[];
18
+ /** Additional command files provided by this feature */
19
+ commands?: string[];
20
+ }
21
+
22
+ /**
23
+ * Plugin manifest from package.json omp or pi field.
24
+ */
25
+ export interface PluginManifest {
26
+ /** Plugin display name (defaults to package name) */
27
+ name?: string;
28
+ /** Plugin version (copied from package.json version) */
29
+ version: string;
30
+ /** Human-readable description */
31
+ description?: string;
32
+
33
+ /** Entry point for base tools (relative path from package root) */
34
+ tools?: string;
35
+ /** Entry point for base hooks (relative path from package root) */
36
+ hooks?: string;
37
+ /** Command files (relative paths from package root) */
38
+ commands?: string[];
39
+
40
+ /** Feature definitions for selective installation */
41
+ features?: Record<string, PluginFeature>;
42
+
43
+ /** Settings schema for plugin configuration */
44
+ settings?: Record<string, PluginSettingSchema>;
45
+ }
46
+
47
+ // =============================================================================
48
+ // Plugin Settings Schema Types
49
+ // =============================================================================
50
+
51
+ export type PluginSettingType = "string" | "number" | "boolean" | "enum";
52
+
53
+ interface PluginSettingBase {
54
+ /** Setting type */
55
+ type: PluginSettingType;
56
+ /** Human-readable description */
57
+ description?: string;
58
+ /** If true, mask value in UI and logs */
59
+ secret?: boolean;
60
+ /** Environment variable to use as fallback value */
61
+ env?: string;
62
+ }
63
+
64
+ export interface StringSetting extends PluginSettingBase {
65
+ type: "string";
66
+ default?: string;
67
+ }
68
+
69
+ export interface NumberSetting extends PluginSettingBase {
70
+ type: "number";
71
+ default?: number;
72
+ min?: number;
73
+ max?: number;
74
+ step?: number;
75
+ }
76
+
77
+ export interface BooleanSetting extends PluginSettingBase {
78
+ type: "boolean";
79
+ default?: boolean;
80
+ }
81
+
82
+ export interface EnumSetting extends PluginSettingBase {
83
+ type: "enum";
84
+ /** Allowed values */
85
+ values: string[];
86
+ default?: string;
87
+ }
88
+
89
+ export type PluginSettingSchema = StringSetting | NumberSetting | BooleanSetting | EnumSetting;
90
+
91
+ // =============================================================================
92
+ // Installed Plugin Types
93
+ // =============================================================================
94
+
95
+ /**
96
+ * Represents an installed plugin with full metadata.
97
+ */
98
+ export interface InstalledPlugin {
99
+ /** npm package name */
100
+ name: string;
101
+ /** Installed version */
102
+ version: string;
103
+ /** Absolute path to package directory */
104
+ path: string;
105
+ /** Parsed omp/pi manifest */
106
+ manifest: PluginManifest;
107
+ /**
108
+ * Enabled features:
109
+ * - null: use defaults (all features with default: true)
110
+ * - string[]: specific features enabled
111
+ */
112
+ enabledFeatures: string[] | null;
113
+ /** Whether the plugin is enabled */
114
+ enabled: boolean;
115
+ }
116
+
117
+ // =============================================================================
118
+ // Runtime Config Types (stored in pi-plugins.lock.json)
119
+ // =============================================================================
120
+
121
+ /**
122
+ * Per-plugin runtime state stored in lock file.
123
+ */
124
+ export interface PluginRuntimeState {
125
+ /** Installed version */
126
+ version: string;
127
+ /** Enabled features (null = defaults) */
128
+ enabledFeatures: string[] | null;
129
+ /** Whether the plugin is enabled */
130
+ enabled: boolean;
131
+ }
132
+
133
+ /**
134
+ * Runtime configuration persisted to pi-plugins.lock.json.
135
+ * Tracks plugin states and settings across sessions.
136
+ */
137
+ export interface PluginRuntimeConfig {
138
+ /** Plugin states keyed by package name */
139
+ plugins: Record<string, PluginRuntimeState>;
140
+ /** Plugin settings keyed by package name, then setting key */
141
+ settings: Record<string, Record<string, unknown>>;
142
+ }
143
+
144
+ // =============================================================================
145
+ // Project Override Types
146
+ // =============================================================================
147
+
148
+ /**
149
+ * Project-local plugin overrides (stored in .pi/plugin-overrides.json).
150
+ * Allows per-project plugin configuration without modifying global state.
151
+ */
152
+ export interface ProjectPluginOverrides {
153
+ /** Plugins to disable in this project */
154
+ disabled?: string[];
155
+ /** Per-plugin feature overrides */
156
+ features?: Record<string, string[]>;
157
+ /** Per-plugin setting overrides */
158
+ settings?: Record<string, Record<string, unknown>>;
159
+ }
160
+
161
+ // =============================================================================
162
+ // Doctor Types
163
+ // =============================================================================
164
+
165
+ export interface DoctorCheck {
166
+ /** Check identifier */
167
+ name: string;
168
+ /** Check result status */
169
+ status: "ok" | "warning" | "error";
170
+ /** Human-readable message */
171
+ message: string;
172
+ /** Whether --fix resolved this issue */
173
+ fixed?: boolean;
174
+ }
175
+
176
+ // =============================================================================
177
+ // Install Options Types
178
+ // =============================================================================
179
+
180
+ export interface InstallOptions {
181
+ /** Overwrite existing without prompting */
182
+ force?: boolean;
183
+ /** Preview changes without applying */
184
+ dryRun?: boolean;
185
+ }
186
+
187
+ export interface DoctorOptions {
188
+ /** Attempt automatic fixes */
189
+ fix?: boolean;
190
+ }