dsh-super-code 0.3.7 → 0.3.9
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.en.md +144 -0
- package/README.md +89 -180
- package/client/index.js +1022 -181
- package/cordis.patch.yml +1 -1
- package/docs/Acknowledgements.md +38 -67
- package/docs/Changelog.md +160 -79
- package/docs/Compatibility.md +98 -248
- package/docs/EvaluationResults.md +165 -155
- package/docs/UsageGuide.md +210 -172
- package/docs/en/Acknowledgements.md +76 -0
- package/docs/en/Changelog.md +160 -0
- package/docs/en/Compatibility.md +146 -0
- package/docs/en/EvaluationResults.md +224 -0
- package/docs/en/UsageGuide.md +304 -0
- package/docs/images/agent-tree-preview.png +0 -0
- package/docs/images/agent-tree.png +0 -0
- package/docs/images/install-tgz-preview.png +0 -0
- package/docs/images/install-tgz.png +0 -0
- package/docs/images/preset-settings-preview.png +0 -0
- package/docs/images/preset-settings.png +0 -0
- package/docs/images/task-status-preview.png +0 -0
- package/docs/images/task-status.png +0 -0
- package/lib/connection/approvals.d.ts +21 -0
- package/lib/connection/approvals.d.ts.map +1 -0
- package/lib/connection/approvals.js +83 -0
- package/lib/connection/approvals.js.map +1 -0
- package/lib/connection/client.d.ts +8 -0
- package/lib/connection/client.d.ts.map +1 -0
- package/lib/connection/client.js +34 -0
- package/lib/connection/client.js.map +1 -0
- package/lib/connection/directories.d.ts +30 -0
- package/lib/connection/directories.d.ts.map +1 -0
- package/lib/connection/directories.js +82 -0
- package/lib/connection/directories.js.map +1 -0
- package/lib/connection/git.d.ts +5 -0
- package/lib/connection/git.d.ts.map +1 -0
- package/lib/connection/git.js +86 -0
- package/lib/connection/git.js.map +1 -0
- package/lib/connection/guidance.d.ts +10 -0
- package/lib/connection/guidance.d.ts.map +1 -0
- package/lib/connection/guidance.js +27 -0
- package/lib/connection/guidance.js.map +1 -0
- package/lib/connection/http.d.ts +38 -0
- package/lib/connection/http.d.ts.map +1 -0
- package/lib/connection/http.js +342 -0
- package/lib/connection/http.js.map +1 -0
- package/lib/connection/service.d.ts +59 -0
- package/lib/connection/service.d.ts.map +1 -0
- package/lib/connection/service.js +176 -0
- package/lib/connection/service.js.map +1 -0
- package/lib/connection/store.d.ts +21 -0
- package/lib/connection/store.d.ts.map +1 -0
- package/lib/connection/store.js +141 -0
- package/lib/connection/store.js.map +1 -0
- package/lib/connection/tasks.d.ts +124 -0
- package/lib/connection/tasks.d.ts.map +1 -0
- package/lib/connection/tasks.js +393 -0
- package/lib/connection/tasks.js.map +1 -0
- package/lib/connection/types.d.ts +159 -0
- package/lib/connection/types.d.ts.map +1 -0
- package/lib/connection/types.js +23 -0
- package/lib/connection/types.js.map +1 -0
- package/lib/connection-cli.d.ts +3 -0
- package/lib/connection-cli.d.ts.map +1 -0
- package/lib/connection-cli.js +40 -0
- package/lib/connection-cli.js.map +1 -0
- package/lib/dsh/connection-approval.d.ts +5 -0
- package/lib/dsh/connection-approval.d.ts.map +1 -0
- package/lib/dsh/connection-approval.js +72 -0
- package/lib/dsh/connection-approval.js.map +1 -0
- package/lib/dsh/connection-history.d.ts +6 -0
- package/lib/dsh/connection-history.d.ts.map +1 -0
- package/lib/dsh/connection-history.js +52 -0
- package/lib/dsh/connection-history.js.map +1 -0
- package/lib/dsh/connection-host.d.ts +114 -0
- package/lib/dsh/connection-host.d.ts.map +1 -0
- package/lib/dsh/connection-host.js +208 -0
- package/lib/dsh/connection-host.js.map +1 -0
- package/lib/dsh/connection.d.ts +72 -0
- package/lib/dsh/connection.d.ts.map +1 -0
- package/lib/dsh/connection.js +186 -0
- package/lib/dsh/connection.js.map +1 -0
- package/lib/dsh/index.d.ts.map +1 -1
- package/lib/dsh/index.js +2 -0
- package/lib/dsh/index.js.map +1 -1
- package/package.json +14 -6
- package/presets/super-code/agent.cordis.yml +1 -1
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
# Usage Guide
|
|
2
|
+
|
|
3
|
+
[中文](../UsageGuide.md) · English
|
|
4
|
+
|
|
5
|
+
New here? Read the Install and Use sections of the [README](../../README.en.md) first. This page covers the details.
|
|
6
|
+
|
|
7
|
+
- [Model](#model)
|
|
8
|
+
- [Can't find the preset](#cant-find-the-preset)
|
|
9
|
+
- [Settings](#settings)
|
|
10
|
+
- [Preset version and reinstall](#preset-version-and-reinstall)
|
|
11
|
+
- [Sidebar](#sidebar)
|
|
12
|
+
- [Batched tool calls](#batched-tool-calls)
|
|
13
|
+
- [Runtime budgets](#runtime-budgets)
|
|
14
|
+
- [Deletion protection](#deletion-protection)
|
|
15
|
+
- [MCP connection](#mcp-connection)
|
|
16
|
+
- [Frontend Skill](#frontend-skill)
|
|
17
|
+
|
|
18
|
+
## Model
|
|
19
|
+
|
|
20
|
+
The plugin has no model settings of its own. If you already have a working model, just use it. Otherwise add a provider under Harness **Settings → Models**, then pick a model and reasoning effort below the message input.
|
|
21
|
+
|
|
22
|
+
Child Agents use the parent's model by default. Harness manages permissions and tools.
|
|
23
|
+
|
|
24
|
+
## Can't find the preset
|
|
25
|
+
|
|
26
|
+
First make sure the plugin is enabled, then check your host version against [Compatibility](Compatibility.md). Then:
|
|
27
|
+
|
|
28
|
+
**Harness 0.1.7 and later (declarative presets)**: the plugin declares the preset and the host loads it. Go to **Settings → Super Code** and click **Install preset**. If the host doesn't expose management APIs, the page says so.
|
|
29
|
+
|
|
30
|
+
**Harness 0.1.5 / 0.1.6 (directory presets)**: the plugin installs a user copy on first load. If it's missing, install it manually from **Settings → Super Code**.
|
|
31
|
+
|
|
32
|
+
- If the default identifier `super-code` is taken, pick another one. Existing presets are never overwritten.
|
|
33
|
+
- If you delete this copy yourself, a restart won't bring it back. Install it again manually.
|
|
34
|
+
|
|
35
|
+
Before plugin 0.2.0, the settings page lives under **Plugins → Plugin configuration**.
|
|
36
|
+
|
|
37
|
+
## Settings
|
|
38
|
+
|
|
39
|
+
**Settings → Super Code** has five tabs:
|
|
40
|
+
|
|
41
|
+
| Tab | Contents |
|
|
42
|
+
|---|---|
|
|
43
|
+
| Home | Preset status and versions, deletion-protection level, MCP switch, connected/past conversation counts |
|
|
44
|
+
| Preset configuration | Install, reinstall, rename |
|
|
45
|
+
| Context settings | [Runtime budgets](#runtime-budgets) |
|
|
46
|
+
| Deletion protection | [Deletion protection](#deletion-protection) |
|
|
47
|
+
| Connection | [MCP connection](#mcp-connection) |
|
|
48
|
+
|
|
49
|
+
Switching tabs keeps unsaved input.
|
|
50
|
+
|
|
51
|
+
### Names and language
|
|
52
|
+
|
|
53
|
+
- The identifier selects the preset; the display name can be changed separately. Chinese characters and spaces are fine, up to 120 characters.
|
|
54
|
+
- Default names and descriptions follow Harness's Chinese/English setting. Fields you've edited are left alone.
|
|
55
|
+
- Changing the language only updates display fields, not preset content or version.
|
|
56
|
+
- Older Harness versions cache the preset list, so the page reloads once when the wording changes.
|
|
57
|
+
- Preset files on one host share one language; different clients can't show different languages at the same time.
|
|
58
|
+
- A read-only install directory or YAML the plugin can't safely parse may block syncing. Refresh and retry from Settings.
|
|
59
|
+
|
|
60
|
+
## Preset version and reinstall
|
|
61
|
+
|
|
62
|
+
Settings shows the **plugin version** and the **preset version** separately.
|
|
63
|
+
|
|
64
|
+
- Same version: the preset matches the installed plugin. It doesn't mean there's no newer release on npm.
|
|
65
|
+
- Old preset without a version: shows "Version not recorded" and isn't treated as current.
|
|
66
|
+
- Updating the plugin doesn't update an installed preset. To get the new preset, reinstall.
|
|
67
|
+
|
|
68
|
+
**Reinstall**: click **Reinstall preset** → the dialog lists the presets to be replaced plus the new name and identifier → check and confirm.
|
|
69
|
+
|
|
70
|
+
- You can remove entries, but not confirm an empty list. Cancel or Esc changes nothing.
|
|
71
|
+
- Reinstalling overwrites the old preset. Save your customizations first.
|
|
72
|
+
- Existing sessions keep the old preset; new sessions use the new one.
|
|
73
|
+
|
|
74
|
+
**Safety**:
|
|
75
|
+
|
|
76
|
+
- Only presets verifiably installed by this plugin are replaced (directory: install record, UUID, path, directory identity; declarative: source marker or install record). Unmarked old copies and same-name declarations are left alone.
|
|
77
|
+
- The old content is backed up in `.super-code-backup-*`: under the user preset root for directory hosts, under the current profile for declarative hosts (ownership records in `.super-code-presets.json`).
|
|
78
|
+
- A failed install restores automatically. After an unexpected crash, restore manually from the backup.
|
|
79
|
+
|
|
80
|
+
## Sidebar
|
|
81
|
+
|
|
82
|
+
In the right sidebar choose **Super Code**. Three sections, at most one open at a time, Tasks by default. Click the open heading to collapse all sections. Switching keeps reading position, filters, and drafts. The UI follows Harness's Chinese/English setting.
|
|
83
|
+
|
|
84
|
+
### Tasks
|
|
85
|
+
|
|
86
|
+
Read-only. Shows what's already recorded in the session:
|
|
87
|
+
|
|
88
|
+
- **Goal**: the recorded task goal, or the user's original message if there is none.
|
|
89
|
+
- **Steps**: todos the model wrote down, shown as done/total. No steps means no invented plan or progress.
|
|
90
|
+
- **Tool calls**: success, failure, and running counts grouped by tool.
|
|
91
|
+
- **Files**: successful file changes that can be confirmed from tool arguments or diffs, including nested PTC calls.
|
|
92
|
+
|
|
93
|
+
Notes:
|
|
94
|
+
|
|
95
|
+
- A stopped run doesn't mean the task is done.
|
|
96
|
+
- The file list isn't a full Git diff: indirect changes from the terminal or external scripts may be missing, and a past change doesn't mean the file still differs. Failed, pending, read-only, and inherited child-Agent operations don't count.
|
|
97
|
+
- Everything is expanded in a virtual list, so long histories stay smooth. There is a display limit; you'll see a notice when it's hit, and full content is in the details.
|
|
98
|
+
- It doesn't change prompts, model requests, or tool definitions, and writes nothing into model context.
|
|
99
|
+
|
|
100
|
+
### Agent execution
|
|
101
|
+
|
|
102
|
+
The Agent tree, with status, usage, and cache rate for each Agent.
|
|
103
|
+
|
|
104
|
+
- Drag empty space to pan; zoom with the wheel or buttons.
|
|
105
|
+
- Click a node to open its details in a new sidebar tab. The main conversation stays put.
|
|
106
|
+
- Details are shown as a chat: user task, Agent replies, expandable tool calls and results. The header shows status, tokens, and cache; open **Details** for more usage, task records, and memory activity.
|
|
107
|
+
- Running animations respect the system's reduced-motion setting.
|
|
108
|
+
|
|
109
|
+
The [task](../images/task-status.png) and [tree screenshots](../images/agent-tree.png) render the current plugin with official frontend components and sample data. They illustrate the UI, not model quality.
|
|
110
|
+
|
|
111
|
+
### Memory library
|
|
112
|
+
|
|
113
|
+
Pick **This project** or **Global preferences**, then browse by topic or search (topic, summary, identifier). Click an entry for details and source. You can add, edit, and delete (with confirmation). Manually edited entries are marked as manual, with current content only and no version history.
|
|
114
|
+
|
|
115
|
+
Memory has three layers:
|
|
116
|
+
|
|
117
|
+
| Layer | What it keeps | Scope |
|
|
118
|
+
|---|---|---|
|
|
119
|
+
| Task state | Current goal, constraints, progress, checks | Current conversation |
|
|
120
|
+
| Project memory | Sourced project facts, lessons, agreements | Same workspace path, by topic |
|
|
121
|
+
| Global preferences | Preferences you explicitly want across projects | Same Harness storage root |
|
|
122
|
+
|
|
123
|
+
- To keep an agreement long-term, just tell the Agent. It's saved when the tool reports success and it shows up in the library.
|
|
124
|
+
- Project memory saved by an Agent must link to a real tool result; global preferences need your own words and a clear cross-project intent.
|
|
125
|
+
- Projects at different paths, including Git worktrees, don't share project memory.
|
|
126
|
+
- Memory lives in local host storage, not in project files, and the whole library is never sent to the model. At most 4 summaries from the current topic (≤2 KiB) and 4 from global preferences (≤1 KiB) are included automatically; details require an explicit read.
|
|
127
|
+
- Memory can't override the current request, grant permissions, or prove code is unchanged since it was recorded.
|
|
128
|
+
- You can browse memory from past sessions without resuming an Agent or calling the model.
|
|
129
|
+
|
|
130
|
+
### Which memory each Agent used
|
|
131
|
+
|
|
132
|
+
Click a node in the tree → open **Details** → expand **Memory activity**. It distinguishes context inclusion, summary reads, detail reads, saves, and deletions. Click a record to jump to that entry in the library.
|
|
133
|
+
|
|
134
|
+
- These are actions recorded by the host, not proof that the model understood or followed them.
|
|
135
|
+
- History a child Agent inherits from its parent doesn't count as its own read; failed calls don't count as reads.
|
|
136
|
+
- Up to the latest 100 are shown; the full record is in the session log.
|
|
137
|
+
- If an entry is later edited or deleted, the record stays, but the library only shows current content.
|
|
138
|
+
|
|
139
|
+
## Batched tool calls
|
|
140
|
+
|
|
141
|
+
Super Code uses Harness-native PTC: one model call can combine several tool operations, such as reading a few unrelated files at once, then decide what to do next. No separate mode needed.
|
|
142
|
+
|
|
143
|
+
- Independent reads run in parallel; writes, tests, state changes, and dependent steps run in order.
|
|
144
|
+
- On partial failure, successful results are kept and only failed or stale reads are retried.
|
|
145
|
+
- The plugin declares which of its task and memory actions can run in parallel; unknown actions run alone. Other tools follow their own Harness declarations.
|
|
146
|
+
- The host handles permissions, cancellation, and result storage.
|
|
147
|
+
|
|
148
|
+
Batching cuts round trips between the model and tools. It doesn't make every operation faster.
|
|
149
|
+
|
|
150
|
+
## Runtime budgets
|
|
151
|
+
|
|
152
|
+
Under the **Context settings** tab. The plugin already uses the better-performing legacy budgets, so you usually don't need to touch this. Values in parentheses are the host's own defaults, for comparison.
|
|
153
|
+
|
|
154
|
+
| Type | Includes | Applies to |
|
|
155
|
+
|---|---|---|
|
|
156
|
+
| Common budgets | Compression ratios, summary cap, PTC deadlines, retries | Super Code by default; also Standard, PTC, Minimal, and Create when "Also apply to official presets" is on |
|
|
157
|
+
| Super Code only | Active task record limit, task-memory capacity | Super Code only |
|
|
158
|
+
|
|
159
|
+
- "Also apply to official presets" is off by default. It only changes budgets, not official tools or prompts, and never touches custom presets.
|
|
160
|
+
- Saved changes apply to new Agents. Running Agents keep their settings and aren't restarted.
|
|
161
|
+
- Leave a field blank to use the plugin default; **Reset to defaults** clears UI overrides.
|
|
162
|
+
- A failed save keeps your input. If it says budgets were changed elsewhere, reload first.
|
|
163
|
+
- On older hosts without `ptcRuntime`, PTC deadline fields are disabled; other budgets still work.
|
|
164
|
+
|
|
165
|
+
Plugin defaults (no need to add them to your config; only write the fields you want to change):
|
|
166
|
+
|
|
167
|
+
```yaml
|
|
168
|
+
budgets:
|
|
169
|
+
pressureBasis: window # use the full context window; "host" follows the host policy
|
|
170
|
+
thresholdRatio: 0.8 # start compressing at 80%
|
|
171
|
+
retainRatio: 0.16 # keep the latest 16% verbatim; must be below thresholdRatio
|
|
172
|
+
summaryMaxTokens: 8192 # summary cap
|
|
173
|
+
compactionRetries: 1 # extra compression attempts
|
|
174
|
+
maxOverflowRetries: 1 # overflow retries
|
|
175
|
+
ptcTimeoutMs: 600000 # default PTC deadline (ms, including tool waits)
|
|
176
|
+
ptcMaxTimeoutMs: 600000 # PTC deadline cap, never above the host cap
|
|
177
|
+
applyToOfficialPresets: false
|
|
178
|
+
maxTasks: 32 # Super Code: active task records
|
|
179
|
+
maxContextBytes: 32768 # Super Code: task-memory context bytes
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
- A shorter deadline set explicitly on a call still applies.
|
|
183
|
+
- Older hosts time PTC by busy CPU time; newer hosts by elapsed time. The two aren't comparable.
|
|
184
|
+
- Raising `maxTasks` or `maxContextBytes` uses more context. The defaults are usually fine.
|
|
185
|
+
|
|
186
|
+
## Deletion protection
|
|
187
|
+
|
|
188
|
+
Under the **Deletion protection** tab. Default is **Relaxed**.
|
|
189
|
+
|
|
190
|
+
| Mode | Behavior |
|
|
191
|
+
|---|---|
|
|
192
|
+
| Off | No instructions, no blocking |
|
|
193
|
+
| Relaxed (default) | Tells Agents to delete with recoverable `trash`, in scripts too. If you explicitly ask for `rm`, it's used without extra plugin confirmation |
|
|
194
|
+
| Strict | No direct `rm`, even in scripts. Recognized permanent deletions need your approval each time, and only temp-file or build-artifact cleanup is allowed |
|
|
195
|
+
|
|
196
|
+
The exact Relaxed instruction: **Delete files or directories with `trash <path>` (recoverable) by default; use `rm` only for temp files or build artifacts after I've confirmed.**
|
|
197
|
+
|
|
198
|
+
- Only Super Code is protected by default. "Also apply to official presets" is off by default (independent of the budget switch with the same name).
|
|
199
|
+
- Saved changes apply to later commands.
|
|
200
|
+
- Legacy `true` means Strict, `false` means Off.
|
|
201
|
+
|
|
202
|
+
Strict mode checks terminal commands before they run for `rm`, common wrappers, inline shell scripts, and PowerShell deletion commands such as `Remove-Item`, including terminal calls inside PTC.
|
|
203
|
+
|
|
204
|
+
- Only a one-time host approval that you accept lets it through; rejection, cancellation, and errors all block. Each approval covers that one call.
|
|
205
|
+
- If `trash` isn't available, the Agent should use another recoverable method or stop.
|
|
206
|
+
- It isn't an OS sandbox: it doesn't inspect external script files, obfuscated programs, or every language's delete API. Use the host sandbox for process-level isolation.
|
|
207
|
+
|
|
208
|
+
Relaxed mode relies on instructions only and blocks nothing. Host permission checks still apply.
|
|
209
|
+
|
|
210
|
+
## MCP connection
|
|
211
|
+
|
|
212
|
+
Lets external MCP clients (such as other AI coding tools) hand tasks to DSH. Off by default, listens on `127.0.0.1` only, uses Streamable HTTP with token auth.
|
|
213
|
+
|
|
214
|
+
### Turn it on
|
|
215
|
+
|
|
216
|
+
Under the **Connection** tab:
|
|
217
|
+
|
|
218
|
+
1. Check the working directories to allow (subdirectories included).
|
|
219
|
+
2. Adjust the port and maximum connections if needed.
|
|
220
|
+
3. Turn the switch on. Changes save automatically.
|
|
221
|
+
|
|
222
|
+
**Allow MCP to create conversations** is on by default. Turning it off requires explicit reuse. New conversations join the existing workspace; an unregistered directory gets a workspace with the same name and no suffix. New titles start with `[MCP]`.
|
|
223
|
+
|
|
224
|
+
**Allow caller approval** is off by default. When enabled, an exact one-time tool approval for a delegated task can be sent to the caller through an interactive form or `dsh_approve`. Host policy remains authoritative, and directory consent always stays in DSH.
|
|
225
|
+
|
|
226
|
+
Directories:
|
|
227
|
+
|
|
228
|
+
- The DSH workspace list is reread every time you open the tab. On first setup, existing workspaces are preselected; workspaces added later are **not** granted access automatically.
|
|
229
|
+
- Add directories with the directory picker. Uncheck to revoke; unchecking the last one also turns MCP off.
|
|
230
|
+
|
|
231
|
+
Connections:
|
|
232
|
+
|
|
233
|
+
- Maximum connections defaults to 3, up to 32, and is also the task concurrency limit.
|
|
234
|
+
- Disconnect clients from the Connection tab; idle connections drop after 10 minutes. Disconnecting doesn't cancel accepted tasks.
|
|
235
|
+
- "Connected conversations" on Home means the linked MCP connection is still online, regardless of whether the task finished. After disconnect they count as past conversations.
|
|
236
|
+
|
|
237
|
+
Port conflicts are reported directly. Use the URL shown on the page.
|
|
238
|
+
|
|
239
|
+
### Configure the client
|
|
240
|
+
|
|
241
|
+
1. Copy **Connection Prompt** from the Connection tab and give it to a client that supports Streamable HTTP MCP. It includes the URL, auth method, and tool notes, but **not** the real token.
|
|
242
|
+
2. Copy the token separately and configure it in the client as `Authorization: Bearer <token>`. Don't put the token in a repository or a shared prompt.
|
|
243
|
+
3. Keep DSH running. Rotating the token invalidates the old one immediately; update the client.
|
|
244
|
+
|
|
245
|
+
Whether a client can set up MCP from the prompt by itself depends on the client. You can also enter the URL and auth manually. The token is shown by default on the Connection tab and hidden when you leave.
|
|
246
|
+
|
|
247
|
+
### Tools
|
|
248
|
+
|
|
249
|
+
| Tool | Purpose |
|
|
250
|
+
|---|---|
|
|
251
|
+
| `dsh_status` | Inspect directories, policies, capacity, blocking tasks, and recovery guidance |
|
|
252
|
+
| `dsh_models` | List exact model/effort IDs for `dsh_run` and `dsh_send`; omission retains the current/default selection |
|
|
253
|
+
| `dsh_read` | Page through owned conversations and managed children, including public messages, tool results, and failure details; excludes reasoning and private configuration |
|
|
254
|
+
| `dsh_approve` | Approve or reject one exact pending operation only when caller approval is enabled |
|
|
255
|
+
| `dsh_sessions` | Call first after connecting: lists recent conversations per directory with status, whether they can be reused, connection capacity, and task concurrency |
|
|
256
|
+
| `dsh_run` | Start a task. Pass `taskId` to reuse a specific conversation, or `newConversation: true` for a new one (passing neither also creates new). It **never** picks the latest conversation on its own. Same `requestId` + same input won't dispatch twice; different input is a conflict |
|
|
257
|
+
| `dsh_wait` | Read task status, output, workspace changes, and new events, waiting up to 30 seconds. Without a task ID, lists all tasks page by page |
|
|
258
|
+
| `dsh_send` | Add a follow-up or continue in the same conversation, with a new `requestId`. Never approves permissions for you |
|
|
259
|
+
| `dsh_request_directory` | Ask for a new working directory; you approve it in DSH |
|
|
260
|
+
| `dsh_cancel` | Request cancellation of the conversation and its child tasks. Keep checking status to confirm it actually stopped |
|
|
261
|
+
|
|
262
|
+
### Requesting a new directory
|
|
263
|
+
|
|
264
|
+
The client calls `dsh_request_directory` with a `requestId`, an existing absolute `path`, and a `reason`. DSH shows a global dialog (Settings doesn't need to be open) with the client name, directory, and reason.
|
|
265
|
+
|
|
266
|
+
- Access is granted only when you click **Allow access**. A model's auto-approval can't do it for you.
|
|
267
|
+
- Repeat the same call to check status: `pending` / `approved` / `rejected` / `expired`.
|
|
268
|
+
- Tasks can't run in that directory until it's approved.
|
|
269
|
+
- At most 8 pending requests, expiring after 5 minutes. Rejection, stopping the service, or restarting never grants access.
|
|
270
|
+
- Client name and reason are filled in by the client; treat them as hints only.
|
|
271
|
+
|
|
272
|
+
### Task status and recovery
|
|
273
|
+
|
|
274
|
+
- Tasks use the conversation's current or explicitly selected model, the Super Code preset, and your permissions. Model/effort choices persist in that conversation. Permissions are never auto-approved.
|
|
275
|
+
- The client's sandbox doesn't carry over to DSH. Allowed directories only control where tasks can start; they aren't a file sandbox.
|
|
276
|
+
- Tasks in the same workspace don't run in parallel. For parallel work, prepare separate worktrees yourself; the plugin doesn't create, delete, or merge worktrees.
|
|
277
|
+
- `waiting_confirmation`: the caller can decide only when caller approval is enabled and an exact pending request exists; otherwise the user handles it in DSH.
|
|
278
|
+
- `finished`: execution ended, but `acceptance` is always `not-verified`. The caller must check the result.
|
|
279
|
+
- Returned file info is an observation of the Git workspace, including changes that existed before the task, so it doesn't prove the task made them. Non-Git directories or exceeded limits are marked unavailable.
|
|
280
|
+
- Wait timeouts and client disconnects don't cancel tasks. Turning off the connection just stops new requests.
|
|
281
|
+
- After a restart, prompts are never resent automatically. Find the ID via `dsh_sessions` or the task list, check the state, then continue explicitly. If the state can't be confirmed, it shows `interrupted` or `unavailable`; tasks not confirmed as stopped keep their concurrency slot.
|
|
282
|
+
|
|
283
|
+
On capacity refusal, retain the same `requestId` and input and wait through `dsh_status` and `dsh_wait`. Do not cancel other clients' tasks or reconfigure the serving app. Release SDK sessions with `transport.terminateSession()` before `client.close()`; closing alone does not release server capacity. The packaged `super-code-mcp` CLI accepts JSON on stdin and reads its token from the private `DSH_MCP_TOKEN` environment variable.
|
|
284
|
+
|
|
285
|
+
### Storage and limits
|
|
286
|
+
|
|
287
|
+
- Task records, settings, and the token are stored in the profile's `super-code-connection` directory (directory 0700, files 0600). One service instance per profile.
|
|
288
|
+
- Limits: 200 task records, 128 follow-ups per task, the latest 200 events, the last 12,000 output characters. Directory-request history keeps up to 100 entries, in memory only.
|
|
289
|
+
- When task records are full, new tasks are rejected explicitly; old records are never dropped silently.
|
|
290
|
+
|
|
291
|
+
## Frontend Skill
|
|
292
|
+
|
|
293
|
+
The plugin ships `super-code-frontend`, used for pages, components, visual tweaks, responsive layout, interaction states, and browser checks. It focuses on:
|
|
294
|
+
|
|
295
|
+
- whether elements line up on the same edges
|
|
296
|
+
- whether what you see matches what you can click
|
|
297
|
+
- whether controls stay put, are easy to reach, and need little input
|
|
298
|
+
|
|
299
|
+
It keeps the project's own visual style, needs no particular framework, and adds no tools. Normally only its name and short description go to the model; the body and relevant references load when a task matches. You can also ask for it directly: "use super-code-frontend".
|
|
300
|
+
|
|
301
|
+
- Only presets installed or reinstalled from 0.3.3 onward include it. For existing presets, back up your customizations, then reinstall.
|
|
302
|
+
- A project or user skill with the same name overrides the bundled one, following host precedence.
|
|
303
|
+
- The browser-check part is guidance only: no enforced loop detection, no automatic long-term memory writes.
|
|
304
|
+
- Whether it improves frontend quality needs a separate real-task evaluation; install tests and SWE scores can't show that.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CallerApproval, CallerApprovalDecision } from './types.js';
|
|
2
|
+
export type ApprovalOutcome = 'allowed-once' | 'rejected' | 'cancelled' | 'unavailable';
|
|
3
|
+
export type ApprovalAnswer = ApprovalOutcome | 'host';
|
|
4
|
+
export declare class CallerApprovals {
|
|
5
|
+
private readonly now;
|
|
6
|
+
private readonly requests;
|
|
7
|
+
private readonly settled;
|
|
8
|
+
private readonly presenting;
|
|
9
|
+
constructor(now?: () => number);
|
|
10
|
+
request(input: Omit<CallerApproval, 'id' | 'createdAt' | 'expiresAt'>, signal?: AbortSignal): Promise<ApprovalAnswer>;
|
|
11
|
+
private expire;
|
|
12
|
+
pending(taskId: string): CallerApproval[];
|
|
13
|
+
present(taskId: string, id: string): boolean;
|
|
14
|
+
defer(taskId: string, id: string): void;
|
|
15
|
+
decide(taskId: string, id: string, decision: CallerApprovalDecision): {
|
|
16
|
+
outcome: ApprovalOutcome;
|
|
17
|
+
repeated: boolean;
|
|
18
|
+
};
|
|
19
|
+
withdraw(taskId?: string, answer?: ApprovalAnswer): void;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=approvals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approvals.d.ts","sourceRoot":"","sources":["../../src/connection/approvals.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAExE,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG,UAAU,GAAG,WAAW,GAAG,aAAa,CAAC;AACxF,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,MAAM,CAAC;AAEtD,qBAAa,eAAe;IAId,OAAO,CAAC,QAAQ,CAAC,GAAG;IAHhC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6B;IACtD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0E;IAClG,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoB;gBAClB,GAAG,GAAE,MAAM,MAAiB;IACnD,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC;IAkB3H,OAAO,CAAC,MAAM;IAGd,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,EAAE;IAIzC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO;IAM5C,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IAIvC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,sBAAsB,GAAG;QAAE,OAAO,EAAE,eAAe,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE;IAgBrH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,GAAE,cAAuB,GAAG,IAAI;CAGjE"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/** Ephemeral, exact-call decisions. The host approval service owns the durable audit. */
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import { ConnectionError } from './types.js';
|
|
4
|
+
export class CallerApprovals {
|
|
5
|
+
now;
|
|
6
|
+
requests = new Map();
|
|
7
|
+
settled = new Map();
|
|
8
|
+
presenting = new Set();
|
|
9
|
+
constructor(now = Date.now) {
|
|
10
|
+
this.now = now;
|
|
11
|
+
}
|
|
12
|
+
async request(input, signal) {
|
|
13
|
+
if (signal?.aborted)
|
|
14
|
+
return 'cancelled';
|
|
15
|
+
if (this.requests.size >= 32 || input.arguments.length > 16000 || input.reason.length > 8000 || input.toolName.length > 256)
|
|
16
|
+
return 'host';
|
|
17
|
+
const createdAt = this.now(), view = { ...input, id: randomUUID(), createdAt, expiresAt: createdAt + 5 * 60 * 1000 };
|
|
18
|
+
return new Promise(resolve => {
|
|
19
|
+
const timer = setTimeout(() => settle('host'), 5 * 60 * 1000);
|
|
20
|
+
timer.unref();
|
|
21
|
+
const abort = () => settle('cancelled');
|
|
22
|
+
const settle = (answer) => {
|
|
23
|
+
if (!this.requests.delete(view.id))
|
|
24
|
+
return;
|
|
25
|
+
this.presenting.delete(view.id);
|
|
26
|
+
clearTimeout(timer);
|
|
27
|
+
signal?.removeEventListener('abort', abort);
|
|
28
|
+
resolve(answer);
|
|
29
|
+
};
|
|
30
|
+
this.requests.set(view.id, { view, settle });
|
|
31
|
+
signal?.addEventListener('abort', abort, { once: true });
|
|
32
|
+
if (signal?.aborted)
|
|
33
|
+
abort();
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
expire() {
|
|
37
|
+
for (const row of this.requests.values())
|
|
38
|
+
if (row.view.expiresAt <= this.now())
|
|
39
|
+
row.settle('host');
|
|
40
|
+
}
|
|
41
|
+
pending(taskId) {
|
|
42
|
+
this.expire();
|
|
43
|
+
return [...this.requests.values()].filter(row => row.view.taskId === taskId).map(row => ({ ...row.view }));
|
|
44
|
+
}
|
|
45
|
+
present(taskId, id) {
|
|
46
|
+
this.expire();
|
|
47
|
+
if (this.requests.get(id)?.view.taskId !== taskId || this.presenting.has(id))
|
|
48
|
+
return false;
|
|
49
|
+
this.presenting.add(id);
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
defer(taskId, id) {
|
|
53
|
+
const row = this.requests.get(id);
|
|
54
|
+
if (row?.view.taskId === taskId)
|
|
55
|
+
row.settle('host');
|
|
56
|
+
}
|
|
57
|
+
decide(taskId, id, decision) {
|
|
58
|
+
this.expire();
|
|
59
|
+
const prior = this.settled.get(id);
|
|
60
|
+
if (prior) {
|
|
61
|
+
if (prior.taskId !== taskId)
|
|
62
|
+
throw new ConnectionError('approval-not-found');
|
|
63
|
+
if (prior.decision !== decision)
|
|
64
|
+
throw new ConnectionError('approval-conflict');
|
|
65
|
+
return { outcome: decision === 'approve' ? 'allowed-once' : 'rejected', repeated: true };
|
|
66
|
+
}
|
|
67
|
+
const row = this.requests.get(id);
|
|
68
|
+
if (!row || row.view.taskId !== taskId)
|
|
69
|
+
throw new ConnectionError('approval-not-found');
|
|
70
|
+
this.settled.set(id, { taskId, decision });
|
|
71
|
+
if (this.settled.size > 200)
|
|
72
|
+
this.settled.delete(this.settled.keys().next().value);
|
|
73
|
+
const outcome = decision === 'approve' ? 'allowed-once' : 'rejected';
|
|
74
|
+
row.settle(outcome);
|
|
75
|
+
return { outcome, repeated: false };
|
|
76
|
+
}
|
|
77
|
+
withdraw(taskId, answer = 'host') {
|
|
78
|
+
for (const row of this.requests.values())
|
|
79
|
+
if (!taskId || row.view.taskId === taskId)
|
|
80
|
+
row.settle(answer);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=approvals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approvals.js","sourceRoot":"","sources":["../../src/connection/approvals.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface ConnectionRequest {
|
|
2
|
+
url: string;
|
|
3
|
+
token: string;
|
|
4
|
+
tool: string;
|
|
5
|
+
arguments: Record<string, unknown>;
|
|
6
|
+
}
|
|
7
|
+
export declare function invokeConnectionTool(request: ConnectionRequest, signal?: AbortSignal): Promise<Record<string, unknown>>;
|
|
8
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/connection/client.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,iBAAiB;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE;AACnH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAoB7H"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** A one-shot fallback for clients without native MCP tools; always release its own session. */
|
|
2
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
3
|
+
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
4
|
+
import { pluginVersion } from '../dsh/preset-version.js';
|
|
5
|
+
export async function invokeConnectionTool(request, signal) {
|
|
6
|
+
const url = new URL(request.url);
|
|
7
|
+
if (url.protocol !== 'http:' || !['127.0.0.1', 'localhost'].includes(url.hostname) || url.pathname !== '/mcp' || url.username || url.password || url.search || url.hash || !/^[a-f0-9]{64}$/.test(request.token))
|
|
8
|
+
throw new Error('invalid-connection-configuration');
|
|
9
|
+
if (request.tool !== 'tools' && !/^dsh_[a-z_]+$/.test(request.tool))
|
|
10
|
+
throw new Error('invalid-tool-name');
|
|
11
|
+
const client = new Client({ name: 'super-code-mcp-cli', version: pluginVersion });
|
|
12
|
+
const transport = new StreamableHTTPClientTransport(url, {
|
|
13
|
+
requestInit: { headers: { authorization: `Bearer ${request.token}` } },
|
|
14
|
+
fetch: (input, init) => fetch(input, init?.method === 'DELETE'
|
|
15
|
+
? { ...init, signal: init.signal ? AbortSignal.any([init.signal, AbortSignal.timeout(5000)]) : AbortSignal.timeout(5000) }
|
|
16
|
+
: init),
|
|
17
|
+
});
|
|
18
|
+
try {
|
|
19
|
+
signal?.throwIfAborted();
|
|
20
|
+
await client.connect(transport, { ...(signal ? { signal } : {}), timeout: 15000 });
|
|
21
|
+
return request.tool === 'tools' ? await client.listTools({}, { ...(signal ? { signal } : {}), timeout: 15000 })
|
|
22
|
+
: await client.callTool({ name: request.tool, arguments: request.arguments }, undefined, { ...(signal ? { signal } : {}), timeout: 45000 });
|
|
23
|
+
}
|
|
24
|
+
finally {
|
|
25
|
+
// SDK close() only aborts local connections; it does not DELETE the remote session.
|
|
26
|
+
try {
|
|
27
|
+
await transport.terminateSession();
|
|
28
|
+
}
|
|
29
|
+
finally {
|
|
30
|
+
await client.close();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/connection/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface DirectoryApplication {
|
|
2
|
+
requestId: string;
|
|
3
|
+
path: string;
|
|
4
|
+
reason: string;
|
|
5
|
+
}
|
|
6
|
+
export interface DirectoryRequest {
|
|
7
|
+
id: string;
|
|
8
|
+
requestId: string;
|
|
9
|
+
path: string;
|
|
10
|
+
reason: string;
|
|
11
|
+
client: string;
|
|
12
|
+
createdAt: number;
|
|
13
|
+
status: 'pending' | 'approved' | 'rejected' | 'expired';
|
|
14
|
+
}
|
|
15
|
+
/** Pending consent is deliberately ephemeral; only an approved allowlist is persisted. */
|
|
16
|
+
export declare class DirectoryRequests {
|
|
17
|
+
private readonly allowed;
|
|
18
|
+
private readonly now;
|
|
19
|
+
private readonly requests;
|
|
20
|
+
private readonly sources;
|
|
21
|
+
constructor(allowed: () => string[], now?: () => number);
|
|
22
|
+
private expire;
|
|
23
|
+
request(input: DirectoryApplication, client: string): Promise<DirectoryRequest>;
|
|
24
|
+
pending(): DirectoryRequest[];
|
|
25
|
+
resolve(id: string, decision: 'approved' | 'rejected', grant: (path: string) => Promise<void>): Promise<{
|
|
26
|
+
status: DirectoryRequest['status'];
|
|
27
|
+
}>;
|
|
28
|
+
rejectPending(): void;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=directories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directories.d.ts","sourceRoot":"","sources":["../../src/connection/directories.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,oBAAoB;IAAG,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AACzF,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAC/F,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC;CACzD;AACD,0FAA0F;AAC1F,qBAAa,iBAAiB;IAGhB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAkB,OAAO,CAAC,QAAQ,CAAC,GAAG;IAF1E,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsC;IAC/D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;gBACvB,OAAO,EAAE,MAAM,MAAM,EAAE,EAAmB,GAAG,GAAE,MAAM,MAAiB;IACnG,OAAO,CAAC,MAAM;IAKR,OAAO,CAAC,KAAK,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAsBrF,OAAO,IAAI,gBAAgB,EAAE;IACvB,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,GAAG,UAAU,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAA;KAAE,CAAC;IAarJ,aAAa,IAAI,IAAI;CACtB"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { realpath, stat } from 'node:fs/promises';
|
|
3
|
+
import { isAbsolute } from 'node:path';
|
|
4
|
+
import { ConnectionError } from './types.js';
|
|
5
|
+
import { withinDirectory } from './tasks.js';
|
|
6
|
+
/** Pending consent is deliberately ephemeral; only an approved allowlist is persisted. */
|
|
7
|
+
export class DirectoryRequests {
|
|
8
|
+
allowed;
|
|
9
|
+
now;
|
|
10
|
+
requests = new Map();
|
|
11
|
+
sources = new Map();
|
|
12
|
+
constructor(allowed, now = Date.now) {
|
|
13
|
+
this.allowed = allowed;
|
|
14
|
+
this.now = now;
|
|
15
|
+
}
|
|
16
|
+
expire() {
|
|
17
|
+
for (const row of this.requests.values()) {
|
|
18
|
+
if (row.status === 'pending' && this.now() - row.createdAt >= 5 * 60 * 1000)
|
|
19
|
+
row.status = 'expired';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async request(input, client) {
|
|
23
|
+
this.expire();
|
|
24
|
+
const existing = this.requests.get(input.requestId);
|
|
25
|
+
if (existing) {
|
|
26
|
+
if (this.sources.get(input.requestId) !== input.path || existing.reason !== input.reason)
|
|
27
|
+
throw new ConnectionError('request-conflict');
|
|
28
|
+
return { ...existing };
|
|
29
|
+
}
|
|
30
|
+
if (!isAbsolute(input.path))
|
|
31
|
+
throw new ConnectionError('absolute-directory-required');
|
|
32
|
+
let path;
|
|
33
|
+
try {
|
|
34
|
+
path = await realpath(input.path);
|
|
35
|
+
if (!(await stat(path)).isDirectory())
|
|
36
|
+
throw new Error();
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
throw new ConnectionError('directory-unavailable');
|
|
40
|
+
}
|
|
41
|
+
if (this.pending().length >= 8)
|
|
42
|
+
throw new ConnectionError('directory-request-limit');
|
|
43
|
+
if (this.requests.size >= 100) {
|
|
44
|
+
const oldest = [...this.requests.entries()].find(([, row]) => row.status !== 'pending');
|
|
45
|
+
if (oldest) {
|
|
46
|
+
this.requests.delete(oldest[0]);
|
|
47
|
+
this.sources.delete(oldest[0]);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const row = { id: randomUUID(), ...input, path, client: client.slice(0, 80), createdAt: this.now(),
|
|
51
|
+
status: this.allowed().some(parent => withinDirectory(parent, path)) ? 'approved' : 'pending' };
|
|
52
|
+
this.requests.set(input.requestId, row);
|
|
53
|
+
this.sources.set(input.requestId, input.path);
|
|
54
|
+
return { ...row };
|
|
55
|
+
}
|
|
56
|
+
pending() { this.expire(); return [...this.requests.values()].filter(row => row.status === 'pending').map(row => ({ ...row })); }
|
|
57
|
+
async resolve(id, decision, grant) {
|
|
58
|
+
this.expire();
|
|
59
|
+
const row = [...this.requests.values()].find(row => row.id === id);
|
|
60
|
+
if (!row)
|
|
61
|
+
throw new ConnectionError('directory-request-not-found');
|
|
62
|
+
if (row.status !== 'pending')
|
|
63
|
+
return { status: row.status };
|
|
64
|
+
if (decision === 'approved') {
|
|
65
|
+
try {
|
|
66
|
+
if (await realpath(row.path) !== row.path || !(await stat(row.path)).isDirectory())
|
|
67
|
+
throw new Error();
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
row.status = 'rejected';
|
|
71
|
+
throw new ConnectionError('directory-changed');
|
|
72
|
+
}
|
|
73
|
+
await grant(row.path);
|
|
74
|
+
}
|
|
75
|
+
row.status = decision;
|
|
76
|
+
return { status: row.status };
|
|
77
|
+
}
|
|
78
|
+
rejectPending() { for (const row of this.requests.values())
|
|
79
|
+
if (row.status === 'pending')
|
|
80
|
+
row.status = 'rejected'; }
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=directories.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directories.js","sourceRoot":"","sources":["../../src/connection/directories.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { GitSnapshot, WorkspaceChanges } from './types.js';
|
|
2
|
+
export declare function gitWorktreeRoot(cwd: string): Promise<string | false>;
|
|
3
|
+
export declare function gitSnapshot(cwd: string): Promise<GitSnapshot>;
|
|
4
|
+
export declare function workspaceChanges(cwd: string, baseline: GitSnapshot): Promise<WorkspaceChanges>;
|
|
5
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/connection/git.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAkC/D,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC,CAE1E;AACD,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAcnE;AACD,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAQpG"}
|