@oh-my-pi/pi-coding-agent 15.11.4 → 15.11.7

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 (98) hide show
  1. package/CHANGELOG.md +82 -1
  2. package/dist/cli.js +520 -451
  3. package/dist/types/cli/bench-cli.d.ts +78 -0
  4. package/dist/types/cli/usage-cli.d.ts +10 -1
  5. package/dist/types/commands/bench.d.ts +29 -0
  6. package/dist/types/commands/usage.d.ts +9 -0
  7. package/dist/types/config/model-resolver.d.ts +3 -2
  8. package/dist/types/config/settings-schema.d.ts +125 -3
  9. package/dist/types/edit/renderer.d.ts +1 -0
  10. package/dist/types/modes/components/oauth-selector.d.ts +10 -1
  11. package/dist/types/modes/components/reset-usage-selector.d.ts +12 -0
  12. package/dist/types/modes/components/session-selector.d.ts +1 -1
  13. package/dist/types/modes/components/settings-selector.d.ts +8 -1
  14. package/dist/types/modes/components/snapcompact-shape-preview.d.ts +31 -0
  15. package/dist/types/modes/components/tool-execution.d.ts +18 -0
  16. package/dist/types/modes/controllers/selector-controller.d.ts +1 -0
  17. package/dist/types/modes/interactive-mode.d.ts +10 -0
  18. package/dist/types/modes/session-observer-registry.d.ts +2 -0
  19. package/dist/types/modes/setup-wizard/scenes/sign-in.d.ts +3 -0
  20. package/dist/types/modes/setup-wizard/scenes/types.d.ts +10 -1
  21. package/dist/types/modes/setup-wizard/scenes/web-search.d.ts +3 -0
  22. package/dist/types/modes/types.d.ts +2 -0
  23. package/dist/types/modes/utils/context-usage.d.ts +6 -1
  24. package/dist/types/session/agent-session.d.ts +14 -1
  25. package/dist/types/session/auth-storage.d.ts +1 -1
  26. package/dist/types/session/codex-auto-reset.d.ts +107 -0
  27. package/dist/types/session/snapcompact-inline.d.ts +107 -4
  28. package/dist/types/slash-commands/helpers/reset-usage.d.ts +27 -0
  29. package/dist/types/task/render.d.ts +1 -0
  30. package/dist/types/tools/bash.d.ts +2 -0
  31. package/dist/types/tools/eval-render.d.ts +1 -0
  32. package/dist/types/tools/renderers.d.ts +13 -0
  33. package/dist/types/tools/ssh.d.ts +1 -0
  34. package/dist/types/tools/todo.d.ts +0 -11
  35. package/package.json +11 -11
  36. package/src/cli/bench-cli.ts +437 -0
  37. package/src/cli/usage-cli.ts +187 -16
  38. package/src/cli-commands.ts +1 -0
  39. package/src/commands/bench.ts +42 -0
  40. package/src/commands/usage.ts +8 -0
  41. package/src/config/model-registry.ts +52 -5
  42. package/src/config/model-resolver.ts +36 -5
  43. package/src/config/settings-schema.ts +148 -3
  44. package/src/config/settings.ts +9 -0
  45. package/src/edit/renderer.ts +5 -0
  46. package/src/hindsight/client.ts +26 -1
  47. package/src/hindsight/state.ts +6 -2
  48. package/src/internal-urls/docs-index.generated.ts +2 -2
  49. package/src/mcp/transports/stdio.ts +81 -7
  50. package/src/modes/components/oauth-selector.ts +67 -7
  51. package/src/modes/components/reset-usage-selector.ts +161 -0
  52. package/src/modes/components/session-selector.ts +8 -2
  53. package/src/modes/components/settings-selector.ts +89 -47
  54. package/src/modes/components/snapcompact-shape-preview-doc.md +11 -0
  55. package/src/modes/components/snapcompact-shape-preview.ts +192 -0
  56. package/src/modes/components/tool-execution.ts +26 -0
  57. package/src/modes/components/transcript-container.ts +23 -1
  58. package/src/modes/controllers/command-controller.ts +24 -1
  59. package/src/modes/controllers/input-controller.ts +8 -6
  60. package/src/modes/controllers/selector-controller.ts +72 -2
  61. package/src/modes/interactive-mode.ts +83 -0
  62. package/src/modes/session-observer-registry.ts +61 -3
  63. package/src/modes/setup-wizard/index.ts +1 -0
  64. package/src/modes/setup-wizard/scenes/glyph.ts +24 -6
  65. package/src/modes/setup-wizard/scenes/providers.ts +36 -2
  66. package/src/modes/setup-wizard/scenes/sign-in.ts +10 -1
  67. package/src/modes/setup-wizard/scenes/theme.ts +28 -1
  68. package/src/modes/setup-wizard/scenes/types.ts +10 -1
  69. package/src/modes/setup-wizard/scenes/web-search.ts +22 -6
  70. package/src/modes/setup-wizard/wizard-overlay.ts +38 -1
  71. package/src/modes/theme/theme.ts +2 -2
  72. package/src/modes/types.ts +2 -0
  73. package/src/modes/utils/context-usage.ts +75 -1
  74. package/src/prompts/bench.md +7 -0
  75. package/src/prompts/system/snapcompact-context-frames-note.md +1 -0
  76. package/src/prompts/system/snapcompact-context-stub.md +1 -0
  77. package/src/prompts/system/snapcompact-toolresult-note.md +1 -1
  78. package/src/prompts/tools/browser.md +33 -43
  79. package/src/prompts/tools/eval.md +27 -50
  80. package/src/prompts/tools/irc.md +29 -31
  81. package/src/prompts/tools/read.md +31 -37
  82. package/src/prompts/tools/todo.md +1 -2
  83. package/src/sdk.ts +4 -2
  84. package/src/session/agent-session.ts +136 -6
  85. package/src/session/auth-storage.ts +3 -0
  86. package/src/session/codex-auto-reset.ts +190 -0
  87. package/src/session/snapcompact-inline.ts +404 -75
  88. package/src/slash-commands/builtin-registry.ts +145 -8
  89. package/src/slash-commands/helpers/context-report.ts +28 -1
  90. package/src/slash-commands/helpers/reset-usage.ts +66 -0
  91. package/src/slash-commands/helpers/usage-report.ts +12 -0
  92. package/src/task/index.ts +30 -7
  93. package/src/task/render.ts +34 -19
  94. package/src/tools/bash.ts +3 -0
  95. package/src/tools/eval-render.ts +4 -0
  96. package/src/tools/renderers.ts +13 -0
  97. package/src/tools/ssh.ts +3 -0
  98. package/src/tools/todo.ts +8 -128
package/src/tools/todo.ts CHANGED
@@ -21,13 +21,6 @@ export type TodoStatus = "pending" | "in_progress" | "completed" | "abandoned";
21
21
  export interface TodoItem {
22
22
  content: string;
23
23
  status: TodoStatus;
24
- /**
25
- * Append-only list of freeform notes attached by `op: "note"`.
26
- * Each element is one note and may itself be multi-line.
27
- * Rendered as text only when the task is in_progress; otherwise shown as a
28
- * dim marker indicating the task has notes.
29
- */
30
- notes?: string[];
31
24
  }
32
25
 
33
26
  export interface TodoPhase {
@@ -51,7 +44,7 @@ export interface TodoToolDetails {
51
44
  // =============================================================================
52
45
 
53
46
  const TodoOp = z
54
- .enum(["init", "start", "done", "rm", "drop", "append", "note", "view"] as const)
47
+ .enum(["init", "start", "done", "rm", "drop", "append", "view"] as const)
55
48
  .describe("operation to apply");
56
49
 
57
50
  const InitListEntry = z.object({
@@ -65,7 +58,6 @@ const TodoOpEntry = z.object({
65
58
  task: z.string().optional().describe("task content"),
66
59
  phase: z.string().optional().describe("phase name"),
67
60
  items: z.array(z.string().describe("task content")).min(1).optional().describe("tasks to append"),
68
- text: z.string().optional().describe("note text"),
69
61
  });
70
62
 
71
63
  const todoSchema = z
@@ -94,9 +86,7 @@ function findPhaseByName(phases: TodoPhase[], name: string): TodoPhase | undefin
94
86
  }
95
87
 
96
88
  function cloneTask(task: TodoItem): TodoItem {
97
- const out: TodoItem = { content: task.content, status: task.status };
98
- if (task.notes && task.notes.length > 0) out.notes = [...task.notes];
99
- return out;
89
+ return { content: task.content, status: task.status };
100
90
  }
101
91
 
102
92
  function clonePhases(phases: TodoPhase[]): TodoPhase[] {
@@ -392,17 +382,6 @@ function applyEntry(phases: TodoPhase[], entry: TodoOpEntryValue, errors: string
392
382
  }
393
383
  case "rm":
394
384
  return removeTasks(phases, entry, errors);
395
- case "note": {
396
- const hit = resolveTaskOrError(phases, entry.task, errors);
397
- if (!hit) return phases;
398
- const text = (entry.text ?? "").replace(/\s+$/u, "");
399
- if (!text) {
400
- errors.push("Missing text for note operation");
401
- return phases;
402
- }
403
- hit.task.notes = hit.task.notes ? [...hit.task.notes, text] : [text];
404
- return phases;
405
- }
406
385
  case "append":
407
386
  return appendItems(phases, entry, errors);
408
387
  case "view":
@@ -448,14 +427,6 @@ export function phasesToMarkdown(phases: TodoPhase[]): string {
448
427
  out.push(`# ${phases[i].name}`);
449
428
  for (const task of phases[i].tasks) {
450
429
  out.push(`- [${STATUS_TO_MARKER[task.status]}] ${task.content}`);
451
- if (task.notes && task.notes.length > 0) {
452
- for (let j = 0; j < task.notes.length; j++) {
453
- if (j > 0) out.push(" >");
454
- for (const noteLine of task.notes[j].split("\n")) {
455
- out.push(noteLine === "" ? " >" : ` > ${noteLine}`);
456
- }
457
- }
458
- }
459
430
  }
460
431
  }
461
432
  return `${out.join("\n")}\n`;
@@ -477,45 +448,16 @@ export function markdownToPhases(md: string): { phases: TodoPhase[]; errors: str
477
448
  const errors: string[] = [];
478
449
  const phases: TodoPhase[] = [];
479
450
  let currentPhase: TodoPhase | undefined;
480
- let currentTask: TodoItem | undefined;
481
- let noteBuf: string[] = [];
482
-
483
- const flushNote = () => {
484
- if (!currentTask || noteBuf.length === 0) {
485
- noteBuf = [];
486
- return;
487
- }
488
- while (noteBuf.length > 0 && noteBuf[noteBuf.length - 1] === "") noteBuf.pop();
489
- if (noteBuf.length === 0) return;
490
- const joined = noteBuf.join("\n");
491
- currentTask.notes = currentTask.notes ? [...currentTask.notes, joined] : [joined];
492
- noteBuf = [];
493
- };
494
451
 
495
452
  const lines = md.split(/\r?\n/);
496
453
  for (let lineNum = 0; lineNum < lines.length; lineNum++) {
497
454
  const raw = lines[lineNum];
498
455
 
499
- // Blockquote line attached to the current task: ` > text` or ` >`
500
- const noteMatch = /^\s*>\s?(.*)$/.exec(raw);
501
- if (noteMatch && currentTask) {
502
- const noteLine = noteMatch[1];
503
- if (noteLine === "") {
504
- // Blank `>` separates two distinct notes
505
- flushNote();
506
- } else {
507
- noteBuf.push(noteLine);
508
- }
509
- continue;
510
- }
511
-
512
456
  const trimmed = raw.trim();
513
457
  if (!trimmed) continue;
514
458
 
515
459
  const headingMatch = /^#{1,6}\s+(.+?)\s*$/.exec(trimmed);
516
460
  if (headingMatch) {
517
- flushNote();
518
- currentTask = undefined;
519
461
  currentPhase = { name: headingMatch[1].trim(), tasks: [] };
520
462
  phases.push(currentPhase);
521
463
  continue;
@@ -523,7 +465,6 @@ export function markdownToPhases(md: string): { phases: TodoPhase[]; errors: str
523
465
 
524
466
  const taskMatch = /^[-*+]\s*\[(.?)\]\s+(.+?)\s*$/.exec(trimmed);
525
467
  if (taskMatch) {
526
- flushNote();
527
468
  if (!currentPhase) {
528
469
  currentPhase = { name: "Todos", tasks: [] };
529
470
  phases.push(currentPhase);
@@ -532,19 +473,14 @@ export function markdownToPhases(md: string): { phases: TodoPhase[]; errors: str
532
473
  const status = MARKER_TO_STATUS[marker];
533
474
  if (!status) {
534
475
  errors.push(`Line ${lineNum + 1}: unknown status marker "[${marker}]" (use [ ], [x], [/], [-])`);
535
- currentTask = undefined;
536
476
  continue;
537
477
  }
538
- currentTask = { content: taskMatch[2].trim(), status };
539
- currentPhase.tasks.push(currentTask);
478
+ currentPhase.tasks.push({ content: taskMatch[2].trim(), status });
540
479
  continue;
541
480
  }
542
481
 
543
- flushNote();
544
- currentTask = undefined;
545
482
  errors.push(`Line ${lineNum + 1}: unrecognized syntax "${trimmed}"`);
546
483
  }
547
- flushNote();
548
484
 
549
485
  normalizeInProgressTask(phases);
550
486
  return { phases, errors };
@@ -596,17 +532,7 @@ function formatSummary(phases: TodoPhase[], errors: string[], readOnly = false):
596
532
  : task.status === "abandoned"
597
533
  ? "✗"
598
534
  : "○";
599
- const noteCount = task.notes?.length ?? 0;
600
- const noteMarker = noteCount > 0 ? ` (+${noteCount} note${noteCount === 1 ? "" : "s"})` : "";
601
- lines.push(` ${sym} ${task.content}${noteMarker}`);
602
- if (task.status === "in_progress" && task.notes && task.notes.length > 0) {
603
- for (let j = 0; j < task.notes.length; j++) {
604
- if (j > 0) lines.push(" ---");
605
- for (const noteLine of task.notes[j].split("\n")) {
606
- lines.push(` ${noteLine}`);
607
- }
608
- }
609
- }
535
+ lines.push(` ${sym} ${task.content}`);
610
536
  }
611
537
  }
612
538
  return lines.join("\n");
@@ -675,27 +601,6 @@ type TodoRenderArgs = {
675
601
  }>;
676
602
  };
677
603
 
678
- const SUP_DIGITS: Record<string, string> = {
679
- "0": "\u2070",
680
- "1": "\u00b9",
681
- "2": "\u00b2",
682
- "3": "\u00b3",
683
- "4": "\u2074",
684
- "5": "\u2075",
685
- "6": "\u2076",
686
- "7": "\u2077",
687
- "8": "\u2078",
688
- "9": "\u2079",
689
- };
690
-
691
- function toSuperscript(n: number): string {
692
- return n
693
- .toString()
694
- .split("")
695
- .map(d => SUP_DIGITS[d] ?? d)
696
- .join("");
697
- }
698
-
699
604
  // =============================================================================
700
605
  // Phase numbering (display-only)
701
606
  // =============================================================================
@@ -735,11 +640,6 @@ export function formatPhaseDisplayName(name: string, oneBasedIndex: number): str
735
640
  return `${phaseRomanNumeral(oneBasedIndex)}. ${name}`;
736
641
  }
737
642
 
738
- function noteMarker(count: number, uiTheme: Theme): string {
739
- if (count <= 0) return "";
740
- return uiTheme.fg("dim", chalk.italic(` \u207a${toSuperscript(count)}`));
741
- }
742
-
743
643
  export const TODO_STRIKE_HOLD_FRAMES = 2;
744
644
  export const TODO_STRIKE_REVEAL_FRAMES = 12;
745
645
  export const TODO_STRIKE_TOTAL_FRAMES = TODO_STRIKE_HOLD_FRAMES + TODO_STRIKE_REVEAL_FRAMES;
@@ -775,7 +675,6 @@ function formatTodoLine(
775
675
  frame: number | undefined,
776
676
  ): string {
777
677
  const checkbox = uiTheme.checkbox;
778
- const marker = noteMarker(item.notes?.length ?? 0, uiTheme);
779
678
  switch (item.status) {
780
679
  case "completed": {
781
680
  const revealCount = completionKeys.has(item.content) ? strikeRevealCount(item.content, frame) : undefined;
@@ -783,33 +682,15 @@ function formatTodoLine(
783
682
  revealCount === undefined
784
683
  ? strikethroughText(item.content)
785
684
  : partialStrikethrough(item.content, revealCount);
786
- return uiTheme.fg("success", `${prefix}${checkbox.checked} ${content}`) + marker;
685
+ return uiTheme.fg("success", `${prefix}${checkbox.checked} ${content}`);
787
686
  }
788
687
  case "in_progress":
789
- return uiTheme.fg("accent", `${prefix}${checkbox.unchecked} ${item.content}`) + marker;
688
+ return uiTheme.fg("accent", `${prefix}${checkbox.unchecked} ${item.content}`);
790
689
  case "abandoned":
791
- return uiTheme.fg("error", `${prefix}${checkbox.unchecked} ${strikethroughText(item.content)}`) + marker;
690
+ return uiTheme.fg("error", `${prefix}${checkbox.unchecked} ${strikethroughText(item.content)}`);
792
691
  default:
793
- return uiTheme.fg("dim", `${prefix}${checkbox.unchecked} ${item.content}`) + marker;
794
- }
795
- }
796
-
797
- function renderNoteAttachments(phases: TodoPhase[], uiTheme: Theme, indent: string): string[] {
798
- const lines: string[] = [];
799
- for (const phase of phases) {
800
- for (const task of phase.tasks) {
801
- if (task.status !== "in_progress" || !task.notes || task.notes.length === 0) continue;
802
- lines.push("");
803
- lines.push(`${indent}${uiTheme.fg("dim", chalk.italic(`§ notes — ${task.content}`))}`);
804
- for (let j = 0; j < task.notes.length; j++) {
805
- if (j > 0) lines.push("");
806
- for (const noteLine of task.notes[j].split("\n")) {
807
- lines.push(`${indent} ${uiTheme.fg("dim", noteLine)}`);
808
- }
809
- }
810
- }
692
+ return uiTheme.fg("dim", `${prefix}${checkbox.unchecked} ${item.content}`);
811
693
  }
812
- return lines;
813
694
  }
814
695
 
815
696
  /**
@@ -966,7 +847,6 @@ export const todoToolRenderer = {
966
847
  bodyLines.push(`${indent}${line}`);
967
848
  }
968
849
  }
969
- bodyLines.push(...renderNoteAttachments(phases, uiTheme, indent));
970
850
  while (bodyLines.length > 0 && bodyLines[0].trim() === "") bodyLines.shift();
971
851
  return {
972
852
  header,