@oh-my-pi/pi-coding-agent 14.5.8 → 14.5.9

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 (37) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/package.json +7 -7
  3. package/src/config/settings-schema.ts +3 -3
  4. package/src/edit/modes/atom.lark +7 -5
  5. package/src/edit/modes/atom.ts +462 -56
  6. package/src/edit/modes/hashline.ts +21 -1
  7. package/src/lsp/index.ts +2 -4
  8. package/src/lsp/render.ts +0 -3
  9. package/src/lsp/types.ts +1 -4
  10. package/src/lsp/utils.ts +18 -14
  11. package/src/modes/controllers/command-controller.ts +17 -0
  12. package/src/modes/controllers/input-controller.ts +7 -1
  13. package/src/modes/interactive-mode.ts +30 -23
  14. package/src/modes/types.ts +4 -2
  15. package/src/modes/utils/context-usage.ts +294 -0
  16. package/src/prompts/tools/atom.md +99 -44
  17. package/src/prompts/tools/exit-plan-mode.md +5 -39
  18. package/src/prompts/tools/lsp.md +2 -3
  19. package/src/prompts/tools/{run-command.md → recipe.md} +1 -1
  20. package/src/prompts/tools/task.md +34 -147
  21. package/src/prompts/tools/todo-write.md +22 -64
  22. package/src/session/compaction/compaction.ts +35 -22
  23. package/src/session/session-dump-format.ts +1 -0
  24. package/src/slash-commands/builtin-registry.ts +12 -5
  25. package/src/tools/debug.ts +57 -70
  26. package/src/tools/index.ts +7 -7
  27. package/src/tools/{run-command → recipe}/index.ts +19 -19
  28. package/src/tools/recipe/render.ts +19 -0
  29. package/src/tools/{run-command → recipe}/runner.ts +28 -7
  30. package/src/tools/{run-command → recipe}/runners/pkg.ts +23 -53
  31. package/src/tools/renderers.ts +2 -2
  32. package/src/tools/run-command/render.ts +0 -18
  33. /package/src/tools/{run-command → recipe}/runners/cargo.ts +0 -0
  34. /package/src/tools/{run-command → recipe}/runners/index.ts +0 -0
  35. /package/src/tools/{run-command → recipe}/runners/just.ts +0 -0
  36. /package/src/tools/{run-command → recipe}/runners/make.ts +0 -0
  37. /package/src/tools/{run-command → recipe}/runners/task.ts +0 -0
@@ -9,9 +9,23 @@ interface PackageJsonInfo {
9
9
  workspaces: string[];
10
10
  }
11
11
 
12
- interface PackageCommandInfo {
13
- rootCommandPrefix: string;
14
- workspaceCommandPrefix: (relativeDir: string) => string;
12
+ async function resolvePackageRunner(cwd: string): Promise<string> {
13
+ if ((await isFile(path.join(cwd, "bun.lock"))) || (await isFile(path.join(cwd, "bun.lockb")))) {
14
+ return "bun run";
15
+ }
16
+ if (await isFile(path.join(cwd, "pnpm-lock.yaml"))) {
17
+ return "pnpm run";
18
+ }
19
+ if (await isFile(path.join(cwd, "yarn.lock"))) {
20
+ return "yarn";
21
+ }
22
+ if ((await isFile(path.join(cwd, "package-lock.json"))) || (await isFile(path.join(cwd, "npm-shrinkwrap.json")))) {
23
+ return "npm run";
24
+ }
25
+ if ($which("bun")) {
26
+ return "bun run";
27
+ }
28
+ return "npm run";
15
29
  }
16
30
 
17
31
  function isRecord(value: unknown): value is Record<string, unknown> {
@@ -32,43 +46,6 @@ async function isFile(filePath: string): Promise<boolean> {
32
46
  }
33
47
  }
34
48
 
35
- async function resolvePackageRunner(cwd: string): Promise<PackageCommandInfo> {
36
- if ((await isFile(path.join(cwd, "bun.lock"))) || (await isFile(path.join(cwd, "bun.lockb")))) {
37
- return {
38
- rootCommandPrefix: "bun run",
39
- workspaceCommandPrefix: relativeDir => `bun --cwd ${shellQuote(relativeDir)} run`,
40
- };
41
- }
42
- if (await isFile(path.join(cwd, "pnpm-lock.yaml"))) {
43
- return {
44
- rootCommandPrefix: "pnpm run",
45
- workspaceCommandPrefix: relativeDir => `pnpm --dir ${shellQuote(relativeDir)} run`,
46
- };
47
- }
48
- if (await isFile(path.join(cwd, "yarn.lock"))) {
49
- return {
50
- rootCommandPrefix: "yarn",
51
- workspaceCommandPrefix: relativeDir => `yarn --cwd ${shellQuote(relativeDir)}`,
52
- };
53
- }
54
- if ((await isFile(path.join(cwd, "package-lock.json"))) || (await isFile(path.join(cwd, "npm-shrinkwrap.json")))) {
55
- return {
56
- rootCommandPrefix: "npm run",
57
- workspaceCommandPrefix: relativeDir => `npm --prefix ${shellQuote(relativeDir)} run`,
58
- };
59
- }
60
- if ($which("bun")) {
61
- return {
62
- rootCommandPrefix: "bun run",
63
- workspaceCommandPrefix: relativeDir => `bun --cwd ${shellQuote(relativeDir)} run`,
64
- };
65
- }
66
- return {
67
- rootCommandPrefix: "npm run",
68
- workspaceCommandPrefix: relativeDir => `npm --prefix ${shellQuote(relativeDir)} run`,
69
- };
70
- }
71
-
72
49
  function parseWorkspacePatterns(pkg: Record<string, unknown>): string[] {
73
50
  const { workspaces } = pkg;
74
51
  if (Array.isArray(workspaces)) return workspaces.filter((entry): entry is string => typeof entry === "string");
@@ -129,22 +106,17 @@ function packageTaskName(packageName: string | undefined, packageDir: string, sc
129
106
  return `${packageName ?? packageDir}/${scriptName}`;
130
107
  }
131
108
 
132
- function tasksForPackage(options: {
133
- pkg: PackageJsonInfo;
134
- packageDir: string;
135
- commandPrefix: string;
136
- namespaced: boolean;
137
- }): RunnerTask[] {
109
+ function tasksForPackage(options: { pkg: PackageJsonInfo; packageDir: string; namespaced: boolean }): RunnerTask[] {
138
110
  return options.pkg.scripts.map(scriptName => ({
139
111
  name: options.namespaced ? packageTaskName(options.pkg.name, options.packageDir, scriptName) : scriptName,
140
112
  doc: options.namespaced ? options.packageDir : undefined,
141
113
  parameters: [],
142
- commandPrefix: options.commandPrefix,
114
+ cwd: options.namespaced ? options.packageDir : undefined,
143
115
  commandName: shellQuote(scriptName),
144
116
  }));
145
117
  }
146
118
 
147
- async function readPackageTasks(cwd: string, commandInfo: PackageCommandInfo): Promise<RunnerTask[] | null> {
119
+ async function readPackageTasks(cwd: string): Promise<RunnerTask[] | null> {
148
120
  const rootPkg = await readPackageJson(path.join(cwd, "package.json"));
149
121
  if (!rootPkg) return null;
150
122
  const workspacePackageJsons = await findWorkspacePackageJsons(cwd, rootPkg.workspaces);
@@ -155,7 +127,6 @@ async function readPackageTasks(cwd: string, commandInfo: PackageCommandInfo): P
155
127
  ...tasksForPackage({
156
128
  pkg: rootPkg,
157
129
  packageDir: ".",
158
- commandPrefix: commandInfo.rootCommandPrefix,
159
130
  namespaced: false,
160
131
  }),
161
132
  );
@@ -169,7 +140,6 @@ async function readPackageTasks(cwd: string, commandInfo: PackageCommandInfo): P
169
140
  ...tasksForPackage({
170
141
  pkg,
171
142
  packageDir,
172
- commandPrefix: commandInfo.workspaceCommandPrefix(packageDir),
173
143
  namespaced: true,
174
144
  }),
175
145
  );
@@ -183,10 +153,10 @@ export const pkgRunner: TaskRunner = {
183
153
  label: "Pkg",
184
154
  async detect(cwd: string): Promise<DetectedRunner | null> {
185
155
  try {
186
- const commandInfo = await resolvePackageRunner(cwd);
187
- const tasks = await readPackageTasks(cwd, commandInfo);
156
+ const commandPrefix = await resolvePackageRunner(cwd);
157
+ const tasks = await readPackageTasks(cwd);
188
158
  if (!tasks || tasks.length === 0) return null;
189
- return { id: "pkg", label: "Pkg", commandPrefix: commandInfo.rootCommandPrefix, tasks };
159
+ return { id: "pkg", label: "Pkg", commandPrefix, tasks };
190
160
  } catch (err) {
191
161
  logger.debug("package runner probe failed", { error: err instanceof Error ? err.message : String(err) });
192
162
  return null;
@@ -23,8 +23,8 @@ import { jobToolRenderer } from "./job";
23
23
  import { notebookToolRenderer } from "./notebook";
24
24
  import { pythonToolRenderer } from "./python";
25
25
  import { readToolRenderer } from "./read";
26
+ import { recipeToolRenderer } from "./recipe/render";
26
27
  import { resolveToolRenderer } from "./resolve";
27
- import { runCommandToolRenderer } from "./run-command/render";
28
28
  import { searchToolRenderer } from "./search";
29
29
  import { searchToolBm25Renderer } from "./search-tool-bm25";
30
30
  import { sshToolRenderer } from "./ssh";
@@ -49,7 +49,7 @@ export const toolRenderers: Record<string, ToolRenderer> = {
49
49
  ast_grep: astGrepToolRenderer as ToolRenderer,
50
50
  ast_edit: astEditToolRenderer as ToolRenderer,
51
51
  bash: bashToolRenderer as ToolRenderer,
52
- run_command: runCommandToolRenderer as ToolRenderer,
52
+ recipe: recipeToolRenderer as ToolRenderer,
53
53
  debug: debugToolRenderer as ToolRenderer,
54
54
  python: pythonToolRenderer as ToolRenderer,
55
55
  calc: calculatorToolRenderer as ToolRenderer,
@@ -1,18 +0,0 @@
1
- import { createShellRenderer } from "../bash";
2
- import type { DetectedRunner } from "./runner";
3
- import { commandFromOp, titleFromOp } from "./runner";
4
-
5
- export interface RunCommandRenderArgs {
6
- op?: string;
7
- __partialJson?: string;
8
- [key: string]: unknown;
9
- }
10
-
11
- export function createRunCommandToolRenderer(runners: DetectedRunner[]) {
12
- return createShellRenderer<RunCommandRenderArgs>({
13
- resolveTitle: args => titleFromOp(args?.op, runners),
14
- resolveCommand: args => commandFromOp(args?.op, runners),
15
- });
16
- }
17
-
18
- export const runCommandToolRenderer = createRunCommandToolRenderer([]);