@junwu168/openshell 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/dist/core/audit/log-store.js +1 -1
  2. package/dist/core/orchestrator.d.ts +2 -2
  3. package/dist/core/orchestrator.js +3 -3
  4. package/dist/core/result.d.ts +1 -1
  5. package/dist/index.d.ts +3 -3
  6. package/dist/index.js +3 -3
  7. package/dist/opencode/plugin.d.ts +1 -1
  8. package/dist/opencode/plugin.js +8 -8
  9. package/package.json +6 -1
  10. package/.claude/settings.local.json +0 -25
  11. package/bun.lock +0 -368
  12. package/docs/superpowers/notes/2026-03-25-opencode-remote-tools-handoff.md +0 -81
  13. package/docs/superpowers/notes/2026-03-26-openshell-pre-release-review.md +0 -174
  14. package/docs/superpowers/plans/2026-03-25-opencode-remote-tools.md +0 -1656
  15. package/docs/superpowers/plans/2026-03-25-server-registry-cli.md +0 -54
  16. package/docs/superpowers/plans/2026-03-26-config-backed-credential-registry.md +0 -494
  17. package/docs/superpowers/plans/2026-03-26-openshell-release-prep.md +0 -639
  18. package/docs/superpowers/specs/2026-03-25-opencode-remote-tools-design.md +0 -378
  19. package/docs/superpowers/specs/2026-03-26-config-backed-credential-registry-design.md +0 -272
  20. package/docs/superpowers/specs/2026-03-26-openshell-release-prep-design.md +0 -197
  21. package/examples/opencode-local/opencode.json +0 -19
  22. package/scripts/openshell.ts +0 -3
  23. package/scripts/server-registry.ts +0 -3
  24. package/src/cli/openshell.ts +0 -65
  25. package/src/cli/server-registry.ts +0 -476
  26. package/src/core/audit/git-audit-repo.ts +0 -42
  27. package/src/core/audit/log-store.ts +0 -20
  28. package/src/core/audit/redact.ts +0 -4
  29. package/src/core/contracts.ts +0 -51
  30. package/src/core/orchestrator.ts +0 -1082
  31. package/src/core/patch.ts +0 -11
  32. package/src/core/paths.ts +0 -32
  33. package/src/core/policy.ts +0 -30
  34. package/src/core/registry/server-registry.ts +0 -505
  35. package/src/core/result.ts +0 -16
  36. package/src/core/ssh/ssh-runtime.ts +0 -355
  37. package/src/index.ts +0 -3
  38. package/src/opencode/plugin.ts +0 -242
  39. package/src/product/install.ts +0 -43
  40. package/src/product/opencode-config.ts +0 -118
  41. package/src/product/uninstall.ts +0 -47
  42. package/src/product/workspace-tracker.ts +0 -69
  43. package/tests/integration/fake-ssh-server.ts +0 -97
  44. package/tests/integration/install-lifecycle.test.ts +0 -85
  45. package/tests/integration/orchestrator.test.ts +0 -767
  46. package/tests/integration/ssh-runtime.test.ts +0 -122
  47. package/tests/unit/audit.test.ts +0 -221
  48. package/tests/unit/build-layout.test.ts +0 -28
  49. package/tests/unit/opencode-config.test.ts +0 -100
  50. package/tests/unit/opencode-plugin.test.ts +0 -358
  51. package/tests/unit/openshell-cli.test.ts +0 -60
  52. package/tests/unit/paths.test.ts +0 -64
  53. package/tests/unit/plugin-export.test.ts +0 -10
  54. package/tests/unit/policy.test.ts +0 -53
  55. package/tests/unit/release-docs.test.ts +0 -31
  56. package/tests/unit/result.test.ts +0 -28
  57. package/tests/unit/server-registry-cli.test.ts +0 -673
  58. package/tests/unit/server-registry.test.ts +0 -452
  59. package/tests/unit/workspace-tracker.test.ts +0 -57
  60. package/tsconfig.json +0 -14
@@ -1,54 +0,0 @@
1
- # Server Registry CLI Implementation Plan
2
-
3
- > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
-
5
- **Goal:** Add an interactive password-based server registry CLI for real OpenCode smoke testing, with `add`, `list`, and `remove` commands backed by the existing encrypted registry.
6
-
7
- **Architecture:** Extend the existing encrypted registry with delete support, add a small CLI module that owns prompt flow and output formatting, and expose it through a thin script entrypoint plus a package script alias. Keep the OpenCode plugin and SSH runtime unchanged.
8
-
9
- **Tech Stack:** TypeScript, Bun, Node readline/TTY APIs, existing encrypted registry + Keychain secret provider
10
-
11
- ---
12
-
13
- ### Task 1: Add Registry Delete Coverage
14
-
15
- **Files:**
16
- - Modify: `tests/unit/server-registry.test.ts`
17
- - Modify: `src/core/registry/server-registry.ts`
18
-
19
- - [ ] **Step 1: Write failing tests for deleting an existing record and removing a missing id safely**
20
- - [ ] **Step 2: Run `~/.bun/bin/bun test tests/unit/server-registry.test.ts` and confirm the new cases fail**
21
- - [ ] **Step 3: Add `remove(id)` to the registry interface and implementation with the existing write queue + lock discipline**
22
- - [ ] **Step 4: Re-run `~/.bun/bin/bun test tests/unit/server-registry.test.ts` and confirm it passes**
23
-
24
- ### Task 2: Add CLI Behavior Tests
25
-
26
- **Files:**
27
- - Create: `tests/unit/server-registry-cli.test.ts`
28
- - Create: `src/cli/server-registry.ts`
29
-
30
- - [ ] **Step 1: Write failing tests for `list`, interactive `add`, and interactive `remove` using a fake prompt/output adapter**
31
- - [ ] **Step 2: Run `~/.bun/bin/bun test tests/unit/server-registry-cli.test.ts` and confirm the new cases fail**
32
- - [ ] **Step 3: Implement a CLI module with command dispatch, interactive prompts, confirmation flow, and safe non-secret listing output**
33
- - [ ] **Step 4: Re-run `~/.bun/bin/bun test tests/unit/server-registry-cli.test.ts` and confirm it passes**
34
-
35
- ### Task 3: Wire The Script Entry Point
36
-
37
- **Files:**
38
- - Create: `scripts/server-registry.ts`
39
- - Modify: `package.json`
40
-
41
- - [ ] **Step 1: Add a thin script entry point that calls the CLI module**
42
- - [ ] **Step 2: Add a package script alias such as `server-registry`**
43
- - [ ] **Step 3: Run `~/.bun/bin/bun run server-registry list` against an empty registry and confirm it exits cleanly**
44
-
45
- ### Task 4: Verify End To End
46
-
47
- **Files:**
48
- - Modify: `README.md`
49
-
50
- - [ ] **Step 1: Document the real-server smoke workflow using the new CLI**
51
- - [ ] **Step 2: Run `~/.bun/bin/bun test tests/unit/server-registry.test.ts tests/unit/server-registry-cli.test.ts`**
52
- - [ ] **Step 3: Run `~/.bun/bin/bun run typecheck`**
53
- - [ ] **Step 4: Run `~/.bun/bin/bun run build`**
54
- - [ ] **Step 5: Run `~/.bun/bin/bun test` with elevated container-runtime access if needed, or note the environment limitation explicitly**
@@ -1,494 +0,0 @@
1
- # Config-Backed Credential Registry Implementation Plan
2
-
3
- > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
-
5
- **Goal:** Replace the current encrypted and keychain-backed credential registry with a layered workspace/global config model that stores plain-text passwords and path-only key or certificate references.
6
-
7
- **Architecture:** Keep the existing orchestrator, policy, audit, and OpenCode tool surface intact while swapping only the credential-storage layer. The new backend reads and writes JSON config files from workspace and global scopes, resolves an effective server view with workspace override semantics, and normalizes path-based auth before building SSH connection options.
8
-
9
- **Tech Stack:** TypeScript, Bun, OpenCode plugin SDK, `ssh2`, `env-paths`, Bun test
10
-
11
- ---
12
-
13
- ### Task 1: Replace Runtime Path And Registry Types
14
-
15
- **Files:**
16
- - Modify: `/Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli/src/core/paths.ts`
17
- - Modify: `/Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli/src/core/registry/server-registry.ts`
18
- - Delete: `/Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli/src/core/registry/crypto.ts`
19
- - Delete: `/Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli/src/core/registry/keychain-provider.ts`
20
- - Delete: `/Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli/src/core/registry/secret-provider.ts`
21
- - Test: `/Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli/tests/unit/paths.test.ts`
22
- - Test: `/Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli/tests/unit/server-registry.test.ts`
23
-
24
- - [ ] **Step 1: Write the failing path and registry tests**
25
-
26
- Add tests that define the new backend contract:
27
-
28
- ```ts
29
- test("runtime paths expose global and workspace server config locations", () => {
30
- const runtime = createRuntimePaths("/repo")
31
- expect(runtime.globalRegistryFile.endsWith("servers.json")).toBe(true)
32
- expect(runtime.workspaceRegistryFile).toBe("/repo/.open-code/servers.json")
33
- })
34
-
35
- test("workspace records override global records by id", async () => {
36
- const registry = createServerRegistry({
37
- globalRegistryFile,
38
- workspaceRegistryFile,
39
- workspaceRoot,
40
- })
41
-
42
- expect(await registry.resolve("prod-a")).toMatchObject({
43
- id: "prod-a",
44
- scope: "workspace",
45
- shadowingGlobal: true,
46
- })
47
- })
48
- ```
49
-
50
- Also replace the old encryption-oriented tests with config-oriented expectations:
51
-
52
- - plain-text password is written as plain JSON
53
- - workspace and global scopes are loaded separately
54
- - `list()` returns effective merged records with scope metadata
55
- - `listRaw("workspace")` and `listRaw("global")` return unmerged records
56
-
57
- - [ ] **Step 2: Run targeted tests to verify they fail**
58
-
59
- Run:
60
-
61
- ```bash
62
- ~/.bun/bin/bun test tests/unit/paths.test.ts tests/unit/server-registry.test.ts
63
- ```
64
-
65
- Expected:
66
-
67
- - FAIL because `runtimePaths` still exposes `servers.enc.json`
68
- - FAIL because `createServerRegistry()` still expects `secretProvider`
69
- - FAIL because scope metadata and layered reads do not exist yet
70
-
71
- - [ ] **Step 3: Implement the new path model and registry types**
72
-
73
- Update `src/core/paths.ts` to expose:
74
-
75
- ```ts
76
- export const runtimePaths = {
77
- configDir: paths.config,
78
- dataDir: paths.data,
79
- globalRegistryFile: `${paths.config}/servers.json`,
80
- auditLogFile: `${paths.data}/audit/actions.jsonl`,
81
- auditRepoDir: `${paths.data}/audit/repo`,
82
- }
83
-
84
- export const workspaceRegistryFile = (workspaceRoot: string) =>
85
- `${workspaceRoot}/.open-code/servers.json`
86
- ```
87
-
88
- Replace the registry backend in `src/core/registry/server-registry.ts` with a JSON-file implementation:
89
-
90
- - remove encryption and `SecretProvider`
91
- - add scoped file loading for `global` and `workspace`
92
- - add config schema types:
93
- - `PasswordAuthRecord` with `secret`
94
- - `PrivateKeyAuthRecord` with `privateKeyPath`
95
- - `CertificateAuthRecord` with `certificatePath` and `privateKeyPath`
96
- - add scope-aware result types, for example:
97
-
98
- ```ts
99
- export type RegistryScope = "global" | "workspace"
100
-
101
- export type ResolvedServerRecord = ServerRecord & {
102
- scope: RegistryScope
103
- shadowingGlobal?: boolean
104
- workspaceRoot?: string
105
- }
106
- ```
107
-
108
- Add methods needed by the spec:
109
-
110
- - `list()`
111
- - `resolve(id)`
112
- - `upsert(scope, record)`
113
- - `remove(scope, id)`
114
- - `listRaw(scope)`
115
-
116
- Keep atomic write behavior with temp-file + rename. Keep per-file lock behavior only if still needed for concurrent writes; if retained, scope the lock to the target config file rather than an encrypted-registry assumption.
117
-
118
- - [ ] **Step 4: Run targeted tests to verify they pass**
119
-
120
- Run:
121
-
122
- ```bash
123
- ~/.bun/bin/bun test tests/unit/paths.test.ts tests/unit/server-registry.test.ts
124
- ```
125
-
126
- Expected:
127
-
128
- - PASS with config-path and scope-aware registry assertions green
129
-
130
- - [ ] **Step 5: Commit**
131
-
132
- ```bash
133
- git -C /Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli add \
134
- src/core/paths.ts \
135
- src/core/registry/server-registry.ts \
136
- tests/unit/paths.test.ts \
137
- tests/unit/server-registry.test.ts
138
- git -C /Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli rm \
139
- src/core/registry/crypto.ts \
140
- src/core/registry/keychain-provider.ts \
141
- src/core/registry/secret-provider.ts
142
- git -C /Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli commit -m "refactor: replace encrypted registry with layered config backend"
143
- ```
144
-
145
- ### Task 2: Update Orchestrator And Plugin Runtime For Path-Based Auth
146
-
147
- **Files:**
148
- - Modify: `/Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli/src/core/orchestrator.ts`
149
- - Modify: `/Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli/src/opencode/plugin.ts`
150
- - Modify: `/Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli/src/core/contracts.ts`
151
- - Test: `/Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli/tests/integration/orchestrator.test.ts`
152
- - Test: `/Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli/tests/unit/opencode-plugin.test.ts`
153
-
154
- - [ ] **Step 1: Write the failing orchestrator and plugin tests**
155
-
156
- Add tests that cover:
157
-
158
- - path-based auth records are converted into `ssh2` connect config by reading file contents at runtime
159
- - missing key or certificate files return structured validation errors before SSH execution
160
- - plugin runtime dependencies no longer construct a Keychain-backed registry
161
-
162
- Example test shape:
163
-
164
- ```ts
165
- test("remote_exec reads privateKeyPath from workspace-scoped server records", async () => {
166
- await writeFile(join(workspaceRoot, "keys/id_rsa"), "PRIVATE KEY")
167
-
168
- const result = await orchestrator.remoteExec({
169
- server: "prod-a",
170
- command: "cat /etc/hosts",
171
- })
172
-
173
- expect(fakeSsh.execCalls[0]?.connection.privateKey).toContain("PRIVATE KEY")
174
- })
175
-
176
- test("missing private key path returns KEY_PATH_NOT_FOUND", async () => {
177
- expect(result).toMatchObject({
178
- status: "error",
179
- code: "KEY_PATH_NOT_FOUND",
180
- execution: { attempted: false, completed: false },
181
- })
182
- })
183
- ```
184
-
185
- - [ ] **Step 2: Run targeted tests to verify they fail**
186
-
187
- Run:
188
-
189
- ```bash
190
- ~/.bun/bin/bun test tests/integration/orchestrator.test.ts tests/unit/opencode-plugin.test.ts
191
- ```
192
-
193
- Expected:
194
-
195
- - FAIL because `toConnectConfig()` still expects in-memory key material
196
- - FAIL because plugin still imports `createKeychainSecretProvider()`
197
-
198
- - [ ] **Step 3: Implement scope-aware auth normalization in the orchestrator and plugin**
199
-
200
- In `src/core/orchestrator.ts`:
201
-
202
- - add a helper that turns a resolved server record into `ConnectConfig`
203
- - for `password`, pass the plain `secret`
204
- - for `privateKey`, read `privateKeyPath` from disk
205
- - for `certificate`, read `privateKeyPath` and validate `certificatePath` exists even if `ssh2` does not need separate certificate material for the current flow
206
- - resolve relative paths only for workspace-scoped records
207
- - reject relative paths in global records
208
- - return structured errors such as:
209
- - `AUTH_PATH_INVALID`
210
- - `KEY_PATH_NOT_FOUND`
211
- - `CERTIFICATE_PATH_NOT_FOUND`
212
- - `AUTH_PATH_UNREADABLE`
213
-
214
- In `src/opencode/plugin.ts`:
215
-
216
- - remove `createKeychainSecretProvider`
217
- - construct the registry with global and workspace config paths derived from the current working directory
218
- - keep the tool surface and approval behavior unchanged
219
-
220
- Update any contracts if result payload types need new error codes.
221
-
222
- - [ ] **Step 4: Run targeted tests to verify they pass**
223
-
224
- Run:
225
-
226
- ```bash
227
- ~/.bun/bin/bun test tests/integration/orchestrator.test.ts tests/unit/opencode-plugin.test.ts
228
- ```
229
-
230
- Expected:
231
-
232
- - PASS with path-based auth and plugin wiring assertions green
233
-
234
- - [ ] **Step 5: Commit**
235
-
236
- ```bash
237
- git -C /Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli add \
238
- src/core/orchestrator.ts \
239
- src/opencode/plugin.ts \
240
- src/core/contracts.ts \
241
- tests/integration/orchestrator.test.ts \
242
- tests/unit/opencode-plugin.test.ts
243
- git -C /Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli commit -m "feat: resolve ssh auth from layered config files"
244
- ```
245
-
246
- ### Task 3: Rework The Registry CLI For Scope Selection And Auth Modes
247
-
248
- **Files:**
249
- - Modify: `/Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli/src/cli/server-registry.ts`
250
- - Modify: `/Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli/scripts/server-registry.ts`
251
- - Test: `/Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli/tests/unit/server-registry-cli.test.ts`
252
-
253
- - [ ] **Step 1: Write the failing CLI tests**
254
-
255
- Add tests for:
256
-
257
- - defaulting to workspace scope when a workspace config already exists
258
- - defaulting to global when no workspace config exists
259
- - prompting for auth kind: `password`, `privateKey`, `certificate`
260
- - warning before storing a plain-text password
261
- - warning when a workspace `id` overrides a global `id`
262
- - prompting which scope to remove from when both contain the same `id`
263
- - listing source scope and shadowing status
264
-
265
- Example:
266
-
267
- ```ts
268
- test("add warns when a workspace record overrides a global record", async () => {
269
- expect(stdout.toString()).toContain("will override global entry")
270
- })
271
-
272
- test("remove prompts for scope when the same id exists in both configs", async () => {
273
- expect(promptCalls).toContainEqual(
274
- expect.objectContaining({ message: expect.stringContaining("Remove from which scope") }),
275
- )
276
- })
277
- ```
278
-
279
- - [ ] **Step 2: Run targeted tests to verify they fail**
280
-
281
- Run:
282
-
283
- ```bash
284
- ~/.bun/bin/bun test tests/unit/server-registry-cli.test.ts
285
- ```
286
-
287
- Expected:
288
-
289
- - FAIL because CLI currently assumes one registry file
290
- - FAIL because only password auth is supported
291
- - FAIL because scope-aware list/remove flows do not exist
292
-
293
- - [ ] **Step 3: Implement the CLI changes**
294
-
295
- In `src/cli/server-registry.ts`:
296
-
297
- - inject workspace root and scoped registry methods into CLI deps
298
- - add scope selection prompt with defaults:
299
- - workspace if workspace config exists
300
- - otherwise global
301
- - add auth-kind selection prompt
302
- - support these persisted shapes:
303
-
304
- ```ts
305
- auth: { kind: "password", secret: "plain-text" }
306
- auth: { kind: "privateKey", privateKeyPath: "./keys/id_rsa", passphrase?: "..." }
307
- auth: {
308
- kind: "certificate",
309
- certificatePath: "./keys/client.pem",
310
- privateKeyPath: "./keys/client-key.pem",
311
- passphrase?: "...",
312
- }
313
- ```
314
-
315
- - warn before plain-text password storage
316
- - for `list`, print scope and shadowing markers
317
- - for `remove`, resolve scope explicitly before deleting
318
-
319
- Keep the script entrypoint unchanged so `bun run server-registry` still works.
320
-
321
- - [ ] **Step 4: Run targeted tests to verify they pass**
322
-
323
- Run:
324
-
325
- ```bash
326
- ~/.bun/bin/bun test tests/unit/server-registry-cli.test.ts
327
- ```
328
-
329
- Expected:
330
-
331
- - PASS with new scope and auth prompt behavior covered
332
-
333
- - [ ] **Step 5: Commit**
334
-
335
- ```bash
336
- git -C /Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli add \
337
- src/cli/server-registry.ts \
338
- scripts/server-registry.ts \
339
- tests/unit/server-registry-cli.test.ts
340
- git -C /Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli commit -m "feat: add layered config flows to server registry cli"
341
- ```
342
-
343
- ### Task 4: Remove Keychain Dependency From Build And Docs
344
-
345
- **Files:**
346
- - Modify: `/Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli/package.json`
347
- - Modify: `/Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli/README.md`
348
- - Modify: `/Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli/docs/superpowers/specs/2026-03-26-config-backed-credential-registry-design.md`
349
- - Test: `/Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli/tests/unit/build-layout.test.ts`
350
-
351
- - [ ] **Step 1: Write the failing dependency and docs assertions**
352
-
353
- Add or update a lightweight test to assert the published build no longer depends on `keytar` or deleted registry modules where practical.
354
-
355
- Example:
356
-
357
- ```ts
358
- test("package metadata no longer declares keytar", async () => {
359
- const pkg = JSON.parse(await readFile("package.json", "utf8"))
360
- expect(pkg.dependencies.keytar).toBeUndefined()
361
- })
362
- ```
363
-
364
- - [ ] **Step 2: Run targeted tests to verify they fail**
365
-
366
- Run:
367
-
368
- ```bash
369
- ~/.bun/bin/bun test tests/unit/build-layout.test.ts
370
- ```
371
-
372
- Expected:
373
-
374
- - FAIL because `package.json` still includes `keytar`
375
-
376
- - [ ] **Step 3: Remove obsolete dependencies and update docs**
377
-
378
- In `package.json`:
379
-
380
- - remove `keytar`
381
-
382
- In `README.md`:
383
-
384
- - document the new config file locations
385
- - document that plain-text password storage is unsafe but supported
386
- - document that key/cert auth stores file paths only
387
- - include a short example for both workspace and global configs
388
-
389
- If the spec doc needs a brief implementation note after planning, keep it synchronized.
390
-
391
- - [ ] **Step 4: Run targeted tests to verify they pass**
392
-
393
- Run:
394
-
395
- ```bash
396
- ~/.bun/bin/bun test tests/unit/build-layout.test.ts
397
- ~/.bun/bin/bun run typecheck
398
- ~/.bun/bin/bun run build
399
- ```
400
-
401
- Expected:
402
-
403
- - PASS
404
- - build succeeds without `keytar`
405
-
406
- - [ ] **Step 5: Commit**
407
-
408
- ```bash
409
- git -C /Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli add \
410
- package.json \
411
- README.md \
412
- tests/unit/build-layout.test.ts
413
- git -C /Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli commit -m "chore: remove keychain dependency from credential registry"
414
- ```
415
-
416
- ### Task 5: Run Full Verification And Realistic Smoke Coverage
417
-
418
- **Files:**
419
- - Modify if needed: `/Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli/examples/opencode-local/opencode.json`
420
- - Modify if needed: `/Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli/examples/opencode-local/.opencode/package.json`
421
- - Test: `/Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli/tests/integration/orchestrator.test.ts`
422
- - Test: `/Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli/tests/integration/ssh-runtime.test.ts`
423
- - Test: `/Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli/tests/unit/*.test.ts`
424
-
425
- - [ ] **Step 1: Run the full automated test suite**
426
-
427
- Run:
428
-
429
- ```bash
430
- ~/.bun/bin/bun test
431
- ```
432
-
433
- Expected:
434
-
435
- - PASS across unit and integration coverage
436
-
437
- - [ ] **Step 2: Run typecheck and build**
438
-
439
- Run:
440
-
441
- ```bash
442
- ~/.bun/bin/bun run typecheck
443
- ~/.bun/bin/bun run build
444
- ```
445
-
446
- Expected:
447
-
448
- - PASS
449
-
450
- - [ ] **Step 3: Run manual Docker smoke test against the new config model**
451
-
452
- Use the disposable SSH container flow:
453
-
454
- ```bash
455
- docker run -d --name open-code-smoke-ssh \
456
- -e USER_NAME=open \
457
- -e USER_PASSWORD=openpass \
458
- -e PASSWORD_ACCESS=true \
459
- -e SUDO_ACCESS=false \
460
- -p 22222:2222 \
461
- linuxserver/openssh-server:10.2_p1-r0-ls219
462
- ```
463
-
464
- Create a workspace or global `servers.json` matching the new schema, then validate:
465
-
466
- - `bun run server-registry list`
467
- - `opencode` -> `list_servers`
468
- - `remote_exec` with `cat /tmp/open-code/hosts`
469
- - `remote_write_file` still prompts for approval
470
-
471
- Expected:
472
-
473
- - config-backed server appears in `list_servers`
474
- - safe `remote_exec` succeeds without approval prompt
475
- - write tool still requires approval
476
-
477
- - [ ] **Step 4: Clean up smoke artifacts**
478
-
479
- Run:
480
-
481
- ```bash
482
- docker rm -f open-code-smoke-ssh
483
- ```
484
-
485
- Delete any temporary test configs created during the smoke run.
486
-
487
- - [ ] **Step 5: Commit follow-up fixes if verification required any**
488
-
489
- ```bash
490
- git -C /Users/wujunming/Documents/experimental/openshell/.worktrees/registry-cli status -sb
491
- ```
492
-
493
- If no code changes were needed, do not create an empty commit.
494
-