@oh-my-pi/pi-coding-agent 16.1.16 → 16.1.18
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 +49 -0
- package/dist/cli.js +16646 -16608
- package/dist/types/auto-thinking/classifier.d.ts +4 -2
- package/dist/types/cli/usage-cli.d.ts +14 -0
- package/dist/types/commands/token.d.ts +9 -0
- package/dist/types/config/model-discovery.d.ts +1 -0
- package/dist/types/config/model-registry.d.ts +4 -0
- package/dist/types/extensibility/plugins/legacy-pi-bundled-registry.d.ts +7 -0
- package/dist/types/extensibility/plugins/legacy-pi-compat.d.ts +34 -15
- package/dist/types/extensibility/plugins/loader.d.ts +16 -9
- package/dist/types/extensibility/tool-event-input.d.ts +2 -0
- package/dist/types/hindsight/content.d.ts +2 -10
- package/dist/types/modes/components/chat-transcript-builder.d.ts +2 -0
- package/dist/types/modes/components/custom-editor.d.ts +3 -0
- package/dist/types/modes/components/extensions/extension-dashboard.d.ts +26 -10
- package/dist/types/modes/components/extensions/extension-list.d.ts +13 -0
- package/dist/types/modes/components/status-line/types.d.ts +1 -0
- package/dist/types/modes/controllers/command-controller.d.ts +2 -0
- package/dist/types/modes/controllers/input-controller.d.ts +14 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +11 -0
- package/dist/types/session/agent-session.d.ts +6 -6
- package/dist/types/session/provider-image-budget.d.ts +3 -0
- package/dist/types/session/session-context.d.ts +6 -5
- package/dist/types/task/parallel.d.ts +4 -0
- package/dist/types/thinking.d.ts +8 -1
- package/dist/types/tiny/title-client.d.ts +2 -2
- package/dist/types/utils/tools-manager.d.ts +2 -0
- package/package.json +12 -12
- package/scripts/build-binary.ts +9 -16
- package/src/auto-thinking/classifier.ts +7 -2
- package/src/cli/profile-alias.ts +38 -7
- package/src/cli/usage-cli.ts +40 -5
- package/src/commands/token.ts +54 -0
- package/src/config/model-discovery.ts +59 -8
- package/src/config/model-registry.ts +74 -3
- package/src/discovery/omp-extension-roots.ts +1 -3
- package/src/extensibility/extensions/wrapper.ts +3 -2
- package/src/extensibility/hooks/tool-wrapper.ts +4 -3
- package/src/extensibility/plugins/legacy-pi-bundled-registry.ts +40 -0
- package/src/extensibility/plugins/legacy-pi-compat.ts +240 -90
- package/src/extensibility/plugins/loader.ts +71 -23
- package/src/extensibility/plugins/marketplace/manager.ts +134 -0
- package/src/extensibility/tool-event-input.ts +57 -0
- package/src/hindsight/content.ts +21 -12
- package/src/mcp/tool-bridge.ts +27 -2
- package/src/mnemopi/state.ts +5 -2
- package/src/modes/components/agent-transcript-viewer.ts +193 -41
- package/src/modes/components/chat-transcript-builder.ts +6 -0
- package/src/modes/components/custom-editor.test.ts +18 -1
- package/src/modes/components/custom-editor.ts +77 -45
- package/src/modes/components/extensions/extension-dashboard.ts +221 -165
- package/src/modes/components/extensions/extension-list.ts +66 -33
- package/src/modes/components/hook-editor.ts +15 -2
- package/src/modes/components/settings-selector.ts +2 -2
- package/src/modes/components/status-line/component.ts +52 -8
- package/src/modes/components/status-line/segments.ts +5 -1
- package/src/modes/components/status-line/types.ts +1 -0
- package/src/modes/components/welcome.ts +12 -14
- package/src/modes/controllers/command-controller.ts +16 -5
- package/src/modes/controllers/input-controller.ts +115 -3
- package/src/modes/controllers/selector-controller.ts +23 -1
- package/src/modes/interactive-mode.ts +3 -3
- package/src/modes/utils/ui-helpers.ts +3 -3
- package/src/sdk.ts +8 -10
- package/src/session/agent-session.ts +193 -49
- package/src/session/provider-image-budget.ts +86 -0
- package/src/session/session-context.ts +14 -7
- package/src/session/session-storage.ts +24 -2
- package/src/session/snapcompact-inline.ts +19 -3
- package/src/slash-commands/builtin-registry.ts +0 -22
- package/src/slash-commands/helpers/usage-report.ts +9 -1
- package/src/task/parallel.ts +6 -1
- package/src/thinking.ts +9 -2
- package/src/tiny/title-client.ts +75 -21
- package/src/utils/tools-manager.ts +67 -10
|
@@ -25,10 +25,12 @@ export interface ClassifyDifficultyDeps {
|
|
|
25
25
|
metadataResolver?: (provider: string) => Record<string, unknown> | undefined;
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
|
-
* Classify `promptText` and return a concrete effort clamped to `deps.model
|
|
28
|
+
* Classify `promptText` and return a concrete effort clamped to `deps.model`,
|
|
29
|
+
* or `undefined` when the model has no controllable effort surface (auto has
|
|
30
|
+
* nothing to pick — the caller leaves the prior reasoning level in place).
|
|
29
31
|
* @throws when the backend cannot produce a usable classification.
|
|
30
32
|
*/
|
|
31
|
-
export declare function classifyDifficulty(promptText: string, deps: ClassifyDifficultyDeps): Promise<Effort>;
|
|
33
|
+
export declare function classifyDifficulty(promptText: string, deps: ClassifyDifficultyDeps): Promise<Effort | undefined>;
|
|
32
34
|
/** Map the online 4-way level keyword to an {@link Effort}; earliest match wins. */
|
|
33
35
|
export declare function parseDifficultyLevel(text: string): Effort | undefined;
|
|
34
36
|
/** Map the local 3-way bucket keyword to an {@link Effort}; earliest match wins. */
|
|
@@ -78,4 +78,18 @@ export declare function formatUsageBreakdown(reports: UsageReport[], accounts: U
|
|
|
78
78
|
* peak-per-bucket sparkline per limit window plus latest/peak percentages.
|
|
79
79
|
*/
|
|
80
80
|
export declare function formatUsageHistory(entries: UsageHistoryEntry[], sinceMs: number, nowMs: number, redaction?: Map<string, string>): string;
|
|
81
|
+
/**
|
|
82
|
+
* Keep only accounts worth a usage row: those whose provider has a usage
|
|
83
|
+
* provider, so a missing report is a real gap rather than the absence of any
|
|
84
|
+
* usage concept. Providers with no usage endpoint (web-search keys, local /
|
|
85
|
+
* keyless servers, inference providers without a usage API) would only ever
|
|
86
|
+
* render as noise, so they are dropped.
|
|
87
|
+
*
|
|
88
|
+
* `hasUsageProvider` is injected (in practice {@link AuthStorage.usageProviderFor})
|
|
89
|
+
* so custom/broker resolvers stay authoritative — no provider list is duplicated
|
|
90
|
+
* here. An explicit `--provider` request bypasses the cull, so
|
|
91
|
+
* `omp usage --provider xai` can still confirm the stored credential has no
|
|
92
|
+
* usage endpoint.
|
|
93
|
+
*/
|
|
94
|
+
export declare function selectReportableAccounts(accounts: UsageAccountIdentity[], hasUsageProvider: (provider: string) => boolean, explicitProvider?: string): UsageAccountIdentity[];
|
|
81
95
|
export declare function runUsageCommand(cmd: UsageCommandArgs): Promise<void>;
|
|
@@ -19,6 +19,15 @@ export default class Token extends Command {
|
|
|
19
19
|
description: string;
|
|
20
20
|
default: boolean;
|
|
21
21
|
};
|
|
22
|
+
account: import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"integer"> & {
|
|
23
|
+
char: string;
|
|
24
|
+
description: string;
|
|
25
|
+
};
|
|
26
|
+
list: import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"boolean"> & {
|
|
27
|
+
char: string;
|
|
28
|
+
description: string;
|
|
29
|
+
default: boolean;
|
|
30
|
+
};
|
|
22
31
|
};
|
|
23
32
|
static examples: string[];
|
|
24
33
|
run(): Promise<void>;
|
|
@@ -38,6 +38,7 @@ export interface DiscoveryContext {
|
|
|
38
38
|
export declare function discoverModelsByProviderType(providerConfig: DiscoveryProviderConfig, ctx: DiscoveryContext): Promise<Model<Api>[]>;
|
|
39
39
|
export declare function discoverOllamaModels(providerConfig: DiscoveryProviderConfig, ctx: DiscoveryContext): Promise<Model<Api>[]>;
|
|
40
40
|
export declare function discoverLlamaCppModels(providerConfig: DiscoveryProviderConfig, ctx: DiscoveryContext): Promise<Model<Api>[]>;
|
|
41
|
+
export declare function discoverLlamaCppModelContextWindow(model: Pick<Model<Api>, "provider" | "id" | "baseUrl" | "headers">, ctx: DiscoveryContext): Promise<number | undefined>;
|
|
41
42
|
export declare function discoverOpenAIModelsList(providerConfig: DiscoveryProviderConfig, ctx: DiscoveryContext): Promise<Model<Api>[]>;
|
|
42
43
|
/**
|
|
43
44
|
* Discover models from an Anthropic+OpenAI-compatible reseller proxy that
|
|
@@ -89,6 +89,10 @@ export declare class ModelRegistry {
|
|
|
89
89
|
refresh(strategy?: ModelRefreshStrategy): Promise<void>;
|
|
90
90
|
refreshInBackground(strategy?: ModelRefreshStrategy): void;
|
|
91
91
|
refreshProvider(providerId: string, strategy?: ModelRefreshStrategy): Promise<void>;
|
|
92
|
+
/**
|
|
93
|
+
* Refresh dynamic metadata that can appear only after a local model loads.
|
|
94
|
+
*/
|
|
95
|
+
refreshSelectedModelMetadata(model: Model<Api>): Promise<Model<Api>>;
|
|
92
96
|
/**
|
|
93
97
|
* Discover models for providers registered at runtime via `fetchDynamicModels`
|
|
94
98
|
* (extension providers). Merges the discovered catalog into the existing model
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical specifier → live module namespace. Keys MUST match the right-hand
|
|
3
|
+
* side of `bundledRegistryVirtualSpecifier(...)` calls in
|
|
4
|
+
* `legacy-pi-compat.ts`; the synthesizer enumerates each namespace's own
|
|
5
|
+
* enumerable exports at extension load time.
|
|
6
|
+
*/
|
|
7
|
+
export declare const BUNDLED_PI_REGISTRY: Readonly<Record<string, Readonly<Record<string, unknown>>>>;
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
*
|
|
10
|
-
* the source
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* Exported for tests; production callers use `BUNFS_PACKAGE_ROOT` below.
|
|
3
|
+
* Test seam: builds the synthetic ES module source for a virtual specifier
|
|
4
|
+
* against an explicit registry. Pure (no globalThis read); the emitted source
|
|
5
|
+
* still routes runtime lookups through `globalThis[BUNDLED_REGISTRY_GLOBAL]`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function __synthesizeLegacyPiBundledSourceWithRegistry(registryKey: string, registry: Readonly<Record<string, Readonly<Record<string, unknown>>>>): string;
|
|
8
|
+
/**
|
|
9
|
+
* Test seam: returns the globalThis key the synthetic loader reads from. Tests
|
|
10
|
+
* assert that the emitted source addresses the exact stash key the install
|
|
11
|
+
* function writes to, so a rename can't break extension loads silently.
|
|
14
12
|
*/
|
|
15
|
-
export declare function
|
|
13
|
+
export declare function __getLegacyPiBundledRegistryGlobal(): string;
|
|
16
14
|
/**
|
|
17
15
|
* Compute the package root for the npm prebuilt `dist/cli.js` bundle.
|
|
18
16
|
*
|
|
@@ -23,10 +21,31 @@ export declare function __computeBunfsPackageRoot(metaDir: string, pathImpl?: ty
|
|
|
23
21
|
*/
|
|
24
22
|
export declare function __computeBundledSelfPackageRoot(metaDir: string, pathImpl?: typeof path): string;
|
|
25
23
|
/**
|
|
26
|
-
*
|
|
27
|
-
* the
|
|
24
|
+
* Resolve the path the TypeBox compatibility shim ships at, then drop it when
|
|
25
|
+
* the source file is missing.
|
|
26
|
+
*
|
|
27
|
+
* In compiled-binary mode the shim is served through the
|
|
28
|
+
* `omp-legacy-pi-bundled:` virtual namespace (issue #3423) — bunfs paths are
|
|
29
|
+
* unreachable on Bun 1.3.14+, so the virtual specifier is always available and
|
|
30
|
+
* needs no filesystem probe. In dev / source-link / installed-package mode the
|
|
31
|
+
* shim is an on-disk source file; validation mirrors
|
|
32
|
+
* `__validateLegacyPiPackageRootOverrides` (#2168): if the computed candidate
|
|
33
|
+
* doesn't exist (e.g. an install that dropped the source — issue #3414),
|
|
34
|
+
* `resolveTypeBoxSpecifier` returns `undefined` and
|
|
35
|
+
* `rewriteLegacyExtensionSource` leaves bare `typebox` / `@sinclair/typebox`
|
|
36
|
+
* specifiers alone, so Bun falls through to native resolution against the
|
|
37
|
+
* extension's own `node_modules`.
|
|
38
|
+
*
|
|
39
|
+
* Exported for tests; production callers use `TYPEBOX_SHIM_PATH`.
|
|
40
|
+
*/
|
|
41
|
+
export declare function __resolveTypeBoxShimPath(isCompiled: boolean, sourcePath: string, pathExistsSync?: (p: string) => boolean): string | null;
|
|
42
|
+
/**
|
|
43
|
+
* Drop overrides whose filesystem targets are missing so they can fall
|
|
44
|
+
* through to the canonical-resolution path. Virtual `omp-legacy-pi-bundled:`
|
|
45
|
+
* entries always pass — the bundled registry is the source of truth in
|
|
46
|
+
* compiled-binary mode where bunfs paths are unreachable (issue #3423).
|
|
28
47
|
*
|
|
29
|
-
* `pathExistsSync` defaults to `fs.existsSync`;
|
|
48
|
+
* `pathExistsSync` defaults to `fs.existsSync`; tests inject a stub to
|
|
30
49
|
* simulate the missing-entrypoint failure mode without touching the real FS.
|
|
31
50
|
*/
|
|
32
51
|
export declare function __validateLegacyPiPackageRootOverrides(candidates: Record<string, string>, pathExistsSync?: (p: string) => boolean): Record<string, string>;
|
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
import type { InstalledPlugin } from "./types";
|
|
2
|
+
/** Installed plugin plus the root scope that supplied its runtime metadata. */
|
|
3
|
+
export interface ScopedInstalledPlugin extends InstalledPlugin {
|
|
4
|
+
scope: "user" | "project";
|
|
5
|
+
}
|
|
2
6
|
/**
|
|
3
7
|
* Get list of enabled plugins with their resolved configurations.
|
|
4
8
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* `
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* Enumerates two plugin roots in order: the user root
|
|
10
|
+
* (`getPluginsDir(home)`) and, when a project anchor (`.omp/` or `.git/`)
|
|
11
|
+
* exists at or above `cwd`, the project root
|
|
12
|
+
* (`<projectAnchor>/.omp/plugins`). Each root contributes the union of its
|
|
13
|
+
* `package.json#dependencies` and `omp-plugins.lock.json#plugins`. Project
|
|
14
|
+
* entries shadow user entries with the same package name, matching the
|
|
15
|
+
* shadow semantics of `MarketplaceManager.listInstalledPlugins`.
|
|
16
|
+
*
|
|
17
|
+
* The optional `home` parameter pins the user plugins root for callers that
|
|
18
|
+
* need to enumerate plugins relative to a non-default home (tests with a
|
|
19
|
+
* tempdir, discovery loaders threaded with `LoadContext.home`).
|
|
13
20
|
*/
|
|
14
21
|
export declare function getEnabledPlugins(cwd: string, opts?: {
|
|
15
22
|
home?: string;
|
|
16
|
-
}): Promise<
|
|
23
|
+
}): Promise<ScopedInstalledPlugin[]>;
|
|
17
24
|
/**
|
|
18
25
|
* Declared manifest entries paired with their resolved file path. Returns one
|
|
19
26
|
* record per declared entry — base entries first, then enabled-feature entries
|
|
@@ -64,14 +64,6 @@ export interface RetentionTranscript {
|
|
|
64
64
|
transcript: string | null;
|
|
65
65
|
messageCount: number;
|
|
66
66
|
}
|
|
67
|
-
/**
|
|
68
|
-
* Format messages into a retention transcript using `[role: ...]` markers.
|
|
69
|
-
*
|
|
70
|
-
* - When `retainFullWindow` is true, all messages are included (used when the
|
|
71
|
-
* caller pre-sliced the window itself).
|
|
72
|
-
* - Otherwise, only the last user turn (last user message → end) is retained.
|
|
73
|
-
*
|
|
74
|
-
* Messages are tag-stripped before framing to break the recall→retain loop.
|
|
75
|
-
* Returns `{ transcript: null }` when nothing meaningful survives.
|
|
76
|
-
*/
|
|
77
67
|
export declare function prepareRetentionTranscript(messages: HindsightMessage[], retainFullWindow?: boolean): RetentionTranscript;
|
|
68
|
+
/** Format only user-authored messages for memory fact/entity extraction. */
|
|
69
|
+
export declare function prepareUserRetentionTranscript(messages: HindsightMessage[]): RetentionTranscript;
|
|
@@ -34,6 +34,8 @@ export declare class ChatTranscriptBuilder {
|
|
|
34
34
|
get isEmpty(): boolean;
|
|
35
35
|
/** Discard all components and rebuild the whole transcript from `entries`. */
|
|
36
36
|
rebuild(entries: SessionMessageEntry[]): void;
|
|
37
|
+
/** Append newly persisted entries without rebuilding already rendered rows. */
|
|
38
|
+
append(entries: SessionMessageEntry[]): void;
|
|
37
39
|
/** Toggle tool-output expansion across every expandable component. */
|
|
38
40
|
setExpanded(expanded: boolean): void;
|
|
39
41
|
get expanded(): boolean;
|
|
@@ -19,6 +19,7 @@ export declare const SPACE_HOLD_MECHANICAL_RUN = 2;
|
|
|
19
19
|
/** Idle gap (ms) after the last repeated space that counts as the space bar being released, ending
|
|
20
20
|
* the push-to-talk recording. Must comfortably exceed the OS key-repeat interval. */
|
|
21
21
|
export declare const SPACE_HOLD_RELEASE_MS = 250;
|
|
22
|
+
export declare function extractBracketedPastePaths(data: string): string[] | undefined;
|
|
22
23
|
export declare function extractBracketedImagePastePaths(data: string): string[] | undefined;
|
|
23
24
|
export declare function extractBracketedImagePastePath(data: string): string | undefined;
|
|
24
25
|
/**
|
|
@@ -86,6 +87,8 @@ export declare class CustomEditor extends Editor {
|
|
|
86
87
|
onPasteImage?: () => Promise<boolean>;
|
|
87
88
|
/** Called when a bracketed paste contains one or more image-file paths. */
|
|
88
89
|
onPasteImagePath?: (path: string) => void | Promise<void>;
|
|
90
|
+
/** Called when a bracketed paste contains one or more non-image file paths. */
|
|
91
|
+
onPasteFilePath?: (path: string) => void | Promise<void>;
|
|
89
92
|
/** Called when the configured raw text-paste shortcut is pressed. */
|
|
90
93
|
onPasteTextRaw?: () => void;
|
|
91
94
|
/** Called when the configured dequeue shortcut is pressed. */
|
|
@@ -1,19 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ExtensionDashboard -
|
|
2
|
+
* ExtensionDashboard - Fullscreen alternate-screen control center for extensions.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Chrome mirrors the `/settings` overlay: a titled rounded box, a shared
|
|
5
|
+
* {@link TabBar} for provider selection, and a two-column body (inventory list |
|
|
6
|
+
* inspector). Both panes are mouse-aware — wheel scrolls, hover highlights, and
|
|
7
|
+
* clicks select/activate — routed from a single SGR-mouse handler.
|
|
7
8
|
*
|
|
8
9
|
* Navigation:
|
|
9
|
-
* -
|
|
10
|
-
* - Up/Down/j/k:
|
|
11
|
-
* - Space:
|
|
12
|
-
* -
|
|
10
|
+
* - Tab/Shift+Tab or ←/→: switch provider tab
|
|
11
|
+
* - Up/Down/j/k or wheel: move list selection
|
|
12
|
+
* - Space/Enter or click: toggle selected item (or provider master switch)
|
|
13
|
+
* - Wheel over the inspector: scroll the detail pane
|
|
14
|
+
* - Esc: clear search (if active) then close
|
|
13
15
|
*/
|
|
14
|
-
import {
|
|
16
|
+
import { type Component, type Tab } from "@oh-my-pi/pi-tui";
|
|
15
17
|
import { Settings } from "../../../config/settings";
|
|
16
|
-
|
|
18
|
+
import type { ProviderTab } from "./types";
|
|
19
|
+
/**
|
|
20
|
+
* Map dashboard provider tabs to {@link TabBar} tabs. Empty *enabled* providers
|
|
21
|
+
* are muted — skipped by keyboard nav and unclickable; disabled providers stay
|
|
22
|
+
* selectable (with a leading disabled glyph) so their master switch can be
|
|
23
|
+
* re-enabled from the list. The "all" tab is never muted or marked.
|
|
24
|
+
*/
|
|
25
|
+
export declare function buildTabBarTabs(tabs: ProviderTab[]): Tab[];
|
|
26
|
+
export declare class ExtensionDashboard implements Component {
|
|
17
27
|
#private;
|
|
18
28
|
private readonly cwd;
|
|
19
29
|
private readonly settings;
|
|
@@ -22,6 +32,12 @@ export declare class ExtensionDashboard extends Container {
|
|
|
22
32
|
onRequestRender?: () => void;
|
|
23
33
|
private constructor();
|
|
24
34
|
static create(cwd: string, settings?: Settings | null, terminalHeight?: number): Promise<ExtensionDashboard>;
|
|
35
|
+
/**
|
|
36
|
+
* Fullscreen frame: titled top border, the tab row(s), a divider, the
|
|
37
|
+
* two-column body sized to fill the viewport, a divider, the footer hint, and
|
|
38
|
+
* the bottom border. Records row geometry for mouse hit-testing.
|
|
39
|
+
*/
|
|
25
40
|
render(width: number): readonly string[];
|
|
41
|
+
invalidate(): void;
|
|
26
42
|
handleInput(data: string): void;
|
|
27
43
|
}
|
|
@@ -35,5 +35,18 @@ export declare class ExtensionList implements Component {
|
|
|
35
35
|
clearSearch(): void;
|
|
36
36
|
invalidate(): void;
|
|
37
37
|
render(width: number): readonly string[];
|
|
38
|
+
/** Highlight the row under the pointer (null clears). */
|
|
39
|
+
setHoverIndex(index: number | null): void;
|
|
40
|
+
/**
|
|
41
|
+
* Map a 0-based line within this component's render to the absolute list-item
|
|
42
|
+
* index, or null when the line is the search banner, a padding row, or outside
|
|
43
|
+
* the visible window. The first two lines are the search banner and a blank
|
|
44
|
+
* separator; item rows follow, windowed at the current scroll offset.
|
|
45
|
+
*/
|
|
46
|
+
hitTest(line: number): number | null;
|
|
47
|
+
/** Wheel notch: move the selection (and the inspector) one row. */
|
|
48
|
+
handleWheel(delta: -1 | 1): void;
|
|
49
|
+
/** Click: select the row under the pointer, or activate it when already selected. */
|
|
50
|
+
handleClick(line: number): void;
|
|
38
51
|
handleInput(data: string): void;
|
|
39
52
|
}
|
|
@@ -3,6 +3,7 @@ import { type ProviderDetails, type UsageReport } from "@oh-my-pi/pi-ai";
|
|
|
3
3
|
import type { CompactOptions } from "../../extensibility/extensions/types";
|
|
4
4
|
import { theme } from "../../modes/theme/theme";
|
|
5
5
|
import type { InteractiveModeContext } from "../../modes/types";
|
|
6
|
+
import type { OAuthAccountIdentity } from "../../session/auth-storage";
|
|
6
7
|
import type { CompactMode } from "../../session/compact-modes";
|
|
7
8
|
import { type ShakeMode } from "../../session/shake-types";
|
|
8
9
|
export declare class CommandController {
|
|
@@ -43,3 +44,4 @@ export declare class CommandController {
|
|
|
43
44
|
handleHandoffCommand(customInstructions?: string): Promise<void>;
|
|
44
45
|
}
|
|
45
46
|
export declare function renderProviderSection(details: ProviderDetails, uiTheme: Pick<typeof theme, "fg">): string;
|
|
47
|
+
export declare function renderUsageReports(reports: UsageReport[], uiTheme: typeof theme, nowMs: number, availableWidth: number, resolveActiveAccount?: (provider: string) => OAuthAccountIdentity | undefined): string;
|
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
import { type AutocompleteProvider, type SlashCommand } from "@oh-my-pi/pi-tui";
|
|
2
2
|
import type { InteractiveModeContext } from "../../modes/types";
|
|
3
3
|
import { readImageFromClipboard, readTextFromClipboard } from "../../utils/clipboard";
|
|
4
|
+
/**
|
|
5
|
+
* Slash commands that may carry secrets in their arguments should never be
|
|
6
|
+
* persisted to history.
|
|
7
|
+
*
|
|
8
|
+
* - /login accepts three callback forms (redirect URL, query string, raw auth
|
|
9
|
+
* code) — all can contain OAuth code=/state= params.
|
|
10
|
+
* - /join <link> carries a 32-byte room key and optional write token.
|
|
11
|
+
* - /mcp add --token <token> carries a bearer token.
|
|
12
|
+
*
|
|
13
|
+
* The command name is extracted the same way as parseSlashCommand() — splitting
|
|
14
|
+
* on the earliest whitespace or colon — so /login:?code=... is correctly matched.
|
|
15
|
+
*/
|
|
16
|
+
export declare function shouldSkipHistory(slashText: string): boolean;
|
|
4
17
|
export declare class InputController {
|
|
5
18
|
#private;
|
|
6
19
|
private ctx;
|
|
@@ -25,6 +38,7 @@ export declare class InputController {
|
|
|
25
38
|
abort?: boolean;
|
|
26
39
|
currentText?: string;
|
|
27
40
|
}): number;
|
|
41
|
+
handleFilePathPaste(filePath: string): Promise<void>;
|
|
28
42
|
handleImagePathPaste(path: string): Promise<void>;
|
|
29
43
|
handleImagePaste(): Promise<boolean>;
|
|
30
44
|
handleClipboardTextRawPaste(): Promise<void>;
|
|
@@ -5,6 +5,17 @@ export declare class SelectorController {
|
|
|
5
5
|
#private;
|
|
6
6
|
private ctx;
|
|
7
7
|
constructor(ctx: InteractiveModeContext);
|
|
8
|
+
/**
|
|
9
|
+
* Restore keyboard focus to whatever currently owns the editor slot. The
|
|
10
|
+
* slot can hold the editor itself or a hook selector/input/editor pushed
|
|
11
|
+
* in by `ExtensionUiController` — e.g. an approval prompt that fired while
|
|
12
|
+
* a fullscreen overlay was up. `overlayHandle.hide()` restores focus to
|
|
13
|
+
* the component focused when the overlay opened, which is stale in that
|
|
14
|
+
* case (the editor was swapped out): keys land on a hidden editor and the
|
|
15
|
+
* visible prompt receives nothing (issue #3349). Call this after the
|
|
16
|
+
* overlay hides to re-target focus at the visible slot owner.
|
|
17
|
+
*/
|
|
18
|
+
focusActiveEditorArea(): void;
|
|
8
19
|
/**
|
|
9
20
|
* Shows a selector component in place of the editor.
|
|
10
21
|
* @param create Factory that receives a `done` callback and returns the component and focus target
|
|
@@ -46,7 +46,7 @@ import type { CheckpointState } from "../tools/checkpoint";
|
|
|
46
46
|
import { type TodoItem, type TodoPhase } from "../tools/todo";
|
|
47
47
|
import type { ClientBridge } from "./client-bridge";
|
|
48
48
|
import { type CustomMessage } from "./messages";
|
|
49
|
-
import type { SessionContext } from "./session-context";
|
|
49
|
+
import type { BuildSessionContextOptions, SessionContext } from "./session-context";
|
|
50
50
|
import type { BranchSummaryEntry, NewSessionOptions } from "./session-entries";
|
|
51
51
|
import type { SessionManager } from "./session-manager";
|
|
52
52
|
import type { ShakeMode, ShakeResult } from "./shake-types";
|
|
@@ -590,12 +590,12 @@ export declare class AgentSession {
|
|
|
590
590
|
}[];
|
|
591
591
|
buildDisplaySessionContext(): SessionContext;
|
|
592
592
|
/**
|
|
593
|
-
*
|
|
594
|
-
*
|
|
595
|
-
*
|
|
596
|
-
*
|
|
593
|
+
* Transcript for TUI display. Full history is kept for export/resume-style
|
|
594
|
+
* callers; live chat can collapse compacted history to keep the hot render
|
|
595
|
+
* surface bounded. Display-only — NEVER feed the result to
|
|
596
|
+
* `agent.replaceMessages` or a provider.
|
|
597
597
|
*/
|
|
598
|
-
buildTranscriptSessionContext(): SessionContext;
|
|
598
|
+
buildTranscriptSessionContext(options?: Pick<BuildSessionContextOptions, "collapseCompactedHistory">): SessionContext;
|
|
599
599
|
/** Convert session messages using the same pre-LLM pipeline as the active session. */
|
|
600
600
|
convertMessagesToLlm(messages: AgentMessage[], signal?: AbortSignal): Promise<Message[]>;
|
|
601
601
|
/** Apply session-level stream hooks to a direct side request. */
|
|
@@ -32,13 +32,14 @@ export declare function getRestorableSessionModels(models: Readonly<Record<strin
|
|
|
32
32
|
export declare function getLatestCompactionEntry(entries: SessionEntry[]): CompactionEntry | null;
|
|
33
33
|
export interface BuildSessionContextOptions {
|
|
34
34
|
/**
|
|
35
|
-
* Build the
|
|
36
|
-
* every path entry
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* result to a provider.
|
|
35
|
+
* Build the display transcript instead of the LLM context. By default this
|
|
36
|
+
* preserves every path entry with compactions inline; set
|
|
37
|
+
* `collapseCompactedHistory` for the live TUI surface to render only the
|
|
38
|
+
* latest compacted tail.
|
|
40
39
|
*/
|
|
41
40
|
transcript?: boolean;
|
|
41
|
+
/** In transcript mode, elide entries replaced by the latest compaction. */
|
|
42
|
+
collapseCompactedHistory?: boolean;
|
|
42
43
|
}
|
|
43
44
|
/**
|
|
44
45
|
* Build the session context from entries using tree traversal.
|
|
@@ -25,6 +25,10 @@ export interface ParallelResult<R> {
|
|
|
25
25
|
export declare function mapWithConcurrencyLimit<T, R>(items: T[], concurrency: number, fn: (item: T, index: number, signal: AbortSignal) => Promise<R>, signal?: AbortSignal): Promise<ParallelResult<R>>;
|
|
26
26
|
/**
|
|
27
27
|
* Simple counting semaphore for limiting concurrency across independently-scheduled async work.
|
|
28
|
+
*
|
|
29
|
+
* `max <= 0` (or any non-finite input) means unbounded — every `acquire()` resolves
|
|
30
|
+
* immediately — matching `task.maxConcurrency = 0`'s "Unlimited" semantics in the
|
|
31
|
+
* settings UI ([#3305](https://github.com/can1357/oh-my-pi/issues/3305)).
|
|
28
32
|
*/
|
|
29
33
|
export declare class Semaphore {
|
|
30
34
|
#private;
|
package/dist/types/thinking.d.ts
CHANGED
|
@@ -77,8 +77,15 @@ export declare function parseCliThinkingLevel(value: string | null | undefined):
|
|
|
77
77
|
* above Low (falling back to the full supported set only when the model maxes
|
|
78
78
|
* out below Low). Within that pool the request snaps to the highest level not
|
|
79
79
|
* exceeding it, or the pool minimum when the request is below the pool.
|
|
80
|
+
*
|
|
81
|
+
* Returns `undefined` for reasoning-capable models without a controllable
|
|
82
|
+
* effort surface (`thinking.efforts` empty — e.g. devin-agent models, where
|
|
83
|
+
* Cascade selects effort by routing to sibling model ids). Matches
|
|
84
|
+
* {@link clampThinkingLevelForModel}: with no effort to pick, `auto` must not
|
|
85
|
+
* forward a concrete effort that would then trip {@link requireSupportedEffort}
|
|
86
|
+
* downstream.
|
|
80
87
|
*/
|
|
81
|
-
export declare function clampAutoThinkingEffort(model: Model | undefined, effort: Effort): Effort;
|
|
88
|
+
export declare function clampAutoThinkingEffort(model: Model | undefined, effort: Effort): Effort | undefined;
|
|
82
89
|
/**
|
|
83
90
|
* The provisional concrete level shown while `auto` is configured but before a
|
|
84
91
|
* turn has been classified. Prefers the model's `defaultLevel`, otherwise High,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type RefCountedWorkerHandle, type SpawnedSubprocess } from "../subprocess/worker-client";
|
|
2
2
|
import type { TinyTitleProgressEvent, TinyTitleWorkerInbound, TinyTitleWorkerOutbound } from "./title-protocol";
|
|
3
3
|
export interface TinyTitleDownloadOptions {
|
|
4
4
|
signal?: AbortSignal;
|
|
@@ -44,7 +44,7 @@ export declare function tinyWorkerEnv(): Record<string, string>;
|
|
|
44
44
|
export declare function createTinyTitleSubprocess(): SpawnedSubprocess<TinyTitleWorkerOutbound>;
|
|
45
45
|
export declare class TinyTitleClient {
|
|
46
46
|
#private;
|
|
47
|
-
constructor(spawnWorker?: () =>
|
|
47
|
+
constructor(spawnWorker?: () => RefCountedWorkerHandle<TinyTitleWorkerInbound, TinyTitleWorkerOutbound>);
|
|
48
48
|
onProgress(listener: (event: TinyTitleProgressEvent) => void): () => void;
|
|
49
49
|
generate(modelKey: string, message: string, signal?: AbortSignal): Promise<string | null>;
|
|
50
50
|
generate(modelKey: string, message: string, options?: TinyTitleGenerateOptions): Promise<string | null>;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export declare function ffmpegAssetName(_version: string, plat: string, architecture: string): string | null;
|
|
2
2
|
export type ToolName = "sd" | "sg" | "yt-dlp" | "trafilatura" | "ffmpeg";
|
|
3
3
|
export declare function getToolPath(tool: ToolName): string | null;
|
|
4
|
+
/** Download a tool asset without handing the streaming Response to Bun.write. */
|
|
5
|
+
export declare function downloadFile(url: string, dest: string, signal?: AbortSignal): Promise<void>;
|
|
4
6
|
type EnsureToolOptions = {
|
|
5
7
|
signal?: AbortSignal;
|
|
6
8
|
silent?: boolean;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
4
|
-
"version": "16.1.
|
|
4
|
+
"version": "16.1.18",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -48,17 +48,17 @@
|
|
|
48
48
|
"@agentclientprotocol/sdk": "0.25.0",
|
|
49
49
|
"@babel/parser": "^7.29.7",
|
|
50
50
|
"@mozilla/readability": "^0.6.0",
|
|
51
|
-
"@oh-my-pi/hashline": "16.1.
|
|
52
|
-
"@oh-my-pi/omp-stats": "16.1.
|
|
53
|
-
"@oh-my-pi/pi-agent-core": "16.1.
|
|
54
|
-
"@oh-my-pi/pi-ai": "16.1.
|
|
55
|
-
"@oh-my-pi/pi-catalog": "16.1.
|
|
56
|
-
"@oh-my-pi/pi-mnemopi": "16.1.
|
|
57
|
-
"@oh-my-pi/pi-natives": "16.1.
|
|
58
|
-
"@oh-my-pi/pi-tui": "16.1.
|
|
59
|
-
"@oh-my-pi/pi-utils": "16.1.
|
|
60
|
-
"@oh-my-pi/pi-wire": "16.1.
|
|
61
|
-
"@oh-my-pi/snapcompact": "16.1.
|
|
51
|
+
"@oh-my-pi/hashline": "16.1.18",
|
|
52
|
+
"@oh-my-pi/omp-stats": "16.1.18",
|
|
53
|
+
"@oh-my-pi/pi-agent-core": "16.1.18",
|
|
54
|
+
"@oh-my-pi/pi-ai": "16.1.18",
|
|
55
|
+
"@oh-my-pi/pi-catalog": "16.1.18",
|
|
56
|
+
"@oh-my-pi/pi-mnemopi": "16.1.18",
|
|
57
|
+
"@oh-my-pi/pi-natives": "16.1.18",
|
|
58
|
+
"@oh-my-pi/pi-tui": "16.1.18",
|
|
59
|
+
"@oh-my-pi/pi-utils": "16.1.18",
|
|
60
|
+
"@oh-my-pi/pi-wire": "16.1.18",
|
|
61
|
+
"@oh-my-pi/snapcompact": "16.1.18",
|
|
62
62
|
"@opentelemetry/api": "^1.9.1",
|
|
63
63
|
"@opentelemetry/context-async-hooks": "^2.7.1",
|
|
64
64
|
"@opentelemetry/exporter-trace-otlp-proto": "^0.218.0",
|
package/scripts/build-binary.ts
CHANGED
|
@@ -82,22 +82,15 @@ async function main(): Promise<void> {
|
|
|
82
82
|
"--root",
|
|
83
83
|
".",
|
|
84
84
|
"./packages/coding-agent/src/cli.ts",
|
|
85
|
-
// Legacy pi-* extension compat
|
|
86
|
-
//
|
|
87
|
-
//
|
|
88
|
-
//
|
|
89
|
-
//
|
|
90
|
-
//
|
|
91
|
-
//
|
|
92
|
-
//
|
|
93
|
-
//
|
|
94
|
-
"./packages/agent/src/index.ts",
|
|
95
|
-
"./packages/natives/native/index.js",
|
|
96
|
-
"./packages/tui/src/index.ts",
|
|
97
|
-
"./packages/utils/src/index.ts",
|
|
98
|
-
"./packages/coding-agent/src/extensibility/typebox.ts",
|
|
99
|
-
"./packages/coding-agent/src/extensibility/legacy-pi-ai-shim.ts",
|
|
100
|
-
"./packages/coding-agent/src/extensibility/legacy-pi-coding-agent-shim.ts",
|
|
85
|
+
// Legacy pi-* extension compat surfaces (host packages + shims)
|
|
86
|
+
// were previously listed as explicit `--compile` entries so the
|
|
87
|
+
// rewrite path could emit `/$bunfs/root/...` URLs against them.
|
|
88
|
+
// Bun 1.3.14 made bunfs files unreachable at runtime (issue
|
|
89
|
+
// #3423), so `legacy-pi-compat.ts` now serves them through a
|
|
90
|
+
// virtual namespace backed by `legacy-pi-bundled-registry.ts`,
|
|
91
|
+
// which static-imports each surface — the bundler already
|
|
92
|
+
// includes them via the main module graph, so no `--compile`
|
|
93
|
+
// extras are required.
|
|
101
94
|
"--outfile",
|
|
102
95
|
`packages/coding-agent/dist/${outName}`,
|
|
103
96
|
],
|
|
@@ -55,10 +55,15 @@ export interface ClassifyDifficultyDeps {
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
/**
|
|
58
|
-
* Classify `promptText` and return a concrete effort clamped to `deps.model
|
|
58
|
+
* Classify `promptText` and return a concrete effort clamped to `deps.model`,
|
|
59
|
+
* or `undefined` when the model has no controllable effort surface (auto has
|
|
60
|
+
* nothing to pick — the caller leaves the prior reasoning level in place).
|
|
59
61
|
* @throws when the backend cannot produce a usable classification.
|
|
60
62
|
*/
|
|
61
|
-
export async function classifyDifficulty(
|
|
63
|
+
export async function classifyDifficulty(
|
|
64
|
+
promptText: string,
|
|
65
|
+
deps: ClassifyDifficultyDeps,
|
|
66
|
+
): Promise<Effort | undefined> {
|
|
62
67
|
const backend = deps.settings.get("providers.autoThinkingModel");
|
|
63
68
|
const input = prepareClassifierInput(promptText);
|
|
64
69
|
const effort =
|