pi-ultracode 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -10
- package/README.zh-CN.md +26 -10
- package/extensions/ultracode.ts +18 -85
- package/package.json +2 -2
- package/src/commands.ts +26 -24
- package/src/depth.ts +37 -0
- package/src/index.ts +8 -0
- package/src/mode.ts +81 -407
- package/src/prompts.ts +65 -31
- package/src/thinking.ts +2 -2
- package/src/workflow/runtime.ts +3 -3
- package/src/workflow/tool.ts +6 -7
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Deterministic multi-agent workflows for [Pi](https://github.com/earendil-works/p
|
|
|
4
4
|
|
|
5
5
|
**English** · [简体中文](https://github.com/ekil1100/pi-ultracode/blob/main/README.zh-CN.md)
|
|
6
6
|
|
|
7
|
-
`pi-ultracode` adds
|
|
7
|
+
`pi-ultracode` adds opt-in semantic analysis-depth modes to Pi. It can route each task automatically or hold a fixed focused, standard, or deep policy. When delegation adds value, the main agent can run a bounded JavaScript workflow with parallel subagents, isolated worktrees, structured output, durable resume, and live progress.
|
|
8
8
|
|
|
9
9
|
The project combines the terminal-first agentic experience of [Claude Code](https://github.com/anthropics/claude-code) with the explicit workflow and structural-control ideas found in [Grok Build](https://github.com/xai-org/grok-build), while keeping Pi as the runtime.
|
|
10
10
|
|
|
@@ -14,14 +14,14 @@ The project combines the terminal-first agentic experience of [Claude Code](http
|
|
|
14
14
|
pi install npm:pi-ultracode
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
Then reload Pi and
|
|
17
|
+
Then reload Pi and enable adaptive Ultracode:
|
|
18
18
|
|
|
19
19
|
```text
|
|
20
20
|
/reload
|
|
21
21
|
/ultracode
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
You can also
|
|
24
|
+
You can also start directly in `auto` mode:
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
27
|
pi --ultracode
|
|
@@ -33,7 +33,7 @@ Current releases are tested with Pi 0.84.
|
|
|
33
33
|
|
|
34
34
|
## Core features
|
|
35
35
|
|
|
36
|
-
- **
|
|
36
|
+
- **Adaptive semantic depth** — choose `auto`, `focused`, `standard`, or `deep`; `auto` selects the smallest evidence-sufficient depth while the parent effort remains under user control.
|
|
37
37
|
- **Explicit workflows** — compose work with `agent()`, `parallel()`, `pipeline()`, and nested `workflow()` calls.
|
|
38
38
|
- **Independent subagents** — each agent gets its own Pi session, context, tools, model selection, and optional role.
|
|
39
39
|
- **Parallel worktree isolation** — writing agents can work in temporary git worktrees before their patches are integrated.
|
|
@@ -44,7 +44,7 @@ Current releases are tested with Pi 0.84.
|
|
|
44
44
|
|
|
45
45
|
## Quick start
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
Enable adaptive Ultracode and describe a task:
|
|
48
48
|
|
|
49
49
|
```text
|
|
50
50
|
/ultracode
|
|
@@ -59,16 +59,32 @@ Useful commands:
|
|
|
59
59
|
|
|
60
60
|
| Command | Action |
|
|
61
61
|
| --- | --- |
|
|
62
|
-
| `/ultracode` |
|
|
63
|
-
| `/ultracode
|
|
64
|
-
| `/ultracode
|
|
65
|
-
| `/ultracode
|
|
62
|
+
| `/ultracode` | Enable `auto` from off; disable any active mode |
|
|
63
|
+
| `/ultracode auto` | Select adaptive semantic-depth routing |
|
|
64
|
+
| `/ultracode focused` | Fix the lightweight, narrowly scoped policy |
|
|
65
|
+
| `/ultracode standard` | Fix the balanced policy with conditional verification |
|
|
66
|
+
| `/ultracode deep` | Fix the high-assurance policy with deep verification |
|
|
67
|
+
| `/ultracode off` | Disable it without changing the parent effort |
|
|
68
|
+
| `/ultracode status` | Show the configured semantic-depth mode |
|
|
66
69
|
| `/workflows` or `F6` | Open the workflow browser |
|
|
67
70
|
| `/workflows <runId>` | Open a specific run |
|
|
68
71
|
| `/workflows abort` | Abort active runs |
|
|
69
72
|
|
|
70
73
|
Press `Esc` to cancel a running workflow. In Pi's fullscreen TUI, use `Ctrl+PageUp`, `Ctrl+PageDown`, and `Ctrl+End` inside workflow details.
|
|
71
74
|
|
|
75
|
+
## Analysis depth
|
|
76
|
+
|
|
77
|
+
Depth is semantic, not time-based:
|
|
78
|
+
|
|
79
|
+
- **Focused** prefers the parent agent and one bounded line of inquiry. It does not run adversarial verification by default.
|
|
80
|
+
- **Standard** covers the few independent dimensions that can change the answer and verifies only high-risk, conflicting, or weakly evidenced claims.
|
|
81
|
+
- **Deep** uses bounded multi-perspective investigation and adversarial verification for high-risk or explicitly comprehensive work.
|
|
82
|
+
- **Auto** routes to the smallest sufficient level from user intent, consequence risk, scope, ambiguity, available evidence, and conflicts. It escalates only when evidence requires it.
|
|
83
|
+
|
|
84
|
+
Research stops when key claims have direct evidence, no material conflict or unresolved high-risk question remains, and another round would repeat known evidence. Wall-clock time, deadlines, and duration limits are never used to choose or stop analysis depth. `maxAgents` and `reserveAgents` remain structural admission limits.
|
|
85
|
+
|
|
86
|
+
Ultracode never changes the parent session's effort. For workflow children, the parent selects effort per assigned task with a model suffix: typically `:medium` for bounded discovery or synthesis, `:high` for substantive analysis or implementation, and `:max` only for deep or decisive high-risk verification. The workflow UI reports each child's actual model-clamped effort. If no suffix is supplied, the child uses its normal user/model configuration. A separate skeptic or synthesis agent is not automatic.
|
|
87
|
+
|
|
72
88
|
## Workflow example
|
|
73
89
|
|
|
74
90
|
The main agent normally writes workflows for you. Reusable workflows can also be saved under `.pi/ultracode/workflows/*.workflow.js` or `~/.pi/ultracode/workflows/*.workflow.js`. Project-scoped workflows are discovered only after Pi marks the project as trusted; user-scoped workflows remain available in untrusted projects.
|
|
@@ -133,7 +149,7 @@ Workflow agent sessions retain project context and ordinary skills, but do not i
|
|
|
133
149
|
|
|
134
150
|
Resume is intentionally immutable: the normalized script, arguments, canonical repository/relative cwd, project-trust context, agent definitions, effective models, and call structure must still match. Worktree delivery writes a durable recovery intent before changing the shared repository; an interrupted or conflicted delivery blocks automatic replay and reports its recovery patch. Changed work starts a new run.
|
|
135
151
|
|
|
136
|
-
Token and cost data are reported for observability, not enforced as a budget. Worker and VM restrictions are determinism and liveness guards, not a security sandbox.
|
|
152
|
+
Token and cost data are reported for observability, not enforced as a budget. Worker and VM restrictions are determinism and liveness guards, not a security sandbox and not analysis-depth controls.
|
|
137
153
|
|
|
138
154
|
## Design inspiration
|
|
139
155
|
|
package/README.zh-CN.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
[English](README.md) · **简体中文**
|
|
6
6
|
|
|
7
|
-
`pi-ultracode` 为 Pi
|
|
7
|
+
`pi-ultracode` 为 Pi 增加可选的语义化分析深度模式。它既可以自动判断任务需要的深度,也可以固定使用 focused、standard 或 deep 策略。当委派确有价值时,主代理可以运行有边界的 JavaScript 工作流,使用并行子代理、隔离 worktree、结构化输出、持久恢复和实时进度。
|
|
8
8
|
|
|
9
9
|
项目结合了 [Claude Code](https://github.com/anthropics/claude-code) 的终端 Agentic 体验,以及 [Grok Build](https://github.com/xai-org/grok-build) 的显式工作流和结构控制思路,同时继续使用 Pi 作为运行时。
|
|
10
10
|
|
|
@@ -14,14 +14,14 @@
|
|
|
14
14
|
pi install npm:pi-ultracode
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
然后重新加载 Pi
|
|
17
|
+
然后重新加载 Pi,并用主命令开启自适应 Ultracode:
|
|
18
18
|
|
|
19
19
|
```text
|
|
20
20
|
/reload
|
|
21
21
|
/ultracode
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
也可以在启动时直接进入 `auto` 模式:
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
27
|
pi --ultracode
|
|
@@ -33,7 +33,7 @@ pi --ultracode
|
|
|
33
33
|
|
|
34
34
|
## 核心特性
|
|
35
35
|
|
|
36
|
-
-
|
|
36
|
+
- **自适应语义深度**:可选择 `auto`、`focused`、`standard` 或 `deep`;`auto` 使用证据充分的最小深度,父代理 effort 始终由用户控制。
|
|
37
37
|
- **显式工作流**:通过 `agent()`、`parallel()`、`pipeline()` 和嵌套 `workflow()` 组合任务。
|
|
38
38
|
- **独立子代理**:每个代理拥有独立的 Pi 会话、上下文、工具、模型选择和可选角色。
|
|
39
39
|
- **并行 worktree 隔离**:写入型代理可在临时 git worktree 中工作,再集成补丁。
|
|
@@ -44,7 +44,7 @@ pi --ultracode
|
|
|
44
44
|
|
|
45
45
|
## 快速开始
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
用主命令开启自适应 Ultracode,然后描述任务:
|
|
48
48
|
|
|
49
49
|
```text
|
|
50
50
|
/ultracode
|
|
@@ -59,16 +59,32 @@ Pi 会自行判断工作流是否有帮助。小任务仍可继续使用普通
|
|
|
59
59
|
|
|
60
60
|
| 命令 | 作用 |
|
|
61
61
|
| --- | --- |
|
|
62
|
-
| `/ultracode` |
|
|
63
|
-
| `/ultracode
|
|
64
|
-
| `/ultracode
|
|
65
|
-
| `/ultracode
|
|
62
|
+
| `/ultracode` | 关闭时开启 `auto`;任一模式已开启时关闭 |
|
|
63
|
+
| `/ultracode auto` | 使用自适应语义深度路由 |
|
|
64
|
+
| `/ultracode focused` | 固定使用轻量、聚焦的分析策略 |
|
|
65
|
+
| `/ultracode standard` | 固定使用平衡策略和条件验证 |
|
|
66
|
+
| `/ultracode deep` | 固定使用高保障深度验证 |
|
|
67
|
+
| `/ultracode off` | 关闭且不改变父代理 effort |
|
|
68
|
+
| `/ultracode status` | 查看配置的语义深度模式 |
|
|
66
69
|
| `/workflows` 或 `F6` | 打开工作流浏览器 |
|
|
67
70
|
| `/workflows <runId>` | 打开指定运行 |
|
|
68
71
|
| `/workflows abort` | 中止活动运行 |
|
|
69
72
|
|
|
70
73
|
按 `Esc` 可取消正在运行的工作流。在 Pi 的 fullscreen TUI 中,请在工作流详情内使用 `Ctrl+PageUp`、`Ctrl+PageDown` 和 `Ctrl+End`。
|
|
71
74
|
|
|
75
|
+
## 分析深度
|
|
76
|
+
|
|
77
|
+
深度是语义化质量决策,不按运行时间判断:
|
|
78
|
+
|
|
79
|
+
- **Focused** 优先使用主代理和单一、边界明确的调查路径,默认不做对抗验证。
|
|
80
|
+
- **Standard** 覆盖少量真正会改变结论的独立维度,只验证高风险、冲突或证据薄弱的结论。
|
|
81
|
+
- **Deep** 面向高风险或用户明确要求全面分析的任务,使用有界的多视角调查和对抗验证。
|
|
82
|
+
- **Auto** 根据用户意图、影响风险、范围、歧义、现有证据和结论冲突,选择足够完成任务的最小等级;仅在证据要求升级时加深。
|
|
83
|
+
|
|
84
|
+
当关键结论已有直接证据、没有实质冲突或未解决的高风险问题,且下一轮只会重复已知证据时停止。墙钟时间、deadline 和 duration limit 不得用于选择或停止分析深度。`maxAgents` 与 `reserveAgents` 继续作为结构性准入限制。
|
|
85
|
+
|
|
86
|
+
Ultracode 不会修改父会话的 effort。对于 workflow 子代理,父代理会按具体任务通过模型后缀选择 effort:边界明确的搜索或汇总通常使用 `:medium`,实质分析或实现使用 `:high`,只有深度调查或决定性的高风险验证才使用 `:max`。Workflow UI 会展示每个子代理经模型裁剪后实际生效的 effort;未指定后缀时,子会话使用正常的用户/模型配置。skeptic 和独立 synthesis agent 都不是默认步骤。
|
|
87
|
+
|
|
72
88
|
## 工作流示例
|
|
73
89
|
|
|
74
90
|
通常由主代理自动编写工作流。需要复用时,可以保存到 `.pi/ultracode/workflows/*.workflow.js` 或 `~/.pi/ultracode/workflows/*.workflow.js`。只有 Pi 将项目标记为可信后,才会发现项目级工作流;用户级工作流在未信任项目中仍可使用。
|
|
@@ -133,7 +149,7 @@ Workflow 子代理会保留项目上下文和普通 skills,但不会初始化
|
|
|
133
149
|
|
|
134
150
|
Resume 刻意保持不可变:规范化脚本、参数、规范仓库及仓内相对 cwd、项目信任上下文、代理定义、实际模型和调用结构都必须匹配。Worktree 交付会在修改共享仓库前先写入持久恢复意图;中断或冲突的交付会阻止自动回放,并报告恢复补丁。工作内容发生变化时,应启动新的 run。
|
|
135
151
|
|
|
136
|
-
Token 和成本只用于可观测性,不作为执行预算。Worker 与 VM
|
|
152
|
+
Token 和成本只用于可观测性,不作为执行预算。Worker 与 VM 限制用于确定性和存活性保护,不是安全沙箱,也不参与分析深度判断。
|
|
137
153
|
|
|
138
154
|
## 设计参考
|
|
139
155
|
|
package/extensions/ultracode.ts
CHANGED
|
@@ -1,21 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* pi-ultracode extension entrypoint.
|
|
3
3
|
*
|
|
4
|
-
* Wires together
|
|
5
|
-
*
|
|
6
|
-
* 2. The full `workflow` orchestration tool.
|
|
7
|
-
* 3. The `/ultracode` and `/workflows` commands.
|
|
4
|
+
* Wires together Ultracode's semantic analysis-depth modes, deterministic
|
|
5
|
+
* workflow orchestration, and the `/ultracode` / `/workflows` commands.
|
|
8
6
|
*/
|
|
9
7
|
|
|
10
|
-
import {
|
|
11
|
-
getAgentDir,
|
|
12
|
-
SettingsManager,
|
|
13
|
-
VERSION as PI_VERSION,
|
|
14
|
-
type ExtensionAPI,
|
|
15
|
-
} from "@earendil-works/pi-coding-agent";
|
|
8
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
16
9
|
import { createWorkflowTool, type WorkflowToolDeps } from "../src/workflow/tool.ts";
|
|
17
10
|
import { UltracodeMode, type ThinkingPreferenceStore } from "../src/mode.ts";
|
|
18
|
-
import { isThinkingLevel, piVersionSupportsMaxThinking } from "../src/thinking.ts";
|
|
19
11
|
import { registerCommands } from "../src/commands.ts";
|
|
20
12
|
import { WorkflowRegistry } from "../src/workflow/registry.ts";
|
|
21
13
|
|
|
@@ -25,7 +17,7 @@ export interface ThinkingPreferenceContext {
|
|
|
25
17
|
}
|
|
26
18
|
|
|
27
19
|
export interface UltracodeExtensionDeps extends Partial<WorkflowToolDeps> {
|
|
28
|
-
/**
|
|
20
|
+
/** @deprecated Parent effort is user-owned; retained for source compatibility. */
|
|
29
21
|
createThinkingPreferenceStore?: (
|
|
30
22
|
context: ThinkingPreferenceContext,
|
|
31
23
|
) => ThinkingPreferenceStore | undefined;
|
|
@@ -33,15 +25,13 @@ export interface UltracodeExtensionDeps extends Partial<WorkflowToolDeps> {
|
|
|
33
25
|
|
|
34
26
|
export default function extension(pi: ExtensionAPI, extraDeps: UltracodeExtensionDeps = {}): void {
|
|
35
27
|
const mode = new UltracodeMode("workflow");
|
|
36
|
-
mode.setRuntimeSupportsMaxThinking(piVersionSupportsMaxThinking(PI_VERSION));
|
|
37
28
|
const {
|
|
38
|
-
createThinkingPreferenceStore
|
|
29
|
+
createThinkingPreferenceStore: _unusedThinkingPreferenceStore,
|
|
39
30
|
...workflowDeps
|
|
40
31
|
} = extraDeps;
|
|
41
32
|
|
|
42
33
|
const registry = workflowDeps.registry ?? new WorkflowRegistry();
|
|
43
34
|
const workflowTool = createWorkflowTool({
|
|
44
|
-
getThinkingLevel: () => mode.getSubagentThinkingLevel(),
|
|
45
35
|
...workflowDeps,
|
|
46
36
|
registry,
|
|
47
37
|
isExecutionAllowed: () => mode.isEnforcing(),
|
|
@@ -53,7 +43,7 @@ export default function extension(pi: ExtensionAPI, extraDeps: UltracodeExtensio
|
|
|
53
43
|
// Opt-in via CLI flag: `pi --ultracode`.
|
|
54
44
|
pi.registerFlag("ultracode", {
|
|
55
45
|
type: "boolean",
|
|
56
|
-
description: "Start the session in
|
|
46
|
+
description: "Start the session in adaptive Ultracode mode.",
|
|
57
47
|
});
|
|
58
48
|
|
|
59
49
|
// SDK-created sessions can prompt without emitting session_start. Sync during
|
|
@@ -68,22 +58,12 @@ export default function extension(pi: ExtensionAPI, extraDeps: UltracodeExtensio
|
|
|
68
58
|
if (event.toolName === workflowTool.name && !mode.isEnforcing()) {
|
|
69
59
|
return {
|
|
70
60
|
block: true,
|
|
71
|
-
reason: "The workflow tool is disabled. Run /ultracode
|
|
61
|
+
reason: "The workflow tool is disabled. Run /ultracode or select an Ultracode depth before using it.",
|
|
72
62
|
};
|
|
73
63
|
}
|
|
74
64
|
});
|
|
75
65
|
|
|
76
66
|
pi.on("session_start", async (_event, ctx) => {
|
|
77
|
-
await mode.flushThinkingPreference();
|
|
78
|
-
mode.setCurrentModelSupportsThinking(ctx.model ? Boolean(ctx.model.reasoning) : undefined);
|
|
79
|
-
try {
|
|
80
|
-
mode.bindThinkingPreferenceStore(createThinkingPreferenceStore({
|
|
81
|
-
cwd: ctx.cwd,
|
|
82
|
-
projectTrusted: ctx.isProjectTrusted(),
|
|
83
|
-
}));
|
|
84
|
-
} catch {
|
|
85
|
-
mode.bindThinkingPreferenceStore(undefined);
|
|
86
|
-
}
|
|
87
67
|
// Restore persisted mode state across reload / resume / fork.
|
|
88
68
|
try {
|
|
89
69
|
// Mode entries are branch-local; discarded future branches must not win.
|
|
@@ -92,85 +72,38 @@ export default function extension(pi: ExtensionAPI, extraDeps: UltracodeExtensio
|
|
|
92
72
|
// ignore
|
|
93
73
|
}
|
|
94
74
|
if (!mode.isEnabled() && pi.getFlag?.("ultracode") === true) {
|
|
95
|
-
mode.enable(pi);
|
|
75
|
+
mode.enable(pi, "auto");
|
|
96
76
|
}
|
|
97
77
|
// Registration makes extension tools discoverable; activation remains opt-in.
|
|
98
78
|
mode.syncWorkflowTool(pi);
|
|
99
|
-
await mode.flushThinkingPreference();
|
|
100
79
|
if (ctx.hasUI) {
|
|
101
|
-
ctx.ui.setStatus(
|
|
80
|
+
ctx.ui.setStatus(
|
|
81
|
+
"ultracode",
|
|
82
|
+
mode.isEnabled() ? mode.statusLine((label) => ctx.ui.theme.fg("accent", label)) : undefined,
|
|
83
|
+
);
|
|
102
84
|
}
|
|
103
85
|
});
|
|
104
86
|
|
|
105
87
|
pi.on("session_tree", async (_event, ctx) => {
|
|
106
|
-
await mode.flushThinkingPreference();
|
|
107
88
|
if (mode.isSuspended()) return;
|
|
108
|
-
mode.setCurrentModelSupportsThinking(ctx.model ? Boolean(ctx.model.reasoning) : undefined);
|
|
109
89
|
mode.restore(pi, ctx.sessionManager.getBranch() as any);
|
|
110
|
-
await mode.flushThinkingPreference();
|
|
111
90
|
if (ctx.hasUI) {
|
|
112
|
-
ctx.ui.setStatus(
|
|
91
|
+
ctx.ui.setStatus(
|
|
92
|
+
"ultracode",
|
|
93
|
+
mode.isEnabled() ? mode.statusLine((label) => ctx.ui.theme.fg("accent", label)) : undefined,
|
|
94
|
+
);
|
|
113
95
|
}
|
|
114
96
|
});
|
|
115
97
|
|
|
116
|
-
pi.on("model_select", async (event, ctx) => {
|
|
117
|
-
mode.setCurrentModelSupportsThinking(Boolean(event.model.reasoning));
|
|
118
|
-
const refreshStatus = mode.handleModelSelect(pi);
|
|
119
|
-
await mode.flushThinkingPreference();
|
|
120
|
-
if (refreshStatus && ctx.hasUI) ctx.ui.setStatus("ultracode", mode.statusLine());
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
pi.on("thinking_level_select", async (event, ctx) => {
|
|
124
|
-
if (!mode.handleThinkingLevelSelect(pi, event.level)) return;
|
|
125
|
-
await mode.flushThinkingPreference();
|
|
126
|
-
if (ctx.hasUI) ctx.ui.setStatus("ultracode", mode.statusLine());
|
|
127
|
-
});
|
|
128
|
-
|
|
129
98
|
pi.on("session_shutdown", async () => {
|
|
130
|
-
//
|
|
131
|
-
// persisted enabled state remains on for reload/resume/fork replacements.
|
|
99
|
+
// The persisted configured mode remains active for reload/resume/fork replacements.
|
|
132
100
|
mode.suspend(pi);
|
|
133
|
-
await mode.flushThinkingPreference();
|
|
134
101
|
});
|
|
135
102
|
|
|
136
103
|
pi.on("before_agent_start", async (event) => {
|
|
137
|
-
// Reconcile
|
|
104
|
+
// Reconcile tool availability and append the standing policy on every
|
|
138
105
|
// enforcing turn, even when another active-tool writer caused drift.
|
|
139
106
|
mode.syncWorkflowTool(pi);
|
|
140
|
-
mode.reapplyMaximumThinking(pi);
|
|
141
|
-
await mode.flushThinkingPreference();
|
|
142
107
|
return mode.beforeAgentStart(event);
|
|
143
108
|
});
|
|
144
109
|
}
|
|
145
|
-
|
|
146
|
-
function createPiThinkingPreferenceStore(
|
|
147
|
-
context: ThinkingPreferenceContext,
|
|
148
|
-
): ThinkingPreferenceStore {
|
|
149
|
-
const createSettings = () => SettingsManager.create(
|
|
150
|
-
context.cwd,
|
|
151
|
-
getAgentDir(),
|
|
152
|
-
{ projectTrusted: context.projectTrusted },
|
|
153
|
-
);
|
|
154
|
-
return {
|
|
155
|
-
getThinkingPreference() {
|
|
156
|
-
// Use a fresh manager so a selection made after session_start is visible;
|
|
157
|
-
// SettingsManager instances intentionally keep their own cached snapshot.
|
|
158
|
-
const settings = createSettings();
|
|
159
|
-
const global = settings.getGlobalSettings().defaultThinkingLevel;
|
|
160
|
-
const effective = settings.getDefaultThinkingLevel();
|
|
161
|
-
return {
|
|
162
|
-
global: isThinkingLevel(global) ? global : undefined,
|
|
163
|
-
effective: isThinkingLevel(effective) ? effective : "medium",
|
|
164
|
-
};
|
|
165
|
-
},
|
|
166
|
-
async setDefaultThinkingLevel(level) {
|
|
167
|
-
// Use a fresh queue after the mode's macrotask barrier. This serializes
|
|
168
|
-
// behind Pi's already-enqueued writes instead of racing a long-lived peer.
|
|
169
|
-
const settings = createSettings();
|
|
170
|
-
// An absent setting is semantically Pi's `medium` default. SettingsManager
|
|
171
|
-
// has no unset operation, so restore that equivalent value explicitly.
|
|
172
|
-
settings.setDefaultThinkingLevel((level ?? "medium") as any);
|
|
173
|
-
await settings.flush();
|
|
174
|
-
},
|
|
175
|
-
};
|
|
176
|
-
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-ultracode",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"description": "Adaptive semantic-depth workflow orchestration for Pi, with focused, standard, and deep modes, isolated subagents, worktree delivery, structured output, and durable resume.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"pi-package",
|
package/src/commands.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
6
|
+
import { ACTIVE_ULTRACODE_MODES, isActiveUltracodeMode } from "./depth.ts";
|
|
6
7
|
import type { UltracodeMode } from "./mode.ts";
|
|
7
8
|
import type { WorkflowRegistry } from "./workflow/registry.ts";
|
|
8
9
|
import { workflowRunsDir } from "./workflow/tool.ts";
|
|
@@ -10,59 +11,60 @@ import { openWorkflowOverlay } from "./workflow/workflow-overlay.ts";
|
|
|
10
11
|
|
|
11
12
|
export function registerCommands(pi: ExtensionAPI, mode: UltracodeMode, registry: WorkflowRegistry): void {
|
|
12
13
|
pi.registerCommand("ultracode", {
|
|
13
|
-
description: "Toggle
|
|
14
|
+
description: "Toggle adaptive Ultracode, or select a fixed semantic depth: auto|focused|standard|deep|off|status",
|
|
14
15
|
getArgumentCompletions(prefix: string) {
|
|
15
|
-
return [
|
|
16
|
-
.filter((
|
|
16
|
+
return [...ACTIVE_ULTRACODE_MODES, "off", "status"]
|
|
17
|
+
.filter((value) => value.startsWith(prefix))
|
|
17
18
|
.map((value) => ({ value, label: value }));
|
|
18
19
|
},
|
|
19
20
|
handler: async (args: string, ctx) => {
|
|
20
|
-
mode.setCurrentModelSupportsThinking(ctx.model ? Boolean(ctx.model.reasoning) : undefined);
|
|
21
21
|
const parts = args.trim().split(/\s+/).filter(Boolean);
|
|
22
22
|
const sub = (parts[0] ?? "").toLowerCase();
|
|
23
23
|
|
|
24
|
-
// Bare `/ultracode`
|
|
24
|
+
// Bare `/ultracode` enables auto from off and disables any active mode.
|
|
25
25
|
if (sub === "") {
|
|
26
26
|
const nowOn = mode.toggle(pi);
|
|
27
|
-
await mode.flushThinkingPreference();
|
|
28
27
|
ctx.ui.notify(
|
|
29
|
-
nowOn
|
|
28
|
+
nowOn
|
|
29
|
+
? `Ultracode auto — ${mode.statusLine()}`
|
|
30
|
+
: "Ultracode off — workflow tool disabled; parent effort unchanged.",
|
|
30
31
|
"info",
|
|
31
32
|
);
|
|
32
|
-
ctx.ui.setStatus(
|
|
33
|
+
ctx.ui.setStatus(
|
|
34
|
+
"ultracode",
|
|
35
|
+
nowOn ? mode.statusLine((label) => ctx.ui.theme.fg("accent", label)) : undefined,
|
|
36
|
+
);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (parts.length > 1) {
|
|
41
|
+
ctx.ui.notify(ultracodeUsage(), "error");
|
|
33
42
|
return;
|
|
34
43
|
}
|
|
35
44
|
|
|
36
45
|
if (sub === "status") {
|
|
37
|
-
if (parts.length > 1) {
|
|
38
|
-
ctx.ui.notify(ultracodeUsage(), "error");
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
46
|
ctx.ui.notify(mode.statusLine(), "info");
|
|
42
47
|
return;
|
|
43
48
|
}
|
|
44
49
|
|
|
45
50
|
if (sub === "off") {
|
|
46
|
-
if (parts.length > 1) {
|
|
47
|
-
ctx.ui.notify(ultracodeUsage(), "error");
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
51
|
mode.disable(pi);
|
|
51
|
-
|
|
52
|
-
ctx.ui.notify("Ultracode off — thinking restored and workflow tool disabled.", "info");
|
|
52
|
+
ctx.ui.notify("Ultracode off — workflow tool disabled; parent effort unchanged.", "info");
|
|
53
53
|
ctx.ui.setStatus("ultracode", undefined);
|
|
54
54
|
return;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
if (sub
|
|
57
|
+
if (!isActiveUltracodeMode(sub)) {
|
|
58
58
|
ctx.ui.notify(ultracodeUsage(), "error");
|
|
59
59
|
return;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
mode.enable(pi);
|
|
63
|
-
|
|
64
|
-
ctx.ui.
|
|
65
|
-
|
|
62
|
+
mode.enable(pi, sub);
|
|
63
|
+
ctx.ui.notify(`Ultracode ${sub} — ${mode.statusLine()}`, "info");
|
|
64
|
+
ctx.ui.setStatus(
|
|
65
|
+
"ultracode",
|
|
66
|
+
mode.statusLine((label) => ctx.ui.theme.fg("accent", label)),
|
|
67
|
+
);
|
|
66
68
|
},
|
|
67
69
|
});
|
|
68
70
|
|
|
@@ -100,5 +102,5 @@ export function registerCommands(pi: ExtensionAPI, mode: UltracodeMode, registry
|
|
|
100
102
|
}
|
|
101
103
|
|
|
102
104
|
function ultracodeUsage(): string {
|
|
103
|
-
return "Usage: /ultracode [
|
|
105
|
+
return "Usage: /ultracode [auto|focused|standard|deep|off|status]";
|
|
104
106
|
}
|
package/src/depth.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** Ultracode's configured semantic analysis-depth modes. */
|
|
2
|
+
|
|
3
|
+
import type { ThinkingLevel } from "./thinking.ts";
|
|
4
|
+
|
|
5
|
+
export const ACTIVE_ULTRACODE_MODES = ["auto", "focused", "standard", "deep"] as const;
|
|
6
|
+
|
|
7
|
+
export type ActiveUltracodeMode = (typeof ACTIVE_ULTRACODE_MODES)[number];
|
|
8
|
+
export type UltracodeModeName = "off" | ActiveUltracodeMode;
|
|
9
|
+
|
|
10
|
+
const ACTIVE_MODE_SET = new Set<string>(ACTIVE_ULTRACODE_MODES);
|
|
11
|
+
|
|
12
|
+
export function isActiveUltracodeMode(value: unknown): value is ActiveUltracodeMode {
|
|
13
|
+
return typeof value === "string" && ACTIVE_MODE_SET.has(value);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function isUltracodeModeName(value: unknown): value is UltracodeModeName {
|
|
17
|
+
return value === "off" || isActiveUltracodeMode(value);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @deprecated Legacy mode-to-effort mapping retained for API compatibility.
|
|
22
|
+
* Ultracode no longer applies it to the parent or as a workflow child default;
|
|
23
|
+
* each child selects effort per task and Pi clamps it to model capabilities.
|
|
24
|
+
*/
|
|
25
|
+
export function thinkingLevelForMode(mode: UltracodeModeName): ThinkingLevel | undefined {
|
|
26
|
+
switch (mode) {
|
|
27
|
+
case "focused":
|
|
28
|
+
return "medium";
|
|
29
|
+
case "auto":
|
|
30
|
+
case "standard":
|
|
31
|
+
return "high";
|
|
32
|
+
case "deep":
|
|
33
|
+
return "max";
|
|
34
|
+
case "off":
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
export { default } from "../extensions/ultracode.ts";
|
|
4
4
|
export { UltracodeMode, MODE_ENTRY_TYPE } from "./mode.ts";
|
|
5
|
+
export {
|
|
6
|
+
ACTIVE_ULTRACODE_MODES,
|
|
7
|
+
isActiveUltracodeMode,
|
|
8
|
+
isUltracodeModeName,
|
|
9
|
+
thinkingLevelForMode,
|
|
10
|
+
type ActiveUltracodeMode,
|
|
11
|
+
type UltracodeModeName,
|
|
12
|
+
} from "./depth.ts";
|
|
5
13
|
export { registerCommands } from "./commands.ts";
|
|
6
14
|
export {
|
|
7
15
|
ULTRACODE_TAGLINE,
|