@oh-my-pi/pi-coding-agent 17.2.11 → 17.2.12

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 (152) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/{CHANGELOG-d9xenpn9.md → CHANGELOG-k9ghy5sn.md} +13 -0
  3. package/dist/cli.js +10795 -10791
  4. package/dist/types/advisor/runtime.d.ts +1 -1
  5. package/dist/types/config/custom-models.d.ts +31 -0
  6. package/dist/types/config/model-config-values.d.ts +19 -0
  7. package/dist/types/config/model-patch.d.ts +93 -0
  8. package/dist/types/config/model-provider-discovery.d.ts +51 -0
  9. package/dist/types/config/model-registry.d.ts +5 -52
  10. package/dist/types/config/settings.d.ts +5 -3
  11. package/dist/types/debug/raw-sse-buffer.d.ts +9 -0
  12. package/dist/types/discovery/agent-plugin-format.d.ts +6 -13
  13. package/dist/types/discovery/contained-path.d.ts +2 -3
  14. package/dist/types/eval/executor-base.d.ts +8 -2
  15. package/dist/types/eval/kernel-session-registry.d.ts +60 -0
  16. package/dist/types/export/share.d.ts +1 -1
  17. package/dist/types/lsp/diagnostics.d.ts +96 -0
  18. package/dist/types/lsp/index.d.ts +7 -128
  19. package/dist/types/lsp/servers.d.ts +72 -0
  20. package/dist/types/lsp/tool.d.ts +42 -0
  21. package/dist/types/lsp/workspace-diagnostics.d.ts +12 -0
  22. package/dist/types/lsp/writethrough.d.ts +33 -0
  23. package/dist/types/mcp/transports/header-policy.d.ts +2 -1
  24. package/dist/types/modes/components/agent-hub-projection.d.ts +2 -7
  25. package/dist/types/modes/components/agent-hub-renderer.d.ts +0 -7
  26. package/dist/types/modes/theme/color.d.ts +19 -0
  27. package/dist/types/modes/theme/loader.d.ts +19 -0
  28. package/dist/types/modes/theme/schema.d.ts +175 -0
  29. package/dist/types/modes/theme/symbols.d.ts +28 -0
  30. package/dist/types/modes/theme/theme-class.d.ts +244 -0
  31. package/dist/types/modes/theme/theme.d.ts +9 -280
  32. package/dist/types/modes/theme/tui-adapters.d.ts +13 -0
  33. package/dist/types/registry/agent-registry.d.ts +1 -3
  34. package/dist/types/secrets/index.d.ts +3 -1
  35. package/dist/types/secrets/message-transform.d.ts +40 -0
  36. package/dist/types/secrets/obfuscator.d.ts +0 -108
  37. package/dist/types/secrets/placeholder-scan.d.ts +95 -0
  38. package/dist/types/secrets/placeholder.d.ts +94 -0
  39. package/dist/types/secrets/replacement.d.ts +82 -0
  40. package/dist/types/session/agent-session-types.d.ts +6 -0
  41. package/dist/types/session/agent-session.d.ts +1 -1
  42. package/dist/types/session/session-handoff.d.ts +3 -3
  43. package/dist/types/session/session-manager.d.ts +32 -0
  44. package/dist/types/session/session-provider-boundary.d.ts +1 -1
  45. package/dist/types/session/turn-recovery.d.ts +2 -2
  46. package/dist/types/slash-commands/builtin-collaboration.d.ts +2 -0
  47. package/dist/types/slash-commands/builtin-completions.d.ts +36 -0
  48. package/dist/types/slash-commands/builtin-control.d.ts +2 -0
  49. package/dist/types/slash-commands/builtin-lifecycle.d.ts +3 -0
  50. package/dist/types/slash-commands/builtin-marketplace.d.ts +11 -0
  51. package/dist/types/slash-commands/builtin-modes.d.ts +5 -0
  52. package/dist/types/slash-commands/builtin-registry.d.ts +1 -1
  53. package/dist/types/slash-commands/builtin-session.d.ts +2 -0
  54. package/dist/types/tools/gh-common.d.ts +69 -0
  55. package/dist/types/tools/gh-pr-checkout.d.ts +84 -0
  56. package/dist/types/tools/gh-pr-diff.d.ts +102 -0
  57. package/dist/types/tools/gh-run-watch.d.ts +78 -0
  58. package/dist/types/tools/gh-search.d.ts +61 -0
  59. package/dist/types/tools/gh-types.d.ts +340 -0
  60. package/dist/types/tools/gh-view.d.ts +88 -0
  61. package/dist/types/tools/gh.d.ts +4 -201
  62. package/dist/types/tools/read-archive.d.ts +16 -0
  63. package/dist/types/tools/read-format.d.ts +104 -0
  64. package/dist/types/tools/read-path-resolution.d.ts +19 -0
  65. package/dist/types/tools/read-pdf-images.d.ts +12 -0
  66. package/dist/types/tools/read-renderer.d.ts +24 -0
  67. package/dist/types/tools/read-selector.d.ts +27 -0
  68. package/dist/types/tools/read-sqlite.d.ts +16 -0
  69. package/dist/types/tools/read-summary.d.ts +19 -0
  70. package/dist/types/tools/read.d.ts +1 -23
  71. package/dist/types/tools/shell-tokenize.d.ts +2 -1
  72. package/dist/types/utils/changelog.d.ts +0 -5
  73. package/package.json +13 -13
  74. package/src/advisor/runtime.ts +12 -7
  75. package/src/config/custom-models.ts +188 -0
  76. package/src/config/model-config-values.ts +128 -0
  77. package/src/config/model-patch.ts +252 -0
  78. package/src/config/model-provider-discovery.ts +132 -0
  79. package/src/config/model-registry.ts +64 -704
  80. package/src/config/settings.ts +7 -3
  81. package/src/debug/raw-sse-buffer.ts +20 -0
  82. package/src/discovery/agent-plugin-format.ts +7 -7
  83. package/src/discovery/contained-path.ts +2 -5
  84. package/src/edit/hashline/diff.ts +5 -1
  85. package/src/eval/executor-base.ts +39 -6
  86. package/src/eval/jl/executor.ts +82 -371
  87. package/src/eval/kernel-session-registry.ts +398 -0
  88. package/src/eval/py/executor.ts +53 -261
  89. package/src/eval/rb/executor.ts +36 -279
  90. package/src/export/share.ts +2 -1
  91. package/src/lsp/diagnostics.ts +516 -0
  92. package/src/lsp/index.ts +20 -2819
  93. package/src/lsp/servers.ts +296 -0
  94. package/src/lsp/tool.ts +1352 -0
  95. package/src/lsp/workspace-diagnostics.ts +170 -0
  96. package/src/lsp/writethrough.ts +561 -0
  97. package/src/mcp/transports/header-policy.ts +1 -1
  98. package/src/modes/components/agent-hub-projection.ts +2 -2
  99. package/src/modes/components/agent-hub-renderer.ts +3 -7
  100. package/src/modes/controllers/command-controller.ts +4 -1
  101. package/src/modes/theme/color.ts +133 -0
  102. package/src/modes/theme/loader.ts +178 -0
  103. package/src/modes/theme/schema.ts +263 -0
  104. package/src/modes/theme/symbols.ts +1000 -0
  105. package/src/modes/theme/theme-class.ts +611 -0
  106. package/src/modes/theme/theme.ts +27 -2453
  107. package/src/modes/theme/tui-adapters.ts +279 -0
  108. package/src/registry/agent-registry.ts +2 -2
  109. package/src/secrets/index.ts +6 -12
  110. package/src/secrets/message-transform.ts +287 -0
  111. package/src/secrets/obfuscator.ts +39 -1303
  112. package/src/secrets/placeholder-scan.ts +506 -0
  113. package/src/secrets/placeholder.ts +309 -0
  114. package/src/secrets/replacement.ts +216 -0
  115. package/src/session/agent-session-types.ts +6 -0
  116. package/src/session/agent-session.ts +113 -7
  117. package/src/session/indexed-session-storage.ts +7 -2
  118. package/src/session/session-advisors.ts +32 -34
  119. package/src/session/session-handoff.ts +39 -20
  120. package/src/session/session-manager.ts +67 -3
  121. package/src/session/session-provider-boundary.ts +3 -6
  122. package/src/session/turn-recovery.ts +21 -12
  123. package/src/slash-commands/builtin-collaboration.ts +504 -0
  124. package/src/slash-commands/builtin-completions.ts +291 -0
  125. package/src/slash-commands/builtin-control.ts +78 -0
  126. package/src/slash-commands/builtin-lifecycle.ts +506 -0
  127. package/src/slash-commands/builtin-marketplace.ts +567 -0
  128. package/src/slash-commands/builtin-modes.ts +518 -0
  129. package/src/slash-commands/builtin-registry.ts +21 -3000
  130. package/src/slash-commands/builtin-session.ts +592 -0
  131. package/src/task/executor.ts +17 -14
  132. package/src/tools/gh-common.ts +288 -0
  133. package/src/tools/gh-pr-checkout.ts +679 -0
  134. package/src/tools/gh-pr-diff.ts +473 -0
  135. package/src/tools/gh-run-watch.ts +1015 -0
  136. package/src/tools/gh-search.ts +500 -0
  137. package/src/tools/gh-types.ts +379 -0
  138. package/src/tools/gh-view.ts +612 -0
  139. package/src/tools/gh.ts +109 -3821
  140. package/src/tools/read-archive.ts +209 -0
  141. package/src/tools/read-format.ts +593 -0
  142. package/src/tools/read-path-resolution.ts +36 -0
  143. package/src/tools/read-pdf-images.ts +250 -0
  144. package/src/tools/read-renderer.ts +289 -0
  145. package/src/tools/read-selector.ts +84 -0
  146. package/src/tools/read-sqlite.ts +215 -0
  147. package/src/tools/read-summary.ts +199 -0
  148. package/src/tools/read.ts +77 -1820
  149. package/src/tools/shell-tokenize.ts +1 -1
  150. package/src/utils/changelog.ts +1 -1
  151. package/src/utils/title-generator.ts +3 -1
  152. package/src/web/search/providers/zai.ts +12 -3
@@ -1,6 +1,6 @@
1
1
  import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
2
2
  import type { AssistantMessage } from "@oh-my-pi/pi-ai";
3
- import { type SecretObfuscator } from "../secrets/obfuscator.js";
3
+ import type { SecretObfuscator } from "../secrets/obfuscator.js";
4
4
  /**
5
5
  * Minimal slice of `Agent` the runtime drives — satisfied by pi-agent-core
6
6
  * `Agent`. `state.error` mirrors `Agent.state.error`: provider/stream failures
@@ -0,0 +1,31 @@
1
+ import type { Api, Model, ModelSpec, RemoteCompactionConfig } from "@oh-my-pi/pi-ai/types";
2
+ import { type HeaderSource } from "./model-config-values.js";
3
+ import { type ModelPatch } from "./model-patch.js";
4
+ import type { ModelOverride, ProviderAuthMode } from "./models-config-schema.js";
5
+ export interface CustomModelDefinitionLike extends ModelPatch {
6
+ id: string;
7
+ api?: Api;
8
+ baseUrl?: string;
9
+ cost?: Model<Api>["cost"];
10
+ }
11
+ export interface CustomModelBuildOptions {
12
+ useDefaults: boolean;
13
+ }
14
+ export interface CustomModelOverlay extends ModelPatch {
15
+ id: string;
16
+ provider: string;
17
+ api: Api;
18
+ baseUrl: string;
19
+ cost?: Model<Api>["cost"];
20
+ isOAuth?: boolean;
21
+ }
22
+ export declare function mergeAuthHeaderSources(sources: readonly HeaderSource[], authHeader: boolean | undefined, apiKeyConfig: string | undefined): Record<string, string> | undefined;
23
+ export declare function buildCustomModelOverlay(providerName: string, providerBaseUrl: string, providerApi: Api | undefined, providerHeaders: Record<string, string> | undefined, providerApiKey: string | undefined, authHeader: boolean | undefined, providerCompat: ModelSpec<Api>["compat"] | undefined, providerAuth: ProviderAuthMode | undefined, providerRemoteCompaction: RemoteCompactionConfig<Api> | undefined, modelDef: CustomModelDefinitionLike): CustomModelOverlay | undefined;
24
+ export declare function finalizeCustomModel(model: CustomModelOverlay, options: CustomModelBuildOptions): Model<Api>;
25
+ export declare function normalizeSuppressedSelector(selector: string, hasLiveModel?: (provider: string, id: string) => boolean): string;
26
+ /**
27
+ * Look up a model's override, falling back to entries keyed by retired
28
+ * effort-tier variant ids (models.yml authored before collapsing). A raw key
29
+ * only re-binds when no live model holds that id.
30
+ */
31
+ export declare function resolveModelOverrideWithAliases(overrides: Map<string, ModelOverride>, model: Model<Api>, hasLiveModel: (provider: string, id: string) => boolean): ModelOverride | undefined;
@@ -0,0 +1,19 @@
1
+ export declare function isCommandConfigValue(valueConfig: string | undefined): valueConfig is string;
2
+ export interface CommandApiKeyResolution {
3
+ configured: boolean;
4
+ value?: string;
5
+ }
6
+ /**
7
+ * Resolve a models.yml/models.yaml secret/config value to an actual value.
8
+ * `!cmd` runs a shell command and returns trimmed stdout, otherwise env vars are
9
+ * checked first and the input falls back to a literal value.
10
+ */
11
+ export declare function resolveConfigValue(valueConfig: string): string | undefined;
12
+ export type HeaderSource = Record<string, string> | undefined;
13
+ interface HeaderResolutionOptions {
14
+ authHeader?: boolean;
15
+ apiKeyConfig?: string;
16
+ }
17
+ export declare function createLiveConfigHeaders(sources: readonly HeaderSource[], options?: HeaderResolutionOptions): Record<string, string> | undefined;
18
+ export declare function resolveConfigHeaders(headers: Record<string, string> | undefined): Record<string, string> | undefined;
19
+ export {};
@@ -0,0 +1,93 @@
1
+ import type { Api, Model, ModelSpec, RemoteCompactionConfig, ThinkingConfig } from "@oh-my-pi/pi-ai/types";
2
+ import type { ModelOverride } from "./models-config-schema.js";
3
+ /** Provider override config (baseUrl, headers, apiKey, compat, transport) without custom models */
4
+ export interface ProviderOverride {
5
+ baseUrl?: string;
6
+ headers?: Record<string, string>;
7
+ apiKey?: string;
8
+ authHeader?: boolean;
9
+ compat?: ModelSpec<Api>["compat"];
10
+ remoteCompaction?: RemoteCompactionConfig<Api>;
11
+ transport?: Model<Api>["transport"];
12
+ }
13
+ /**
14
+ * Merge a freshly discovered model with the matching bundled/configured entry
15
+ * (or a runtime provider override when no bundled entry exists).
16
+ *
17
+ * `baseUrl` resolution priority:
18
+ * 1. User-set `providerOverride.baseUrl` (explicit override in models.json)
19
+ * 2. Discovered baseUrl (xiaomi `tp-` token-plan keys resolve to
20
+ * `token-plan-sgp.xiaomimimo.com` at discovery time)
21
+ * 3. Existing bundled baseUrl (the host baked into `models.json`)
22
+ *
23
+ * `transport` resolution priority:
24
+ * 1. `providerOverride.transport` (e.g. `pi-native` for auth-gateway users)
25
+ * 2. `existing.transport` (carried over from boot-time override application)
26
+ * 3. `model.transport` (rarely set — discovery defaults omit it)
27
+ *
28
+ * Without (1), the user's override would lose to discovery; without (2)
29
+ * preferred over (3), the bundled `api.xiaomimimo.com` would shadow the
30
+ * tp- token-plan host and produce 401s on the first stream call.
31
+ * Without explicit transport propagation, an openrouter (or any) entry
32
+ * marked `transport: pi-native` in models.yml silently reverts to the
33
+ * default openai-completions transport after the background catalog
34
+ * refresh — so the first `/model` switch after boot hits the raw OpenAI
35
+ * chat-completions URL instead of the gateway's `/v1/pi/stream` (#2555).
36
+ * See `xiaomi-tp-discovery-merge.test.ts` and the `refresh()` baseUrl-override
37
+ * regression in `model-registry.test.ts`.
38
+ */
39
+ export declare function mergeDiscoveredModel<TApi extends Api>(model: Model<TApi>, existing: Model<Api> | undefined, providerOverride?: Pick<ProviderOverride, "baseUrl" | "compat" | "headers" | "remoteCompaction" | "transport">): Model<TApi>;
40
+ export declare const AUTHORITATIVE_RUNTIME_CATALOG_PROVIDERS: Set<string>;
41
+ export declare function providersWithAuthoritativeProjectCatalog(models: readonly Model<Api>[]): Set<string>;
42
+ export declare function dropProviderModels(models: readonly Model<Api>[], providers: ReadonlySet<string>): Model<Api>[];
43
+ /**
44
+ * Merge `incoming` entries into a copy of `base`, keyed by `provider`+`id`.
45
+ * Matches are replaced with `combine(existing, entry)`; new entries are
46
+ * appended as `combine(undefined, entry)`.
47
+ */
48
+ export declare function mergeByModelKey<T extends {
49
+ provider: string;
50
+ id: string;
51
+ }>(base: readonly Model<Api>[], incoming: readonly T[], combine: (existing: Model<Api> | undefined, entry: T) => Model<Api>): Model<Api>[];
52
+ export declare function mergeCompat<TBase extends object, TOverride extends object>(baseCompat: TBase | null | undefined, overrideCompat: TOverride | null | undefined): (TBase & TOverride) | TBase | TOverride | undefined;
53
+ export declare function mergeRemoteCompactionConfig(baseConfig: RemoteCompactionConfig<Api> | undefined, overrideConfig: RemoteCompactionConfig<Api> | undefined): RemoteCompactionConfig<Api> | undefined;
54
+ export declare function mergeProviderRemoteCompactionConfig(modelConfig: RemoteCompactionConfig<Api> | undefined, providerConfig: RemoteCompactionConfig<Api> | undefined): RemoteCompactionConfig<Api> | undefined;
55
+ /**
56
+ * Project a built model back to spec shape for the model-manager/cache
57
+ * boundary: sparse compat comes from `compatConfig`, never from the resolved
58
+ * record.
59
+ */
60
+ export declare function toModelSpec<TApi extends Api>(model: Model<TApi>): ModelSpec<TApi>;
61
+ /**
62
+ * The patchable subset of `Model` fields shared by `modelOverrides` entries,
63
+ * custom model definitions, and parsed custom-model overlays. `undefined`
64
+ * always means "leave the base value alone".
65
+ */
66
+ export interface ModelPatch {
67
+ name?: string;
68
+ reasoning?: boolean;
69
+ thinking?: ThinkingConfig;
70
+ input?: ("text" | "image")[];
71
+ supportsTools?: boolean;
72
+ cost?: Partial<Model<Api>["cost"]>;
73
+ contextWindow?: number;
74
+ maxTokens?: number;
75
+ omitMaxOutputTokens?: boolean;
76
+ headers?: Record<string, string>;
77
+ compat?: ModelSpec<Api>["compat"];
78
+ contextPromotionTarget?: string;
79
+ compactionModel?: string;
80
+ remoteCompaction?: RemoteCompactionConfig<Api>;
81
+ premiumMultiplier?: number;
82
+ }
83
+ /**
84
+ * How a patch treats the base model's transport metadata (headers/compat):
85
+ * - `merge`: fold the patch into the base's (modelOverrides semantics).
86
+ * - `replace`: the patch owns transport wholesale — same-id custom definitions
87
+ * already folded provider-level headers/compat in during parsing, so bundled
88
+ * transport metadata must not be re-merged (see `#mergeCustomModels`).
89
+ */
90
+ type ModelTransportPolicy = "merge" | "replace";
91
+ export declare function applyModelPatch(base: Model<Api>, patch: ModelPatch, transport: ModelTransportPolicy): Model<Api>;
92
+ export declare function applyModelOverride(model: Model<Api>, override: ModelOverride): Model<Api>;
93
+ export {};
@@ -0,0 +1,51 @@
1
+ import type { Api, Model } from "@oh-my-pi/pi-ai/types";
2
+ import { type OpenAICodexAccount } from "@oh-my-pi/pi-catalog/provider-models";
3
+ import type { AuthStorage, OAuthCredential } from "../session/auth-storage.js";
4
+ export declare const STARTUP_MODEL_CACHE_PROVIDER_IDS: readonly string[];
5
+ /**
6
+ * Hard bound for extension-provided fetchDynamicModels to prevent indefinite hangs
7
+ * during runtime provider discovery. Uses a cancellable manual timer (not AbortSignal.timeout)
8
+ * so a successful fast path does not leave an armed timeout signal for concurrent GC.
9
+ */
10
+ export declare const RUNTIME_DYNAMIC_MODEL_FETCH_TIMEOUT_MS = 15000;
11
+ export declare const BUILT_IN_DISCOVERY_CACHE_TTL_MS: number;
12
+ export declare const BUILT_IN_DISCOVERY_NON_AUTHORITATIVE_RETRY_MS: number;
13
+ export declare const kNoAuth = "N/A";
14
+ export declare function isAuthenticated(apiKey: string | undefined | null): apiKey is string;
15
+ export declare function isDiscoveryBearerApiKey(apiKey: string | undefined | null): apiKey is string;
16
+ /**
17
+ * Wraps an extension-provided fetchDynamicModels call with a hard timeout.
18
+ * Uses a cancellable manual timer (not AbortSignal.timeout) so that a fast
19
+ * successful path does not leave an armed timeout signal for concurrent GC.
20
+ * The inner fetcher does not receive a signal (extension contract has none).
21
+ */
22
+ export declare function withRuntimeDynamicModelsTimeout<T>(timeoutMs: number, run: () => Promise<T>): Promise<T>;
23
+ export interface BuiltInDiscoveryResult {
24
+ models: Model<Api>[];
25
+ authoritativeProviders: Set<string>;
26
+ }
27
+ export type ProviderDiscoveryStatus = "idle" | "ok" | "empty" | "cached" | "unavailable" | "unauthenticated";
28
+ export interface ProviderDiscoveryState {
29
+ provider: string;
30
+ status: ProviderDiscoveryStatus;
31
+ optional: boolean;
32
+ stale: boolean;
33
+ fetchedAt?: number;
34
+ models: string[];
35
+ error?: string;
36
+ }
37
+ export declare function extractGoogleOAuthToken(value: string | undefined): string | undefined;
38
+ export declare function getOAuthCredentialsForProvider(authStorage: AuthStorage, provider: string): OAuthCredential[];
39
+ /**
40
+ * Resolve every configured Codex OAuth account for catalog discovery, refreshing
41
+ * each credential exactly once. Codex `/models` is account-scoped, so discovery
42
+ * must fetch per account and union the results; resolving a single access token
43
+ * (as before) hid models available only through a sibling account (#6265).
44
+ *
45
+ * Returns `null` when any stored account fails to resolve (e.g. a transient
46
+ * refresh failure): the Codex manager is authoritative, so unioning only the
47
+ * accounts that resolved would cache a partial catalog and hide the failed
48
+ * account's models for the cache TTL. Aborting keeps the previous/bundled
49
+ * catalog instead.
50
+ */
51
+ export declare function resolveCodexDiscoveryAccounts(authStorage: AuthStorage, resolvedAccessToken: string): Promise<OpenAICodexAccount[] | null>;
@@ -1,60 +1,14 @@
1
+ import type { ApiKeyResolver, FetchImpl } from "@oh-my-pi/pi-ai";
2
+ import type { OAuthCredentials, OAuthLoginCallbacks } from "@oh-my-pi/pi-ai/oauth/types";
1
3
  import type { Api, Context, Model, ModelSpec, RemoteCompactionConfig, SimpleStreamOptions, ThinkingConfig } from "@oh-my-pi/pi-ai/types";
2
4
  import type { AssistantMessageEventStream } from "@oh-my-pi/pi-ai/utils/event-stream";
3
5
  import { type ModelRefreshStrategy } from "@oh-my-pi/pi-catalog/model-manager";
4
- import type { ApiKeyResolver, FetchImpl } from "@oh-my-pi/pi-ai";
5
- import type { OAuthCredentials, OAuthLoginCallbacks } from "@oh-my-pi/pi-ai/oauth/types";
6
6
  import type { AuthStorage } from "../session/auth-storage.js";
7
7
  import { type ApiKeyResolverModel, type ApiKeyResolverOptions } from "./api-key-resolver.js";
8
8
  import type { ConfigError } from "./config-file.js";
9
- export declare const kNoAuth = "N/A";
10
- export declare function isAuthenticated(apiKey: string | undefined | null): apiKey is string;
11
- /** Provider override config (baseUrl, headers, apiKey, compat, transport) without custom models */
12
- interface ProviderOverride {
13
- baseUrl?: string;
14
- headers?: Record<string, string>;
15
- apiKey?: string;
16
- authHeader?: boolean;
17
- compat?: ModelSpec<Api>["compat"];
18
- remoteCompaction?: RemoteCompactionConfig<Api>;
19
- transport?: Model<Api>["transport"];
20
- }
21
- /**
22
- * Merge a freshly discovered model with the matching bundled/configured entry
23
- * (or a runtime provider override when no bundled entry exists).
24
- *
25
- * `baseUrl` resolution priority:
26
- * 1. User-set `providerOverride.baseUrl` (explicit override in models.json)
27
- * 2. Discovered baseUrl (xiaomi `tp-` token-plan keys resolve to
28
- * `token-plan-sgp.xiaomimimo.com` at discovery time)
29
- * 3. Existing bundled baseUrl (the host baked into `models.json`)
30
- *
31
- * `transport` resolution priority:
32
- * 1. `providerOverride.transport` (e.g. `pi-native` for auth-gateway users)
33
- * 2. `existing.transport` (carried over from boot-time override application)
34
- * 3. `model.transport` (rarely set — discovery defaults omit it)
35
- *
36
- * Without (1), the user's override would lose to discovery; without (2)
37
- * preferred over (3), the bundled `api.xiaomimimo.com` would shadow the
38
- * tp- token-plan host and produce 401s on the first stream call.
39
- * Without explicit transport propagation, an openrouter (or any) entry
40
- * marked `transport: pi-native` in models.yml silently reverts to the
41
- * default openai-completions transport after the background catalog
42
- * refresh — so the first `/model` switch after boot hits the raw OpenAI
43
- * chat-completions URL instead of the gateway's `/v1/pi/stream` (#2555).
44
- * See `xiaomi-tp-discovery-merge.test.ts` and the `refresh()` baseUrl-override
45
- * regression in `model-registry.test.ts`.
46
- */
47
- export declare function mergeDiscoveredModel<TApi extends Api>(model: Model<TApi>, existing: Model<Api> | undefined, providerOverride?: Pick<ProviderOverride, "baseUrl" | "compat" | "headers" | "remoteCompaction" | "transport">): Model<TApi>;
48
- export type ProviderDiscoveryStatus = "idle" | "ok" | "empty" | "cached" | "unavailable" | "unauthenticated";
49
- export interface ProviderDiscoveryState {
50
- provider: string;
51
- status: ProviderDiscoveryStatus;
52
- optional: boolean;
53
- stale: boolean;
54
- fetchedAt?: number;
55
- models: string[];
56
- error?: string;
57
- }
9
+ import { type ProviderDiscoveryState } from "./model-provider-discovery.js";
10
+ export { mergeDiscoveredModel } from "./model-patch.js";
11
+ export { isAuthenticated, kNoAuth, type ProviderDiscoveryState, type ProviderDiscoveryStatus, } from "./model-provider-discovery.js";
58
12
  /** Authentication material returned to legacy extensions for one model request. */
59
13
  export type ResolvedRequestAuth = {
60
14
  ok: true;
@@ -315,4 +269,3 @@ export interface ProviderConfigInput {
315
269
  premiumMultiplier?: number;
316
270
  }>;
317
271
  }
318
- export {};
@@ -55,10 +55,12 @@ export declare class Settings {
55
55
  */
56
56
  static loadIsolated(options?: SettingsOptions): Promise<Settings>;
57
57
  /**
58
- * Create an isolated instance for testing.
59
- * Does not affect the global singleton.
58
+ * Create an in-memory settings instance without affecting the global singleton.
59
+ * A supplied storage handle remains shared for runtime data while setting overrides stay non-persistent.
60
60
  */
61
- static isolated(overrides?: Partial<Record<SettingPath, unknown>>): Settings;
61
+ static isolated(overrides?: Partial<Record<SettingPath, unknown>>, options?: {
62
+ storage?: AgentStorage | null;
63
+ }): Settings;
62
64
  /**
63
65
  * Get the global singleton.
64
66
  * Throws if not initialized.
@@ -40,5 +40,14 @@ export declare class RawSseDebugBuffer {
40
40
  recordEvent(event: RawSseEvent, model?: Model): void;
41
41
  snapshot(): RawSseDebugSnapshot;
42
42
  toRawText(): string;
43
+ /**
44
+ * Drop every retained record and reset accounting. Called from
45
+ * {@link AgentSession} teardown so a disposed (e.g. parked subagent) session
46
+ * stops pinning captured wire frames — each trimmed record holds a
47
+ * `slice()` of its parent SSE frame, which under JSC keeps the whole
48
+ * multi-MB frame alive. Notifies subscribers so a live debug viewer redraws
49
+ * empty.
50
+ */
51
+ clear(): void;
43
52
  }
44
53
  export declare function resolveRawSseDebugBuffer(owner?: object): RawSseDebugBuffer;
@@ -32,7 +32,7 @@ export interface AgentPluginManifest {
32
32
  * - `invalid` — the document targets Agent Plugins but violates the closed schema
33
33
  * fatally; the plugin must be rejected and none of its components loaded (spec §5.2).
34
34
  */
35
- export type AgentPluginManifestResult = {
35
+ type AgentPluginManifestResult = {
36
36
  status: "none";
37
37
  } | {
38
38
  status: "valid";
@@ -42,8 +42,6 @@ export type AgentPluginManifestResult = {
42
42
  status: "invalid";
43
43
  reason: string;
44
44
  };
45
- /** Enforce the plugin `name` constraints from spec §5.5. */
46
- export declare function isValidAgentPluginName(name: string): boolean;
47
45
  /**
48
46
  * Validate `SKILL.md` frontmatter against the Agent Skills specification
49
47
  * (https://agentskills.io/specification), the source of truth for skill
@@ -58,14 +56,8 @@ export declare function validateAgentSkillFrontmatter(frontmatter: Record<string
58
56
  * Agent Plugins 1.0.0 manifest schema (spec §5.2–§5.5, §8.1).
59
57
  */
60
58
  export declare function parseAgentPluginManifest(raw: string): AgentPluginManifestResult;
61
- /**
62
- * Expand `${PLUGIN_ROOT}` and `${PLUGIN_DATA}` in a configuration value
63
- * (spec §9.2). Single non-recursive pass; replacement text is never rescanned,
64
- * and no other placeholder or environment-variable expansion is performed.
65
- */
66
- export declare function expandAgentPluginPlaceholders(value: string, pluginRoot: string, pluginData: string): string;
67
59
  /** A validated `mcp.json` server entry, resolved to launch-ready values. */
68
- export interface AgentPluginMcpServer {
60
+ interface AgentPluginMcpServer {
69
61
  name: string;
70
62
  transport: "stdio" | "http" | "sse";
71
63
  /** Absolute path for `./`-relative commands; bare executable token otherwise. */
@@ -85,7 +77,7 @@ export interface AgentPluginMcpServer {
85
77
  * - `ok` — the document is valid; individually invalid server entries are
86
78
  * skipped with a warning (spec §7.2.2 rule 3).
87
79
  */
88
- export type AgentPluginMcpResult = {
80
+ type AgentPluginMcpResult = {
89
81
  status: "disabled";
90
82
  reason: string;
91
83
  } | {
@@ -93,7 +85,7 @@ export type AgentPluginMcpResult = {
93
85
  servers: AgentPluginMcpServer[];
94
86
  warnings: string[];
95
87
  };
96
- export interface AgentPluginMcpOptions {
88
+ interface AgentPluginMcpOptions {
97
89
  /** Filesystem-resolved plugin root. */
98
90
  pluginRoot: string;
99
91
  /** Client-managed persistent data directory for this plugin (spec §9.1). */
@@ -114,7 +106,7 @@ export declare function parseAgentPluginMcp(raw: string, options: AgentPluginMcp
114
106
  * - `invalid` — the root claims Agent Plugins conformance but its manifest is
115
107
  * fatally invalid; no component may be discovered or executed (spec §11.3).
116
108
  */
117
- export type AgentPluginRootStatus = {
109
+ type AgentPluginRootStatus = {
118
110
  kind: "none";
119
111
  } | {
120
112
  kind: "standard";
@@ -141,3 +133,4 @@ export declare function classifyAgentPluginRoot(rootPath: string): Promise<Agent
141
133
  * hybrid packages. Fatally invalid Agent Plugins packages are rejected entirely.
142
134
  */
143
135
  export declare function legacyProviderAllowed(rootPath: string, surface: "skills" | "mcp" | "other"): Promise<boolean>;
136
+ export {};
@@ -1,9 +1,7 @@
1
- /** Lexical containment: `target` is `base` itself or a descendant of it. */
2
- export declare function isContained(base: string, target: string): boolean;
3
1
  /** Resolve symlinks and equivalents; `null` when the path is missing or unresolvable. */
4
2
  export declare function realpathIfExists(p: string): Promise<string | null>;
5
3
  /** Outcome of resolving a fixed package path without reading it. */
6
- export type ContainedPathResolution = {
4
+ type ContainedPathResolution = {
7
5
  status: "missing";
8
6
  } | {
9
7
  status: "outside";
@@ -32,3 +30,4 @@ export declare function isContainedResolved(realBase: string, target: string): P
32
30
  * (bash `skill://` expansion).
33
31
  */
34
32
  export declare function resolveContainedPathSync(realBase: string, target: string): ContainedPathResolution;
33
+ export {};
@@ -71,7 +71,7 @@ export declare function isTimedOutCancellation(error: unknown, cancelledErrorCla
71
71
  export declare function waitForPromiseWithCancellation<T>(promise: Promise<T>, options: {
72
72
  signal?: AbortSignal;
73
73
  deadlineMs?: number;
74
- }, cancelledErrorClass: CancelledErrorClass): Promise<T>;
74
+ }, cancelledErrorClass: CancelledErrorClass, timedOutResolver?: (error: unknown, signal?: AbortSignal) => boolean): Promise<T>;
75
75
  export declare function createCancelledKernelResult(output: string): KernelExecutionResult;
76
76
  export declare const MANAGED_KERNEL_ENV_KEYS: readonly ["PI_SESSION_FILE", "PI_ARTIFACTS_DIR", "PI_TOOL_BRIDGE_URL", "PI_TOOL_BRIDGE_TOKEN", "PI_TOOL_BRIDGE_SESSION", "PI_EVAL_LOCAL_ROOTS"];
77
77
  interface ManagedKernelEnvOptions {
@@ -84,8 +84,14 @@ interface ManagedKernelEnvOptions {
84
84
  };
85
85
  localRoots?: Record<string, string>;
86
86
  }
87
+ interface ManagedKernelEnvPolicy {
88
+ sparse?: boolean;
89
+ }
87
90
  export declare function buildManagedKernelEnvPatch(options: ManagedKernelEnvOptions): Record<string, string | null>;
88
- export declare function buildManagedKernelEnv(options: ManagedKernelEnvOptions): Record<string, string> | undefined;
91
+ export declare function buildManagedKernelEnvPatch(options: ManagedKernelEnvOptions, policy: {
92
+ sparse: true;
93
+ }): Record<string, string | undefined>;
94
+ export declare function buildManagedKernelEnv(options: ManagedKernelEnvOptions, policy?: ManagedKernelEnvPolicy): Record<string, string> | undefined;
89
95
  export declare function attachSessionOwner(session: {
90
96
  ownerIds: Set<string>;
91
97
  hasFallbackOwner: boolean;
@@ -0,0 +1,60 @@
1
+ import { type CancelledErrorClass, type SessionOwners } from "./executor-base.js";
2
+ interface KernelSessionRegistryOptions {
3
+ sessionId?: string;
4
+ kernelOwnerId?: string;
5
+ interpreter?: string;
6
+ reset?: boolean;
7
+ signal?: AbortSignal;
8
+ deadlineMs?: number;
9
+ bridge?: unknown;
10
+ bridgeSessionId?: string;
11
+ }
12
+ interface RegistryKernelShutdownResult {
13
+ confirmed?: boolean;
14
+ }
15
+ interface RegistryKernel {
16
+ isAlive(): boolean;
17
+ shutdown(options?: {
18
+ timeoutMs: number;
19
+ }): Promise<RegistryKernelShutdownResult>;
20
+ }
21
+ export interface KernelSession<TKernel extends RegistryKernel> extends SessionOwners {
22
+ sessionKey: string;
23
+ sessionId: string;
24
+ cwd: string;
25
+ kernel: TKernel;
26
+ }
27
+ export interface KernelSessionRegistryContext<TKernel extends RegistryKernel, TOptions extends KernelSessionRegistryOptions, TSession extends KernelSession<TKernel>> {
28
+ sessions: Map<string, TSession>;
29
+ startKernel: (cwd: string, options: TOptions) => Promise<TKernel>;
30
+ replaceSessionKernel: (session: TSession, cwd: string, options: TOptions) => Promise<TKernel>;
31
+ }
32
+ interface KernelSessionRegistryDescriptor<TKernel extends RegistryKernel, TOptions extends KernelSessionRegistryOptions, TResult, TSession extends KernelSession<TKernel>> {
33
+ languageLabel: string;
34
+ cancelledErrorClass: CancelledErrorClass;
35
+ buildSessionKey: (sessionId: string, cwd: string, interpreter: string | undefined) => string;
36
+ createSession: (session: KernelSession<TKernel>) => TSession;
37
+ startKernel: (cwd: string, options: TOptions) => Promise<TKernel>;
38
+ executeWithKernel: (kernel: TKernel, code: string, options: TOptions) => Promise<TResult>;
39
+ waitForStartup?: (promise: Promise<TSession>, options: TOptions) => Promise<TSession>;
40
+ replaceSessionKernel?: (session: TSession, cwd: string, options: TOptions, context: KernelSessionRegistryContext<TKernel, TOptions, TSession>) => Promise<TKernel>;
41
+ acquireLiveSessionKernel?: (session: TSession, cwd: string, options: TOptions, context: KernelSessionRegistryContext<TKernel, TOptions, TSession>) => Promise<TKernel>;
42
+ invalidateSession?: (session: TSession) => void;
43
+ shutdownSession?: (session: TSession, resetting: boolean) => Promise<RegistryKernelShutdownResult>;
44
+ clearResetsOnDisposeAll?: boolean;
45
+ logBeforeReplacement?: boolean;
46
+ isCancellation?: (error: unknown) => boolean;
47
+ isTimedOutCancellation?: (error: unknown, signal?: AbortSignal) => boolean;
48
+ validateKernel?: (session: TSession, kernel: TKernel) => boolean;
49
+ }
50
+ interface KernelSessionRegistry<TOptions extends KernelSessionRegistryOptions, TResult> {
51
+ disposeAll(): Promise<void>;
52
+ disposeByOwner(ownerId: string): Promise<void>;
53
+ executeOnSession(code: string, cwd: string, options: TOptions): Promise<TResult>;
54
+ }
55
+ export declare function normalizeKernelSessionCwd(cwd: string): string;
56
+ export declare function requireRemainingKernelTimeoutMs(deadlineMs: number | undefined, cancelledErrorClass: CancelledErrorClass): number | undefined;
57
+ export declare function formatSessionTimeoutAnnotation(timeoutMs?: number): string;
58
+ export declare function formatSessionKernelTimeoutAnnotation(timeoutMs: number | undefined, kernelKilled: boolean): string;
59
+ export declare function createKernelSessionRegistry<TKernel extends RegistryKernel, TOptions extends KernelSessionRegistryOptions, TResult, TSession extends KernelSession<TKernel>>(descriptor: KernelSessionRegistryDescriptor<TKernel, TOptions, TResult, TSession>): KernelSessionRegistry<TOptions, TResult>;
60
+ export {};
@@ -1,6 +1,6 @@
1
1
  import type { AgentState } from "@oh-my-pi/pi-agent-core";
2
2
  import { DEFAULT_SHARE_URL } from "@oh-my-pi/pi-wire";
3
- import { type SecretObfuscator } from "../secrets/obfuscator.js";
3
+ import type { SecretObfuscator } from "../secrets/obfuscator.js";
4
4
  import type { SessionManager } from "../session/session-manager.js";
5
5
  import { type SessionData } from "./html/index.js";
6
6
  export { DEFAULT_SHARE_URL };
@@ -0,0 +1,96 @@
1
+ import type { Diagnostic, Location, LocationLink, LspClient, Position, ServerConfig } from "./types.js";
2
+ export declare const SINGLE_DIAGNOSTICS_WAIT_TIMEOUT_MS = 3000;
3
+ export declare const BATCH_DIAGNOSTICS_WAIT_TIMEOUT_MS = 400;
4
+ /**
5
+ * How long the edit/write writethrough blocks inline waiting for fresh
6
+ * diagnostics before handing slow servers off to the deferred late-injection
7
+ * channel. Keeps the common fast-server case inline while letting an edit
8
+ * return promptly when a server (e.g. a large-monorepo tsserver) is slow to
9
+ * publish fresh diagnostics.
10
+ */
11
+ export declare const INLINE_DIAGNOSTICS_WAIT_TIMEOUT_MS = 500;
12
+ /**
13
+ * Inner per-server diagnostics wait budget for the background/deferred fetch.
14
+ * Longer than the inline cap (and the old 3s default) so a slow server still
15
+ * delivers late instead of giving up before it ever publishes.
16
+ */
17
+ export declare const DEFERRED_DIAGNOSTICS_WAIT_TIMEOUT_MS = 12000;
18
+ export declare const MAX_GLOB_DIAGNOSTIC_TARGETS = 20;
19
+ export declare const WORKSPACE_SYMBOL_LIMIT = 200;
20
+ export declare const PROJECT_INDEXED_ACTIONS: ReadonlySet<string>;
21
+ export declare function hasRustWorkspaceAncestor(filePath: string): boolean;
22
+ export declare function limitDiagnosticMessages(messages: string[]): string[];
23
+ export declare const REFERENCE_CONTEXT_LIMIT = 50;
24
+ export declare const REFERENCES_RETRY_COUNT = 2;
25
+ export declare const REFERENCES_RETRY_DELAY_MS = 250;
26
+ export declare function isOnlyQueriedDeclaration(locations: Location[], uri: string, position: Position): boolean;
27
+ export declare function normalizeLocationResult(result: Location | Location[] | LocationLink | LocationLink[] | null): Location[];
28
+ export declare function formatLocationWithContext(location: Location, cwd: string): Promise<string>;
29
+ interface WaitForDiagnosticsOptions {
30
+ timeoutMs?: number;
31
+ signal?: AbortSignal;
32
+ minVersion?: number;
33
+ expectedDocumentVersion?: number;
34
+ /**
35
+ * Quiescence window (ms). typescript-language-server never echoes the document
36
+ * version (issue #983) and emits diagnostics from several sources at different
37
+ * times, so there is no single "complete, version-matched" publish to gate on.
38
+ * When the server does not exact-version-match, accept the latest publish only
39
+ * after no newer one has arrived for this long, letting an in-flight pre-edit
40
+ * publish be superseded by the fresh one.
41
+ */
42
+ settleMs?: number;
43
+ }
44
+ export declare function waitForDiagnostics(client: LspClient, uri: string, options?: WaitForDiagnosticsOptions): Promise<Diagnostic[]>;
45
+ /** Result from getDiagnosticsForFile */
46
+ export interface FileDiagnosticsResult {
47
+ /** Name of the LSP server used (if available) */
48
+ server?: string;
49
+ /** Formatted diagnostic messages */
50
+ messages: string[];
51
+ /** Summary string (e.g., "2 error(s), 1 warning(s)") */
52
+ summary: string;
53
+ /** Whether there are any errors (severity 1) */
54
+ errored: boolean;
55
+ /** Whether the file was formatted */
56
+ formatter?: FileFormatResult;
57
+ }
58
+ export type ServerVersionMap = Map<string, number>;
59
+ interface GetDiagnosticsForFileOptions {
60
+ signal?: AbortSignal;
61
+ minVersions?: ServerVersionMap;
62
+ expectedDocumentVersions?: ServerVersionMap;
63
+ /** Per-server wait budget (ms). Defaults to {@link SINGLE_DIAGNOSTICS_WAIT_TIMEOUT_MS}. */
64
+ timeoutMs?: number;
65
+ }
66
+ /**
67
+ * Capture current diagnostic versions for all LSP servers.
68
+ * Call this BEFORE syncing content to detect stale diagnostics later.
69
+ */
70
+ export declare function captureDiagnosticVersions(cwd: string, servers: Array<[string, ServerConfig]>, initTimeoutMs?: number, signal?: AbortSignal): Promise<ServerVersionMap>;
71
+ export declare function captureOpenFileVersions(absolutePath: string, cwd: string, servers: Array<[string, ServerConfig]>, signal?: AbortSignal): Promise<ServerVersionMap>;
72
+ /**
73
+ * Get diagnostics for a file using LSP or custom linter client.
74
+ *
75
+ * @param absolutePath - Absolute path to the file
76
+ * @param cwd - Working directory for LSP config resolution
77
+ * @param servers - Servers to query diagnostics for
78
+ * @param minVersions - Minimum diagnostic versions per server (to detect stale results)
79
+ * @returns Diagnostic results or undefined if no servers
80
+ */
81
+ export declare function getDiagnosticsForFile(absolutePath: string, cwd: string, servers: Array<[string, ServerConfig]>, options?: GetDiagnosticsForFileOptions): Promise<FileDiagnosticsResult | undefined>;
82
+ export declare enum FileFormatResult {
83
+ UNCHANGED = "unchanged",
84
+ FORMATTED = "formatted"
85
+ }
86
+ /**
87
+ * Format content using LSP or custom linter client.
88
+ *
89
+ * @param absolutePath - Absolute path (for URI)
90
+ * @param content - Content to format
91
+ * @param cwd - Working directory for LSP config resolution
92
+ * @param servers - Servers to try formatting with
93
+ * @returns Formatted content, or original if no formatter available
94
+ */
95
+ export declare function formatContent(absolutePath: string, content: string, cwd: string, servers: Array<[string, ServerConfig]>, signal?: AbortSignal): Promise<string>;
96
+ export {};