@oh-my-pi/pi-coding-agent 17.1.5 → 17.1.6
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 +31 -0
- package/dist/{CHANGELOG-qs3vd6xf.md → CHANGELOG-x9zt79k8.md} +31 -0
- package/dist/cli.js +2989 -2978
- package/dist/types/capability/index.d.ts +1 -1
- package/dist/types/capability/types.d.ts +23 -1
- package/dist/types/config/settings-schema.d.ts +23 -1
- package/dist/types/internal-urls/mcp-protocol.d.ts +3 -2
- package/dist/types/internal-urls/parse.d.ts +12 -0
- package/dist/types/internal-urls/router.d.ts +6 -0
- package/dist/types/internal-urls/types.d.ts +6 -0
- package/dist/types/lsp/config.d.ts +1 -0
- package/dist/types/lsp/types.d.ts +2 -0
- package/dist/types/mcp/manager.d.ts +5 -0
- package/dist/types/mcp/tool-bridge.d.ts +13 -0
- package/dist/types/modes/controllers/extension-ui-controller.d.ts +1 -1
- package/dist/types/modes/rpc/rpc-mode.d.ts +2 -0
- package/dist/types/sdk.d.ts +3 -1
- package/dist/types/session/agent-session-types.d.ts +3 -1
- package/dist/types/session/agent-session.d.ts +2 -0
- package/dist/types/session/model-controls.d.ts +3 -0
- package/dist/types/session/session-advisors.d.ts +7 -1
- package/dist/types/session/tool-choice-queue.d.ts +6 -4
- package/dist/types/session/turn-recovery.d.ts +4 -2
- package/dist/types/task/index.d.ts +1 -1
- package/dist/types/task/types.d.ts +3 -11
- package/dist/types/thinking.d.ts +21 -2
- package/dist/types/utils/title-generator.d.ts +17 -16
- package/package.json +12 -12
- package/src/capability/index.ts +43 -12
- package/src/capability/mcp.ts +21 -0
- package/src/capability/types.ts +20 -1
- package/src/cli/read-cli.ts +44 -2
- package/src/config/settings-schema.ts +27 -1
- package/src/eval/py/runner.py +16 -2
- package/src/extensibility/extensions/runner.ts +91 -5
- package/src/extensibility/extensions/types.ts +0 -1
- package/src/extensibility/hooks/types.ts +0 -1
- package/src/internal-urls/mcp-protocol.ts +17 -3
- package/src/internal-urls/parse.ts +31 -0
- package/src/internal-urls/router.ts +24 -4
- package/src/internal-urls/types.ts +6 -0
- package/src/live/transport.ts +2 -2
- package/src/lsp/client.ts +2 -2
- package/src/lsp/config.ts +4 -0
- package/src/lsp/types.ts +2 -0
- package/src/mcp/config.ts +26 -14
- package/src/mcp/manager.ts +26 -9
- package/src/mcp/tool-bridge.ts +52 -1
- package/src/memories/index.ts +25 -6
- package/src/modes/components/status-line/segments.ts +3 -1
- package/src/modes/controllers/command-controller.ts +10 -10
- package/src/modes/controllers/extension-ui-controller.ts +3 -3
- package/src/modes/rpc/rpc-mode.ts +60 -47
- package/src/prompts/steering/user-interjection.md +2 -5
- package/src/prompts/tools/task.md +4 -2
- package/src/sdk.ts +17 -8
- package/src/session/agent-session-types.ts +3 -0
- package/src/session/agent-session.ts +21 -4
- package/src/session/model-controls.ts +43 -7
- package/src/session/session-advisors.ts +30 -14
- package/src/session/session-tools.ts +4 -2
- package/src/session/tool-choice-queue.ts +19 -4
- package/src/session/turn-recovery.ts +21 -2
- package/src/task/executor.ts +11 -3
- package/src/task/index.ts +43 -32
- package/src/task/types.ts +12 -17
- package/src/thinking.ts +68 -5
- package/src/tools/read.ts +2 -2
- package/src/utils/title-generator.ts +88 -34
- package/dist/types/advisor/__tests__/advisor.test.d.ts +0 -1
- package/dist/types/advisor/__tests__/config.test.d.ts +0 -1
- package/dist/types/advisor/__tests__/emission-guard.test.d.ts +0 -1
- package/dist/types/cli/__tests__/auth-gateway-catalog.test.d.ts +0 -1
- package/dist/types/cli/update-cli.test.d.ts +0 -1
- package/dist/types/config/__tests__/model-registry.test.d.ts +0 -1
- package/dist/types/eval/__tests__/agent-bridge.test.d.ts +0 -1
- package/dist/types/eval/__tests__/bridge-timeout.test.d.ts +0 -1
- package/dist/types/eval/__tests__/budget-bridge.test.d.ts +0 -1
- package/dist/types/eval/__tests__/completion-bridge.test.d.ts +0 -1
- package/dist/types/eval/__tests__/helpers-local-roots.test.d.ts +0 -1
- package/dist/types/eval/__tests__/idle-timeout.test.d.ts +0 -1
- package/dist/types/eval/__tests__/js-context-manager.test.d.ts +0 -1
- package/dist/types/eval/__tests__/julia-prelude.test.d.ts +0 -1
- package/dist/types/eval/__tests__/kernel-spawn.test.d.ts +0 -1
- package/dist/types/eval/__tests__/prelude-agent.test.d.ts +0 -1
- package/dist/types/eval/__tests__/process-entry-import.test.d.ts +0 -1
- package/dist/types/eval/py/__tests__/prelude.test.d.ts +0 -1
- package/dist/types/eval/py/__tests__/runner-shell-output.test.d.ts +0 -1
- package/dist/types/hindsight/client.test.d.ts +0 -1
- package/dist/types/internal-urls/__tests__/agent-protocol-nested.test.d.ts +0 -1
- package/dist/types/internal-urls/__tests__/ssh-protocol.test.d.ts +0 -1
- package/dist/types/launch/broker-list-order.test.d.ts +0 -1
- package/dist/types/launch/broker-output-snapshot.test.d.ts +0 -1
- package/dist/types/launch/protocol.test.d.ts +0 -1
- package/dist/types/launch/spawn-options.test.d.ts +0 -1
- package/dist/types/launch/terminal-output.test.d.ts +0 -1
- package/dist/types/live/protocol.test.d.ts +0 -1
- package/dist/types/mcp/config-writer.test.d.ts +0 -1
- package/dist/types/mcp/smithery-auth.test.d.ts +0 -1
- package/dist/types/mcp/smithery-registry.test.d.ts +0 -1
- package/dist/types/mcp/transports/stdio.test.d.ts +0 -1
- package/dist/types/modes/components/__tests__/dynamic-border.test.d.ts +0 -1
- package/dist/types/modes/components/__tests__/move-overlay.test.d.ts +0 -1
- package/dist/types/modes/components/__tests__/pause-screen.test.d.ts +0 -1
- package/dist/types/modes/components/__tests__/skill-message.test.d.ts +0 -1
- package/dist/types/modes/components/custom-editor-plugin-ctor.test.d.ts +0 -1
- package/dist/types/modes/components/custom-editor.test.d.ts +0 -1
- package/dist/types/modes/components/login-dialog.test.d.ts +0 -1
- package/dist/types/modes/components/status-line/component.jj-cache.test.d.ts +0 -1
- package/dist/types/modes/components/status-line/component.test.d.ts +0 -1
- package/dist/types/modes/components/tool-execution.test.d.ts +0 -1
- package/dist/types/modes/controllers/extension-ui-controller.test.d.ts +0 -1
- package/dist/types/modes/noninteractive-dispose.test.d.ts +0 -1
- package/dist/types/modes/print-mode.test.d.ts +0 -1
- package/dist/types/modes/session-teardown.test.d.ts +0 -1
- package/dist/types/modes/theme/mermaid-rendering.test.d.ts +0 -1
- package/dist/types/modes/utils/transcript-render-helpers.test.d.ts +0 -1
- package/dist/types/modes/warp-events.test.d.ts +0 -1
- package/dist/types/plan-mode/approved-plan-prompt.test.d.ts +0 -1
- package/dist/types/plan-mode/model-transition.test.d.ts +0 -1
- package/dist/types/plan-mode/reentry-prompt.test.d.ts +0 -1
- package/dist/types/session/agent-session-error-log.test.d.ts +0 -1
- package/dist/types/session/blob-store.test.d.ts +0 -1
- package/dist/types/session/messages.test.d.ts +0 -1
- package/dist/types/session/session-context.test.d.ts +0 -1
- package/dist/types/ssh/__tests__/connection-manager-args.test.d.ts +0 -1
- package/dist/types/ssh/__tests__/connection-manager-timeout.test.d.ts +0 -1
- package/dist/types/ssh/__tests__/file-transfer-posix-guard.test.d.ts +0 -1
- package/dist/types/ssh/__tests__/sshfs-mount.test.d.ts +0 -1
- package/dist/types/system-prompt.test.d.ts +0 -1
- package/dist/types/task/render.test.d.ts +0 -1
- package/dist/types/task/spawn-policy.test.d.ts +0 -1
- package/dist/types/tools/__tests__/eval-description.test.d.ts +0 -1
- package/dist/types/tools/__tests__/glob.test.d.ts +0 -1
- package/dist/types/tools/__tests__/json-tree.test.d.ts +0 -1
- package/dist/types/tools/__tests__/vibe-render.test.d.ts +0 -1
- package/dist/types/tools/hub/launch-compat.test.d.ts +0 -1
- package/dist/types/vibe/__tests__/token-rate.test.d.ts +0 -1
- package/src/advisor/__tests__/advisor.test.ts +0 -4889
- package/src/advisor/__tests__/config.test.ts +0 -349
- package/src/advisor/__tests__/emission-guard.test.ts +0 -147
- package/src/cli/__tests__/auth-gateway-catalog.test.ts +0 -111
- package/src/cli/update-cli.test.ts +0 -28
- package/src/config/__tests__/model-registry.test.ts +0 -182
- package/src/eval/__tests__/agent-bridge.test.ts +0 -1509
- package/src/eval/__tests__/bridge-timeout.test.ts +0 -170
- package/src/eval/__tests__/budget-bridge.test.ts +0 -80
- package/src/eval/__tests__/completion-bridge.test.ts +0 -412
- package/src/eval/__tests__/helpers-local-roots.test.ts +0 -55
- package/src/eval/__tests__/idle-timeout.test.ts +0 -80
- package/src/eval/__tests__/js-context-manager.test.ts +0 -456
- package/src/eval/__tests__/julia-prelude.test.ts +0 -66
- package/src/eval/__tests__/kernel-spawn.test.ts +0 -115
- package/src/eval/__tests__/prelude-agent.test.ts +0 -156
- package/src/eval/__tests__/process-entry-import.test.ts +0 -137
- package/src/eval/py/__tests__/prelude.test.ts +0 -104
- package/src/eval/py/__tests__/runner-shell-output.test.ts +0 -157
- package/src/hindsight/client.test.ts +0 -75
- package/src/internal-urls/__tests__/agent-protocol-nested.test.ts +0 -141
- package/src/internal-urls/__tests__/ssh-protocol.test.ts +0 -331
- package/src/launch/broker-list-order.test.ts +0 -89
- package/src/launch/broker-output-snapshot.test.ts +0 -126
- package/src/launch/protocol.test.ts +0 -59
- package/src/launch/spawn-options.test.ts +0 -31
- package/src/launch/terminal-output.test.ts +0 -107
- package/src/live/protocol.test.ts +0 -140
- package/src/mcp/config-writer.test.ts +0 -43
- package/src/mcp/smithery-auth.test.ts +0 -29
- package/src/mcp/smithery-registry.test.ts +0 -51
- package/src/mcp/transports/stdio.test.ts +0 -427
- package/src/modes/components/__tests__/dynamic-border.test.ts +0 -55
- package/src/modes/components/__tests__/move-overlay.test.ts +0 -252
- package/src/modes/components/__tests__/pause-screen.test.ts +0 -143
- package/src/modes/components/__tests__/skill-message.test.ts +0 -94
- package/src/modes/components/custom-editor-plugin-ctor.test.ts +0 -36
- package/src/modes/components/custom-editor.test.ts +0 -510
- package/src/modes/components/login-dialog.test.ts +0 -56
- package/src/modes/components/status-line/component.jj-cache.test.ts +0 -229
- package/src/modes/components/status-line/component.test.ts +0 -84
- package/src/modes/components/tool-execution.test.ts +0 -162
- package/src/modes/controllers/extension-ui-controller.test.ts +0 -250
- package/src/modes/noninteractive-dispose.test.ts +0 -73
- package/src/modes/print-mode.test.ts +0 -71
- package/src/modes/session-teardown.test.ts +0 -219
- package/src/modes/theme/mermaid-rendering.test.ts +0 -53
- package/src/modes/utils/transcript-render-helpers.test.ts +0 -38
- package/src/modes/warp-events.test.ts +0 -794
- package/src/plan-mode/approved-plan-prompt.test.ts +0 -36
- package/src/plan-mode/model-transition.test.ts +0 -60
- package/src/plan-mode/reentry-prompt.test.ts +0 -41
- package/src/session/agent-session-error-log.test.ts +0 -59
- package/src/session/blob-store.test.ts +0 -56
- package/src/session/messages.test.ts +0 -282
- package/src/session/session-context.test.ts +0 -384
- package/src/ssh/__tests__/connection-manager-args.test.ts +0 -191
- package/src/ssh/__tests__/connection-manager-timeout.test.ts +0 -61
- package/src/ssh/__tests__/file-transfer-posix-guard.test.ts +0 -105
- package/src/ssh/__tests__/sshfs-mount.test.ts +0 -13
- package/src/system-prompt.test.ts +0 -236
- package/src/task/render.test.ts +0 -290
- package/src/task/spawn-policy.test.ts +0 -62
- package/src/tools/__tests__/eval-description.test.ts +0 -18
- package/src/tools/__tests__/glob.test.ts +0 -37
- package/src/tools/__tests__/json-tree.test.ts +0 -35
- package/src/tools/__tests__/vibe-render.test.ts +0 -210
- package/src/tools/hub/launch-compat.test.ts +0 -40
- package/src/vibe/__tests__/token-rate.test.ts +0 -96
package/src/task/index.ts
CHANGED
|
@@ -156,27 +156,31 @@ export function formatResultOutputFallback(result: Pick<SingleResult, "output" |
|
|
|
156
156
|
return result.requests > 0 ? `(no output) after ${result.requests} req` : "(no output)";
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
159
|
+
interface TaskDescriptionOptions {
|
|
160
|
+
agents: AgentDefinition[];
|
|
161
|
+
isolationEnabled: boolean;
|
|
162
|
+
applyIsolatedChanges: boolean;
|
|
163
|
+
disabledAgents: string[];
|
|
164
|
+
batchEnabled: boolean;
|
|
165
|
+
effortEnabled: boolean;
|
|
166
|
+
asyncEnabled: boolean;
|
|
167
|
+
ircEnabled: boolean;
|
|
168
|
+
parentSpawns: string;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/** Render the tool description from a cached agent list and current settings. */
|
|
172
|
+
function renderDescription(options: TaskDescriptionOptions): string {
|
|
173
|
+
const spawnPolicy = resolveSpawnPolicy(options.parentSpawns);
|
|
173
174
|
const spawningDisabled = !spawnPolicy.enabled;
|
|
174
|
-
let filteredAgents =
|
|
175
|
+
let filteredAgents =
|
|
176
|
+
options.disabledAgents.length > 0
|
|
177
|
+
? options.agents.filter(agent => !options.disabledAgents.includes(agent.name))
|
|
178
|
+
: options.agents;
|
|
175
179
|
if (spawningDisabled) {
|
|
176
180
|
filteredAgents = [];
|
|
177
181
|
} else if (spawnPolicy.allowedAgents !== null) {
|
|
178
182
|
const allowed = new Set(spawnPolicy.allowedAgents);
|
|
179
|
-
filteredAgents = filteredAgents.filter(
|
|
183
|
+
filteredAgents = filteredAgents.filter(agent => allowed.has(agent.name));
|
|
180
184
|
}
|
|
181
185
|
const renderedAgents = filteredAgents.map(agent => ({
|
|
182
186
|
name: agent.name,
|
|
@@ -188,12 +192,13 @@ function renderDescription(
|
|
|
188
192
|
agents: renderedAgents,
|
|
189
193
|
spawningDisabled,
|
|
190
194
|
defaultAgent: spawnPolicy.defaultAgent,
|
|
191
|
-
isolationEnabled,
|
|
192
|
-
applyIsolatedChanges,
|
|
193
|
-
batchEnabled,
|
|
194
|
-
|
|
195
|
+
isolationEnabled: options.isolationEnabled,
|
|
196
|
+
applyIsolatedChanges: options.applyIsolatedChanges,
|
|
197
|
+
batchEnabled: options.batchEnabled,
|
|
198
|
+
effortEnabled: options.effortEnabled,
|
|
199
|
+
asyncEnabled: options.asyncEnabled,
|
|
195
200
|
hasBlockingAgents: renderedAgents.some(agent => agent.blocking),
|
|
196
|
-
ircEnabled,
|
|
201
|
+
ircEnabled: options.ircEnabled,
|
|
197
202
|
});
|
|
198
203
|
}
|
|
199
204
|
|
|
@@ -581,28 +586,34 @@ export class TaskTool implements AgentTool<TaskToolSchemaInstance, TaskToolDetai
|
|
|
581
586
|
const planMode = this.session.getPlanModeState?.()?.enabled === true;
|
|
582
587
|
const isolationEnabled = !planMode && this.session.settings.get("task.isolation.mode") !== "none";
|
|
583
588
|
const defaultAgent = resolveSpawnPolicy(this.session.getSessionSpawns()).defaultAgent;
|
|
584
|
-
return getTaskSchema({
|
|
589
|
+
return getTaskSchema({
|
|
590
|
+
isolationEnabled,
|
|
591
|
+
batchEnabled: this.#isBatchEnabled(),
|
|
592
|
+
effortEnabled: this.session.settings.get("task.enableEffort"),
|
|
593
|
+
defaultAgent,
|
|
594
|
+
});
|
|
585
595
|
}
|
|
586
596
|
|
|
587
597
|
renderCall(args: unknown, options: Parameters<typeof renderTaskCall>[1], theme: Theme) {
|
|
588
598
|
return renderTaskCall(repairTaskParams(args as TaskParams), options, theme);
|
|
589
599
|
}
|
|
590
600
|
|
|
591
|
-
/** Dynamic description that reflects current
|
|
601
|
+
/** Dynamic description that reflects current task settings. */
|
|
592
602
|
get description(): string {
|
|
593
603
|
const disabledAgents = this.session.settings.get("task.disabledAgents") as string[];
|
|
594
604
|
const planMode = this.session.getPlanModeState?.()?.enabled === true;
|
|
595
605
|
const isolationMode = this.session.settings.get("task.isolation.mode");
|
|
596
|
-
return renderDescription(
|
|
597
|
-
this.#discoveredAgents,
|
|
598
|
-
!planMode && isolationMode !== "none",
|
|
599
|
-
this.session.settings.get("task.isolation.apply"),
|
|
606
|
+
return renderDescription({
|
|
607
|
+
agents: this.#discoveredAgents,
|
|
608
|
+
isolationEnabled: !planMode && isolationMode !== "none",
|
|
609
|
+
applyIsolatedChanges: this.session.settings.get("task.isolation.apply"),
|
|
600
610
|
disabledAgents,
|
|
601
|
-
this.#isBatchEnabled(),
|
|
602
|
-
this.session.settings.get("
|
|
603
|
-
|
|
604
|
-
this.session.
|
|
605
|
-
|
|
611
|
+
batchEnabled: this.#isBatchEnabled(),
|
|
612
|
+
effortEnabled: this.session.settings.get("task.enableEffort"),
|
|
613
|
+
asyncEnabled: this.session.settings.get("async.enabled"),
|
|
614
|
+
ircEnabled: isIrcEnabled(this.session.settings, this.session.taskDepth ?? 0),
|
|
615
|
+
parentSpawns: this.session.getSessionSpawns() ?? "*",
|
|
616
|
+
});
|
|
606
617
|
}
|
|
607
618
|
private constructor(
|
|
608
619
|
private readonly session: ToolSession,
|
package/src/task/types.ts
CHANGED
|
@@ -115,7 +115,6 @@ export const taskItemSchema = type({
|
|
|
115
115
|
"name?": "string",
|
|
116
116
|
agent: "string = 'task'",
|
|
117
117
|
task: "string",
|
|
118
|
-
"effort?": effortRule,
|
|
119
118
|
"outputSchema?": outputSchemaInputSchema,
|
|
120
119
|
"schemaMode?": '"permissive" | "strict"',
|
|
121
120
|
"+": "delete",
|
|
@@ -124,7 +123,6 @@ const taskItemSchemaIsolated = type({
|
|
|
124
123
|
"name?": "string",
|
|
125
124
|
agent: "string = 'task'",
|
|
126
125
|
task: "string",
|
|
127
|
-
"effort?": effortRule,
|
|
128
126
|
"outputSchema?": outputSchemaInputSchema,
|
|
129
127
|
"schemaMode?": '"permissive" | "strict"',
|
|
130
128
|
"isolated?": "boolean",
|
|
@@ -153,7 +151,6 @@ export const taskSchema = type({
|
|
|
153
151
|
"name?": "string",
|
|
154
152
|
agent: "string = 'task'",
|
|
155
153
|
task: "string",
|
|
156
|
-
"effort?": effortRule,
|
|
157
154
|
"outputSchema?": outputSchemaInputSchema,
|
|
158
155
|
"schemaMode?": '"permissive" | "strict"',
|
|
159
156
|
"isolated?": "boolean",
|
|
@@ -163,7 +160,6 @@ const taskSchemaNoIsolation = type({
|
|
|
163
160
|
"name?": "string",
|
|
164
161
|
agent: "string = 'task'",
|
|
165
162
|
task: "string",
|
|
166
|
-
"effort?": effortRule,
|
|
167
163
|
"outputSchema?": outputSchemaInputSchema,
|
|
168
164
|
"schemaMode?": '"permissive" | "strict"',
|
|
169
165
|
"+": "delete",
|
|
@@ -200,15 +196,17 @@ function createTaskSchema(options: {
|
|
|
200
196
|
isolationEnabled: boolean;
|
|
201
197
|
batchEnabled: boolean;
|
|
202
198
|
defaultAgent: string;
|
|
199
|
+
effortEnabled: boolean;
|
|
203
200
|
}): BaseType {
|
|
204
201
|
const agent = taskAgentSchemaRule(options.defaultAgent);
|
|
202
|
+
const effortField = options.effortEnabled ? { "effort?": effortRule } : {};
|
|
205
203
|
if (options.batchEnabled) {
|
|
206
204
|
if (options.isolationEnabled) {
|
|
207
205
|
const item = type.raw({
|
|
208
206
|
"name?": "string",
|
|
209
207
|
agent,
|
|
210
208
|
task: "string",
|
|
211
|
-
|
|
209
|
+
...effortField,
|
|
212
210
|
"outputSchema?": outputSchemaInputSchema,
|
|
213
211
|
"schemaMode?": '"permissive" | "strict"',
|
|
214
212
|
"isolated?": "boolean",
|
|
@@ -224,7 +222,7 @@ function createTaskSchema(options: {
|
|
|
224
222
|
"name?": "string",
|
|
225
223
|
agent,
|
|
226
224
|
task: "string",
|
|
227
|
-
|
|
225
|
+
...effortField,
|
|
228
226
|
"outputSchema?": outputSchemaInputSchema,
|
|
229
227
|
"schemaMode?": '"permissive" | "strict"',
|
|
230
228
|
"+": "delete",
|
|
@@ -240,7 +238,7 @@ function createTaskSchema(options: {
|
|
|
240
238
|
"name?": "string",
|
|
241
239
|
agent,
|
|
242
240
|
task: "string",
|
|
243
|
-
|
|
241
|
+
...effortField,
|
|
244
242
|
"outputSchema?": outputSchemaInputSchema,
|
|
245
243
|
"schemaMode?": '"permissive" | "strict"',
|
|
246
244
|
"isolated?": "boolean",
|
|
@@ -251,33 +249,30 @@ function createTaskSchema(options: {
|
|
|
251
249
|
"name?": "string",
|
|
252
250
|
agent,
|
|
253
251
|
task: "string",
|
|
254
|
-
|
|
252
|
+
...effortField,
|
|
255
253
|
"outputSchema?": outputSchemaInputSchema,
|
|
256
254
|
"schemaMode?": '"permissive" | "strict"',
|
|
257
255
|
"+": "delete",
|
|
258
256
|
});
|
|
259
257
|
}
|
|
260
258
|
|
|
261
|
-
|
|
262
|
-
export function getTaskSchema(options: {
|
|
263
|
-
isolationEnabled: boolean;
|
|
264
|
-
batchEnabled: boolean;
|
|
265
|
-
defaultAgent: string;
|
|
266
|
-
}): TaskToolSchemaInstance;
|
|
259
|
+
/** Build the task wire schema for the current settings and spawn policy. */
|
|
267
260
|
export function getTaskSchema(options: {
|
|
268
261
|
isolationEnabled: boolean;
|
|
269
262
|
batchEnabled: boolean;
|
|
263
|
+
effortEnabled?: boolean;
|
|
270
264
|
defaultAgent?: string;
|
|
271
265
|
}): TaskToolSchemaInstance {
|
|
272
266
|
const defaultAgent = options.defaultAgent ?? "task";
|
|
273
|
-
|
|
267
|
+
const effortEnabled = options.effortEnabled ?? false;
|
|
268
|
+
if (defaultAgent === "task" && !effortEnabled) {
|
|
274
269
|
if (options.batchEnabled) return options.isolationEnabled ? taskSchemaBatch : taskSchemaBatchNoIsolation;
|
|
275
270
|
return options.isolationEnabled ? taskSchema : taskSchemaNoIsolation;
|
|
276
271
|
}
|
|
277
|
-
const key = `${options.isolationEnabled ? "iso" : "flat"}:${options.batchEnabled ? "batch" : "single"}:${defaultAgent}`;
|
|
272
|
+
const key = `${options.isolationEnabled ? "iso" : "flat"}:${options.batchEnabled ? "batch" : "single"}:${effortEnabled ? "effort" : "default"}:${defaultAgent}`;
|
|
278
273
|
const cached = taskSchemaCache.get(key);
|
|
279
274
|
if (cached) return cached;
|
|
280
|
-
const schema = createTaskSchema({ ...options, defaultAgent });
|
|
275
|
+
const schema = createTaskSchema({ ...options, effortEnabled, defaultAgent });
|
|
281
276
|
taskSchemaCache.set(key, schema);
|
|
282
277
|
return schema;
|
|
283
278
|
}
|
package/src/thinking.ts
CHANGED
|
@@ -271,19 +271,82 @@ export type TaskEffort = (typeof TASK_EFFORTS)[number];
|
|
|
271
271
|
* at — high, xhigh, or max), `med` = the middle (lower of the two middles for
|
|
272
272
|
* an even-sized range). Without a model, maps over the full canonical range.
|
|
273
273
|
* Returns `undefined` when the model has no controllable effort surface, so
|
|
274
|
-
* callers fall back to their default selector (e.g. `auto`).
|
|
274
|
+
* callers fall back to their default selector (e.g. `auto`). Throws when the
|
|
275
|
+
* configured ceiling is below the model's lowest supported effort.
|
|
275
276
|
*/
|
|
276
|
-
export function resolveTaskEffortLevel(
|
|
277
|
+
export function resolveTaskEffortLevel(
|
|
278
|
+
model: Model | undefined,
|
|
279
|
+
effort: TaskEffort,
|
|
280
|
+
maxEffort?: Effort,
|
|
281
|
+
): Effort | undefined {
|
|
277
282
|
const supported = model ? getSupportedEfforts(model) : THINKING_EFFORTS;
|
|
278
283
|
if (supported.length === 0) return undefined;
|
|
284
|
+
let resolved: Effort;
|
|
279
285
|
switch (effort) {
|
|
280
286
|
case "lo":
|
|
281
|
-
|
|
287
|
+
resolved = supported[0];
|
|
288
|
+
break;
|
|
282
289
|
case "med":
|
|
283
|
-
|
|
290
|
+
resolved = supported[(supported.length - 1) >> 1];
|
|
291
|
+
break;
|
|
284
292
|
case "hi":
|
|
285
|
-
|
|
293
|
+
resolved = supported[supported.length - 1];
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
296
|
+
if (maxEffort === undefined) return resolved;
|
|
297
|
+
const maxIndex = THINKING_EFFORTS.indexOf(maxEffort);
|
|
298
|
+
const ceiling = supported.findLast(candidate => THINKING_EFFORTS.indexOf(candidate) <= maxIndex);
|
|
299
|
+
if (ceiling === undefined) {
|
|
300
|
+
const modelName = model ? `${model.provider}/${model.id}` : "Selected model";
|
|
301
|
+
throw new RangeError(`${modelName} has no supported thinking effort at or below task.maxEffort=${maxEffort}`);
|
|
286
302
|
}
|
|
303
|
+
return THINKING_EFFORTS.indexOf(resolved) > THINKING_EFFORTS.indexOf(ceiling) ? ceiling : resolved;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Clamps a concrete thinking selector to a per-session effort ceiling (e.g. a
|
|
308
|
+
* task spawn's `task.maxEffort`-capped effort hint). `off`/`inherit`/
|
|
309
|
+
* `undefined` pass through, as do levels already at or below the ceiling.
|
|
310
|
+
* Levels above it snap to the highest model-supported effort at or below the
|
|
311
|
+
* ceiling. A model whose floor exceeds the ceiling has nothing valid to snap
|
|
312
|
+
* to; the requested level is returned unchanged and the caller is responsible
|
|
313
|
+
* for rejecting or skipping such models (see {@link modelSupportsEffortCeiling}).
|
|
314
|
+
*/
|
|
315
|
+
export function clampThinkingLevelToCeiling(
|
|
316
|
+
model: Model | undefined,
|
|
317
|
+
level: Effort | undefined,
|
|
318
|
+
ceiling: Effort | undefined,
|
|
319
|
+
): Effort | undefined;
|
|
320
|
+
export function clampThinkingLevelToCeiling(
|
|
321
|
+
model: Model | undefined,
|
|
322
|
+
level: ThinkingLevel | undefined,
|
|
323
|
+
ceiling: Effort | undefined,
|
|
324
|
+
): ThinkingLevel | undefined;
|
|
325
|
+
export function clampThinkingLevelToCeiling(
|
|
326
|
+
model: Model | undefined,
|
|
327
|
+
level: ThinkingLevel | undefined,
|
|
328
|
+
ceiling: Effort | undefined,
|
|
329
|
+
): ThinkingLevel | undefined {
|
|
330
|
+
if (ceiling === undefined || level === undefined || level === ThinkingLevel.Off || level === ThinkingLevel.Inherit) {
|
|
331
|
+
return level;
|
|
332
|
+
}
|
|
333
|
+
const maxIndex = THINKING_EFFORTS.indexOf(ceiling);
|
|
334
|
+
if (THINKING_EFFORTS.indexOf(level) <= maxIndex) return level;
|
|
335
|
+
const supported = model ? getSupportedEfforts(model) : THINKING_EFFORTS;
|
|
336
|
+
return supported.findLast(candidate => THINKING_EFFORTS.indexOf(candidate) <= maxIndex) ?? level;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* True when `model` can honor a thinking-effort ceiling: it either has no
|
|
341
|
+
* controllable effort surface (nothing to cap) or supports at least one effort
|
|
342
|
+
* at or below the ceiling. Retry-fallback candidate filtering uses this to
|
|
343
|
+
* skip models whose floor would force the session above the ceiling.
|
|
344
|
+
*/
|
|
345
|
+
export function modelSupportsEffortCeiling(model: Model, ceiling: Effort): boolean {
|
|
346
|
+
const supported = getSupportedEfforts(model);
|
|
347
|
+
if (supported.length === 0) return true;
|
|
348
|
+
const maxIndex = THINKING_EFFORTS.indexOf(ceiling);
|
|
349
|
+
return supported.some(candidate => THINKING_EFFORTS.indexOf(candidate) <= maxIndex);
|
|
287
350
|
}
|
|
288
351
|
|
|
289
352
|
/**
|
package/src/tools/read.ts
CHANGED
|
@@ -2250,12 +2250,12 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
2250
2250
|
return executeReadUrl(this.session, { path: parsedUrlTarget.path, raw: urlRaw }, signal);
|
|
2251
2251
|
}
|
|
2252
2252
|
|
|
2253
|
-
// Handle
|
|
2253
|
+
// Handle native OMP URLs and custom-scheme resources advertised by MCP servers.
|
|
2254
2254
|
// Use the internal-URL-aware splitter so malformed selectors are peeled
|
|
2255
2255
|
// off the URL and surfaced via parseSel rather than confusing handlers.
|
|
2256
2256
|
const internalRouter = InternalUrlRouter.instance();
|
|
2257
2257
|
let promotedSelector: string | undefined;
|
|
2258
|
-
if (internalRouter.
|
|
2258
|
+
if (internalRouter.canResolve(readPath)) {
|
|
2259
2259
|
const internalTarget = splitInternalUrlSel(readPath);
|
|
2260
2260
|
const parsed = parseSel(internalTarget.sel);
|
|
2261
2261
|
if (internalTarget.sel !== undefined && parsed.kind === "none") {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Generate session titles using a smol, fast model.
|
|
3
3
|
*/
|
|
4
|
+
import { dlopen, FFIType, ptr } from "bun:ffi";
|
|
4
5
|
import * as path from "node:path";
|
|
5
6
|
|
|
6
7
|
import { type Api, type AssistantMessage, completeSimple, type Model } from "@oh-my-pi/pi-ai";
|
|
@@ -23,6 +24,59 @@ const TITLE_MARKER_INSTRUCTION = prompt.render(titleMarkerInstruction);
|
|
|
23
24
|
const DEFAULT_TERMINAL_TITLE = "π";
|
|
24
25
|
const TERMINAL_TITLE_CONTROL_CHARS = /[\u0000-\u001f\u007f-\u009f]/g;
|
|
25
26
|
|
|
27
|
+
interface WindowsConsoleTitleApi {
|
|
28
|
+
set(title: string): boolean;
|
|
29
|
+
close(): void;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
let windowsConsoleTitleApi: WindowsConsoleTitleApi | null | undefined;
|
|
33
|
+
let lastTerminalTitle: string | undefined;
|
|
34
|
+
|
|
35
|
+
function getWindowsConsoleTitleApi(): WindowsConsoleTitleApi | null {
|
|
36
|
+
if (process.platform !== "win32") return null;
|
|
37
|
+
if (windowsConsoleTitleApi !== undefined) return windowsConsoleTitleApi;
|
|
38
|
+
try {
|
|
39
|
+
const kernel32 = dlopen("kernel32.dll", {
|
|
40
|
+
SetConsoleTitleW: { args: [FFIType.ptr], returns: FFIType.bool },
|
|
41
|
+
});
|
|
42
|
+
windowsConsoleTitleApi = {
|
|
43
|
+
set(title) {
|
|
44
|
+
const wideTitle = Buffer.from(`${title}\0`, "utf16le");
|
|
45
|
+
return kernel32.symbols.SetConsoleTitleW(ptr(wideTitle));
|
|
46
|
+
},
|
|
47
|
+
close: () => kernel32.close(),
|
|
48
|
+
};
|
|
49
|
+
} catch {
|
|
50
|
+
windowsConsoleTitleApi = null;
|
|
51
|
+
}
|
|
52
|
+
return windowsConsoleTitleApi;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function setWindowsConsoleTitle(title: string): boolean {
|
|
56
|
+
const api = getWindowsConsoleTitleApi();
|
|
57
|
+
if (!api) return false;
|
|
58
|
+
try {
|
|
59
|
+
return api.set(title);
|
|
60
|
+
} catch {
|
|
61
|
+
try {
|
|
62
|
+
api.close();
|
|
63
|
+
} catch {
|
|
64
|
+
// Ignore cleanup failures after the native title path has already failed.
|
|
65
|
+
}
|
|
66
|
+
windowsConsoleTitleApi = null;
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function disposeWindowsConsoleTitleApi(): void {
|
|
72
|
+
try {
|
|
73
|
+
windowsConsoleTitleApi?.close();
|
|
74
|
+
} catch {
|
|
75
|
+
// Terminal teardown must remain best-effort.
|
|
76
|
+
}
|
|
77
|
+
windowsConsoleTitleApi = undefined;
|
|
78
|
+
}
|
|
79
|
+
|
|
26
80
|
// Cover the "backend ignores `disableReasoning`" case unconditionally: the
|
|
27
81
|
// static `model.reasoning` catalog flag can't distinguish a thinking model that
|
|
28
82
|
// was declared with `reasoning: false` (e.g. Qwen3 served locally via llama.cpp,
|
|
@@ -379,11 +433,16 @@ export function formatSessionTerminalTitle(sessionName: string | undefined, cwd?
|
|
|
379
433
|
}
|
|
380
434
|
|
|
381
435
|
/**
|
|
382
|
-
* Set the terminal title
|
|
436
|
+
* Set the terminal title through the native Win32 API or OSC 0.
|
|
437
|
+
*
|
|
438
|
+
* Repeating the same sanitized title is a no-op on every platform.
|
|
383
439
|
*/
|
|
384
440
|
export function setTerminalTitle(title: string): void {
|
|
385
441
|
if (!process.stdout.isTTY || isTerminalHeadless()) return;
|
|
386
|
-
|
|
442
|
+
const next = sanitizeTerminalTitlePart(title) ?? DEFAULT_TERMINAL_TITLE;
|
|
443
|
+
if (next === lastTerminalTitle) return;
|
|
444
|
+
if (!setWindowsConsoleTitle(next)) process.stdout.write(`\x1b]0;${next}\x07`);
|
|
445
|
+
lastTerminalTitle = next;
|
|
387
446
|
}
|
|
388
447
|
|
|
389
448
|
export function setSessionTerminalTitle(sessionName: string | undefined, cwd?: string): void {
|
|
@@ -396,9 +455,9 @@ export function setSessionTerminalTitle(sessionName: string | undefined, cwd?: s
|
|
|
396
455
|
|
|
397
456
|
/**
|
|
398
457
|
* Set a terminal title from an extension's `setTitle()`. Unlike the session base
|
|
399
|
-
* title, this owns the terminal verbatim:
|
|
400
|
-
* it
|
|
401
|
-
*
|
|
458
|
+
* title, this owns the terminal verbatim: periodic and run-state updates will not
|
|
459
|
+
* rewrite it. Cleared when the app next sets an authoritative session title via
|
|
460
|
+
* {@link setSessionTerminalTitle}.
|
|
402
461
|
*/
|
|
403
462
|
export function setExtensionTerminalTitle(title: string): void {
|
|
404
463
|
terminalTitleRuntime.extensionOverride = title;
|
|
@@ -407,12 +466,9 @@ export function setExtensionTerminalTitle(title: string): void {
|
|
|
407
466
|
|
|
408
467
|
export type TerminalTitleState = "idle" | "working" | "attention";
|
|
409
468
|
|
|
410
|
-
/**
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
* set) to avoid a utils→modes import cycle; OSC titles render in tab/window bars
|
|
414
|
-
* that handle Unicode. */
|
|
415
|
-
const TITLE_SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"] as const;
|
|
469
|
+
/** Windows uses a static working separator instead of scheduling title animation. */
|
|
470
|
+
const WINDOWS_TITLE_WORKING_SEPARATOR = ":";
|
|
471
|
+
const TITLE_SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
416
472
|
const TITLE_SPINNER_INTERVAL_MS = 80;
|
|
417
473
|
/** The user's turn: the title reads like a shell prompt awaiting input. */
|
|
418
474
|
const TITLE_IDLE_SEPARATOR = ">";
|
|
@@ -425,7 +481,6 @@ const terminalTitleRuntime: {
|
|
|
425
481
|
frame: number;
|
|
426
482
|
enabled: boolean;
|
|
427
483
|
timer: NodeJS.Timeout | undefined;
|
|
428
|
-
lastEmitted: string | undefined;
|
|
429
484
|
/** A title an extension set via `setTitle()`. While set, it owns the terminal
|
|
430
485
|
* title verbatim: the run-state separator never rewrites it. Cleared when the
|
|
431
486
|
* app next establishes an authoritative session title (rename, new session,
|
|
@@ -437,19 +492,16 @@ const terminalTitleRuntime: {
|
|
|
437
492
|
frame: 0,
|
|
438
493
|
enabled: true,
|
|
439
494
|
timer: undefined,
|
|
440
|
-
lastEmitted: undefined,
|
|
441
495
|
extensionOverride: undefined,
|
|
442
496
|
};
|
|
443
497
|
|
|
444
498
|
/**
|
|
445
|
-
* Compose the terminal title from the `π` brand, a state-carrying
|
|
446
|
-
* the session label.
|
|
447
|
-
*
|
|
448
|
-
*
|
|
449
|
-
* - `
|
|
450
|
-
* -
|
|
451
|
-
* - `attention`: `π ! label` — agent blocked on the user;
|
|
452
|
-
* - disabled: `π: label` — the pre-state layout.
|
|
499
|
+
* Compose the terminal title from the `π` brand, a state-carrying separator, and
|
|
500
|
+
* the session label. Pure (no I/O) so the state→separator contract is testable:
|
|
501
|
+
* - `idle` (user's turn): `π > label`;
|
|
502
|
+
* - `working`: `π ⠋ label` (`π : label` on Windows);
|
|
503
|
+
* - `attention`: `π ! label`;
|
|
504
|
+
* - disabled: `π: label`.
|
|
453
505
|
* Without a label the separator trails the brand (`π >`) so the state stays visible.
|
|
454
506
|
*/
|
|
455
507
|
export function buildTerminalTitleWithState(
|
|
@@ -457,11 +509,14 @@ export function buildTerminalTitleWithState(
|
|
|
457
509
|
state: TerminalTitleState,
|
|
458
510
|
frame: number,
|
|
459
511
|
enabled: boolean,
|
|
512
|
+
platform: NodeJS.Platform = process.platform,
|
|
460
513
|
): string {
|
|
461
514
|
if (!enabled) return label ? `${DEFAULT_TERMINAL_TITLE}: ${label}` : DEFAULT_TERMINAL_TITLE;
|
|
462
515
|
const separator =
|
|
463
516
|
state === "working"
|
|
464
|
-
?
|
|
517
|
+
? platform === "win32"
|
|
518
|
+
? WINDOWS_TITLE_WORKING_SEPARATOR
|
|
519
|
+
: TITLE_SPINNER_FRAMES[frame % TITLE_SPINNER_FRAMES.length]
|
|
465
520
|
: state === "attention"
|
|
466
521
|
? TITLE_ATTENTION_SEPARATOR
|
|
467
522
|
: TITLE_IDLE_SEPARATOR;
|
|
@@ -469,8 +524,8 @@ export function buildTerminalTitleWithState(
|
|
|
469
524
|
}
|
|
470
525
|
|
|
471
526
|
function emitTerminalTitle(): void {
|
|
472
|
-
// An extension override owns the terminal verbatim; the
|
|
473
|
-
//
|
|
527
|
+
// An extension override owns the terminal verbatim; the terminal sink
|
|
528
|
+
// deduplicates repeated state updates.
|
|
474
529
|
const next =
|
|
475
530
|
terminalTitleRuntime.extensionOverride ??
|
|
476
531
|
buildTerminalTitleWithState(
|
|
@@ -479,20 +534,16 @@ function emitTerminalTitle(): void {
|
|
|
479
534
|
terminalTitleRuntime.frame,
|
|
480
535
|
terminalTitleRuntime.enabled,
|
|
481
536
|
);
|
|
482
|
-
if (next === terminalTitleRuntime.lastEmitted) return;
|
|
483
|
-
terminalTitleRuntime.lastEmitted = next;
|
|
484
537
|
setTerminalTitle(next);
|
|
485
538
|
}
|
|
486
539
|
|
|
487
540
|
function stopTerminalTitleSpinner(): void {
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
terminalTitleRuntime.timer = undefined;
|
|
491
|
-
}
|
|
541
|
+
clearInterval(terminalTitleRuntime.timer);
|
|
542
|
+
terminalTitleRuntime.timer = undefined;
|
|
492
543
|
}
|
|
493
544
|
|
|
494
545
|
function startTerminalTitleSpinner(): void {
|
|
495
|
-
if (terminalTitleRuntime.timer || !process.stdout.isTTY) return;
|
|
546
|
+
if (process.platform === "win32" || terminalTitleRuntime.timer || !process.stdout.isTTY) return;
|
|
496
547
|
terminalTitleRuntime.timer = setInterval(() => {
|
|
497
548
|
terminalTitleRuntime.frame = (terminalTitleRuntime.frame + 1) % TITLE_SPINNER_FRAMES.length;
|
|
498
549
|
emitTerminalTitle();
|
|
@@ -503,8 +554,9 @@ function startTerminalTitleSpinner(): void {
|
|
|
503
554
|
|
|
504
555
|
/**
|
|
505
556
|
* Reflect the agent run state in the terminal title's separator: `working`
|
|
506
|
-
* animates
|
|
507
|
-
* `attention` shows `!` (agent blocked on you). Gated off by
|
|
557
|
+
* animates outside Windows and stays `:` on Windows, `idle` shows `>` (your
|
|
558
|
+
* turn), and `attention` shows `!` (agent blocked on you). Gated off by
|
|
559
|
+
* `tui.titleState`.
|
|
508
560
|
*/
|
|
509
561
|
export function setTerminalTitleState(state: TerminalTitleState): void {
|
|
510
562
|
terminalTitleRuntime.state = state;
|
|
@@ -521,9 +573,11 @@ export function setTerminalTitleStateEnabled(enabled: boolean): void {
|
|
|
521
573
|
emitTerminalTitle();
|
|
522
574
|
}
|
|
523
575
|
|
|
524
|
-
/**
|
|
576
|
+
/** Release terminal-title runtime resources. */
|
|
525
577
|
export function disposeTerminalTitleState(): void {
|
|
526
578
|
stopTerminalTitleSpinner();
|
|
579
|
+
disposeWindowsConsoleTitleApi();
|
|
580
|
+
lastTerminalTitle = undefined;
|
|
527
581
|
}
|
|
528
582
|
|
|
529
583
|
/**
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|