@oh-my-pi/pi-coding-agent 15.5.15 → 15.7.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.
- package/CHANGELOG.md +81 -0
- package/dist/types/capability/rule-buckets.d.ts +30 -0
- package/dist/types/capability/rule.d.ts +7 -0
- package/dist/types/cli/classify-install-target.d.ts +0 -10
- package/dist/types/cli/completion-gen.d.ts +80 -0
- package/dist/types/cli/initial-message.d.ts +1 -1
- package/dist/types/cli/tiny-models-cli.d.ts +9 -0
- package/dist/types/commands/complete.d.ts +6 -0
- package/dist/types/commands/completions.d.ts +13 -0
- package/dist/types/commands/setup.d.ts +10 -1
- package/dist/types/commands/tiny-models.d.ts +22 -0
- package/dist/types/commit/analysis/conventional.d.ts +1 -1
- package/dist/types/commit/analysis/summary.d.ts +1 -1
- package/dist/types/commit/changelog/generate.d.ts +1 -1
- package/dist/types/commit/changelog/index.d.ts +2 -2
- package/dist/types/commit/map-reduce/map-phase.d.ts +1 -1
- package/dist/types/commit/map-reduce/reduce-phase.d.ts +1 -1
- package/dist/types/config/model-id-affixes.d.ts +10 -0
- package/dist/types/config/settings-schema.d.ts +402 -17
- package/dist/types/discovery/builtin-defaults.d.ts +1 -0
- package/dist/types/discovery/builtin-rules/index.d.ts +7 -0
- package/dist/types/discovery/helpers.d.ts +1 -1
- package/dist/types/discovery/index.d.ts +1 -0
- package/dist/types/discovery/substitute-plugin-root.d.ts +0 -4
- package/dist/types/edit/hashline/block-resolver.d.ts +9 -0
- package/dist/types/edit/hashline/index.d.ts +1 -0
- package/dist/types/eval/js/shared/rewrite-imports.d.ts +16 -1
- package/dist/types/eval/py/kernel.d.ts +3 -0
- package/dist/types/eval/py/runtime.d.ts +11 -1
- package/dist/types/export/html/template.generated.d.ts +1 -1
- package/dist/types/internal-urls/agent-protocol.d.ts +2 -1
- package/dist/types/internal-urls/artifact-protocol.d.ts +2 -1
- package/dist/types/internal-urls/local-protocol.d.ts +2 -1
- package/dist/types/internal-urls/memory-protocol.d.ts +2 -1
- package/dist/types/internal-urls/omp-protocol.d.ts +2 -1
- package/dist/types/internal-urls/router.d.ts +8 -1
- package/dist/types/internal-urls/rule-protocol.d.ts +2 -1
- package/dist/types/internal-urls/skill-protocol.d.ts +2 -1
- package/dist/types/internal-urls/types.d.ts +26 -0
- package/dist/types/main.d.ts +1 -0
- package/dist/types/memory-backend/index.d.ts +1 -0
- package/dist/types/memory-backend/resolve.d.ts +2 -1
- package/dist/types/memory-backend/types.d.ts +7 -1
- package/dist/types/mnemosyne/backend.d.ts +4 -0
- package/dist/types/mnemosyne/config.d.ts +29 -0
- package/dist/types/mnemosyne/index.d.ts +3 -0
- package/dist/types/mnemosyne/state.d.ts +72 -0
- package/dist/types/modes/components/custom-editor.d.ts +2 -3
- package/dist/types/modes/components/hook-selector.d.ts +27 -0
- package/dist/types/modes/components/index.d.ts +2 -0
- package/dist/types/modes/components/segment-track.d.ts +22 -0
- package/dist/types/modes/components/status-line/context-thresholds.d.ts +6 -0
- package/dist/types/modes/components/tiny-title-download-progress.d.ts +11 -0
- package/dist/types/modes/components/welcome.d.ts +22 -0
- package/dist/types/modes/controllers/extension-ui-controller.d.ts +4 -1
- package/dist/types/modes/gradient-highlight.d.ts +23 -0
- package/dist/types/modes/interactive-mode.d.ts +7 -4
- package/dist/types/modes/internal-url-autocomplete.d.ts +43 -0
- package/dist/types/modes/orchestrate.d.ts +10 -0
- package/dist/types/modes/setup-wizard/index.d.ts +16 -0
- package/dist/types/modes/setup-wizard/scenes/glyph.d.ts +2 -0
- package/dist/types/modes/setup-wizard/scenes/outro.d.ts +2 -0
- package/dist/types/modes/setup-wizard/scenes/providers.d.ts +2 -0
- package/dist/types/modes/setup-wizard/scenes/sign-in.d.ts +19 -0
- package/dist/types/modes/setup-wizard/scenes/splash.d.ts +11 -0
- package/dist/types/modes/setup-wizard/scenes/theme.d.ts +2 -0
- package/dist/types/modes/setup-wizard/scenes/types.d.ts +43 -0
- package/dist/types/modes/setup-wizard/scenes/web-search.d.ts +19 -0
- package/dist/types/modes/setup-wizard/wizard-overlay.d.ts +14 -0
- package/dist/types/modes/theme/defaults/index.d.ts +8406 -8406
- package/dist/types/modes/theme/shimmer.d.ts +2 -0
- package/dist/types/modes/theme/theme.d.ts +11 -0
- package/dist/types/modes/types.d.ts +5 -1
- package/dist/types/modes/ultrathink.d.ts +3 -3
- package/dist/types/modes/utils/keybinding-matchers.d.ts +5 -0
- package/dist/types/sdk.d.ts +3 -0
- package/dist/types/session/agent-session.d.ts +33 -0
- package/dist/types/system-prompt.d.ts +2 -0
- package/dist/types/task/executor.d.ts +2 -0
- package/dist/types/task/render.d.ts +5 -1
- package/dist/types/tiny/device.d.ts +78 -0
- package/dist/types/tiny/dtype.d.ts +85 -0
- package/dist/types/tiny/models.d.ts +185 -0
- package/dist/types/tiny/text.d.ts +19 -0
- package/dist/types/tiny/title-client.d.ts +32 -0
- package/dist/types/tiny/title-protocol.d.ts +74 -0
- package/dist/types/tiny/worker.d.ts +2 -0
- package/dist/types/tools/bash.d.ts +3 -2
- package/dist/types/tools/eval.d.ts +1 -1
- package/dist/types/tools/index.d.ts +7 -4
- package/dist/types/tools/memory-edit.d.ts +40 -0
- package/dist/types/tools/{hindsight-recall.d.ts → memory-recall.d.ts} +6 -6
- package/dist/types/tools/{hindsight-reflect.d.ts → memory-reflect.d.ts} +6 -6
- package/dist/types/tools/memory-render.d.ts +60 -0
- package/dist/types/tools/{hindsight-retain.d.ts → memory-retain.d.ts} +6 -6
- package/dist/types/tools/todo-write.d.ts +8 -0
- package/dist/types/tools/tool-result.d.ts +2 -0
- package/dist/types/tui/code-cell.d.ts +2 -0
- package/dist/types/tui/output-block.d.ts +17 -0
- package/dist/types/utils/title-generator.d.ts +3 -0
- package/package.json +18 -14
- package/scripts/build-binary.ts +1 -0
- package/src/capability/rule-buckets.ts +64 -0
- package/src/capability/rule.ts +8 -0
- package/src/cli/completion-gen.ts +550 -0
- package/src/cli/setup-cli.ts +5 -3
- package/src/cli/tiny-models-cli.ts +127 -0
- package/src/cli-commands.ts +3 -0
- package/src/cli.ts +9 -15
- package/src/commands/complete.ts +66 -0
- package/src/commands/completions.ts +60 -0
- package/src/commands/setup.ts +29 -4
- package/src/commands/tiny-models.ts +36 -0
- package/src/config/model-equivalence.ts +43 -2
- package/src/config/model-id-affixes.ts +64 -0
- package/src/config/model-registry.ts +84 -10
- package/src/config/settings-schema.ts +275 -15
- package/src/discovery/builtin-defaults.ts +39 -0
- package/src/discovery/builtin-rules/index.ts +48 -0
- package/src/discovery/builtin-rules/rs-box-leak.md +48 -0
- package/src/discovery/builtin-rules/rs-future-prelude.md +23 -0
- package/src/discovery/builtin-rules/rs-lazylock.md +51 -0
- package/src/discovery/builtin-rules/rs-match-ergonomics.md +67 -0
- package/src/discovery/builtin-rules/rs-parking-lot.md +44 -0
- package/src/discovery/builtin-rules/rs-result-type.md +19 -0
- package/src/discovery/builtin-rules/ts-bare-catch.md +38 -0
- package/src/discovery/builtin-rules/ts-import-type.md +42 -0
- package/src/discovery/builtin-rules/ts-no-any.md +56 -0
- package/src/discovery/builtin-rules/ts-no-dynamic-import.md +39 -0
- package/src/discovery/builtin-rules/ts-no-return-type.md +45 -0
- package/src/discovery/builtin-rules/ts-no-tiny-functions.md +50 -0
- package/src/discovery/builtin-rules/ts-promise-with-resolvers.md +65 -0
- package/src/discovery/builtin-rules/ts-set-map.md +28 -0
- package/src/discovery/index.ts +1 -0
- package/src/edit/hashline/block-resolver.ts +14 -0
- package/src/edit/hashline/diff.ts +9 -8
- package/src/edit/hashline/execute.ts +2 -1
- package/src/edit/hashline/index.ts +1 -0
- package/src/eval/__tests__/shared-executors.test.ts +36 -0
- package/src/eval/js/shared/local-module-loader.ts +13 -1
- package/src/eval/js/shared/rewrite-imports.ts +31 -26
- package/src/eval/py/kernel.ts +37 -15
- package/src/eval/py/runtime.ts +57 -28
- package/src/export/html/template.generated.ts +1 -1
- package/src/export/html/template.js +0 -12
- package/src/export/ttsr.ts +2 -0
- package/src/internal-urls/agent-protocol.ts +18 -1
- package/src/internal-urls/artifact-protocol.ts +19 -1
- package/src/internal-urls/docs-index.generated.ts +8 -7
- package/src/internal-urls/local-protocol.ts +14 -1
- package/src/internal-urls/memory-protocol.ts +6 -1
- package/src/internal-urls/omp-protocol.ts +5 -1
- package/src/internal-urls/router.ts +20 -1
- package/src/internal-urls/rule-protocol.ts +8 -1
- package/src/internal-urls/skill-protocol.ts +8 -1
- package/src/internal-urls/types.ts +27 -0
- package/src/lsp/render.ts +1 -1
- package/src/main.ts +18 -1
- package/src/mcp/oauth-flow.ts +2 -2
- package/src/memory-backend/index.ts +1 -0
- package/src/memory-backend/resolve.ts +4 -1
- package/src/memory-backend/types.ts +8 -1
- package/src/mnemosyne/backend.ts +374 -0
- package/src/mnemosyne/config.ts +160 -0
- package/src/mnemosyne/index.ts +3 -0
- package/src/mnemosyne/state.ts +548 -0
- package/src/modes/acp/acp-agent.ts +11 -6
- package/src/modes/components/agent-dashboard.ts +4 -4
- package/src/modes/components/custom-editor.ts +3 -2
- package/src/modes/components/diff.ts +2 -2
- package/src/modes/components/extensions/extension-list.ts +3 -2
- package/src/modes/components/footer.ts +5 -6
- package/src/modes/components/history-search.ts +3 -3
- package/src/modes/components/hook-selector.ts +92 -8
- package/src/modes/components/index.ts +2 -0
- package/src/modes/components/mcp-add-wizard.ts +3 -3
- package/src/modes/components/model-selector.ts +5 -4
- package/src/modes/components/oauth-selector.ts +3 -3
- package/src/modes/components/segment-track.ts +52 -0
- package/src/modes/components/session-observer-overlay.ts +19 -13
- package/src/modes/components/session-selector.ts +3 -3
- package/src/modes/components/settings-defs.ts +7 -0
- package/src/modes/components/status-line/context-thresholds.ts +11 -0
- package/src/modes/components/status-line/segments.ts +2 -2
- package/src/modes/components/tiny-title-download-progress.ts +90 -0
- package/src/modes/components/tips.txt +13 -0
- package/src/modes/components/tool-execution.ts +72 -4
- package/src/modes/components/tree-selector.ts +3 -3
- package/src/modes/components/user-message-selector.ts +3 -3
- package/src/modes/components/welcome.ts +102 -43
- package/src/modes/controllers/command-controller.ts +16 -1
- package/src/modes/controllers/extension-ui-controller.ts +3 -1
- package/src/modes/controllers/input-controller.ts +69 -21
- package/src/modes/gradient-highlight.ts +70 -0
- package/src/modes/interactive-mode.ts +75 -114
- package/src/modes/internal-url-autocomplete.ts +143 -0
- package/src/modes/orchestrate.ts +36 -0
- package/src/modes/prompt-action-autocomplete.ts +12 -0
- package/src/modes/setup-wizard/index.ts +88 -0
- package/src/modes/setup-wizard/scenes/glyph.ts +96 -0
- package/src/modes/setup-wizard/scenes/outro.ts +35 -0
- package/src/modes/setup-wizard/scenes/providers.ts +69 -0
- package/src/modes/setup-wizard/scenes/sign-in.ts +193 -0
- package/src/modes/setup-wizard/scenes/splash.ts +201 -0
- package/src/modes/setup-wizard/scenes/theme.ts +299 -0
- package/src/modes/setup-wizard/scenes/types.ts +48 -0
- package/src/modes/setup-wizard/scenes/web-search.ts +128 -0
- package/src/modes/setup-wizard/wizard-overlay.ts +275 -0
- package/src/modes/theme/shimmer.ts +5 -0
- package/src/modes/theme/theme.ts +44 -20
- package/src/modes/types.ts +6 -1
- package/src/modes/ultrathink.ts +9 -53
- package/src/modes/utils/keybinding-matchers.ts +11 -0
- package/src/prompts/system/memory-consolidation-system.md +8 -0
- package/src/prompts/system/memory-extraction-system.md +26 -0
- package/src/prompts/{commands/orchestrate.md → system/orchestrate-notice.md} +6 -17
- package/src/prompts/system/system-prompt.md +2 -0
- package/src/prompts/system/tiny-title-system.md +8 -0
- package/src/prompts/tools/memory-edit.md +8 -0
- package/src/prompts/tools/read.md +4 -0
- package/src/prompts/tools/task.md +4 -7
- package/src/sdk.ts +13 -21
- package/src/session/agent-session.ts +128 -44
- package/src/slash-commands/builtin-registry.ts +18 -1
- package/src/system-prompt.ts +4 -0
- package/src/task/commands.ts +1 -5
- package/src/task/executor.ts +8 -0
- package/src/task/index.ts +2 -0
- package/src/task/render.ts +69 -26
- package/src/tiny/device.ts +117 -0
- package/src/tiny/dtype.ts +101 -0
- package/src/tiny/models.ts +218 -0
- package/src/tiny/text.ts +54 -0
- package/src/tiny/title-client.ts +395 -0
- package/src/tiny/title-protocol.ts +51 -0
- package/src/tiny/worker.ts +587 -0
- package/src/tools/bash.ts +74 -29
- package/src/tools/browser/tab-worker.ts +1 -1
- package/src/tools/eval.ts +9 -4
- package/src/tools/index.ts +17 -22
- package/src/tools/memory-edit.ts +59 -0
- package/src/tools/memory-recall.ts +100 -0
- package/src/tools/memory-reflect.ts +88 -0
- package/src/tools/memory-render.ts +185 -0
- package/src/tools/memory-retain.ts +91 -0
- package/src/tools/read.ts +1 -0
- package/src/tools/renderers.ts +4 -2
- package/src/tools/todo-write.ts +128 -29
- package/src/tools/tool-result.ts +8 -0
- package/src/tui/code-cell.ts +6 -1
- package/src/tui/output-block.ts +199 -38
- package/src/utils/title-generator.ts +115 -13
- package/dist/types/tools/recipe/index.d.ts +0 -46
- package/dist/types/tools/recipe/render.d.ts +0 -36
- package/dist/types/tools/recipe/runner.d.ts +0 -60
- package/dist/types/tools/recipe/runners/cargo.d.ts +0 -16
- package/dist/types/tools/recipe/runners/index.d.ts +0 -2
- package/dist/types/tools/recipe/runners/just.d.ts +0 -2
- package/dist/types/tools/recipe/runners/make.d.ts +0 -2
- package/dist/types/tools/recipe/runners/pkg.d.ts +0 -2
- package/dist/types/tools/recipe/runners/task.d.ts +0 -2
- package/src/prompts/tools/recipe.md +0 -16
- package/src/tools/hindsight-recall.ts +0 -69
- package/src/tools/hindsight-reflect.ts +0 -58
- package/src/tools/hindsight-retain.ts +0 -57
- package/src/tools/recipe/index.ts +0 -81
- package/src/tools/recipe/render.ts +0 -19
- package/src/tools/recipe/runner.ts +0 -219
- package/src/tools/recipe/runners/cargo.ts +0 -131
- package/src/tools/recipe/runners/index.ts +0 -8
- package/src/tools/recipe/runners/just.ts +0 -73
- package/src/tools/recipe/runners/make.ts +0 -101
- package/src/tools/recipe/runners/pkg.ts +0 -167
- package/src/tools/recipe/runners/task.ts +0 -72
package/src/tui/output-block.ts
CHANGED
|
@@ -15,8 +15,81 @@ export interface OutputBlockOptions {
|
|
|
15
15
|
sections?: Array<{ label?: string; lines: string[] }>;
|
|
16
16
|
width: number;
|
|
17
17
|
applyBg?: boolean;
|
|
18
|
+
/** Animate the border with a sweeping dark segment (pending/running state). */
|
|
19
|
+
animate?: boolean;
|
|
18
20
|
}
|
|
19
21
|
|
|
22
|
+
const BORDER_SHIMMER_TICK_MS = 50;
|
|
23
|
+
/** Duration of one full clockwise lap around the border, in ms. Fixed so a box
|
|
24
|
+
* growing (new output line) or resizing only nudges the segment proportionally
|
|
25
|
+
* instead of teleporting it. */
|
|
26
|
+
const BORDER_LAP_MS = 4000;
|
|
27
|
+
/** Length, in border cells, of the moving segment. */
|
|
28
|
+
const BORDER_SEGMENT_LEN = 8;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Monotonic frame counter for animated borders. Quantized coarse enough to
|
|
32
|
+
* coalesce multiple render passes inside one frame, fine enough to advance on
|
|
33
|
+
* every spinner interval so cached blocks re-render while the segment travels.
|
|
34
|
+
*/
|
|
35
|
+
export function borderShimmerTick(): number {
|
|
36
|
+
return Math.floor(Date.now() / BORDER_SHIMMER_TICK_MS);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Ease-in-out so the segment decelerates into and accelerates out of corners. */
|
|
40
|
+
function easeInOutQuad(t: number): number {
|
|
41
|
+
return t < 0.5 ? 2 * t * t : 1 - (-2 * t + 2) ** 2 / 2;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Perimeter index of the moving segment's head for a box of inner width `W` and
|
|
46
|
+
* height `H` at time `now`. The lap is split across the four edges in proportion
|
|
47
|
+
* to their length (so the average speed is uniform) and each edge is eased, for a
|
|
48
|
+
* deliberate, non-linear glide that slows at every corner. Position is derived
|
|
49
|
+
* from the wall clock against a fixed lap duration, so a perimeter change (new
|
|
50
|
+
* row / resize) shifts the head by at most a cell or two — no reset.
|
|
51
|
+
*/
|
|
52
|
+
export function borderSegmentHead(W: number, H: number, now: number): number {
|
|
53
|
+
const P = 2 * W + 2 * H - 4;
|
|
54
|
+
if (P <= 0) return 0;
|
|
55
|
+
// Edge cell counts, clockwise from top-left: top, right, bottom, left.
|
|
56
|
+
const edgeLens = [W, H - 1, W - 1, H - 2];
|
|
57
|
+
const t = (((now % BORDER_LAP_MS) + BORDER_LAP_MS) % BORDER_LAP_MS) / BORDER_LAP_MS;
|
|
58
|
+
let acc = 0;
|
|
59
|
+
let start = 0;
|
|
60
|
+
for (let i = 0; i < 4; i++) {
|
|
61
|
+
const len = edgeLens[i]!;
|
|
62
|
+
const frac = len / P;
|
|
63
|
+
if (len > 0 && t < acc + frac) {
|
|
64
|
+
const lf = (t - acc) / frac;
|
|
65
|
+
return (start + Math.floor(easeInOutQuad(lf) * len)) % P;
|
|
66
|
+
}
|
|
67
|
+
acc += frac;
|
|
68
|
+
start += len;
|
|
69
|
+
}
|
|
70
|
+
return P - 1;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Scale a truecolor foreground escape toward black by `factor`. Returns
|
|
75
|
+
* undefined for 256-color escapes (no RGB to scale) so callers fall back to a
|
|
76
|
+
* dimmer theme color.
|
|
77
|
+
*/
|
|
78
|
+
function darkenFgAnsi(ansi: string, factor: number): string | undefined {
|
|
79
|
+
const m = /38;2;(\d+);(\d+);(\d+)/.exec(ansi);
|
|
80
|
+
if (!m) return undefined;
|
|
81
|
+
const r = Math.round(Number(m[1]) * factor);
|
|
82
|
+
const g = Math.round(Number(m[2]) * factor);
|
|
83
|
+
const b = Math.round(Number(m[3]) * factor);
|
|
84
|
+
return `\x1b[38;2;${r};${g};${b}m`;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
type BlockRow =
|
|
88
|
+
| { kind: "bar"; leftChar: string; rightChar: string; label?: string; meta?: string }
|
|
89
|
+
| { kind: "bottom"; leftChar: string; rightChar: string }
|
|
90
|
+
| { kind: "content"; inner: string }
|
|
91
|
+
| { kind: "sixel"; raw: string };
|
|
92
|
+
|
|
20
93
|
export function renderOutputBlock(options: OutputBlockOptions, theme: Theme): string[] {
|
|
21
94
|
const { header, headerMeta, state, sections = [], width, applyBg = true } = options;
|
|
22
95
|
const h = theme.boxSharp.horizontal;
|
|
@@ -46,62 +119,148 @@ export function renderOutputBlock(options: OutputBlockOptions, theme: Theme): st
|
|
|
46
119
|
};
|
|
47
120
|
})();
|
|
48
121
|
|
|
49
|
-
const
|
|
50
|
-
const left = border(`${leftChar}${cap}`);
|
|
51
|
-
const right = border(rightChar);
|
|
52
|
-
if (lineWidth <= 0) return left + right;
|
|
53
|
-
const labelText = [label, meta].filter(Boolean).join(theme.sep.dot);
|
|
54
|
-
const rawLabel = labelText ? ` ${labelText} ` : " ";
|
|
55
|
-
const leftWidth = visibleWidth(left);
|
|
56
|
-
const rightWidth = visibleWidth(right);
|
|
57
|
-
const maxLabelWidth = Math.max(0, lineWidth - leftWidth - rightWidth);
|
|
58
|
-
const trimmedLabel = truncateToWidth(rawLabel, maxLabelWidth);
|
|
59
|
-
const labelWidth = visibleWidth(trimmedLabel);
|
|
60
|
-
const fillCount = Math.max(0, lineWidth - leftWidth - labelWidth - rightWidth);
|
|
61
|
-
return `${left}${trimmedLabel}${border(h.repeat(fillCount))}${right}`;
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
const contentPrefix = border(`${v} `);
|
|
65
|
-
const contentSuffix = border(v);
|
|
66
|
-
const contentWidth = Math.max(0, lineWidth - visibleWidth(contentPrefix) - visibleWidth(contentSuffix));
|
|
67
|
-
const lines: string[] = [];
|
|
122
|
+
const contentWidth = Math.max(0, lineWidth - visibleWidth(`${v} `) - visibleWidth(v));
|
|
68
123
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
124
|
+
// ── Layout pass: collect row descriptors so the border perimeter length is
|
|
125
|
+
// known before the moving segment is positioned. ──
|
|
126
|
+
const rows: BlockRow[] = [];
|
|
127
|
+
rows.push({
|
|
128
|
+
kind: "bar",
|
|
129
|
+
leftChar: theme.boxSharp.topLeft,
|
|
130
|
+
rightChar: theme.boxSharp.topRight,
|
|
131
|
+
label: header,
|
|
132
|
+
meta: headerMeta,
|
|
133
|
+
});
|
|
72
134
|
|
|
73
|
-
const
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
for (let i = 0; i < normalizedSections.length; i++) {
|
|
77
|
-
const section = normalizedSections[i];
|
|
135
|
+
const normalizedSections = sections.length > 0 ? sections : [{ lines: [] as string[] }];
|
|
136
|
+
for (const section of normalizedSections) {
|
|
78
137
|
if (section.label) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
138
|
+
rows.push({
|
|
139
|
+
kind: "bar",
|
|
140
|
+
leftChar: theme.boxSharp.teeRight,
|
|
141
|
+
rightChar: theme.boxSharp.teeLeft,
|
|
142
|
+
label: section.label,
|
|
143
|
+
});
|
|
82
144
|
}
|
|
83
145
|
const allLines = section.lines.flatMap(l => l.split("\n"));
|
|
84
146
|
const sixelLineMask = TERMINAL.imageProtocol === ImageProtocol.Sixel ? getSixelLineMask(allLines) : undefined;
|
|
85
147
|
for (let lineIndex = 0; lineIndex < allLines.length; lineIndex++) {
|
|
86
148
|
const line = allLines[lineIndex]!;
|
|
87
149
|
if (sixelLineMask?.[lineIndex]) {
|
|
88
|
-
|
|
150
|
+
rows.push({ kind: "sixel", raw: line });
|
|
89
151
|
continue;
|
|
90
152
|
}
|
|
91
153
|
const wrappedLines = wrapTextWithAnsi(line.trimEnd(), contentWidth);
|
|
92
154
|
for (const wrappedLine of wrappedLines) {
|
|
93
155
|
const innerPadding = padding(Math.max(0, contentWidth - visibleWidth(wrappedLine)));
|
|
94
|
-
|
|
95
|
-
lines.push(padToWidth(fullLine, lineWidth, bgFn));
|
|
156
|
+
rows.push({ kind: "content", inner: `${wrappedLine}${innerPadding}` });
|
|
96
157
|
}
|
|
97
158
|
}
|
|
98
159
|
}
|
|
99
160
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
const
|
|
103
|
-
const
|
|
104
|
-
|
|
161
|
+
rows.push({ kind: "bottom", leftChar: theme.boxSharp.bottomLeft, rightChar: theme.boxSharp.bottomRight });
|
|
162
|
+
|
|
163
|
+
const H = rows.length;
|
|
164
|
+
const W = lineWidth;
|
|
165
|
+
const animate = (options.animate ?? false) && (state === "running" || state === "pending") && W >= 2 && H >= 2;
|
|
166
|
+
|
|
167
|
+
// ── Segment geometry: one dark run travels the outer edge clockwise,
|
|
168
|
+
// top → right → bottom → left → top. ──
|
|
169
|
+
const P = animate ? 2 * W + 2 * H - 4 : 0;
|
|
170
|
+
const segLen = Math.min(BORDER_SEGMENT_LEN, P);
|
|
171
|
+
const head = animate ? borderSegmentHead(W, H, Date.now()) : 0;
|
|
172
|
+
const segAnsi = animate ? (darkenFgAnsi(theme.getFgAnsi(borderColor), 0.4) ?? theme.getFgAnsi("borderMuted")) : "";
|
|
173
|
+
const seg = (text: string) => `${segAnsi}${text}\x1b[39m`;
|
|
174
|
+
|
|
175
|
+
// Perimeter index of border cell (row r, col c), clockwise from top-left.
|
|
176
|
+
const perimIndex = (r: number, c: number): number => {
|
|
177
|
+
if (r === 0) return c;
|
|
178
|
+
if (c === W - 1) return W - 1 + r;
|
|
179
|
+
if (r === H - 1) return W - 1 + (H - 1) + (W - 1 - c);
|
|
180
|
+
return W - 1 + (H - 1) + (W - 1) + (H - 1 - r);
|
|
181
|
+
};
|
|
182
|
+
const isLit = (idx: number): boolean => (((idx - head) % P) + P) % P < segLen;
|
|
183
|
+
// Color a run of border glyphs starting at (row r, col startCol), grouping
|
|
184
|
+
// consecutive same-state cells so each run emits a single escape pair.
|
|
185
|
+
const colorEdge = (glyphs: string, r: number, startCol: number): string => {
|
|
186
|
+
let out = "";
|
|
187
|
+
let runLit: boolean | null = null;
|
|
188
|
+
let buf = "";
|
|
189
|
+
for (let i = 0; i < glyphs.length; i++) {
|
|
190
|
+
const lit = isLit(perimIndex(r, startCol + i));
|
|
191
|
+
if (lit !== runLit) {
|
|
192
|
+
if (runLit !== null) out += (runLit ? seg : border)(buf);
|
|
193
|
+
buf = "";
|
|
194
|
+
runLit = lit;
|
|
195
|
+
}
|
|
196
|
+
buf += glyphs[i];
|
|
197
|
+
}
|
|
198
|
+
if (runLit !== null) out += (runLit ? seg : border)(buf);
|
|
199
|
+
return out;
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
const renderBar = (
|
|
203
|
+
row: { leftChar: string; rightChar: string; label?: string; meta?: string },
|
|
204
|
+
r: number,
|
|
205
|
+
): string => {
|
|
206
|
+
const leftGlyphs = `${row.leftChar}${cap}`;
|
|
207
|
+
const rightGlyph = row.rightChar;
|
|
208
|
+
if (lineWidth <= 0) return border(leftGlyphs) + border(rightGlyph);
|
|
209
|
+
const labelText = [row.label, row.meta].filter(Boolean).join(theme.sep.dot);
|
|
210
|
+
const rawLabel = labelText ? ` ${labelText} ` : " ";
|
|
211
|
+
const leftWidth = visibleWidth(leftGlyphs);
|
|
212
|
+
const rightWidth = visibleWidth(rightGlyph);
|
|
213
|
+
const maxLabelWidth = Math.max(0, lineWidth - leftWidth - rightWidth);
|
|
214
|
+
const trimmedLabel = truncateToWidth(rawLabel, maxLabelWidth);
|
|
215
|
+
const labelWidth = visibleWidth(trimmedLabel);
|
|
216
|
+
const fillCount = Math.max(0, lineWidth - leftWidth - labelWidth - rightWidth);
|
|
217
|
+
const fillGlyphs = h.repeat(fillCount);
|
|
218
|
+
if (!animate) {
|
|
219
|
+
return `${border(leftGlyphs)}${trimmedLabel}${border(fillGlyphs)}${border(rightGlyph)}`;
|
|
220
|
+
}
|
|
221
|
+
if (r === 0 || r === H - 1) {
|
|
222
|
+
// Top/bottom edge: the whole horizontal run lies on the perimeter.
|
|
223
|
+
const leftStr = colorEdge(leftGlyphs, r, 0);
|
|
224
|
+
const fillStr = colorEdge(fillGlyphs, r, leftWidth + labelWidth);
|
|
225
|
+
const rightStr = colorEdge(rightGlyph, r, lineWidth - rightWidth);
|
|
226
|
+
return `${leftStr}${trimmedLabel}${fillStr}${rightStr}`;
|
|
227
|
+
}
|
|
228
|
+
// Interior separator: only the first/last cell sit on the outer edge.
|
|
229
|
+
return `${colorEdge(row.leftChar, r, 0)}${border(cap)}${trimmedLabel}${border(fillGlyphs)}${colorEdge(rightGlyph, r, lineWidth - rightWidth)}`;
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
const renderBottom = (row: { leftChar: string; rightChar: string }, r: number): string => {
|
|
233
|
+
const leftGlyphs = `${row.leftChar}${cap}`;
|
|
234
|
+
const rightGlyph = row.rightChar;
|
|
235
|
+
const fillCount = Math.max(0, lineWidth - visibleWidth(leftGlyphs) - visibleWidth(rightGlyph));
|
|
236
|
+
const fillGlyphs = h.repeat(fillCount);
|
|
237
|
+
if (!animate) return `${border(leftGlyphs)}${border(fillGlyphs)}${border(rightGlyph)}`;
|
|
238
|
+
const leftStr = colorEdge(leftGlyphs, r, 0);
|
|
239
|
+
const fillStr = colorEdge(fillGlyphs, r, visibleWidth(leftGlyphs));
|
|
240
|
+
const rightStr = colorEdge(rightGlyph, r, lineWidth - visibleWidth(rightGlyph));
|
|
241
|
+
return `${leftStr}${fillStr}${rightStr}`;
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
const renderContent = (inner: string, r: number): string => {
|
|
245
|
+
if (!animate) return `${border(`${v} `)}${inner}${border(v)}`;
|
|
246
|
+
return `${colorEdge(v, r, 0)} ${inner}${colorEdge(v, r, lineWidth - 1)}`;
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
const lines: string[] = [];
|
|
250
|
+
for (let r = 0; r < H; r++) {
|
|
251
|
+
const row = rows[r]!;
|
|
252
|
+
if (row.kind === "sixel") {
|
|
253
|
+
lines.push(row.raw);
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
const line =
|
|
257
|
+
row.kind === "bar"
|
|
258
|
+
? renderBar(row, r)
|
|
259
|
+
: row.kind === "bottom"
|
|
260
|
+
? renderBottom(row, r)
|
|
261
|
+
: renderContent(row.inner, r);
|
|
262
|
+
lines.push(padToWidth(line, lineWidth, bgFn));
|
|
263
|
+
}
|
|
105
264
|
|
|
106
265
|
return lines;
|
|
107
266
|
}
|
|
@@ -137,6 +296,8 @@ export class CachedOutputBlock {
|
|
|
137
296
|
h.optional(options.headerMeta);
|
|
138
297
|
h.optional(options.state);
|
|
139
298
|
h.bool(options.applyBg ?? true);
|
|
299
|
+
h.bool(options.animate ?? false);
|
|
300
|
+
if (options.animate) h.u32(borderShimmerTick());
|
|
140
301
|
if (options.sections) {
|
|
141
302
|
for (const s of options.sections) {
|
|
142
303
|
h.optional(s.label);
|
|
@@ -9,13 +9,16 @@ import type { ModelRegistry } from "../config/model-registry";
|
|
|
9
9
|
import { resolveRoleSelection } from "../config/model-resolver";
|
|
10
10
|
import type { Settings } from "../config/settings";
|
|
11
11
|
import titleSystemPrompt from "../prompts/system/title-system.md" with { type: "text" };
|
|
12
|
+
import { ONLINE_TINY_TITLE_MODEL_KEY } from "../tiny/models";
|
|
13
|
+
import { formatTitleUserMessage, normalizeGeneratedTitle } from "../tiny/text";
|
|
14
|
+
import { tinyTitleClient } from "../tiny/title-client";
|
|
12
15
|
|
|
13
16
|
const TITLE_SYSTEM_PROMPT = prompt.render(titleSystemPrompt);
|
|
14
17
|
|
|
15
18
|
const DEFAULT_TERMINAL_TITLE = "π";
|
|
16
19
|
const TERMINAL_TITLE_CONTROL_CHARS = /[\u0000-\u001f\u007f-\u009f]/g;
|
|
17
20
|
|
|
18
|
-
const
|
|
21
|
+
export const TITLE_LOCAL_FALLBACK_DELAY_MS = 10_000;
|
|
19
22
|
const TITLE_MAX_TOKENS = 30;
|
|
20
23
|
const REASONING_SAFE_MAX_TOKENS = 1024;
|
|
21
24
|
const SET_TITLE_TOOL_NAME = "set_title";
|
|
@@ -48,6 +51,78 @@ function getTitleModel(registry: ModelRegistry, settings: Settings, currentModel
|
|
|
48
51
|
return undefined;
|
|
49
52
|
}
|
|
50
53
|
|
|
54
|
+
export async function raceFirstNonNull<T>(
|
|
55
|
+
primary: Promise<T | null>,
|
|
56
|
+
startFallback: () => Promise<T | null>,
|
|
57
|
+
delayMs: number = TITLE_LOCAL_FALLBACK_DELAY_MS,
|
|
58
|
+
onPrimaryWinAfterFallback?: () => void,
|
|
59
|
+
): Promise<T | null> {
|
|
60
|
+
const { promise, resolve } = Promise.withResolvers<T | null>();
|
|
61
|
+
let resolved = false;
|
|
62
|
+
let primarySettled = false;
|
|
63
|
+
let fallbackStarted = false;
|
|
64
|
+
let fallbackSettled = false;
|
|
65
|
+
|
|
66
|
+
const resolveOnce = (value: T | null): void => {
|
|
67
|
+
if (resolved) return;
|
|
68
|
+
resolved = true;
|
|
69
|
+
resolve(value);
|
|
70
|
+
};
|
|
71
|
+
const maybeResolveNull = (): void => {
|
|
72
|
+
if (primarySettled && fallbackStarted && fallbackSettled) resolveOnce(null);
|
|
73
|
+
};
|
|
74
|
+
const startFallbackOnce = (): void => {
|
|
75
|
+
if (fallbackStarted || resolved) return;
|
|
76
|
+
fallbackStarted = true;
|
|
77
|
+
let fallback: Promise<T | null>;
|
|
78
|
+
try {
|
|
79
|
+
fallback = startFallback();
|
|
80
|
+
} catch {
|
|
81
|
+
fallbackSettled = true;
|
|
82
|
+
maybeResolveNull();
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
void fallback.then(
|
|
86
|
+
value => {
|
|
87
|
+
fallbackSettled = true;
|
|
88
|
+
if (value !== null) resolveOnce(value);
|
|
89
|
+
else maybeResolveNull();
|
|
90
|
+
},
|
|
91
|
+
() => {
|
|
92
|
+
fallbackSettled = true;
|
|
93
|
+
maybeResolveNull();
|
|
94
|
+
},
|
|
95
|
+
);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const timer = setTimeout(startFallbackOnce, delayMs);
|
|
99
|
+
void primary.then(
|
|
100
|
+
value => {
|
|
101
|
+
primarySettled = true;
|
|
102
|
+
clearTimeout(timer);
|
|
103
|
+
if (value !== null) {
|
|
104
|
+
if (fallbackStarted) onPrimaryWinAfterFallback?.();
|
|
105
|
+
resolveOnce(value);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
startFallbackOnce();
|
|
109
|
+
maybeResolveNull();
|
|
110
|
+
},
|
|
111
|
+
() => {
|
|
112
|
+
primarySettled = true;
|
|
113
|
+
clearTimeout(timer);
|
|
114
|
+
startFallbackOnce();
|
|
115
|
+
maybeResolveNull();
|
|
116
|
+
},
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
return await promise;
|
|
121
|
+
} finally {
|
|
122
|
+
clearTimeout(timer);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
51
126
|
/**
|
|
52
127
|
* Generate a title for a session based on the first user message.
|
|
53
128
|
*
|
|
@@ -68,6 +143,41 @@ export async function generateSessionTitle(
|
|
|
68
143
|
sessionId?: string,
|
|
69
144
|
currentModel?: Model<Api>,
|
|
70
145
|
metadataResolver?: (provider: string) => Record<string, unknown> | undefined,
|
|
146
|
+
): Promise<string | null> {
|
|
147
|
+
const tinyModel = settings.get("providers.tinyModel");
|
|
148
|
+
if (tinyModel === ONLINE_TINY_TITLE_MODEL_KEY) {
|
|
149
|
+
return generateTitleOnline(firstMessage, registry, settings, sessionId, currentModel, metadataResolver);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const onlineAbortController = new AbortController();
|
|
153
|
+
const localTitle = tinyTitleClient.generate(tinyModel, firstMessage).then(
|
|
154
|
+
title => title || null,
|
|
155
|
+
() => null,
|
|
156
|
+
);
|
|
157
|
+
const startOnline = (): Promise<string | null> =>
|
|
158
|
+
generateTitleOnline(
|
|
159
|
+
firstMessage,
|
|
160
|
+
registry,
|
|
161
|
+
settings,
|
|
162
|
+
sessionId,
|
|
163
|
+
currentModel,
|
|
164
|
+
metadataResolver,
|
|
165
|
+
onlineAbortController.signal,
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
return raceFirstNonNull(localTitle, startOnline, TITLE_LOCAL_FALLBACK_DELAY_MS, () => {
|
|
169
|
+
onlineAbortController.abort();
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export async function generateTitleOnline(
|
|
174
|
+
firstMessage: string,
|
|
175
|
+
registry: ModelRegistry,
|
|
176
|
+
settings: Settings,
|
|
177
|
+
sessionId?: string,
|
|
178
|
+
currentModel?: Model<Api>,
|
|
179
|
+
metadataResolver?: (provider: string) => Record<string, unknown> | undefined,
|
|
180
|
+
signal?: AbortSignal,
|
|
71
181
|
): Promise<string | null> {
|
|
72
182
|
const model = getTitleModel(registry, settings, currentModel);
|
|
73
183
|
if (!model) {
|
|
@@ -75,12 +185,7 @@ export async function generateSessionTitle(
|
|
|
75
185
|
return null;
|
|
76
186
|
}
|
|
77
187
|
|
|
78
|
-
|
|
79
|
-
const truncatedMessage =
|
|
80
|
-
firstMessage.length > MAX_INPUT_CHARS ? `${firstMessage.slice(0, MAX_INPUT_CHARS)}…` : firstMessage;
|
|
81
|
-
const userMessage = `<user-message>
|
|
82
|
-
${truncatedMessage}
|
|
83
|
-
</user-message>`;
|
|
188
|
+
const userMessage = formatTitleUserMessage(firstMessage);
|
|
84
189
|
|
|
85
190
|
const apiKey = await registry.getApiKey(model, sessionId);
|
|
86
191
|
if (!apiKey) {
|
|
@@ -122,6 +227,7 @@ ${truncatedMessage}
|
|
|
122
227
|
disableReasoning: true,
|
|
123
228
|
toolChoice: { type: "tool", name: SET_TITLE_TOOL_NAME },
|
|
124
229
|
metadata,
|
|
230
|
+
signal,
|
|
125
231
|
},
|
|
126
232
|
);
|
|
127
233
|
|
|
@@ -134,7 +240,7 @@ ${truncatedMessage}
|
|
|
134
240
|
return null;
|
|
135
241
|
}
|
|
136
242
|
|
|
137
|
-
const title = extractGeneratedTitle(response.content);
|
|
243
|
+
const title = normalizeGeneratedTitle(extractGeneratedTitle(response.content));
|
|
138
244
|
|
|
139
245
|
logger.debug("title-generator: response", {
|
|
140
246
|
model: request.model,
|
|
@@ -143,11 +249,7 @@ ${truncatedMessage}
|
|
|
143
249
|
stopReason: response.stopReason,
|
|
144
250
|
});
|
|
145
251
|
|
|
146
|
-
|
|
147
|
-
return null;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return title.replace(/^["']|["']$/g, "").replace(/[.!?]$/, "");
|
|
252
|
+
return title;
|
|
151
253
|
} catch (err) {
|
|
152
254
|
logger.debug("title-generator: error", {
|
|
153
255
|
model: request.model,
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
|
|
2
|
-
import type { Component } from "@oh-my-pi/pi-tui";
|
|
3
|
-
import * as z from "zod/v4";
|
|
4
|
-
import type { RenderResultOptions } from "../../extensibility/custom-tools/types";
|
|
5
|
-
import type { Theme } from "../../modes/theme/theme";
|
|
6
|
-
import type { ToolSession } from "..";
|
|
7
|
-
import { type BashRenderContext, type BashToolDetails } from "../bash";
|
|
8
|
-
import { type RecipeRenderArgs } from "./render";
|
|
9
|
-
import { type DetectedRunner } from "./runner";
|
|
10
|
-
declare const recipeSchema: z.ZodObject<{
|
|
11
|
-
op: z.ZodString;
|
|
12
|
-
}, z.core.$strict>;
|
|
13
|
-
type RecipeParams = z.infer<typeof recipeSchema>;
|
|
14
|
-
type RecipeRenderResult = {
|
|
15
|
-
content: Array<{
|
|
16
|
-
type: string;
|
|
17
|
-
text?: string;
|
|
18
|
-
}>;
|
|
19
|
-
details?: BashToolDetails;
|
|
20
|
-
isError?: boolean;
|
|
21
|
-
};
|
|
22
|
-
export declare class RecipeTool implements AgentTool<typeof recipeSchema, BashToolDetails, Theme> {
|
|
23
|
-
#private;
|
|
24
|
-
readonly name = "recipe";
|
|
25
|
-
readonly label = "Run";
|
|
26
|
-
readonly approval: "exec";
|
|
27
|
-
readonly description: string;
|
|
28
|
-
readonly parameters: z.ZodObject<{
|
|
29
|
-
op: z.ZodString;
|
|
30
|
-
}, z.core.$strict>;
|
|
31
|
-
readonly strict = true;
|
|
32
|
-
readonly concurrency = "exclusive";
|
|
33
|
-
readonly loadMode = "discoverable";
|
|
34
|
-
readonly summary = "Execute a saved bash recipe (multi-step shell command preset)";
|
|
35
|
-
readonly mergeCallAndResult = true;
|
|
36
|
-
readonly inline = true;
|
|
37
|
-
readonly renderCall: (args: RecipeRenderArgs, options: RenderResultOptions, uiTheme: Theme) => Component;
|
|
38
|
-
readonly renderResult: (result: RecipeRenderResult, options: RenderResultOptions & {
|
|
39
|
-
renderContext?: BashRenderContext;
|
|
40
|
-
}, uiTheme: Theme, args?: RecipeRenderArgs) => Component;
|
|
41
|
-
constructor(session: ToolSession, runners: DetectedRunner[]);
|
|
42
|
-
static createIf(session: ToolSession): Promise<RecipeTool | null>;
|
|
43
|
-
execute(toolCallId: string, { op }: RecipeParams, signal?: AbortSignal, onUpdate?: AgentToolUpdateCallback<BashToolDetails>, ctx?: AgentToolContext): Promise<AgentToolResult<BashToolDetails>>;
|
|
44
|
-
}
|
|
45
|
-
export * from "./runner";
|
|
46
|
-
export { tasksFromCargoMetadata } from "./runners/cargo";
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import type { DetectedRunner } from "./runner";
|
|
2
|
-
export interface RecipeRenderArgs {
|
|
3
|
-
op?: string;
|
|
4
|
-
__partialJson?: string;
|
|
5
|
-
[key: string]: unknown;
|
|
6
|
-
}
|
|
7
|
-
export declare function createRecipeToolRenderer(runners: DetectedRunner[]): {
|
|
8
|
-
renderCall(args: RecipeRenderArgs, options: import("../..").RenderResultOptions, uiTheme: import("../..").Theme): import("@oh-my-pi/pi-tui").Component;
|
|
9
|
-
renderResult(result: {
|
|
10
|
-
content: {
|
|
11
|
-
type: string;
|
|
12
|
-
text?: string;
|
|
13
|
-
}[];
|
|
14
|
-
details?: import("..").BashToolDetails;
|
|
15
|
-
isError?: boolean;
|
|
16
|
-
}, options: import("../..").RenderResultOptions & {
|
|
17
|
-
renderContext?: import("..").BashRenderContext;
|
|
18
|
-
}, uiTheme: import("../..").Theme, args?: RecipeRenderArgs | undefined): import("@oh-my-pi/pi-tui").Component;
|
|
19
|
-
mergeCallAndResult: boolean;
|
|
20
|
-
inline: boolean;
|
|
21
|
-
};
|
|
22
|
-
export declare const recipeToolRenderer: {
|
|
23
|
-
renderCall(args: RecipeRenderArgs, options: import("../..").RenderResultOptions, uiTheme: import("../..").Theme): import("@oh-my-pi/pi-tui").Component;
|
|
24
|
-
renderResult(result: {
|
|
25
|
-
content: {
|
|
26
|
-
type: string;
|
|
27
|
-
text?: string;
|
|
28
|
-
}[];
|
|
29
|
-
details?: import("..").BashToolDetails;
|
|
30
|
-
isError?: boolean;
|
|
31
|
-
}, options: import("../..").RenderResultOptions & {
|
|
32
|
-
renderContext?: import("..").BashRenderContext;
|
|
33
|
-
}, uiTheme: import("../..").Theme, args?: RecipeRenderArgs | undefined): import("@oh-my-pi/pi-tui").Component;
|
|
34
|
-
mergeCallAndResult: boolean;
|
|
35
|
-
inline: boolean;
|
|
36
|
-
};
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
export interface RunnerTask {
|
|
2
|
-
name: string;
|
|
3
|
-
doc?: string;
|
|
4
|
-
/** Parameter names only; used for the `name foo bar` signature line in the description. */
|
|
5
|
-
parameters: string[];
|
|
6
|
-
/** Override for this specific task, e.g. `cargo run --package crate --bin`. */
|
|
7
|
-
commandPrefix?: string;
|
|
8
|
-
/** Token passed to the runner command; defaults to `name`. Used when display names are namespaced. */
|
|
9
|
-
commandName?: string;
|
|
10
|
-
/** Working directory for the task, relative to the session cwd; absent means the runner's root cwd. */
|
|
11
|
-
cwd?: string;
|
|
12
|
-
}
|
|
13
|
-
export interface DetectedRunner {
|
|
14
|
-
id: string;
|
|
15
|
-
label: string;
|
|
16
|
-
/** Resolved shell prefix, e.g. "just" or "bun run" or "make". */
|
|
17
|
-
commandPrefix: string;
|
|
18
|
-
tasks: RunnerTask[];
|
|
19
|
-
}
|
|
20
|
-
export interface TaskRunner {
|
|
21
|
-
id: string;
|
|
22
|
-
label: string;
|
|
23
|
-
/**
|
|
24
|
-
* Probe `cwd` for the manifest, the binary, and the task list.
|
|
25
|
-
* Returns null when this runner does not apply.
|
|
26
|
-
*/
|
|
27
|
-
detect(cwd: string): Promise<DetectedRunner | null>;
|
|
28
|
-
}
|
|
29
|
-
interface PromptTaskModel {
|
|
30
|
-
name: string;
|
|
31
|
-
paramSig?: string;
|
|
32
|
-
command?: string;
|
|
33
|
-
doc?: string;
|
|
34
|
-
cwd?: string;
|
|
35
|
-
}
|
|
36
|
-
interface PromptRunnerModel {
|
|
37
|
-
id: string;
|
|
38
|
-
label: string;
|
|
39
|
-
commandPrefix: string;
|
|
40
|
-
tasks: PromptTaskModel[];
|
|
41
|
-
hiddenTaskCount?: number;
|
|
42
|
-
}
|
|
43
|
-
export interface RecipePromptModel {
|
|
44
|
-
[key: string]: unknown;
|
|
45
|
-
hasMultipleRunners: boolean;
|
|
46
|
-
ambiguityExampleRunner?: string;
|
|
47
|
-
ambiguityExampleTask?: string;
|
|
48
|
-
runners: PromptRunnerModel[];
|
|
49
|
-
}
|
|
50
|
-
export interface ResolvedTask {
|
|
51
|
-
command: string;
|
|
52
|
-
cwd?: string;
|
|
53
|
-
}
|
|
54
|
-
export declare function resolveCommand(op: string, runners: DetectedRunner[]): ResolvedTask;
|
|
55
|
-
export declare function resolveTaskFromOp(op: string | undefined, runners: DetectedRunner[]): ResolvedTask | undefined;
|
|
56
|
-
export declare function commandFromOp(op: string | undefined, runners: DetectedRunner[]): string | undefined;
|
|
57
|
-
export declare function cwdFromOp(op: string | undefined, runners: DetectedRunner[]): string | undefined;
|
|
58
|
-
export declare function titleFromOp(op: string | undefined, runners: DetectedRunner[]): string;
|
|
59
|
-
export declare function buildPromptModel(runners: DetectedRunner[]): RecipePromptModel;
|
|
60
|
-
export {};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { RunnerTask, TaskRunner } from "../runner";
|
|
2
|
-
export interface CargoMetadataTarget {
|
|
3
|
-
kind?: string[];
|
|
4
|
-
name?: string;
|
|
5
|
-
}
|
|
6
|
-
export interface CargoMetadataPackage {
|
|
7
|
-
id?: string;
|
|
8
|
-
name?: string;
|
|
9
|
-
targets?: CargoMetadataTarget[];
|
|
10
|
-
}
|
|
11
|
-
export interface CargoMetadata {
|
|
12
|
-
packages?: CargoMetadataPackage[];
|
|
13
|
-
workspace_members?: string[];
|
|
14
|
-
}
|
|
15
|
-
export declare function tasksFromCargoMetadata(metadata: CargoMetadata): RunnerTask[];
|
|
16
|
-
export declare const cargoRunner: TaskRunner;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
Run a recipe / script / target from the project's task runners.
|
|
2
|
-
|
|
3
|
-
<instruction>
|
|
4
|
-
- `op` is a single string: task name plus any args, e.g. `{op: "test"}` or `{op: "build --release"}`.
|
|
5
|
-
- In monorepos, package and Cargo target tasks are namespaced with `/`, e.g. `{op: "pkg-a/test"}` or `{op: "crate/bin/server"}`.
|
|
6
|
-
{{#if hasMultipleRunners}}- When the same task name exists in more than one runner, prefix with the runner id, e.g. `{op: "{{ambiguityExampleRunner}}:{{ambiguityExampleTask}}"}`. The available runner ids are: {{#each runners}}`{{id}}`{{#unless @last}}, {{/unless}}{{/each}}.
|
|
7
|
-
{{/if}}- Runs in the session's cwd. Output and exit code are returned in the same shape as `bash`.
|
|
8
|
-
</instruction>
|
|
9
|
-
|
|
10
|
-
{{#each runners}}
|
|
11
|
-
<runner id="{{id}}" label="{{label}}" command="{{commandPrefix}}">
|
|
12
|
-
{{#each tasks}}
|
|
13
|
-
- `{{name}}{{#if paramSig}} {{paramSig}}{{/if}}`{{#if doc}} — {{doc}}{{/if}}{{#if command}} (`{{command}}`{{#if cwd}} in `{{cwd}}`{{/if}}){{/if}}
|
|
14
|
-
{{/each}}
|
|
15
|
-
</runner>
|
|
16
|
-
{{/each}}
|