@xth26/dsh-plan-build-mode 0.2.2 → 0.3.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 +39 -5
- package/README.zh.md +27 -5
- package/lib/client/index.d.ts +86 -0
- package/lib/client/index.d.ts.map +1 -0
- package/lib/client/index.js +139 -0
- package/lib/client/index.js.map +1 -0
- package/lib/client.js +141 -0
- package/lib/helpers.d.ts +9 -0
- package/lib/helpers.d.ts.map +1 -1
- package/lib/helpers.js +9 -0
- package/lib/helpers.js.map +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +34 -31
- package/lib/index.js.map +1 -1
- package/lib/types.d.ts +6 -6
- package/lib/types.d.ts.map +1 -1
- package/package.json +12 -2
package/README.md
CHANGED
|
@@ -73,7 +73,7 @@ For `0.x` versions, the semver range `^0.1.0` only matches `0.1.x` and will **ne
|
|
|
73
73
|
```bash
|
|
74
74
|
# Bump the installed version in the target profile
|
|
75
75
|
# (run this outside a sandboxed agent session; the profile directory is not writable from DSH)
|
|
76
|
-
dsh plugin --profile dsh-tui add @xth26/dsh-plan-build-mode@0.2.
|
|
76
|
+
dsh plugin --profile dsh-tui add @xth26/dsh-plan-build-mode@0.2.3
|
|
77
77
|
|
|
78
78
|
# Restart the DSH process that uses that profile
|
|
79
79
|
# (old Node process still holds the previous plugin code in memory)
|
|
@@ -89,14 +89,39 @@ dsh plugin --profile dsh-tui add @xth26/dsh-plan-build-mode@latest
|
|
|
89
89
|
|
|
90
90
|
## Usage
|
|
91
91
|
|
|
92
|
-
| Command
|
|
92
|
+
| Command | Effect |
|
|
93
93
|
|---|---|
|
|
94
94
|
| `/plan-build` | Toggle between Plan and Build modes |
|
|
95
95
|
| `/plan-build status` | Show the current mode |
|
|
96
96
|
| `/plan-build switch plan` | Enter Plan mode (read-only) |
|
|
97
97
|
| `/plan-build switch build` | Enter Build mode (writable) |
|
|
98
98
|
| `/plan-build switch` | Same as `/plan-build`; toggles between modes |
|
|
99
|
-
|
|
99
|
+
|
|
100
|
+
## Keyboard shortcuts
|
|
101
|
+
|
|
102
|
+
`Ctrl+Alt+Shift+P` toggles between Plan and Build mode (the same action as
|
|
103
|
+
bare `/plan-build`) in both frontends:
|
|
104
|
+
|
|
105
|
+
- **dsh-tui** — bound through the plugin shortcut registry (`ctx.tuiShortcuts`).
|
|
106
|
+
It matches only in the plain chat state; overlays and pickers own the
|
|
107
|
+
keyboard while open.
|
|
108
|
+
- **dsh web** — a global keydown listener runs `/plan-build` against the
|
|
109
|
+
current session. Inert while no session is open and during IME composition.
|
|
110
|
+
|
|
111
|
+
The combo is deliberately complex (three modifiers) so it collides with no
|
|
112
|
+
terminal, browser, or OS built-in. Change it with the `shortcut` config key,
|
|
113
|
+
which accepts a single string or an array:
|
|
114
|
+
|
|
115
|
+
```yaml
|
|
116
|
+
- id: plan-build-mode
|
|
117
|
+
name: '@xth26/dsh-plan-build-mode'
|
|
118
|
+
config:
|
|
119
|
+
shortcut: ['ctrl+alt+shift+p', 'alt+p']
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Combos use the `ctrl+alt+shift+p` grammar and must include Ctrl or Alt. The
|
|
123
|
+
TUI refuses combos reserved by its built-in keymap (with a warning; the plugin
|
|
124
|
+
keeps running).
|
|
100
125
|
|
|
101
126
|
## Configuration
|
|
102
127
|
|
|
@@ -108,10 +133,9 @@ dsh plugin --profile dsh-tui add @xth26/dsh-plan-build-mode@latest
|
|
|
108
133
|
buildSandbox: workspace-write
|
|
109
134
|
denyWriteTools: true
|
|
110
135
|
section: true
|
|
111
|
-
tuiShortcut: ctrl+shift+b
|
|
112
136
|
```
|
|
113
137
|
|
|
114
|
-
`planSandbox` and `buildSandbox` must differ.
|
|
138
|
+
`planSandbox` and `buildSandbox` must differ.
|
|
115
139
|
|
|
116
140
|
## Plan mode: command-line Python for inspection
|
|
117
141
|
|
|
@@ -136,6 +160,16 @@ After installing/linking the plugin in a DSH profile:
|
|
|
136
160
|
5. Ask the agent to call `write` again. It should now be allowed.
|
|
137
161
|
6. Run `/plan-build status` to check the current mode without switching.
|
|
138
162
|
|
|
163
|
+
## Changelog
|
|
164
|
+
|
|
165
|
+
### 0.3.0 (unreleased)
|
|
166
|
+
|
|
167
|
+
- Add a Plan/Build toggle keyboard shortcut (`Ctrl+Alt+Shift+P` by default) in
|
|
168
|
+
both the TUI (`ctx.tuiShortcuts`) and the web frontend (global keydown). The
|
|
169
|
+
shortcut executes `/plan-build`, so mode state, lifecycle events and grants
|
|
170
|
+
stay single-source. Configurable via the new `shortcut` config key (a string
|
|
171
|
+
or an array of combos).
|
|
172
|
+
|
|
139
173
|
## License
|
|
140
174
|
|
|
141
175
|
MIT
|
package/README.zh.md
CHANGED
|
@@ -70,7 +70,7 @@ pnpm link --global @xth26/dsh-plan-build-mode
|
|
|
70
70
|
```bash
|
|
71
71
|
# 在目标 profile 中提升已安装版本
|
|
72
72
|
# (这条命令需要在非沙箱的终端里执行;DSH agent 无法写入 profile 目录)
|
|
73
|
-
dsh plugin --profile dsh-tui add @xth26/dsh-plan-build-mode@0.2.
|
|
73
|
+
dsh plugin --profile dsh-tui add @xth26/dsh-plan-build-mode@0.2.3
|
|
74
74
|
|
|
75
75
|
# 重启使用该 profile 的 DSH 进程
|
|
76
76
|
# (旧的 Node 进程仍缓存着旧插件代码)
|
|
@@ -86,14 +86,31 @@ dsh plugin --profile dsh-tui add @xth26/dsh-plan-build-mode@latest
|
|
|
86
86
|
|
|
87
87
|
## 使用
|
|
88
88
|
|
|
89
|
-
| 命令
|
|
89
|
+
| 命令 | 效果 |
|
|
90
90
|
|---|---|
|
|
91
91
|
| `/plan-build` | 在 Plan 与 Build 模式之间切换 |
|
|
92
92
|
| `/plan-build status` | 显示当前模式 |
|
|
93
93
|
| `/plan-build switch plan` | 进入 Plan 模式(只读) |
|
|
94
94
|
| `/plan-build switch build` | 进入 Build 模式(可写) |
|
|
95
95
|
| `/plan-build switch` | 同 `/plan-build`,切换当前模式 |
|
|
96
|
-
|
|
96
|
+
|
|
97
|
+
## 快捷键
|
|
98
|
+
|
|
99
|
+
`Ctrl+Alt+Shift+P` 在两个前端里都能切换 Plan / Build 模式(等同裸 `/plan-build`):
|
|
100
|
+
|
|
101
|
+
- **dsh-tui** — 通过插件快捷键注册表(`ctx.tuiShortcuts`)绑定。仅在普通聊天态生效;弹层/选择器打开时会独占键盘。
|
|
102
|
+
- **dsh web** — 全局 keydown 监听对当前会话执行 `/plan-build`。无会话打开或处于输入法组合期间不生效。
|
|
103
|
+
|
|
104
|
+
组合键刻意做得复杂(三个修饰键),不会与终端、浏览器或系统的内置快捷键冲突。可通过 `shortcut` 配置修改,支持单个字符串或数组:
|
|
105
|
+
|
|
106
|
+
```yaml
|
|
107
|
+
- id: plan-build-mode
|
|
108
|
+
name: '@xth26/dsh-plan-build-mode'
|
|
109
|
+
config:
|
|
110
|
+
shortcut: ['ctrl+alt+shift+p', 'alt+p']
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
组合键遵循 `ctrl+alt+shift+p` 语法,必须包含 Ctrl 或 Alt。TUI 会拒绝与其内置键位表冲突的组合(仅警告,插件照常运行)。
|
|
97
114
|
|
|
98
115
|
## 配置
|
|
99
116
|
|
|
@@ -105,10 +122,9 @@ dsh plugin --profile dsh-tui add @xth26/dsh-plan-build-mode@latest
|
|
|
105
122
|
buildSandbox: workspace-write
|
|
106
123
|
denyWriteTools: true
|
|
107
124
|
section: true
|
|
108
|
-
tuiShortcut: ctrl+shift+b
|
|
109
125
|
```
|
|
110
126
|
|
|
111
|
-
`planSandbox` 和 `buildSandbox`
|
|
127
|
+
`planSandbox` 和 `buildSandbox` 必须不同。
|
|
112
128
|
|
|
113
129
|
## Plan 模式:命令行 Python 做数据检查
|
|
114
130
|
|
|
@@ -133,6 +149,12 @@ pytest -p no:cacheprovider -q tests/test_sanity.py
|
|
|
133
149
|
5. 再次让 agent 调用 `write`,应允许执行。
|
|
134
150
|
6. 输入 `/plan-build status`,可只查看当前模式而不切换。
|
|
135
151
|
|
|
152
|
+
## 变更日志
|
|
153
|
+
|
|
154
|
+
### 0.3.0(未发布)
|
|
155
|
+
|
|
156
|
+
- 在 TUI(`ctx.tuiShortcuts`)与 web 前端(全局 keydown)都新增 Plan / Build 切换快捷键(默认 `Ctrl+Alt+Shift+P`)。快捷键执行 `/plan-build`,因此模式状态、生命周期事件与授权保持单一来源。可通过新增的 `shortcut` 配置键自定义(单个字符串或组合数组)。
|
|
157
|
+
|
|
136
158
|
## 许可证
|
|
137
159
|
|
|
138
160
|
MIT
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser half of `dsh-plan-build-mode`.
|
|
3
|
+
*
|
|
4
|
+
* Adds a global keyboard shortcut that toggles OpenCode Plan / Build mode by
|
|
5
|
+
* executing the host `/plan-build` command against the current session. The
|
|
6
|
+
* bundle is a pure listener: it renders nothing and occupies no Slot seat.
|
|
7
|
+
*
|
|
8
|
+
* The services are consumed through locally declared structural faces rather
|
|
9
|
+
* than cross-plugin imports on purpose — a browser bundle must not compile a
|
|
10
|
+
* require() edge into the loader module table (bundle purity), and these
|
|
11
|
+
* shapes are small and stable. The default combo is kept deliberately complex
|
|
12
|
+
* (three modifiers) so it collides with no terminal or browser built-in.
|
|
13
|
+
*
|
|
14
|
+
* @module dsh-plan-build-mode/client
|
|
15
|
+
*/
|
|
16
|
+
/** Default shortcut; keep in sync with DEFAULT_SHORTCUT in ../helpers.ts. */
|
|
17
|
+
export declare const DEFAULT_SHORTCUT = "ctrl+alt+shift+p";
|
|
18
|
+
/** Client plugin name. */
|
|
19
|
+
export declare const name = "plan-build-mode-client";
|
|
20
|
+
/**
|
|
21
|
+
* Services required at runtime: the commands Remote for `/plan-build` and the
|
|
22
|
+
* session list for the current session id.
|
|
23
|
+
*/
|
|
24
|
+
export declare const inject: readonly ["remote", "remote.commands", "sessions"];
|
|
25
|
+
/** Optional config subset accepted by the client bundle. */
|
|
26
|
+
export interface PlanBuildModeClientConfig {
|
|
27
|
+
/** One or more `ctrl+alt+shift+p` style combos; defaults to DEFAULT_SHORTCUT. */
|
|
28
|
+
readonly shortcut?: string | readonly string[];
|
|
29
|
+
}
|
|
30
|
+
/** Minimal structural faces of the services this plugin consumes. */
|
|
31
|
+
export interface PlanBuildModeClientContext {
|
|
32
|
+
effect(fn: () => (() => void) | void): void;
|
|
33
|
+
sessions: {
|
|
34
|
+
list: {
|
|
35
|
+
getSnapshot(): {
|
|
36
|
+
current: string | undefined;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
remote: {
|
|
41
|
+
commands: {
|
|
42
|
+
execute(sessionId: string, line: string, images: readonly unknown[]): Promise<{
|
|
43
|
+
ok: boolean;
|
|
44
|
+
error?: {
|
|
45
|
+
code: string;
|
|
46
|
+
message: string;
|
|
47
|
+
};
|
|
48
|
+
}>;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/** A parsed `ctrl+alt+shift+p` style combo. */
|
|
53
|
+
export interface ParsedShortcut {
|
|
54
|
+
readonly ctrl: boolean;
|
|
55
|
+
readonly alt: boolean;
|
|
56
|
+
readonly shift: boolean;
|
|
57
|
+
readonly key: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Parse a `ctrl+alt+shift+p` style combo. Requires at least one of ctrl/alt
|
|
61
|
+
* and exactly one key; returns undefined for malformed or modifier-less
|
|
62
|
+
* combos (mirrors the dsh-tui combo grammar).
|
|
63
|
+
*/
|
|
64
|
+
export declare function parseShortcutCombo(raw: string): ParsedShortcut | undefined;
|
|
65
|
+
/** Structural keydown shape so matching is testable without a DOM. */
|
|
66
|
+
export interface ShortcutKeyEvent {
|
|
67
|
+
readonly ctrlKey: boolean;
|
|
68
|
+
readonly altKey: boolean;
|
|
69
|
+
readonly shiftKey: boolean;
|
|
70
|
+
readonly metaKey: boolean;
|
|
71
|
+
readonly key: string;
|
|
72
|
+
}
|
|
73
|
+
/** Exact modifier + key match against a keydown event. The mac cmd (meta)
|
|
74
|
+
* modifier is never part of a spelled combo, so any meta press is a miss. */
|
|
75
|
+
export declare function shortcutMatches(combo: ParsedShortcut, event: ShortcutKeyEvent): boolean;
|
|
76
|
+
/** Resolve configured combos to parsed form, dropping malformed entries. */
|
|
77
|
+
export declare function resolveCombos(configured: string | readonly string[] | undefined): ParsedShortcut[];
|
|
78
|
+
/**
|
|
79
|
+
* Client plugin body: one global keydown listener that runs `/plan-build`
|
|
80
|
+
* against the current session. Inert without a current session, during IME
|
|
81
|
+
* composition, and on non-matching combos.
|
|
82
|
+
* @param ctx - client root context.
|
|
83
|
+
* @param config - optional config subset (shortcut combos).
|
|
84
|
+
*/
|
|
85
|
+
export declare function apply(ctx: PlanBuildModeClientContext, config?: PlanBuildModeClientConfig): void;
|
|
86
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,6EAA6E;AAC7E,eAAO,MAAM,gBAAgB,qBAAqB,CAAA;AAElD,0BAA0B;AAC1B,eAAO,MAAM,IAAI,2BAA2B,CAAA;AAE5C;;;GAGG;AACH,eAAO,MAAM,MAAM,oDAAqD,CAAA;AAExE,4DAA4D;AAC5D,MAAM,WAAW,yBAAyB;IACxC,iFAAiF;IACjF,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAA;CAC/C;AAED,qEAAqE;AACrE,MAAM,WAAW,0BAA0B;IACzC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAAA;IAC3C,QAAQ,EAAE;QACR,IAAI,EAAE;YACJ,WAAW,IAAI;gBAAE,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;aAAE,CAAA;SAC/C,CAAA;KACF,CAAA;IACD,MAAM,EAAE;QACN,QAAQ,EAAE;YACR,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC;gBAC5E,EAAE,EAAE,OAAO,CAAA;gBACX,KAAK,CAAC,EAAE;oBAAE,IAAI,EAAE,MAAM,CAAC;oBAAC,OAAO,EAAE,MAAM,CAAA;iBAAE,CAAA;aAC1C,CAAC,CAAA;SACH,CAAA;KACF,CAAA;CACF;AAED,+CAA+C;AAC/C,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CA+B1E;AAED,sEAAsE;AACtE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB;AAED;8EAC8E;AAC9E,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAMvF;AAED,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,GAAG,cAAc,EAAE,CASlG;AAED;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,0BAA0B,EAAE,MAAM,GAAE,yBAA8B,GAAG,IAAI,CAwBnG"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Browser half of `dsh-plan-build-mode`.
|
|
4
|
+
*
|
|
5
|
+
* Adds a global keyboard shortcut that toggles OpenCode Plan / Build mode by
|
|
6
|
+
* executing the host `/plan-build` command against the current session. The
|
|
7
|
+
* bundle is a pure listener: it renders nothing and occupies no Slot seat.
|
|
8
|
+
*
|
|
9
|
+
* The services are consumed through locally declared structural faces rather
|
|
10
|
+
* than cross-plugin imports on purpose — a browser bundle must not compile a
|
|
11
|
+
* require() edge into the loader module table (bundle purity), and these
|
|
12
|
+
* shapes are small and stable. The default combo is kept deliberately complex
|
|
13
|
+
* (three modifiers) so it collides with no terminal or browser built-in.
|
|
14
|
+
*
|
|
15
|
+
* @module dsh-plan-build-mode/client
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.inject = exports.name = exports.DEFAULT_SHORTCUT = void 0;
|
|
19
|
+
exports.parseShortcutCombo = parseShortcutCombo;
|
|
20
|
+
exports.shortcutMatches = shortcutMatches;
|
|
21
|
+
exports.resolveCombos = resolveCombos;
|
|
22
|
+
exports.apply = apply;
|
|
23
|
+
/** Default shortcut; keep in sync with DEFAULT_SHORTCUT in ../helpers.ts. */
|
|
24
|
+
exports.DEFAULT_SHORTCUT = 'ctrl+alt+shift+p';
|
|
25
|
+
/** Client plugin name. */
|
|
26
|
+
exports.name = 'plan-build-mode-client';
|
|
27
|
+
/**
|
|
28
|
+
* Services required at runtime: the commands Remote for `/plan-build` and the
|
|
29
|
+
* session list for the current session id.
|
|
30
|
+
*/
|
|
31
|
+
exports.inject = ['remote', 'remote.commands', 'sessions'];
|
|
32
|
+
/**
|
|
33
|
+
* Parse a `ctrl+alt+shift+p` style combo. Requires at least one of ctrl/alt
|
|
34
|
+
* and exactly one key; returns undefined for malformed or modifier-less
|
|
35
|
+
* combos (mirrors the dsh-tui combo grammar).
|
|
36
|
+
*/
|
|
37
|
+
function parseShortcutCombo(raw) {
|
|
38
|
+
const parts = String(raw ?? '')
|
|
39
|
+
.toLowerCase()
|
|
40
|
+
.split('+')
|
|
41
|
+
.map(part => part.trim())
|
|
42
|
+
.filter(part => part !== '');
|
|
43
|
+
if (parts.length < 2)
|
|
44
|
+
return undefined;
|
|
45
|
+
let ctrl = false;
|
|
46
|
+
let alt = false;
|
|
47
|
+
let shift = false;
|
|
48
|
+
let key;
|
|
49
|
+
for (const part of parts) {
|
|
50
|
+
if (part === 'ctrl' || part === 'control') {
|
|
51
|
+
ctrl = true;
|
|
52
|
+
}
|
|
53
|
+
else if (part === 'alt' || part === 'meta' || part === 'option') {
|
|
54
|
+
alt = true;
|
|
55
|
+
}
|
|
56
|
+
else if (part === 'shift') {
|
|
57
|
+
shift = true;
|
|
58
|
+
}
|
|
59
|
+
else if (part === 'space') {
|
|
60
|
+
if (key !== undefined)
|
|
61
|
+
return undefined;
|
|
62
|
+
key = ' ';
|
|
63
|
+
}
|
|
64
|
+
else if ([...part].length === 1) {
|
|
65
|
+
if (key !== undefined)
|
|
66
|
+
return undefined;
|
|
67
|
+
key = part;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (key === undefined)
|
|
74
|
+
return undefined;
|
|
75
|
+
if (!ctrl && !alt)
|
|
76
|
+
return undefined;
|
|
77
|
+
return { ctrl, alt, shift, key };
|
|
78
|
+
}
|
|
79
|
+
/** Exact modifier + key match against a keydown event. The mac cmd (meta)
|
|
80
|
+
* modifier is never part of a spelled combo, so any meta press is a miss. */
|
|
81
|
+
function shortcutMatches(combo, event) {
|
|
82
|
+
if (event.metaKey)
|
|
83
|
+
return false;
|
|
84
|
+
if (event.ctrlKey !== combo.ctrl)
|
|
85
|
+
return false;
|
|
86
|
+
if (event.altKey !== combo.alt)
|
|
87
|
+
return false;
|
|
88
|
+
if (event.shiftKey !== combo.shift)
|
|
89
|
+
return false;
|
|
90
|
+
return event.key.toLowerCase() === combo.key;
|
|
91
|
+
}
|
|
92
|
+
/** Resolve configured combos to parsed form, dropping malformed entries. */
|
|
93
|
+
function resolveCombos(configured) {
|
|
94
|
+
const raw = configured === undefined
|
|
95
|
+
? [exports.DEFAULT_SHORTCUT]
|
|
96
|
+
: typeof configured === 'string'
|
|
97
|
+
? [configured]
|
|
98
|
+
: [...configured];
|
|
99
|
+
return raw
|
|
100
|
+
.map(parseShortcutCombo)
|
|
101
|
+
.filter((combo) => combo !== undefined);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Client plugin body: one global keydown listener that runs `/plan-build`
|
|
105
|
+
* against the current session. Inert without a current session, during IME
|
|
106
|
+
* composition, and on non-matching combos.
|
|
107
|
+
* @param ctx - client root context.
|
|
108
|
+
* @param config - optional config subset (shortcut combos).
|
|
109
|
+
*/
|
|
110
|
+
function apply(ctx, config = {}) {
|
|
111
|
+
const combos = resolveCombos(config.shortcut);
|
|
112
|
+
if (combos.length === 0)
|
|
113
|
+
return;
|
|
114
|
+
ctx.effect(() => {
|
|
115
|
+
const onKeyDown = (event) => {
|
|
116
|
+
if (event.isComposing)
|
|
117
|
+
return;
|
|
118
|
+
for (const combo of combos) {
|
|
119
|
+
if (!shortcutMatches(combo, event))
|
|
120
|
+
continue;
|
|
121
|
+
const sessionId = ctx.sessions.list.getSnapshot().current;
|
|
122
|
+
if (sessionId === undefined)
|
|
123
|
+
return;
|
|
124
|
+
event.preventDefault();
|
|
125
|
+
void ctx.remote.commands.execute(sessionId, '/plan-build', []).then((result) => {
|
|
126
|
+
if (!result.ok && result.error !== undefined) {
|
|
127
|
+
console.warn(`[plan-build-mode] shortcut failed (${result.error.code}): ${result.error.message}`);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
window.addEventListener('keydown', onKeyDown);
|
|
134
|
+
return () => {
|
|
135
|
+
window.removeEventListener('keydown', onKeyDown);
|
|
136
|
+
};
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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"}
|
package/lib/client.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
window.__ModuleLoader__.load({ id: "@xth26/dsh-plan-build-mode", factory: (require) => {
|
|
2
|
+
var module = { exports: {} }; var exports = module.exports;
|
|
3
|
+
"use strict";
|
|
4
|
+
/**
|
|
5
|
+
* Browser half of `dsh-plan-build-mode`.
|
|
6
|
+
*
|
|
7
|
+
* Adds a global keyboard shortcut that toggles OpenCode Plan / Build mode by
|
|
8
|
+
* executing the host `/plan-build` command against the current session. The
|
|
9
|
+
* bundle is a pure listener: it renders nothing and occupies no Slot seat.
|
|
10
|
+
*
|
|
11
|
+
* The services are consumed through locally declared structural faces rather
|
|
12
|
+
* than cross-plugin imports on purpose — a browser bundle must not compile a
|
|
13
|
+
* require() edge into the loader module table (bundle purity), and these
|
|
14
|
+
* shapes are small and stable. The default combo is kept deliberately complex
|
|
15
|
+
* (three modifiers) so it collides with no terminal or browser built-in.
|
|
16
|
+
*
|
|
17
|
+
* @module dsh-plan-build-mode/client
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.inject = exports.name = exports.DEFAULT_SHORTCUT = void 0;
|
|
21
|
+
exports.parseShortcutCombo = parseShortcutCombo;
|
|
22
|
+
exports.shortcutMatches = shortcutMatches;
|
|
23
|
+
exports.resolveCombos = resolveCombos;
|
|
24
|
+
exports.apply = apply;
|
|
25
|
+
/** Default shortcut; keep in sync with DEFAULT_SHORTCUT in ../helpers.ts. */
|
|
26
|
+
exports.DEFAULT_SHORTCUT = 'ctrl+alt+shift+p';
|
|
27
|
+
/** Client plugin name. */
|
|
28
|
+
exports.name = 'plan-build-mode-client';
|
|
29
|
+
/**
|
|
30
|
+
* Services required at runtime: the commands Remote for `/plan-build` and the
|
|
31
|
+
* session list for the current session id.
|
|
32
|
+
*/
|
|
33
|
+
exports.inject = ['remote', 'remote.commands', 'sessions'];
|
|
34
|
+
/**
|
|
35
|
+
* Parse a `ctrl+alt+shift+p` style combo. Requires at least one of ctrl/alt
|
|
36
|
+
* and exactly one key; returns undefined for malformed or modifier-less
|
|
37
|
+
* combos (mirrors the dsh-tui combo grammar).
|
|
38
|
+
*/
|
|
39
|
+
function parseShortcutCombo(raw) {
|
|
40
|
+
const parts = String(raw ?? '')
|
|
41
|
+
.toLowerCase()
|
|
42
|
+
.split('+')
|
|
43
|
+
.map(part => part.trim())
|
|
44
|
+
.filter(part => part !== '');
|
|
45
|
+
if (parts.length < 2)
|
|
46
|
+
return undefined;
|
|
47
|
+
let ctrl = false;
|
|
48
|
+
let alt = false;
|
|
49
|
+
let shift = false;
|
|
50
|
+
let key;
|
|
51
|
+
for (const part of parts) {
|
|
52
|
+
if (part === 'ctrl' || part === 'control') {
|
|
53
|
+
ctrl = true;
|
|
54
|
+
}
|
|
55
|
+
else if (part === 'alt' || part === 'meta' || part === 'option') {
|
|
56
|
+
alt = true;
|
|
57
|
+
}
|
|
58
|
+
else if (part === 'shift') {
|
|
59
|
+
shift = true;
|
|
60
|
+
}
|
|
61
|
+
else if (part === 'space') {
|
|
62
|
+
if (key !== undefined)
|
|
63
|
+
return undefined;
|
|
64
|
+
key = ' ';
|
|
65
|
+
}
|
|
66
|
+
else if ([...part].length === 1) {
|
|
67
|
+
if (key !== undefined)
|
|
68
|
+
return undefined;
|
|
69
|
+
key = part;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (key === undefined)
|
|
76
|
+
return undefined;
|
|
77
|
+
if (!ctrl && !alt)
|
|
78
|
+
return undefined;
|
|
79
|
+
return { ctrl, alt, shift, key };
|
|
80
|
+
}
|
|
81
|
+
/** Exact modifier + key match against a keydown event. The mac cmd (meta)
|
|
82
|
+
* modifier is never part of a spelled combo, so any meta press is a miss. */
|
|
83
|
+
function shortcutMatches(combo, event) {
|
|
84
|
+
if (event.metaKey)
|
|
85
|
+
return false;
|
|
86
|
+
if (event.ctrlKey !== combo.ctrl)
|
|
87
|
+
return false;
|
|
88
|
+
if (event.altKey !== combo.alt)
|
|
89
|
+
return false;
|
|
90
|
+
if (event.shiftKey !== combo.shift)
|
|
91
|
+
return false;
|
|
92
|
+
return event.key.toLowerCase() === combo.key;
|
|
93
|
+
}
|
|
94
|
+
/** Resolve configured combos to parsed form, dropping malformed entries. */
|
|
95
|
+
function resolveCombos(configured) {
|
|
96
|
+
const raw = configured === undefined
|
|
97
|
+
? [exports.DEFAULT_SHORTCUT]
|
|
98
|
+
: typeof configured === 'string'
|
|
99
|
+
? [configured]
|
|
100
|
+
: [...configured];
|
|
101
|
+
return raw
|
|
102
|
+
.map(parseShortcutCombo)
|
|
103
|
+
.filter((combo) => combo !== undefined);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Client plugin body: one global keydown listener that runs `/plan-build`
|
|
107
|
+
* against the current session. Inert without a current session, during IME
|
|
108
|
+
* composition, and on non-matching combos.
|
|
109
|
+
* @param ctx - client root context.
|
|
110
|
+
* @param config - optional config subset (shortcut combos).
|
|
111
|
+
*/
|
|
112
|
+
function apply(ctx, config = {}) {
|
|
113
|
+
const combos = resolveCombos(config.shortcut);
|
|
114
|
+
if (combos.length === 0)
|
|
115
|
+
return;
|
|
116
|
+
ctx.effect(() => {
|
|
117
|
+
const onKeyDown = (event) => {
|
|
118
|
+
if (event.isComposing)
|
|
119
|
+
return;
|
|
120
|
+
for (const combo of combos) {
|
|
121
|
+
if (!shortcutMatches(combo, event))
|
|
122
|
+
continue;
|
|
123
|
+
const sessionId = ctx.sessions.list.getSnapshot().current;
|
|
124
|
+
if (sessionId === undefined)
|
|
125
|
+
return;
|
|
126
|
+
event.preventDefault();
|
|
127
|
+
void ctx.remote.commands.execute(sessionId, '/plan-build', []).then((result) => {
|
|
128
|
+
if (!result.ok && result.error !== undefined) {
|
|
129
|
+
console.warn(`[plan-build-mode] shortcut failed (${result.error.code}): ${result.error.message}`);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
window.addEventListener('keydown', onKeyDown);
|
|
136
|
+
return () => {
|
|
137
|
+
window.removeEventListener('keydown', onKeyDown);
|
|
138
|
+
};
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
return module.exports; } });
|
package/lib/helpers.d.ts
CHANGED
|
@@ -10,6 +10,15 @@ import type { ToolExecution } from '@deepseek-ai/dsh-tools';
|
|
|
10
10
|
export declare const DEFAULT_PLAN_SANDBOX: SandboxMode;
|
|
11
11
|
/** Default sandbox mode while Build mode is active. */
|
|
12
12
|
export declare const DEFAULT_BUILD_SANDBOX: SandboxMode;
|
|
13
|
+
/**
|
|
14
|
+
* Default keyboard shortcut that toggles Plan/Build mode. Kept deliberately
|
|
15
|
+
* complex (three modifiers) so it collides with no terminal or browser
|
|
16
|
+
* built-in: the TUI reserved set (ctrl+c/d/e/a/u/k/w, ctrl+left/right,
|
|
17
|
+
* ctrl+return, alt+return, alt+up, tab, …) and the built-in actions
|
|
18
|
+
* (ctrl+v/r/g/o/t/a/p/e/l/q, …) are all single-modifier, and no browser or
|
|
19
|
+
* OS binds ctrl+alt+shift+p.
|
|
20
|
+
*/
|
|
21
|
+
export declare const DEFAULT_SHORTCUT = "ctrl+alt+shift+p";
|
|
13
22
|
/** Tools forbidden while in Plan mode. */
|
|
14
23
|
export declare const WRITE_TOOLS: Set<string>;
|
|
15
24
|
/**
|
package/lib/helpers.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAG3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAE3D,sDAAsD;AACtD,eAAO,MAAM,oBAAoB,EAAE,WAAyB,CAAA;AAE5D,uDAAuD;AACvD,eAAO,MAAM,qBAAqB,EAAE,WAA+B,CAAA;AAEnE,0CAA0C;AAC1C,eAAO,MAAM,WAAW,aAA6B,CAAA;AAErD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,WAAW,GAAG,SAAS,CAQ3F;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAEnG;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,GAAG,IAAI,CAGhI;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,aAAa,EACnB,WAAW,EAAE,WAAW,EACxB,UAAU,GAAE,WAAW,CAAC,MAAM,CAAe,GAC5C,MAAM,GAAG,SAAS,CAQpB"}
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAG3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAE3D,sDAAsD;AACtD,eAAO,MAAM,oBAAoB,EAAE,WAAyB,CAAA;AAE5D,uDAAuD;AACvD,eAAO,MAAM,qBAAqB,EAAE,WAA+B,CAAA;AAEnE;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,qBAAqB,CAAA;AAElD,0CAA0C;AAC1C,eAAO,MAAM,WAAW,aAA6B,CAAA;AAErD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,WAAW,GAAG,SAAS,CAQ3F;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAEnG;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,GAAG,IAAI,CAGhI;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,aAAa,EACnB,WAAW,EAAE,WAAW,EACxB,UAAU,GAAE,WAAW,CAAC,MAAM,CAAe,GAC5C,MAAM,GAAG,SAAS,CAQpB"}
|
package/lib/helpers.js
CHANGED
|
@@ -6,6 +6,15 @@
|
|
|
6
6
|
export const DEFAULT_PLAN_SANDBOX = 'read-only';
|
|
7
7
|
/** Default sandbox mode while Build mode is active. */
|
|
8
8
|
export const DEFAULT_BUILD_SANDBOX = 'workspace-write';
|
|
9
|
+
/**
|
|
10
|
+
* Default keyboard shortcut that toggles Plan/Build mode. Kept deliberately
|
|
11
|
+
* complex (three modifiers) so it collides with no terminal or browser
|
|
12
|
+
* built-in: the TUI reserved set (ctrl+c/d/e/a/u/k/w, ctrl+left/right,
|
|
13
|
+
* ctrl+return, alt+return, alt+up, tab, …) and the built-in actions
|
|
14
|
+
* (ctrl+v/r/g/o/t/a/p/e/l/q, …) are all single-modifier, and no browser or
|
|
15
|
+
* OS binds ctrl+alt+shift+p.
|
|
16
|
+
*/
|
|
17
|
+
export const DEFAULT_SHORTCUT = 'ctrl+alt+shift+p';
|
|
9
18
|
/** Tools forbidden while in Plan mode. */
|
|
10
19
|
export const WRITE_TOOLS = new Set(['write', 'edit']);
|
|
11
20
|
/**
|
package/lib/helpers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,sDAAsD;AACtD,MAAM,CAAC,MAAM,oBAAoB,GAAgB,WAAW,CAAA;AAE5D,uDAAuD;AACvD,MAAM,CAAC,MAAM,qBAAqB,GAAgB,iBAAiB,CAAA;AAEnE,0CAA0C;AAC1C,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAA;AAErD;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAA+B;IAChE,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAE,CAAA;QACxB,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YAClC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAA;QACxB,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAA+B,EAAE,WAAwB;IACxF,OAAO,kBAAkB,CAAC,MAAM,CAAC,KAAK,WAAW,CAAA;AACnD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAY,EAAE,IAAsB,EAAE,WAAwB,EAAE,YAAyB;IACxH,MAAM,MAAM,GAAgB,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAA;IACxE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;AACxD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAC5B,IAAmB,EACnB,WAAwB,EACxB,aAAkC,WAAW;IAE7C,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IAC9C,IAAI,WAAW,KAAK,WAAW;QAAE,OAAO,SAAS,CAAA;IACjD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC;QAAE,OAAO,SAAS,CAAA;IAC/E,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,OAAO,SAAS,IAAI,CAAC,IAAI,qHAAqH,CAAA;IAChJ,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC"}
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,sDAAsD;AACtD,MAAM,CAAC,MAAM,oBAAoB,GAAgB,WAAW,CAAA;AAE5D,uDAAuD;AACvD,MAAM,CAAC,MAAM,qBAAqB,GAAgB,iBAAiB,CAAA;AAEnE;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,kBAAkB,CAAA;AAElD,0CAA0C;AAC1C,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAA;AAErD;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAA+B;IAChE,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAE,CAAA;QACxB,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YAClC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAA;QACxB,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAA+B,EAAE,WAAwB;IACxF,OAAO,kBAAkB,CAAC,MAAM,CAAC,KAAK,WAAW,CAAA;AACnD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAY,EAAE,IAAsB,EAAE,WAAwB,EAAE,YAAyB;IACxH,MAAM,MAAM,GAAgB,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAA;IACxE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;AACxD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAC5B,IAAmB,EACnB,WAAwB,EACxB,aAAkC,WAAW;IAE7C,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IAC9C,IAAI,WAAW,KAAK,WAAW;QAAE,OAAO,SAAS,CAAA;IACjD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC;QAAE,OAAO,SAAS,CAAA;IAC/E,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,OAAO,SAAS,IAAI,CAAC,IAAI,qHAAqH,CAAA;IAChJ,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC"}
|
package/lib/index.d.ts
CHANGED
|
@@ -26,13 +26,13 @@ export declare const Config: z<Schemastery.ObjectS<{
|
|
|
26
26
|
buildSandbox: z<"read-only" | "workspace-write" | "danger-full-access", "read-only" | "workspace-write" | "danger-full-access">;
|
|
27
27
|
denyWriteTools: z<boolean, boolean>;
|
|
28
28
|
section: z<boolean, boolean>;
|
|
29
|
-
|
|
29
|
+
shortcut: z<string | string[], string | string[]>;
|
|
30
30
|
}>, Schemastery.ObjectT<{
|
|
31
31
|
planSandbox: z<"read-only" | "workspace-write" | "danger-full-access", "read-only" | "workspace-write" | "danger-full-access">;
|
|
32
32
|
buildSandbox: z<"read-only" | "workspace-write" | "danger-full-access", "read-only" | "workspace-write" | "danger-full-access">;
|
|
33
33
|
denyWriteTools: z<boolean, boolean>;
|
|
34
34
|
section: z<boolean, boolean>;
|
|
35
|
-
|
|
35
|
+
shortcut: z<string | string[], string | string[]>;
|
|
36
36
|
}>>;
|
|
37
37
|
/**
|
|
38
38
|
* Plugin entry point.
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,CAAC,MAAM,0BAA0B,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,CAAC,MAAM,0BAA0B,CAAA;AAoBxC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAErD,0BAA0B;AAC1B,eAAO,MAAM,IAAI,wBAAwB,CAAA;AACzC,8CAA8C;AAC9C,eAAO,MAAM,MAAM,8CAA+C,CAAA;AAclE,4BAA4B;AAC5B,eAAO,MAAM,MAAM;;;;;;;;;;;;GAcjB,CAAA;AAEF;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,GAAE,mBAAwB,GAAG,IAAI,CAkI1E"}
|
package/lib/index.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* @module dsh-plan-build-mode
|
|
15
15
|
*/
|
|
16
16
|
import z from '@deepseek-ai/schemastery';
|
|
17
|
-
import { DEFAULT_BUILD_SANDBOX, DEFAULT_PLAN_SANDBOX, isPlanModeActive, planModeDenial, setPlanBuildMode, WRITE_TOOLS, } from "./helpers.js";
|
|
17
|
+
import { DEFAULT_BUILD_SANDBOX, DEFAULT_PLAN_SANDBOX, DEFAULT_SHORTCUT, isPlanModeActive, planModeDenial, setPlanBuildMode, WRITE_TOOLS, } from "./helpers.js";
|
|
18
18
|
/** Cordis plugin name. */
|
|
19
19
|
export const name = 'dsh-plan-build-mode';
|
|
20
20
|
/** Service dependencies for the host half. */
|
|
@@ -33,7 +33,7 @@ export const Config = z.object({
|
|
|
33
33
|
]).required(false),
|
|
34
34
|
denyWriteTools: z.boolean().default(true),
|
|
35
35
|
section: z.boolean().default(true),
|
|
36
|
-
|
|
36
|
+
shortcut: z.union([z.string(), z.array(z.string())]).required(false),
|
|
37
37
|
});
|
|
38
38
|
/**
|
|
39
39
|
* Plugin entry point.
|
|
@@ -48,7 +48,6 @@ export function apply(ctx, config = {}) {
|
|
|
48
48
|
}
|
|
49
49
|
const denyWriteTools = config.denyWriteTools !== false;
|
|
50
50
|
const enableSection = config.section !== false;
|
|
51
|
-
const tuiShortcut = config.tuiShortcut ?? 'ctrl+shift+b';
|
|
52
51
|
ctx.effect(() => {
|
|
53
52
|
const disposers = [];
|
|
54
53
|
// Align existing sessions on load (resumed sessions may already have
|
|
@@ -127,35 +126,39 @@ export function apply(ctx, config = {}) {
|
|
|
127
126
|
return { kind: 'success', text: `Switched to ${target} mode.` };
|
|
128
127
|
},
|
|
129
128
|
}));
|
|
129
|
+
// dsh-tui keyboard shortcut: toggles through the same /plan-build
|
|
130
|
+
// command, so state, lifecycle events and grants stay single-source.
|
|
131
|
+
// Waits on ctx.tuiShortcuts (the dsh-tui-extensions row); inert in web
|
|
132
|
+
// and headless compositions where that service never mounts. The child
|
|
133
|
+
// fiber is cleaned up with the commands scope (same pattern as the
|
|
134
|
+
// outer ctx.inject).
|
|
135
|
+
commandCtx.inject(['tuiShortcuts'], (tuiCtx) => {
|
|
136
|
+
const tuiShortcuts = tuiCtx.get('tuiShortcuts');
|
|
137
|
+
if (tuiShortcuts === undefined)
|
|
138
|
+
return;
|
|
139
|
+
const combos = config.shortcut === undefined
|
|
140
|
+
? [DEFAULT_SHORTCUT]
|
|
141
|
+
: typeof config.shortcut === 'string'
|
|
142
|
+
? [config.shortcut]
|
|
143
|
+
: [...config.shortcut];
|
|
144
|
+
for (const combo of combos) {
|
|
145
|
+
disposers.push(tuiShortcuts.register(combo, {
|
|
146
|
+
description: 'Toggle between OpenCode Plan and Build modes',
|
|
147
|
+
handler: async () => {
|
|
148
|
+
const agent = ctx.agents.list()[0];
|
|
149
|
+
if (agent === undefined)
|
|
150
|
+
return;
|
|
151
|
+
try {
|
|
152
|
+
await commandCtx.commands.execute(agent, '/plan-build', [], new AbortController().signal);
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
ctx.logger.warn('dsh-plan-build-mode: TUI shortcut /plan-build failed: %o', error);
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
}, ctx));
|
|
159
|
+
}
|
|
160
|
+
});
|
|
130
161
|
});
|
|
131
|
-
// TUI-only keyboard shortcut that toggles Plan/Build mode. It is ignored
|
|
132
|
-
// by `dsh web`; it only registers when dsh-tui's shortcut registry is
|
|
133
|
-
// composed, and it skips registration when the configured combo is blank.
|
|
134
|
-
if (tuiShortcut.trim() !== '') {
|
|
135
|
-
const tuiShortcuts = ctx.get('tuiShortcuts');
|
|
136
|
-
if (tuiShortcuts !== undefined) {
|
|
137
|
-
const disposeShortcut = tuiShortcuts.register(tuiShortcut, {
|
|
138
|
-
description: 'Toggle OpenCode Plan/Build mode',
|
|
139
|
-
handler() {
|
|
140
|
-
const agent = ctx.agents.currentInitiator();
|
|
141
|
-
if (agent === undefined)
|
|
142
|
-
return;
|
|
143
|
-
const active = isPlanModeActive(agent.session.events, planSandbox);
|
|
144
|
-
const next = active ? 'build' : 'plan';
|
|
145
|
-
setPlanBuildMode(agent, next, planSandbox, buildSandbox);
|
|
146
|
-
// Best-effort echo the same confirmation the slash command shows.
|
|
147
|
-
const commands = ctx.get('commands');
|
|
148
|
-
if (commands !== undefined) {
|
|
149
|
-
const signal = new AbortController().signal;
|
|
150
|
-
Promise.resolve()
|
|
151
|
-
.then(() => commands.execute(agent, '/plan-build status', [], signal))
|
|
152
|
-
.catch(() => { });
|
|
153
|
-
}
|
|
154
|
-
},
|
|
155
|
-
}, ctx);
|
|
156
|
-
disposers.push(disposeShortcut);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
162
|
return () => {
|
|
160
163
|
for (const dispose of disposers)
|
|
161
164
|
dispose();
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,CAAC,MAAM,0BAA0B,CAAA;AAWxC,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,WAAW,GACZ,MAAM,cAAc,CAAA;AAGrB,0BAA0B;AAC1B,MAAM,CAAC,MAAM,IAAI,GAAG,qBAAqB,CAAA;AACzC,8CAA8C;AAC9C,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,cAAc,CAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/lib/types.d.ts
CHANGED
|
@@ -30,12 +30,12 @@ export interface PlanBuildModeConfig {
|
|
|
30
30
|
*/
|
|
31
31
|
section?: boolean;
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* `alt
|
|
37
|
-
* @default 'ctrl+shift+
|
|
33
|
+
* Keyboard shortcut(s) that toggle between Plan and Build modes in clients
|
|
34
|
+
* exposing a shortcut seam. dsh-tui binds them through `ctx.tuiShortcuts`;
|
|
35
|
+
* the web client binds the same combos through its global keydown listener.
|
|
36
|
+
* Combos use the `ctrl+alt+shift+p` grammar (ctrl or alt required).
|
|
37
|
+
* @default ['ctrl+alt+shift+p']
|
|
38
38
|
*/
|
|
39
|
-
|
|
39
|
+
shortcut?: string | readonly string[];
|
|
40
40
|
}
|
|
41
41
|
//# sourceMappingURL=types.d.ts.map
|
package/lib/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAE3D,OAAO,QAAQ,gCAAgC,CAAC;CAG/C;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB;;;OAGG;IACH,YAAY,CAAC,EAAE,WAAW,CAAA;IAC1B;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;;;OAMG;IACH,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAE3D,OAAO,QAAQ,gCAAgC,CAAC;CAG/C;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB;;;OAGG;IACH,YAAY,CAAC,EAAE,WAAW,CAAA;IAC1B;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAA;CACtC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xth26/dsh-plan-build-mode",
|
|
3
3
|
"description": "OpenCode-style Plan / Build hard permission model for DSH",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.0",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -17,6 +17,10 @@
|
|
|
17
17
|
"types": "./lib/types/invariant.d.ts",
|
|
18
18
|
"default": "./lib/invariant.js"
|
|
19
19
|
},
|
|
20
|
+
"./client": {
|
|
21
|
+
"types": "./lib/client/index.d.ts",
|
|
22
|
+
"default": "./lib/client.js"
|
|
23
|
+
},
|
|
20
24
|
"./src/*": "./src/*",
|
|
21
25
|
"./package.json": "./package.json"
|
|
22
26
|
},
|
|
@@ -30,6 +34,12 @@
|
|
|
30
34
|
"dsh": {
|
|
31
35
|
"bundle": {
|
|
32
36
|
"patch": "./cordis.patch.yml"
|
|
37
|
+
},
|
|
38
|
+
"client": {
|
|
39
|
+
"inject": [
|
|
40
|
+
"@deepseek-ai/dsh-api-remotes"
|
|
41
|
+
],
|
|
42
|
+
"platform": "web"
|
|
33
43
|
}
|
|
34
44
|
},
|
|
35
45
|
"license": "MIT",
|
|
@@ -93,7 +103,7 @@
|
|
|
93
103
|
"vitest": "^2.1.0"
|
|
94
104
|
},
|
|
95
105
|
"scripts": {
|
|
96
|
-
"build": "tsc -b tsconfig.json",
|
|
106
|
+
"build": "tsc -b tsconfig.json && tsc -b tsconfig.client.json && node scripts/build-client-bundle.mjs",
|
|
97
107
|
"test": "vitest run",
|
|
98
108
|
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
99
109
|
}
|