@oh-my-pi/pi-coding-agent 15.7.2 → 15.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +114 -6
- package/dist/types/cli/args.d.ts +1 -1
- package/dist/types/cli/extension-flags.d.ts +36 -0
- package/dist/types/config/config-file.d.ts +4 -0
- package/dist/types/config/file-lock.d.ts +23 -0
- package/dist/types/config/keybindings.d.ts +2 -1
- package/dist/types/config/model-registry.d.ts +6 -0
- package/dist/types/config/settings-schema.d.ts +69 -65
- package/dist/types/edit/hashline/diff.d.ts +3 -3
- package/dist/types/eval/__tests__/agent-bridge.test.d.ts +1 -0
- package/dist/types/eval/__tests__/budget-bridge.test.d.ts +1 -0
- package/dist/types/eval/__tests__/idle-timeout.test.d.ts +1 -0
- package/dist/types/eval/agent-bridge.d.ts +25 -0
- package/dist/types/eval/backend.d.ts +17 -2
- package/dist/types/eval/budget-bridge.d.ts +29 -0
- package/dist/types/eval/idle-timeout.d.ts +28 -0
- package/dist/types/eval/js/executor.d.ts +8 -0
- package/dist/types/eval/js/tool-bridge.d.ts +2 -1
- package/dist/types/eval/py/executor.d.ts +13 -0
- package/dist/types/exec/bash-executor.d.ts +1 -0
- package/dist/types/extensibility/custom-tools/types.d.ts +2 -2
- package/dist/types/extensibility/extensions/runner.d.ts +7 -0
- package/dist/types/extensibility/plugins/git-url.d.ts +11 -1
- package/dist/types/extensibility/plugins/manager.d.ts +12 -1
- package/dist/types/extensibility/shared-events.d.ts +2 -2
- package/dist/types/internal-urls/local-protocol.d.ts +19 -9
- package/dist/types/internal-urls/types.d.ts +14 -0
- package/dist/types/lsp/client.d.ts +3 -0
- package/dist/types/mcp/manager.d.ts +14 -5
- package/dist/types/memory-backend/index.d.ts +1 -1
- package/dist/types/memory-backend/resolve.d.ts +1 -1
- package/dist/types/memory-backend/types.d.ts +3 -3
- package/dist/types/mnemopi/backend.d.ts +4 -0
- package/dist/types/mnemopi/config.d.ts +29 -0
- package/dist/types/mnemopi/state.d.ts +72 -0
- package/dist/types/modes/components/custom-editor.d.ts +2 -2
- package/dist/types/modes/components/omfg-panel.d.ts +19 -0
- package/dist/types/modes/controllers/command-controller.d.ts +6 -0
- package/dist/types/modes/controllers/input-controller.d.ts +1 -3
- package/dist/types/modes/controllers/omfg-controller.d.ts +10 -0
- package/dist/types/modes/controllers/omfg-rule.d.ts +26 -0
- package/dist/types/modes/gradient-highlight.d.ts +5 -1
- package/dist/types/modes/interactive-mode.d.ts +7 -3
- package/dist/types/modes/magic-keywords.d.ts +14 -0
- package/dist/types/modes/markdown-prose.d.ts +27 -0
- package/dist/types/modes/orchestrate.d.ts +7 -2
- package/dist/types/modes/shared.d.ts +1 -1
- package/dist/types/modes/turn-budget.d.ts +18 -0
- package/dist/types/modes/types.d.ts +7 -3
- package/dist/types/modes/ultrathink.d.ts +7 -2
- package/dist/types/modes/workflow.d.ts +15 -0
- package/dist/types/sdk.d.ts +13 -3
- package/dist/types/session/agent-session.d.ts +36 -17
- package/dist/types/session/session-manager.d.ts +18 -0
- package/dist/types/session/session-storage.d.ts +6 -0
- package/dist/types/session/shake-types.d.ts +24 -0
- package/dist/types/task/executor.d.ts +2 -2
- package/dist/types/task/repair-args.d.ts +52 -0
- package/dist/types/tiny/models.d.ts +1 -1
- package/dist/types/tiny/title-client.d.ts +28 -2
- package/dist/types/tiny/title-protocol.d.ts +8 -5
- package/dist/types/tools/find.d.ts +1 -1
- package/dist/types/tools/index.d.ts +19 -3
- package/dist/types/tools/memory-edit.d.ts +1 -1
- package/dist/types/tools/path-utils.d.ts +7 -0
- package/dist/types/tui/output-block.d.ts +7 -7
- package/examples/sdk/09-api-keys-and-oauth.ts +2 -2
- package/package.json +10 -10
- package/scripts/build-binary.ts +0 -1
- package/src/autoresearch/tools/run-experiment.ts +45 -113
- package/src/cli/args.ts +39 -16
- package/src/cli/extension-flags.ts +48 -0
- package/src/cli/plugin-cli.ts +11 -2
- package/src/cli.ts +59 -0
- package/src/config/config-file.ts +98 -13
- package/src/config/file-lock.ts +60 -17
- package/src/config/keybindings.ts +78 -27
- package/src/config/model-registry.ts +7 -1
- package/src/config/settings-schema.ts +73 -67
- package/src/config/settings.ts +22 -0
- package/src/edit/hashline/diff.ts +81 -24
- package/src/edit/renderer.ts +16 -12
- package/src/eval/__tests__/agent-bridge.test.ts +433 -0
- package/src/eval/__tests__/budget-bridge.test.ts +69 -0
- package/src/eval/__tests__/idle-timeout.test.ts +66 -0
- package/src/eval/__tests__/shared-executors.test.ts +21 -0
- package/src/eval/agent-bridge.ts +295 -0
- package/src/eval/backend.ts +17 -2
- package/src/eval/budget-bridge.ts +48 -0
- package/src/eval/idle-timeout.ts +80 -0
- package/src/eval/js/executor.ts +35 -7
- package/src/eval/js/index.ts +2 -1
- package/src/eval/js/shared/prelude.txt +85 -1
- package/src/eval/js/tool-bridge.ts +9 -0
- package/src/eval/py/executor.ts +41 -14
- package/src/eval/py/index.ts +2 -1
- package/src/eval/py/prelude.py +132 -1
- package/src/exec/bash-executor.ts +2 -3
- package/src/extensibility/custom-tools/types.ts +2 -2
- package/src/extensibility/extensions/runner.ts +12 -2
- package/src/extensibility/plugins/git-url.ts +90 -4
- package/src/extensibility/plugins/manager.ts +103 -7
- package/src/extensibility/shared-events.ts +2 -2
- package/src/internal-urls/docs-index.generated.ts +88 -88
- package/src/internal-urls/local-protocol.ts +23 -11
- package/src/internal-urls/types.ts +15 -0
- package/src/lsp/client.ts +28 -5
- package/src/main.ts +44 -55
- package/src/mcp/manager.ts +87 -4
- package/src/memory-backend/index.ts +1 -1
- package/src/memory-backend/resolve.ts +3 -3
- package/src/memory-backend/types.ts +3 -3
- package/src/{mnemosyne → mnemopi}/backend.ts +70 -70
- package/src/{mnemosyne → mnemopi}/config.ts +36 -36
- package/src/{mnemosyne → mnemopi}/state.ts +67 -67
- package/src/modes/components/agent-dashboard.ts +6 -6
- package/src/modes/components/custom-editor.ts +4 -11
- package/src/modes/components/extensions/state-manager.ts +3 -4
- package/src/modes/components/footer.ts +8 -9
- package/src/modes/components/hook-selector.ts +86 -20
- package/src/modes/components/oauth-selector.ts +93 -21
- package/src/modes/components/omfg-panel.ts +141 -0
- package/src/modes/components/settings-defs.ts +2 -2
- package/src/modes/components/tips.txt +2 -1
- package/src/modes/components/tool-execution.ts +38 -19
- package/src/modes/components/tree-selector.ts +4 -3
- package/src/modes/components/user-message-selector.ts +94 -19
- package/src/modes/components/user-message.ts +8 -1
- package/src/modes/controllers/command-controller.ts +25 -0
- package/src/modes/controllers/event-controller.ts +68 -3
- package/src/modes/controllers/input-controller.ts +14 -11
- package/src/modes/controllers/mcp-command-controller.ts +1 -1
- package/src/modes/controllers/omfg-controller.ts +283 -0
- package/src/modes/controllers/omfg-rule.ts +647 -0
- package/src/modes/controllers/selector-controller.ts +1 -0
- package/src/modes/gradient-highlight.ts +23 -6
- package/src/modes/interactive-mode.ts +41 -7
- package/src/modes/magic-keywords.ts +20 -0
- package/src/modes/markdown-prose.ts +247 -0
- package/src/modes/orchestrate.ts +17 -11
- package/src/modes/shared.ts +3 -11
- package/src/modes/turn-budget.ts +31 -0
- package/src/modes/types.ts +7 -1
- package/src/modes/ultrathink.ts +16 -10
- package/src/modes/utils/hotkeys-markdown.ts +1 -1
- package/src/modes/workflow.ts +42 -0
- package/src/prompts/system/omfg-user.md +51 -0
- package/src/prompts/system/project-prompt.md +3 -2
- package/src/prompts/system/subagent-system-prompt.md +12 -8
- package/src/prompts/system/system-prompt.md +9 -6
- package/src/prompts/system/workflow-notice.md +70 -0
- package/src/prompts/tools/eval.md +13 -1
- package/src/prompts/tools/memory-edit.md +1 -1
- package/src/sdk.ts +63 -33
- package/src/session/agent-session.ts +290 -55
- package/src/session/session-manager.ts +32 -0
- package/src/session/session-storage.ts +68 -8
- package/src/session/shake-types.ts +43 -0
- package/src/slash-commands/builtin-registry.ts +39 -16
- package/src/task/executor.ts +17 -7
- package/src/task/index.ts +9 -8
- package/src/task/repair-args.ts +117 -0
- package/src/tiny/models.ts +2 -2
- package/src/tiny/title-client.ts +133 -43
- package/src/tiny/title-protocol.ts +10 -5
- package/src/tiny/worker.ts +3 -46
- package/src/tools/ast-edit.ts +3 -0
- package/src/tools/ast-grep.ts +3 -0
- package/src/tools/eval.ts +202 -26
- package/src/tools/find.ts +20 -6
- package/src/tools/gh.ts +1 -0
- package/src/tools/grouped-file-output.ts +9 -2
- package/src/tools/index.ts +17 -5
- package/src/tools/memory-edit.ts +4 -4
- package/src/tools/memory-recall.ts +5 -5
- package/src/tools/memory-reflect.ts +5 -5
- package/src/tools/memory-retain.ts +4 -4
- package/src/tools/path-utils.ts +13 -2
- package/src/tools/read.ts +1 -0
- package/src/tools/render-utils.ts +2 -1
- package/src/tools/search.ts +491 -76
- package/src/tui/output-block.ts +37 -75
- package/src/utils/git.ts +9 -3
- package/dist/types/mnemosyne/backend.d.ts +0 -4
- package/dist/types/mnemosyne/config.d.ts +0 -29
- package/dist/types/mnemosyne/state.d.ts +0 -72
- /package/dist/types/{mnemosyne → mnemopi}/index.d.ts +0 -0
- /package/src/{mnemosyne → mnemopi}/index.ts +0 -0
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
isEnoent,
|
|
11
11
|
logger,
|
|
12
12
|
} from "@oh-my-pi/pi-utils";
|
|
13
|
+
import { type GitSource, parseGitUrl } from "./git-url";
|
|
13
14
|
import { extractPackageName, parsePluginSpec } from "./parser";
|
|
14
15
|
import type {
|
|
15
16
|
DoctorCheck,
|
|
@@ -29,8 +30,14 @@ import type {
|
|
|
29
30
|
/** Valid npm package name pattern (scoped and unscoped, with optional version) */
|
|
30
31
|
const VALID_PACKAGE_NAME = /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*(@[a-z0-9-._^~>=<]+)?$/i;
|
|
31
32
|
|
|
33
|
+
/** Characters that are never valid in any plugin install spec — git or npm. */
|
|
34
|
+
const SHELL_METACHARS = /[;&|`$(){}<>\\\n\r\t]/;
|
|
35
|
+
|
|
32
36
|
/**
|
|
33
|
-
* Validate package name to prevent command injection.
|
|
37
|
+
* Validate package name to prevent command injection. npm specs only — git
|
|
38
|
+
* specs (`github:user/repo`, `https://github.com/...`, ...) MUST go through
|
|
39
|
+
* {@link validateGitSpec} instead because they contain characters npm rejects
|
|
40
|
+
* (`:`, `/`, `#`, `+`, `@` in non-version positions).
|
|
34
41
|
*/
|
|
35
42
|
function validatePackageName(name: string): void {
|
|
36
43
|
// Remove version specifier for validation
|
|
@@ -44,6 +51,29 @@ function validatePackageName(name: string): void {
|
|
|
44
51
|
}
|
|
45
52
|
}
|
|
46
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Validate a git install spec — accepts `:`, `/`, `#`, `+`, `.`, `-`, `_`,
|
|
56
|
+
* `~`, `@` (which would all fail {@link validatePackageName}) but rejects
|
|
57
|
+
* shell metacharacters so the spec stays safe when forwarded to bun install.
|
|
58
|
+
* `Bun.spawn` does not invoke a shell, but defense-in-depth keeps things
|
|
59
|
+
* obvious for future readers.
|
|
60
|
+
*/
|
|
61
|
+
function validateGitSpec(spec: string): void {
|
|
62
|
+
if (SHELL_METACHARS.test(spec)) {
|
|
63
|
+
throw new Error(`Invalid characters in plugin source: ${spec}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function gitInstallSpec(original: string, source: GitSource): string {
|
|
68
|
+
if (/^github:/i.test(original) || !/^[a-z]+:[^/]/i.test(original)) {
|
|
69
|
+
return original;
|
|
70
|
+
}
|
|
71
|
+
if (!source.ref || source.repo.includes("#")) {
|
|
72
|
+
return source.repo;
|
|
73
|
+
}
|
|
74
|
+
return `${source.repo}#${source.ref}`;
|
|
75
|
+
}
|
|
76
|
+
|
|
47
77
|
// =============================================================================
|
|
48
78
|
// Plugin Manager
|
|
49
79
|
// =============================================================================
|
|
@@ -127,12 +157,39 @@ export class PluginManager {
|
|
|
127
157
|
}
|
|
128
158
|
}
|
|
129
159
|
|
|
160
|
+
/**
|
|
161
|
+
* Read the `dependencies` map from `plugins/package.json`. Returns an empty
|
|
162
|
+
* object when the file does not exist yet so callers can diff `before`
|
|
163
|
+
* against `after` to discover the package bun just installed under its
|
|
164
|
+
* real name (git specs do not encode the package name in the spec itself).
|
|
165
|
+
*/
|
|
166
|
+
async #readDeps(pkgJsonPath: string): Promise<Record<string, string>> {
|
|
167
|
+
try {
|
|
168
|
+
const json = await Bun.file(pkgJsonPath).json();
|
|
169
|
+
return (json.dependencies as Record<string, string>) ?? {};
|
|
170
|
+
} catch (err) {
|
|
171
|
+
if (isEnoent(err)) return {};
|
|
172
|
+
throw err;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
130
176
|
// ==========================================================================
|
|
131
177
|
// Install / Uninstall
|
|
132
178
|
// ==========================================================================
|
|
133
179
|
|
|
134
180
|
/**
|
|
135
|
-
* Install a plugin
|
|
181
|
+
* Install a plugin with optional feature selection.
|
|
182
|
+
*
|
|
183
|
+
* Accepts:
|
|
184
|
+
* - npm specs: `pkg`, `pkg@1.2.3`, `@scope/pkg`, `pkg[features]`
|
|
185
|
+
* - namespaced git shorthand: `github:user/repo[#ref]`, `gitlab:`, `bitbucket:`,
|
|
186
|
+
* `codeberg:`, `sourcehut:`/`srht:`
|
|
187
|
+
* - full git URLs: `https://github.com/user/repo`, `git@github.com:user/repo`,
|
|
188
|
+
* `ssh://…`, `git+https://…`
|
|
189
|
+
*
|
|
190
|
+
* For git specs the package name is not knowable from the spec, so the
|
|
191
|
+
* installer diffs `plugins/package.json` `dependencies` before and after
|
|
192
|
+
* to find the newly added key.
|
|
136
193
|
*
|
|
137
194
|
* @param specString - Package specifier with optional features: "pkg", "pkg[feat]", "pkg[*]", "pkg[]"
|
|
138
195
|
* @param options - Install options
|
|
@@ -140,7 +197,12 @@ export class PluginManager {
|
|
|
140
197
|
*/
|
|
141
198
|
async install(specString: string, options: InstallOptions = {}): Promise<InstalledPlugin> {
|
|
142
199
|
const spec = parsePluginSpec(specString);
|
|
143
|
-
|
|
200
|
+
const gitSource = parseGitUrl(spec.packageName);
|
|
201
|
+
if (gitSource) {
|
|
202
|
+
validateGitSpec(spec.packageName);
|
|
203
|
+
} else {
|
|
204
|
+
validatePackageName(spec.packageName);
|
|
205
|
+
}
|
|
144
206
|
|
|
145
207
|
await this.#ensurePackageJson();
|
|
146
208
|
|
|
@@ -154,9 +216,12 @@ export class PluginManager {
|
|
|
154
216
|
enabled: true,
|
|
155
217
|
};
|
|
156
218
|
}
|
|
219
|
+
const pkgJsonPath = getPluginsPackageJson();
|
|
220
|
+
const depsBefore = gitSource ? await this.#readDeps(pkgJsonPath) : {};
|
|
221
|
+
const packageInstallSpec = gitSource ? gitInstallSpec(spec.packageName, gitSource) : spec.packageName;
|
|
157
222
|
|
|
158
223
|
// Run npm install
|
|
159
|
-
const proc = Bun.spawn(["bun", "install",
|
|
224
|
+
const proc = Bun.spawn(["bun", "install", packageInstallSpec], {
|
|
160
225
|
cwd: getPluginsDir(),
|
|
161
226
|
stdin: "ignore",
|
|
162
227
|
stdout: "pipe",
|
|
@@ -169,9 +234,40 @@ export class PluginManager {
|
|
|
169
234
|
const stderr = await new Response(proc.stderr).text();
|
|
170
235
|
throw new Error(`npm install failed: ${stderr}`);
|
|
171
236
|
}
|
|
172
|
-
|
|
173
|
-
//
|
|
174
|
-
|
|
237
|
+
// Resolve actual package name. npm specs encode the name (strip version);
|
|
238
|
+
// git specs do not, so diff plugins/package.json deps to find the new entry.
|
|
239
|
+
let actualName: string;
|
|
240
|
+
if (gitSource) {
|
|
241
|
+
const depsAfter = await this.#readDeps(pkgJsonPath);
|
|
242
|
+
let resolved: string | undefined;
|
|
243
|
+
for (const key of Object.keys(depsAfter)) {
|
|
244
|
+
if (!(key in depsBefore)) {
|
|
245
|
+
resolved = key;
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
// Fallback: a force-reinstall of an already-present git plugin will not
|
|
250
|
+
// add a new key, just rewrite the existing one to the new spec value.
|
|
251
|
+
// Match by the install value for force-reinstalls where no new key is
|
|
252
|
+
// added (non-GitHub shorthands are normalized before bun sees them).
|
|
253
|
+
if (!resolved) {
|
|
254
|
+
const needle = packageInstallSpec.replace(/^git\+/i, "");
|
|
255
|
+
for (const [key, value] of Object.entries(depsAfter)) {
|
|
256
|
+
if (typeof value === "string" && value.includes(needle)) {
|
|
257
|
+
resolved = key;
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
if (!resolved) {
|
|
263
|
+
throw new Error(
|
|
264
|
+
`Installed ${spec.packageName} but could not determine package name from plugins/package.json`,
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
actualName = resolved;
|
|
268
|
+
} else {
|
|
269
|
+
actualName = extractPackageName(spec.packageName);
|
|
270
|
+
}
|
|
175
271
|
const pkgPath = path.join(getPluginsNodeModules(), actualName, "package.json");
|
|
176
272
|
|
|
177
273
|
let pkg: { name: string; version: string; omp?: PluginManifest; pi?: PluginManifest };
|
|
@@ -204,13 +204,13 @@ export interface TurnEndEvent {
|
|
|
204
204
|
export interface AutoCompactionStartEvent {
|
|
205
205
|
type: "auto_compaction_start";
|
|
206
206
|
reason: "threshold" | "overflow" | "idle" | "incomplete";
|
|
207
|
-
action: "context-full" | "handoff";
|
|
207
|
+
action: "context-full" | "handoff" | "shake";
|
|
208
208
|
}
|
|
209
209
|
|
|
210
210
|
/** Fired when auto-compaction ends */
|
|
211
211
|
export interface AutoCompactionEndEvent {
|
|
212
212
|
type: "auto_compaction_end";
|
|
213
|
-
action: "context-full" | "handoff";
|
|
213
|
+
action: "context-full" | "handoff" | "shake";
|
|
214
214
|
result: CompactionResult | undefined;
|
|
215
215
|
aborted: boolean;
|
|
216
216
|
willRetry: boolean;
|