jeopi-cli 16.4.2 → 16.4.4

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 (148) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/dist/cli.js +3033 -2991
  3. package/dist/types/advisor/advise-tool.d.ts +5 -1
  4. package/dist/types/advisor/config.d.ts +4 -3
  5. package/dist/types/advisor/runtime.d.ts +15 -0
  6. package/dist/types/cli/args.d.ts +2 -0
  7. package/dist/types/cli/update-cli.d.ts +4 -1
  8. package/dist/types/cli/usage-error.d.ts +4 -0
  9. package/dist/types/commit/agentic/agent.d.ts +1 -0
  10. package/dist/types/config/model-registry.d.ts +3 -3
  11. package/dist/types/config/model-resolver.d.ts +7 -1
  12. package/dist/types/config/models-config.d.ts +1 -1
  13. package/dist/types/config/settings-schema.d.ts +3 -13
  14. package/dist/types/eval/py/tool-bridge.d.ts +1 -0
  15. package/dist/types/extensibility/custom-tools/types.d.ts +3 -0
  16. package/dist/types/extensibility/extensions/runner.d.ts +3 -1
  17. package/dist/types/extensibility/extensions/types.d.ts +3 -0
  18. package/dist/types/internal-urls/memory-protocol.d.ts +6 -6
  19. package/dist/types/internal-urls/types.d.ts +7 -0
  20. package/dist/types/irc/bus.d.ts +4 -0
  21. package/dist/types/lsp/deferred-diagnostics.d.ts +11 -0
  22. package/dist/types/modes/components/move-overlay.d.ts +1 -1
  23. package/dist/types/modes/components/plan-review-overlay.d.ts +2 -0
  24. package/dist/types/modes/components/welcome.d.ts +4 -0
  25. package/dist/types/modes/magic-keyword-boundary.d.ts +9 -0
  26. package/dist/types/modes/orchestrate.d.ts +1 -1
  27. package/dist/types/modes/rpc/host-tools.d.ts +2 -0
  28. package/dist/types/modes/rpc/rpc-mode.d.ts +27 -7
  29. package/dist/types/modes/ultrathink.d.ts +1 -1
  30. package/dist/types/modes/utils/transcript-render-helpers.d.ts +9 -0
  31. package/dist/types/modes/workflow.d.ts +1 -1
  32. package/dist/types/session/agent-session.d.ts +6 -0
  33. package/dist/types/session/auth-broker-config.d.ts +2 -2
  34. package/dist/types/tools/bash-skill-urls.d.ts +3 -2
  35. package/dist/types/tools/browser/cmux/cmux-tab.d.ts +3 -1
  36. package/dist/types/tools/browser/cmux/rpc.d.ts +20 -0
  37. package/dist/types/tools/browser/launch.d.ts +1 -0
  38. package/dist/types/tools/browser/run-cancellation.d.ts +17 -2
  39. package/dist/types/tools/browser/run-output.d.ts +25 -0
  40. package/dist/types/tools/browser/tab-worker.d.ts +22 -0
  41. package/dist/types/utils/changelog.d.ts +35 -1
  42. package/package.json +12 -12
  43. package/src/advisor/__tests__/advisor.test.ts +13 -0
  44. package/src/advisor/__tests__/config.test.ts +36 -0
  45. package/src/advisor/advise-tool.ts +6 -1
  46. package/src/advisor/config.ts +11 -8
  47. package/src/advisor/runtime.ts +127 -0
  48. package/src/autolearn/controller.ts +15 -3
  49. package/src/cli/args.ts +12 -0
  50. package/src/cli/flag-tables.ts +21 -7
  51. package/src/cli/update-cli.ts +63 -13
  52. package/src/cli/usage-error.ts +7 -0
  53. package/src/commands/acp.ts +11 -2
  54. package/src/commands/launch.ts +12 -3
  55. package/src/commit/agentic/agent.ts +4 -0
  56. package/src/commit/agentic/index.ts +46 -21
  57. package/src/config/config-file.ts +30 -12
  58. package/src/config/model-registry.ts +7 -7
  59. package/src/config/model-resolver.ts +24 -6
  60. package/src/config/models-config.ts +1 -1
  61. package/src/config/settings-schema.ts +3 -15
  62. package/src/edit/index.ts +10 -76
  63. package/src/edit/renderer.ts +13 -10
  64. package/src/eval/__tests__/agent-bridge.test.ts +19 -14
  65. package/src/eval/__tests__/bridge-timeout.test.ts +60 -0
  66. package/src/eval/executor-base.ts +84 -7
  67. package/src/eval/js/shared/rewrite-imports.ts +31 -13
  68. package/src/eval/py/tool-bridge.ts +13 -14
  69. package/src/exec/non-interactive-env.ts +0 -1
  70. package/src/export/ttsr.ts +0 -3
  71. package/src/extensibility/custom-tools/loader.ts +70 -37
  72. package/src/extensibility/custom-tools/types.ts +3 -0
  73. package/src/extensibility/extensions/runner.ts +3 -0
  74. package/src/extensibility/extensions/types.ts +3 -0
  75. package/src/extensibility/plugins/legacy-pi-bundled-keys.ts +9 -1
  76. package/src/extensibility/plugins/legacy-pi-bundled-registry.ts +30 -3
  77. package/src/extensibility/plugins/manager.ts +21 -0
  78. package/src/internal-urls/docs-index.generated.txt +1 -1
  79. package/src/internal-urls/memory-protocol.ts +13 -8
  80. package/src/internal-urls/skill-protocol.ts +1 -1
  81. package/src/internal-urls/types.ts +7 -0
  82. package/src/irc/bus.ts +48 -18
  83. package/src/lsp/client.ts +7 -1
  84. package/src/lsp/deferred-diagnostics.ts +66 -0
  85. package/src/main.ts +13 -13
  86. package/src/mcp/tool-bridge.ts +57 -6
  87. package/src/mcp/transports/stdio.test.ts +45 -1
  88. package/src/mcp/transports/stdio.ts +6 -3
  89. package/src/modes/acp/acp-agent.ts +73 -2
  90. package/src/modes/acp/acp-event-mapper.ts +5 -0
  91. package/src/modes/acp/acp-mode.ts +11 -0
  92. package/src/modes/components/__tests__/move-overlay.test.ts +16 -1
  93. package/src/modes/components/advisor-config.ts +15 -7
  94. package/src/modes/components/chat-transcript-builder.ts +31 -11
  95. package/src/modes/components/move-overlay.ts +2 -3
  96. package/src/modes/components/plan-review-overlay.ts +7 -0
  97. package/src/modes/components/tips.txt +1 -1
  98. package/src/modes/components/welcome.ts +13 -14
  99. package/src/modes/controllers/command-controller.ts +8 -10
  100. package/src/modes/controllers/event-controller.ts +58 -42
  101. package/src/modes/controllers/input-controller.ts +9 -6
  102. package/src/modes/controllers/selector-controller.ts +3 -2
  103. package/src/modes/controllers/tan-command-controller.ts +40 -1
  104. package/src/modes/interactive-mode.ts +13 -0
  105. package/src/modes/magic-keyword-boundary.ts +23 -0
  106. package/src/modes/orchestrate.ts +6 -5
  107. package/src/modes/print-mode.ts +9 -0
  108. package/src/modes/rpc/host-tools.ts +13 -0
  109. package/src/modes/rpc/rpc-mode.ts +130 -56
  110. package/src/modes/ultrathink.ts +6 -5
  111. package/src/modes/utils/transcript-render-helpers.ts +44 -0
  112. package/src/modes/utils/ui-helpers.ts +16 -1
  113. package/src/modes/workflow.ts +5 -4
  114. package/src/prompts/system/eager-task.md +2 -2
  115. package/src/prompts/system/tan-context-switch.md +17 -0
  116. package/src/prompts/tools/browser.md +5 -5
  117. package/src/sdk.ts +3 -0
  118. package/src/session/agent-session.ts +267 -36
  119. package/src/session/auth-broker-config.ts +4 -4
  120. package/src/session/snapcompact-inline.ts +3 -19
  121. package/src/session/streaming-output.ts +40 -12
  122. package/src/slash-commands/builtin-registry.ts +8 -8
  123. package/src/task/executor.ts +8 -0
  124. package/src/task/render.ts +51 -44
  125. package/src/tools/bash-skill-urls.ts +7 -4
  126. package/src/tools/bash.ts +30 -33
  127. package/src/tools/browser/cmux/cmux-tab.ts +49 -50
  128. package/src/tools/browser/cmux/rpc.ts +50 -0
  129. package/src/tools/browser/launch.ts +8 -4
  130. package/src/tools/browser/run-cancellation.ts +44 -5
  131. package/src/tools/browser/run-output.ts +76 -0
  132. package/src/tools/browser/tab-worker.ts +280 -133
  133. package/src/tools/eval-render.ts +16 -14
  134. package/src/tools/glob.ts +20 -6
  135. package/src/tools/grep.ts +1 -0
  136. package/src/tools/image-gen.ts +3 -4
  137. package/src/tools/irc.ts +27 -13
  138. package/src/tools/path-utils.ts +6 -1
  139. package/src/tools/read.ts +14 -7
  140. package/src/tools/write.ts +22 -5
  141. package/src/tools/yield.ts +29 -1
  142. package/src/utils/changelog.ts +106 -9
  143. package/src/utils/git.ts +0 -1
  144. package/src/utils/title-generator.ts +72 -7
  145. package/src/web/search/index.ts +14 -6
  146. package/src/web/search/providers/perplexity.ts +18 -2
  147. package/dist/types/tools/bash-command-fixup.d.ts +0 -11
  148. package/src/tools/bash-command-fixup.ts +0 -37
@@ -51,6 +51,9 @@ export declare function isAdvisorInterruptImmuneTurnActive(opts: {
51
51
  * - An interrupting `concern`/`blocker` is normally steered into the agent: into
52
52
  * the live turn while one is streaming, or (when idle) a triggered turn so the
53
53
  * advice is acted on immediately.
54
+ * - If the primary tail is already a terminal text answer and there is no queued
55
+ * work, late interrupting advice is preserved as a visible card instead of
56
+ * waking the primary to restate completion.
54
57
  * - After a deliberate user interrupt (`autoResumeSuppressed`) the advisor must
55
58
  * not auto-resume the stopped run. While the agent is idle — or still tearing
56
59
  * the interrupted turn down (`aborting`) — the note is preserved as a visible
@@ -60,13 +63,14 @@ export declare function isAdvisorInterruptImmuneTurnActive(opts: {
60
63
  * run instead strands it (it never reaches the running agent) and the withheld
61
64
  * notes dump as one burst at the next user prompt — the bug this guards.
62
65
  * - During the post-interrupt immune-turn window, further `concern`/`blocker`
63
- * notes are downgraded to asides; suppression preservation still wins.
66
+ * notes are downgraded to asides; preservation still wins.
64
67
  */
65
68
  export declare function resolveAdvisorDeliveryChannel(opts: {
66
69
  severity: AdvisorSeverity | undefined;
67
70
  autoResumeSuppressed: boolean;
68
71
  streaming: boolean;
69
72
  aborting: boolean;
73
+ terminalAnswerNoQueuedWork?: boolean;
70
74
  interruptImmuneTurnActive?: boolean;
71
75
  }): AdvisorDeliveryChannel;
72
76
  /**
@@ -3,9 +3,10 @@
3
3
  * with an optional `:level` thinking suffix (e.g. `x-ai/grok-code-fast:high`),
4
4
  * resolved exactly like any other model override; `tools` is a subset of
5
5
  * `BUILTIN_TOOL_NAMES` — any built-in name, including mutating tools such as
6
- * `edit`/`write`/`bash` (the advisor is a full agent). Omitted or empty falls
7
- * back to the default `read`/`grep`/`glob` subset. `instructions` is the
8
- * advisor's specialization, appended to the shared baseline.
6
+ * `edit`/`write`/`bash` (the advisor is a full agent). Omitted falls back to
7
+ * the default `read`/`grep`/`glob` subset; an explicit empty list grants no
8
+ * tools. `instructions` is the advisor's specialization, appended to the shared
9
+ * baseline.
9
10
  */
10
11
  export interface AdvisorConfig {
11
12
  name: string;
@@ -1,4 +1,5 @@
1
1
  import type { AgentMessage } from "jeopi-agent-core";
2
+ import type { AssistantMessage } from "jeopi-ai";
2
3
  import { type SecretObfuscator } from "../secrets/obfuscator";
3
4
  /**
4
5
  * Minimal slice of `Agent` the runtime drives — satisfied by pi-agent-core
@@ -58,6 +59,20 @@ export interface AdvisorRuntimeOptions {
58
59
  /** Render the primary's thinking blocks into advisor deltas (default true). */
59
60
  includeThinking?: boolean;
60
61
  }
62
+ /** Signals that an advisor response was discarded before it could become model-visible context. */
63
+ export declare class AdvisorOutputQuarantinedError extends Error {
64
+ constructor(message: string);
65
+ }
66
+ /**
67
+ * Replaces an advisor assistant turn that requested unavailable tools or generated
68
+ * output-only destructive directives with a sanitized error before dispatch.
69
+ */
70
+ export declare function quarantineAdvisorUnsafeOutput(message: AssistantMessage, availableToolNames: ReadonlySet<string>, sourceText?: string): string | undefined;
71
+ /**
72
+ * Builds the provenance text used to decide whether hazardous advisor output was
73
+ * generated by the advisor or came from model-visible primary/tool context.
74
+ */
75
+ export declare function buildAdvisorQuarantineSourceText(currentInput: string, messages: readonly AgentMessage[]): string;
61
76
  export declare function isRefusalError(error: unknown): boolean;
62
77
  export declare class AdvisorRuntime {
63
78
  #private;
@@ -76,5 +76,7 @@ export declare function parseArgs(inputArgs: string[], extensionFlags?: Map<stri
76
76
  * process (issue #2459).
77
77
  */
78
78
  export declare function reportUnrecognizedFlags(args: Pick<Args, "unrecognizedFlags">, write?: (text: string) => void): boolean;
79
+ /** Emit a clean CLI usage error without an internal stack trace. */
80
+ export declare function reportCliUsageError(error: unknown, write?: (text: string) => void): boolean;
79
81
  export declare function getExtraHelpText(): string;
80
82
  export declare function printHelp(): void;
@@ -42,11 +42,12 @@ export declare function parseUpdateArgs(args: string[]): {
42
42
  force: boolean;
43
43
  check: boolean;
44
44
  } | undefined;
45
- type UpdateMethod = "brew" | "mise" | "bun" | "binary";
45
+ type UpdateMethod = "brew" | "mise" | "bun" | "npm" | "binary";
46
46
  interface UpdateMethodResolutionOptions {
47
47
  homebrewPrefix?: string;
48
48
  miseBinDirs?: readonly string[];
49
49
  miseDataDir?: string;
50
+ npmBinDir?: string;
50
51
  }
51
52
  export declare function resolveUpdateMethodForTest(jeopiPath: string, bunBinDir: string | undefined, options?: UpdateMethodResolutionOptions): UpdateMethod;
52
53
  /**
@@ -162,6 +163,8 @@ export declare function replaceBinaryForUpdate(options: BinaryReplacementOptions
162
163
  * See #1824.
163
164
  */
164
165
  export declare function buildBunInstallArgs(expectedVersion: string, nativeTag?: string): string[];
166
+ /** Build the npm argv used to update npm-managed global installs. */
167
+ export declare function buildNpmInstallArgs(expectedVersion: string, nativeTag?: string): string[];
165
168
  export declare function buildHomebrewUpdateArgs(force: boolean): string[];
166
169
  export declare function buildMiseUpgradeArgs(): string[];
167
170
  export declare function buildMiseForceInstallArgs(expectedVersion: string): string[];
@@ -0,0 +1,4 @@
1
+ /** Command-line input error that should be rendered without a stack trace. */
2
+ export declare class CliUsageError extends Error {
3
+ constructor(message: string);
4
+ }
@@ -20,6 +20,7 @@ export interface CommitAgentInput {
20
20
  requireChangelog: boolean;
21
21
  diffText?: string;
22
22
  existingChangelogEntries?: ExistingChangelogEntries[];
23
+ onComplete?: (state: CommitAgentState) => Promise<void> | void;
23
24
  }
24
25
  export interface ExistingChangelogEntries {
25
26
  path: string;
@@ -74,7 +74,7 @@ export declare class ModelRegistry {
74
74
  fetch?: FetchImpl;
75
75
  });
76
76
  /**
77
- * Reload models from disk (built-in + custom from models.json).
77
+ * Reload models from disk (built-in + custom config).
78
78
  */
79
79
  refresh(strategy?: ModelRefreshStrategy): Promise<void>;
80
80
  refreshInBackground(strategy?: ModelRefreshStrategy): void;
@@ -94,12 +94,12 @@ export declare class ModelRegistry {
94
94
  */
95
95
  refreshRuntimeProviders(strategy?: ModelRefreshStrategy): Promise<void>;
96
96
  /**
97
- * Get any error from loading models.json (undefined if no error).
97
+ * Get any error from loading custom models config (undefined if no error).
98
98
  */
99
99
  getError(): ConfigError | undefined;
100
100
  /**
101
101
  * Get all models (built-in + custom).
102
- * If models.json had errors, returns only built-in models.
102
+ * If custom config had errors, returns only built-in models.
103
103
  */
104
104
  getAll(): Model<Api>[];
105
105
  /**
@@ -144,6 +144,7 @@ export declare function resolveModelOverride(modelPatterns: string[], modelRegis
144
144
  model?: Model<Api>;
145
145
  thinkingLevel?: ConfiguredThinkingLevel;
146
146
  explicitThinkingLevel: boolean;
147
+ warning?: string;
147
148
  };
148
149
  /**
149
150
  * Resolve a list of override patterns to the first matching model, with an
@@ -156,6 +157,10 @@ export declare function resolveModelOverride(modelPatterns: string[], modelRegis
156
157
  * `modelRoles.task` pointing at an unqualified id whose only available
157
158
  * provider variant has no configured credentials — see #985).
158
159
  *
160
+ * `sessionId` is forwarded to `getApiKey` so that session-sticky OAuth
161
+ * credentials resolve correctly during the pre-flight auth check. Without it,
162
+ * providers with multiple OAuth accounts may return `undefined` even though
163
+ * the credential is usable once the subagent session starts — see #5325.
159
164
  * Keyless-by-design providers (llama.cpp, ollama, lm-studio) advertise the
160
165
  * `kNoAuth` sentinel from `getApiKey` to signal that they do not require
161
166
  * credentials. Those are treated as authenticated here so an explicitly
@@ -166,11 +171,12 @@ export declare function resolveModelOverride(modelPatterns: string[], modelRegis
166
171
  * primary resolution unchanged so the existing error path still surfaces
167
172
  * a meaningful failure downstream.
168
173
  */
169
- export declare function resolveModelOverrideWithAuthFallback(modelPatterns: string[], parentActiveModelPattern: string | undefined, modelRegistry: ModelLookupRegistry & Pick<ModelRegistry, "getApiKey">, settings?: Settings): Promise<{
174
+ export declare function resolveModelOverrideWithAuthFallback(modelPatterns: string[], parentActiveModelPattern: string | undefined, modelRegistry: ModelLookupRegistry & Pick<ModelRegistry, "getApiKey">, settings?: Settings, sessionId?: string): Promise<{
170
175
  model?: Model<Api>;
171
176
  thinkingLevel?: ConfiguredThinkingLevel;
172
177
  explicitThinkingLevel: boolean;
173
178
  authFallbackUsed: boolean;
179
+ warning?: string;
174
180
  }>;
175
181
  /**
176
182
  * Resolve a list of role patterns to the first matching model.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * models.json config file handle and provider configuration validation.
2
+ * Custom model/provider config file handle and validation.
3
3
  */
4
4
  import type { Api, ModelSpec } from "jeopi-ai/types";
5
5
  import { ConfigFile } from "./config-file";
@@ -1262,7 +1262,7 @@ export declare const SETTINGS_SCHEMA: {
1262
1262
  readonly textVerbosity: {
1263
1263
  readonly type: "enum";
1264
1264
  readonly values: readonly ["low", "medium", "high"];
1265
- readonly default: "high";
1265
+ readonly default: "medium";
1266
1266
  readonly ui: {
1267
1267
  readonly tab: "model";
1268
1268
  readonly group: "Sampling";
@@ -1275,11 +1275,11 @@ export declare const SETTINGS_SCHEMA: {
1275
1275
  }, {
1276
1276
  readonly value: "medium";
1277
1277
  readonly label: "Medium";
1278
- readonly description: "Balance brevity and detail";
1278
+ readonly description: "Balance brevity and detail (default)";
1279
1279
  }, {
1280
1280
  readonly value: "high";
1281
1281
  readonly label: "High";
1282
- readonly description: "Prefer detailed responses (default)";
1282
+ readonly description: "Prefer detailed responses";
1283
1283
  }];
1284
1284
  };
1285
1285
  };
@@ -3332,16 +3332,6 @@ export declare const SETTINGS_SCHEMA: {
3332
3332
  readonly type: "array";
3333
3333
  readonly default: BashInterceptorRule[];
3334
3334
  };
3335
- readonly "bash.stripTrailingHeadTail": {
3336
- readonly type: "boolean";
3337
- readonly default: true;
3338
- readonly ui: {
3339
- readonly tab: "shell";
3340
- readonly group: "Bash";
3341
- readonly label: "Strip head/tail Pipes";
3342
- readonly description: "Silently drop trailing `| head`/`| tail` pipes from single-line bash commands. Output is already truncated automatically.";
3343
- };
3344
- };
3345
3335
  readonly "shellMinimizer.enabled": {
3346
3336
  readonly type: "boolean";
3347
3337
  readonly default: true;
@@ -4,6 +4,7 @@ export interface PyToolBridgeEntry {
4
4
  toolSession: ToolSession;
5
5
  signal?: AbortSignal;
6
6
  emitStatus?: (event: JsStatusEvent) => void;
7
+ abortRequested?: () => boolean;
7
8
  }
8
9
  export interface PyToolBridgeInfo {
9
10
  url: string;
@@ -17,6 +17,7 @@ import type { Settings } from "../../config/settings";
17
17
  import type { ExecOptions, ExecResult } from "../../exec/exec";
18
18
  import type { HookUIContext } from "../../extensibility/hooks/types";
19
19
  import type * as PiCodingAgent from "../../index";
20
+ import type { LocalProtocolOptions } from "../../internal-urls/local-protocol";
20
21
  import type { Theme } from "../../modes/theme/theme";
21
22
  import type { ReadonlySessionManager } from "../../session/session-manager";
22
23
  import type { TodoItem } from "../../tools/todo";
@@ -83,6 +84,8 @@ export interface CustomToolContext {
83
84
  settings?: Settings;
84
85
  /** Fetch implementation for outbound HTTP; defaults to global fetch when omitted. */
85
86
  fetch?: FetchImpl;
87
+ /** Calling session's `local://` root mapping for tools that bridge out of the OMP process. */
88
+ localProtocolOptions?: LocalProtocolOptions;
86
89
  /** Whether to auto-approve all destructive tool operations (--auto-approve CLI flag) */
87
90
  autoApprove?: boolean;
88
91
  }
@@ -6,6 +6,7 @@ import type { CredentialDisabledEvent, ImageContent, Model, ProviderResponseMeta
6
6
  import type { KeyId } from "jeopi-tui";
7
7
  import type { ModelRegistry } from "../../config/model-registry";
8
8
  import type { Settings } from "../../config/settings";
9
+ import type { LocalProtocolOptions } from "../../internal-urls/local-protocol";
9
10
  import type { MemoryRuntimeContext } from "../../memory-backend";
10
11
  import type { SessionManager } from "../../session/session-manager";
11
12
  import type { BranchHandler, NavigateTreeHandler, NewSessionHandler } from "../session-handler-types";
@@ -65,7 +66,8 @@ export declare class ExtensionRunner {
65
66
  private readonly sessionManager;
66
67
  private readonly modelRegistry;
67
68
  private readonly settings?;
68
- constructor(extensions: Extension[], runtime: ExtensionRuntime, cwd: string, sessionManager: SessionManager, modelRegistry: ModelRegistry, getMemory?: () => MemoryRuntimeContext | undefined, settings?: Settings | undefined);
69
+ private readonly localProtocolOptions?;
70
+ constructor(extensions: Extension[], runtime: ExtensionRuntime, cwd: string, sessionManager: SessionManager, modelRegistry: ModelRegistry, getMemory?: () => MemoryRuntimeContext | undefined, settings?: Settings | undefined, localProtocolOptions?: LocalProtocolOptions | undefined);
69
71
  initialize(actions: ExtensionActions, contextActions: ExtensionContextActions, commandContextActions?: ExtensionCommandContextActions, uiContext?: ExtensionUIContext): void;
70
72
  /**
71
73
  * Forward a `credential_disabled` event from `AuthStorage` to extension handlers.
@@ -22,6 +22,7 @@ import type { PythonResult } from "../../eval/py/executor";
22
22
  import type { BashResult } from "../../exec/bash-executor";
23
23
  import type { ExecOptions, ExecResult } from "../../exec/exec";
24
24
  import type * as PiCodingAgent from "../../index";
25
+ import type { LocalProtocolOptions } from "../../internal-urls/local-protocol";
25
26
  import type { MemoryRuntimeContext } from "../../memory-backend";
26
27
  import type { CustomEditor } from "../../modes/components/custom-editor";
27
28
  import type { Theme } from "../../modes/theme/theme";
@@ -222,6 +223,8 @@ export interface ExtensionContext {
222
223
  sessionManager: ReadonlySessionManager;
223
224
  /** Model registry for API key resolution */
224
225
  modelRegistry: ModelRegistry;
226
+ /** Calling session's `local://` root mapping for external tool bridges. */
227
+ localProtocolOptions?: LocalProtocolOptions;
225
228
  /** Current model (may be undefined) */
226
229
  model: Model | undefined;
227
230
  /** Read-only model query facade: list / current / resolve / family. */
@@ -1,4 +1,4 @@
1
- import type { InternalResource, InternalUrl, ProtocolHandler, UrlCompletion } from "./types";
1
+ import type { InternalResource, InternalUrl, ProtocolHandler, ResolveContext, UrlCompletion } from "./types";
2
2
  /**
3
3
  * Snapshot of memory roots for every registered session, deduped.
4
4
  * Each session has its own cwd (possibly a worktree), so subagents and main
@@ -12,13 +12,13 @@ export declare function resolveMemoryUrlToPath(url: InternalUrl, memoryRoot: str
12
12
  /**
13
13
  * Protocol handler for memory:// URLs.
14
14
  *
15
- * Walks every active session's memory root. Worktree-based subagents have
16
- * their own root; first one containing the file wins. Parent and subagent
17
- * sharing a cwd see the same file regardless of order.
15
+ * Resolves file-backed roots against the calling session cwd when provided.
16
+ * Contextless callers fall back to the live-session registry for legacy
17
+ * cross-session lookups.
18
18
  */
19
19
  export declare class MemoryProtocolHandler implements ProtocolHandler {
20
20
  readonly scheme = "memory";
21
21
  readonly immutable = true;
22
- resolve(url: InternalUrl): Promise<InternalResource>;
23
- complete(): Promise<UrlCompletion[]>;
22
+ resolve(url: InternalUrl, context?: ResolveContext): Promise<InternalResource>;
23
+ complete(_query?: string, context?: ResolveContext): Promise<UrlCompletion[]>;
24
24
  }
@@ -102,6 +102,13 @@ export interface ResolveContext {
102
102
  * reject directory resources, so they never need the listing.
103
103
  */
104
104
  skipDirectoryListing?: boolean;
105
+ /**
106
+ * When set, handlers that support both a "document" and a "directory" form
107
+ * for the same bare URL (e.g. `skill://name` vs `skill://name/SKILL.md`)
108
+ * resolve to the directory instead of the document. Used by `glob`'s
109
+ * internal-URL find path, which needs a directory to walk.
110
+ */
111
+ pathOnly?: boolean;
105
112
  }
106
113
  /**
107
114
  * Caller context for write operations dispatched to host-owned URI handlers.
@@ -76,6 +76,10 @@ export declare class IrcBus {
76
76
  from?: string;
77
77
  }, timeoutMs: number, signal?: AbortSignal, options?: {
78
78
  drainPending?: boolean;
79
+ liveness?: {
80
+ registry: AgentRegistry;
81
+ senderId: string;
82
+ };
79
83
  }): Promise<IrcMessage | null>;
80
84
  /** Drain (or peek) pending messages for `agentId`. */
81
85
  inbox(agentId: string, opts?: {
@@ -0,0 +1,11 @@
1
+ import type { ToolSession } from "../tools";
2
+ import type { WritethroughDeferredHandle } from "./index";
3
+ /** Coordinates late LSP diagnostics for one mutation tool instance. */
4
+ export declare class DeferredDiagnostics {
5
+ #private;
6
+ private readonly session;
7
+ private readonly deduplicate;
8
+ constructor(session: ToolSession, deduplicate: boolean);
9
+ /** Begin a file mutation and return the handle consumed by LSP writethrough. */
10
+ begin(path: string): WritethroughDeferredHandle;
11
+ }
@@ -18,6 +18,6 @@ export declare class MoveOverlay implements Component, Focusable {
18
18
  get focused(): boolean;
19
19
  set focused(value: boolean);
20
20
  handleInput(data: string): void;
21
- render(_width: number): readonly string[];
21
+ render(width: number): readonly string[];
22
22
  invalidate(): void;
23
23
  }
@@ -25,6 +25,8 @@ export interface PlanReviewOverlayCallbacks {
25
25
  onCancel: () => void;
26
26
  /** Invoked when the external-editor key is pressed (overlay stays open). */
27
27
  onExternalEditor?: () => void;
28
+ /** Invoked with the current full plan text when the copy hotkey is pressed. */
29
+ onCopyPlan?: (content: string) => void | Promise<void>;
28
30
  /** Invoked when the external-editor key edits the active annotation draft. */
29
31
  onAnnotationExternalEditor?: (draft: string, commit: (text: string | null) => void) => void;
30
32
  /** Invoked with the new full plan text after an in-overlay delete/undo. */
@@ -9,6 +9,10 @@ export declare const WELCOME_SESSION_SLOTS = 4;
9
9
  * the box height is constant regardless of how many servers a project has.
10
10
  */
11
11
  export declare const WELCOME_LSP_SLOTS = 4;
12
+ /** Pick a tip from `tips`, biased toward "[NEW]" tips by {@link NEW_TIP_WEIGHT};
13
+ * `r` is a uniform sample in [0, 1). Returns "" when `tips` is empty.
14
+ * Exported for tests. */
15
+ export declare function pickWeightedTip(tips: readonly string[], r: number): string;
12
16
  export declare function renderWelcomeTip(tip: string, boxWidth: number, phase?: number): string[];
13
17
  export interface RecentSession {
14
18
  name: string;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Build a case-sensitive magic-keyword matcher for prose punctuation boundaries.
3
+ *
4
+ * Sentence punctuation and quotes may touch the keyword, but letters, digits,
5
+ * underscores, slashes, backslashes, hyphens, file-extension dots, symbol
6
+ * references (`foo::keyword`), and immediate call parentheses (`keyword()`)
7
+ * keep the occurrence embedded in code rather than prose.
8
+ */
9
+ export declare function magicKeywordRegex(keyword: string, flags?: string): RegExp;
@@ -3,7 +3,7 @@ import { type KeywordHighlighter } from "./gradient-highlight";
3
3
  export declare const ORCHESTRATE_NOTICE: string;
4
4
  /**
5
5
  * Whether `text` contains the standalone keyword "orchestrate" (lowercase,
6
- * whitespace-delimited) in prose — never inside a code block, inline code span,
6
+ * prose-delimited) in prose — never inside a code block, inline code span,
7
7
  * or XML/HTML section.
8
8
  */
9
9
  export declare function containsOrchestrate(text: string): boolean;
@@ -12,5 +12,7 @@ export declare class RpcHostToolBridge {
12
12
  handleUpdate(frame: RpcHostToolUpdate): boolean;
13
13
  requestExecution(definition: RpcHostToolDefinition, toolCallId: string, args: Record<string, unknown>, signal?: AbortSignal, onUpdate?: AgentToolUpdateCallback<unknown>): Promise<AgentToolResult<unknown>>;
14
14
  rejectAllPending(message: string): void;
15
+ /** Reject active and future host tool requests after the RPC client disconnects. */
16
+ close(message: string): void;
15
17
  }
16
18
  export {};
@@ -8,6 +8,13 @@ export type PendingExtensionRequest = {
8
8
  resolve: (response: RpcExtensionUIResponse) => void;
9
9
  reject: (error: Error) => void;
10
10
  };
11
+ /** Pending extension UI request map that can fail closed when the RPC client disconnects. */
12
+ export declare class RpcPendingExtensionRequests extends Map<string, PendingExtensionRequest> {
13
+ #private;
14
+ set(id: string, request: PendingExtensionRequest): this;
15
+ /** Reject every active and future extension UI request. */
16
+ rejectAll(message: string): void;
17
+ }
11
18
  type RpcOutput = (obj: RpcResponse | RpcExtensionUIRequest | RpcHostToolCallRequest | RpcHostToolCancelRequest | RpcHostUriRequest | RpcHostUriCancelRequest | object) => void;
12
19
  export type RpcSessionChangeCommand = Extract<RpcCommand, {
13
20
  type: "new_session";
@@ -38,7 +45,7 @@ export type RpcSkillCommandSession = Pick<AgentSession, "promptCustomMessage" |
38
45
  export type RpcSkillCommandResult = {
39
46
  agentInvoked: true;
40
47
  };
41
- export declare function tryRunRpcSkillCommand(session: RpcSkillCommandSession, text: string): Promise<RpcSkillCommandResult | false>;
48
+ export declare function tryRunRpcSkillCommand(session: RpcSkillCommandSession, text: string, streamingBehavior?: "steer" | "followUp"): Promise<RpcSkillCommandResult | false>;
42
49
  export declare function reportLocalOnlyPromptResult(input: {
43
50
  id: string | undefined;
44
51
  prompt: Promise<boolean>;
@@ -84,15 +91,16 @@ export interface RpcInputFrameDeps {
84
91
  onHostToolUpdate: (frame: RpcHostToolUpdate) => void;
85
92
  onHostUriResult: (frame: RpcHostUriResult) => void;
86
93
  }
94
+ /** Dispatch side-channel frames that must overtake the serialized command queue. */
95
+ export declare function dispatchRpcControlFrame(parsed: unknown, deps: RpcInputFrameDeps): boolean;
87
96
  /**
88
97
  * Dispatch a single parsed frame from the RPC input stream.
89
98
  *
90
- * Bash commands are dispatched in the background so the caller (the stdin loop
91
- * in {@link runRpcMode}) can keep reading subsequent frames while a shell
92
- * command is still running. This lets a client send `abort_bash` (or any other
93
- * command) while a long-running `bash` is in flight. Response correlation is
94
- * preserved via each command's `id`; ordering across concurrent commands is
95
- * not guaranteed and clients MUST match on `id`.
99
+ * Bash commands are dispatched in the background so the caller can keep reading
100
+ * subsequent frames while a shell command is still running. This lets a client
101
+ * send `abort_bash` while a long-running `bash` is in flight. Response
102
+ * correlation is preserved via each command's `id`; ordering across concurrent
103
+ * commands is not guaranteed and clients MUST match on `id`.
96
104
  *
97
105
  * @returns `undefined` when the frame was routed to a side-channel handler
98
106
  * (extension UI response, host tool/URI frames) or dispatched in the
@@ -101,6 +109,18 @@ export interface RpcInputFrameDeps {
101
109
  * on non-`bash` commands propagate; the caller is expected to wrap them.
102
110
  */
103
111
  export declare function dispatchRpcInputFrame(parsed: unknown, deps: RpcInputFrameDeps): Promise<void> | undefined;
112
+ /** Serializes ordinary RPC commands while allowing control frames to dispatch immediately. */
113
+ export declare class RpcInputDispatcher {
114
+ #private;
115
+ constructor(options: {
116
+ deps: RpcInputFrameDeps;
117
+ afterSerialCommand?: () => Promise<void>;
118
+ });
119
+ /** Accept a parsed input frame without blocking the stdin reader. */
120
+ dispatch(parsed: unknown): void;
121
+ /** Await every accepted serial command, including commands queued before EOF. */
122
+ drain(): Promise<void>;
123
+ }
104
124
  /**
105
125
  * Coordinates deferred shutdown with in-flight background input tasks.
106
126
  *
@@ -3,7 +3,7 @@ import { type KeywordHighlighter } from "./gradient-highlight";
3
3
  export declare const ULTRATHINK_NOTICE: string;
4
4
  /**
5
5
  * Whether `text` contains the standalone keyword "ultrathink" (lowercase,
6
- * whitespace-delimited) in prose — never inside a code block, inline code span,
6
+ * prose-delimited) in prose — never inside a code block, inline code span,
7
7
  * or XML/HTML section.
8
8
  */
9
9
  export declare function containsUltrathink(text: string): boolean;
@@ -38,6 +38,15 @@ export declare function buildFileMentionBlock(files: FileMentionMessage["files"]
38
38
  * canonicalization) — i.e. content that closes the current read-tool run.
39
39
  */
40
40
  export declare function assistantHasVisibleContent(message: AssistantAgentMessage): boolean;
41
+ /**
42
+ * Split mixed assistant turns into visible text before tool execution and
43
+ * visible text segments that must render immediately after the preceding tool.
44
+ */
45
+ export declare function splitAssistantMessageToolTimeline(message: AssistantAgentMessage): {
46
+ beforeTools: AssistantAgentMessage;
47
+ afterToolCalls: ReadonlyMap<string, AssistantAgentMessage>;
48
+ hasToolCalls: boolean;
49
+ };
41
50
  /**
42
51
  * Normalize raw tool-call arguments to a plain record, collapsing non-object or
43
52
  * array values to an empty object.
@@ -3,7 +3,7 @@ import { type KeywordHighlighter } from "./gradient-highlight";
3
3
  export declare const WORKFLOW_NOTICE: string;
4
4
  /**
5
5
  * Whether `text` contains the standalone keyword "workflowz"
6
- * (lowercase, whitespace-delimited) in prose — never inside a code block, inline
6
+ * (lowercase, prose-delimited) in prose — never inside a code block, inline
7
7
  * code span, or XML/HTML section.
8
8
  */
9
9
  export declare function containsWorkflow(text: string): boolean;
@@ -754,6 +754,11 @@ export declare class AgentSession {
754
754
  * from role configuration (e.g., "anthropic/claude-sonnet-4-5:xhigh").
755
755
  */
756
756
  resolveRoleModelWithThinking(role: string): ResolvedModelRoleValue;
757
+ /**
758
+ * Resolve the explicit thinking suffix that should apply when a temporary
759
+ * picker selects a model already assigned to a configured role.
760
+ */
761
+ resolveTemporaryModelThinkingLevel(model: Model): ConfiguredThinkingLevel | undefined;
757
762
  get promptTemplates(): ReadonlyArray<PromptTemplate>;
758
763
  /** Replace file-based slash commands used for prompt expansion. */
759
764
  setSlashCommands(slashCommands: FileSlashCommand[]): void;
@@ -811,6 +816,7 @@ export declare class AgentSession {
811
816
  triggerTurn?: boolean;
812
817
  deliverAs?: "steer" | "followUp" | "nextTurn";
813
818
  queueChipText?: string;
819
+ acceptTerminalEmptyStop?: boolean;
814
820
  }): Promise<boolean>;
815
821
  /**
816
822
  * Send a user message to the agent.
@@ -9,13 +9,13 @@
9
9
  * Precedence (highest first):
10
10
  * 1. `JEOPI_AUTH_BROKER_URL` / `JEOPI_AUTH_BROKER_TOKEN` env vars.
11
11
  * 2. `auth.broker.url` / `auth.broker.token` in `~/.jeopi/agent/config.yml`
12
- * (hidden from the settings UI; `!command` resolution supported).
12
+ * or `~/.jeopi/agent/config.yaml` (hidden from the settings UI; `!command` resolution supported).
13
13
  * 3. Token file `~/.jeopi/auth-broker.token` (paired with URL from env or config).
14
14
  *
15
15
  * Returns null when no broker URL is configured — caller falls back to the
16
16
  * local SQLite store.
17
17
  *
18
- * Reads config.yml directly (instead of going through `Settings.init`) because
18
+ * Reads config YAML directly (instead of going through `Settings.init`) because
19
19
  * `discoverAuthStorage` runs before the settings singleton is initialized in
20
20
  * `runRootCommand`, and we want hand-edited config entries to be honoured at
21
21
  * boot without forcing a startup reorder.
@@ -1,15 +1,16 @@
1
1
  import type { Skill } from "../extensibility/skills";
2
2
  import { type LocalProtocolOptions } from "../internal-urls";
3
- import type { InternalResource } from "../internal-urls/types";
3
+ import type { InternalResource, ResolveContext } from "../internal-urls/types";
4
4
  interface InternalUrlResolver {
5
5
  canHandle(input: string): boolean;
6
- resolve(input: string): Promise<InternalResource>;
6
+ resolve(input: string, context?: ResolveContext): Promise<InternalResource>;
7
7
  }
8
8
  export interface InternalUrlExpansionOptions {
9
9
  skills: readonly Skill[];
10
10
  noEscape?: boolean;
11
11
  internalRouter?: InternalUrlResolver;
12
12
  localOptions?: LocalProtocolOptions;
13
+ cwd?: string;
13
14
  ensureLocalParentDirs?: boolean;
14
15
  }
15
16
  /**
@@ -2,6 +2,7 @@ import { JsRuntime } from "../../../eval/js/shared/runtime";
2
2
  import type { ToolSession } from "../../index";
3
3
  import { type AriaSnapshotOptions } from "../aria/aria-snapshot";
4
4
  import { type ReadableFormat } from "../readable";
5
+ import { RunOutput } from "../run-output";
5
6
  import type { Observation, ReadyInfo, RunResultOk, ScreenshotResult, SessionSnapshot } from "../tab-protocol";
6
7
  import type { CmuxSocketClient } from "./socket-client";
7
8
  interface ScreenshotOptions {
@@ -17,7 +18,7 @@ interface ObserveOptions {
17
18
  }
18
19
  interface RunContext {
19
20
  session: SessionSnapshot;
20
- displays: RunResultOk["displays"];
21
+ output: RunOutput;
21
22
  screenshots: ScreenshotResult[];
22
23
  signal: AbortSignal;
23
24
  timeoutMs: number;
@@ -142,6 +143,7 @@ declare class CmuxElementHandle {
142
143
  click(): Promise<void>;
143
144
  type(text: string): Promise<void>;
144
145
  fill(value: string): Promise<void>;
146
+ press(key: string): Promise<void>;
145
147
  focus(): Promise<void>;
146
148
  hover(): Promise<void>;
147
149
  evaluate<TResult, TArgs extends unknown[]>(fn: (element: unknown, ...args: TArgs) => TResult | Promise<TResult>, ...args: TArgs): Promise<TResult>;
@@ -62,6 +62,26 @@ export interface CmuxGeometry {
62
62
  export declare const GEOMETRY_SCRIPT = "(() => ({ innerWidth: window.innerWidth, innerHeight: window.innerHeight, dpr: window.devicePixelRatio||1, scrollX: window.scrollX, scrollY: window.scrollY, scrollWidth: document.documentElement.scrollWidth, scrollHeight: document.documentElement.scrollHeight }))()";
63
63
  export declare function cmuxSnapshotToObservation(result: CmuxSnapshotResult, viewport: Observation["viewport"], geometry: CmuxGeometry): Observation;
64
64
  export declare function serializeEval(fn: string | ((...args: unknown[]) => unknown), args: unknown[]): string;
65
+ /**
66
+ * Like {@link serializeEval}, but wraps the expression in a page-side
67
+ * try/catch envelope so a throwing script surfaces its message + stack
68
+ * instead of the daemon's opaque `js_error: A JavaScript exception occurred`,
69
+ * and a Promise return (which the daemon cannot serialize) is flagged
70
+ * explicitly rather than failing as "unsupported type".
71
+ *
72
+ * String scripts run through indirect eval to keep global-scope semantics;
73
+ * function sources are already expressions and are invoked directly.
74
+ * `undefined` results come back as `null` (JSON cannot carry `undefined`).
75
+ * Decode with {@link unwrapEvalEnvelope}.
76
+ */
77
+ export declare function serializeEvalWithEnvelope(fn: string | ((...args: unknown[]) => unknown), args: unknown[]): string;
78
+ /**
79
+ * Decode a {@link serializeEvalWithEnvelope} result: rethrow page-side
80
+ * exceptions as rich {@link ToolError}s, reject unserializable Promise
81
+ * returns with an actionable message, and pass through values from daemons
82
+ * that did not run the wrapper.
83
+ */
84
+ export declare function unwrapEvalEnvelope<TResult>(value: unknown, label: string): TResult;
65
85
  export declare function mapWaitUntil(waitUntil: string | undefined): "interactive" | "complete";
66
86
  export interface ResolveCmuxKindOptions {
67
87
  surface?: string;