Update completed files milestone docs
This commit is contained in:
parent
28a4e10e79
commit
1fb9db73ec
|
|
@ -25,37 +25,28 @@ These tests:
|
||||||
|
|
||||||
| File | Suite | Tests | Status |
|
| File | Suite | Tests | Status |
|
||||||
|------|-------|-------|--------|
|
|------|-------|-------|--------|
|
||||||
| `plugin-manager-disable-enable.spec.js` | A: Disable/Enable refresh | 4 | 3 pass, 1 fail* |
|
| `plugin-manager-disable-enable.spec.js` | A: Disable/Enable refresh | 4 | pass |
|
||||||
| `sidebar-opens-view.spec.js` | B: Sidebar → view routing | 3 | 3 pass |
|
| `sidebar-opens-view.spec.js` | B: Sidebar → view routing | 3 | 3 pass |
|
||||||
| `reload-updates-state.spec.js` | C: Reload updates UI | 3 | 2 pass, 1 fail* |
|
| `reload-updates-state.spec.js` | C: Reload updates UI | 4 | pass |
|
||||||
|
|
||||||
\* Failing tests document **known bugs** (see below).
|
## Resolved bugs covered by tests
|
||||||
|
|
||||||
## Known bugs detected by tests
|
### Bug M5-1: Sidebar updates when plugin state changes
|
||||||
|
|
||||||
### Bug M5-1: Sidebar does not update when plugin state changes
|
**Previous symptom:** After disabling a plugin in Plugin Manager, the sidebar
|
||||||
|
item for that plugin remained visible. Reloading after external mock state
|
||||||
|
changes also left stale sidebar items.
|
||||||
|
|
||||||
**Symptom:** After disabling a plugin in Plugin Manager, the sidebar item for
|
**Current behavior:** `PluginManager.svelte` dispatches
|
||||||
that plugin remains visible. After re-enabling, it stays visible (doesn't
|
`verstak:plugins-changed` after reload/enable/disable flows. `Sidebar.svelte`
|
||||||
disappear then reappear — it was never gone).
|
listens for that event and re-fetches plugins, vault status, and contributions.
|
||||||
|
|
||||||
**Root cause:** `Sidebar.svelte` loads plugin/contribution data once in
|
**Regression coverage:**
|
||||||
`onMount` and stores it in local `sidebarItems`. When `PluginManager`
|
|
||||||
disables/enables a plugin and calls `ReloadPlugins`, the `PluginManager`
|
|
||||||
component re-fetches data, but `Sidebar` does not react to the change — it
|
|
||||||
still holds the stale list.
|
|
||||||
|
|
||||||
**Affected tests:**
|
|
||||||
- `A: Disable plugin: button changes to Enable, sidebar item disappears`
|
- `A: Disable plugin: button changes to Enable, sidebar item disappears`
|
||||||
- `A: Disable → Enable full flow in sequence`
|
- `A: Disable → Enable full flow in sequence`
|
||||||
- `C: Reload after mock state change reflects new plugin status`
|
- `C: Reload after mock state change reflects new plugin status`
|
||||||
|
|
||||||
**Fix needed:** Sidebar must either:
|
|
||||||
1. Re-fetch contributions when it receives a custom event (e.g.
|
|
||||||
`verstak:plugins-reloaded`), or
|
|
||||||
2. Read plugin state reactively from a shared store that both
|
|
||||||
PluginManager and Sidebar subscribe to.
|
|
||||||
|
|
||||||
## What is NOT tested
|
## What is NOT tested
|
||||||
|
|
||||||
### Real desktop GUI (WebKitGTK + Wails native shell)
|
### Real desktop GUI (WebKitGTK + Wails native shell)
|
||||||
|
|
|
||||||
|
|
@ -181,18 +181,18 @@ type Entry struct {
|
||||||
- Create: `internal/core/files/path.go`
|
- Create: `internal/core/files/path.go`
|
||||||
- Create: `internal/core/files/path_test.go`
|
- Create: `internal/core/files/path_test.go`
|
||||||
|
|
||||||
- [ ] Add `NormalizeVaultRelativePath(relative string) (string, error)`.
|
- [x] Add `NormalizeVaultRelativePath(relative string) (string, error)`.
|
||||||
- [ ] Reject absolute paths, null bytes, `..`, and empty file paths.
|
- [x] Reject absolute paths, null bytes, `..`, and empty file paths.
|
||||||
- [ ] Preserve path case, including canonical `Notes`.
|
- [x] Preserve path case, including canonical `Notes`.
|
||||||
- [ ] Add `IsReservedPath(relative string) bool` returning true for `.verstak`
|
- [x] Add `IsReservedPath(relative string) bool` returning true for `.verstak`
|
||||||
and `.verstak/...`.
|
and `.verstak/...`.
|
||||||
- [ ] Add tests:
|
- [x] Add tests:
|
||||||
`TestNormalizeRejectsAbsolutePath`,
|
`TestNormalizeRejectsAbsolutePath`,
|
||||||
`TestNormalizeRejectsTraversal`,
|
`TestNormalizeRejectsTraversal`,
|
||||||
`TestNormalizeRejectsNullByte`,
|
`TestNormalizeRejectsNullByte`,
|
||||||
`TestNormalizePreservesCase`,
|
`TestNormalizePreservesCase`,
|
||||||
`TestReservedPathPolicy`.
|
`TestReservedPathPolicy`.
|
||||||
- [ ] Run:
|
- [x] Run:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go test ./internal/core/files
|
go test ./internal/core/files
|
||||||
|
|
@ -207,21 +207,21 @@ Expected: all `internal/core/files` tests pass.
|
||||||
- Create: `internal/core/files/service.go`
|
- Create: `internal/core/files/service.go`
|
||||||
- Create/modify: `internal/core/files/service_test.go`
|
- Create/modify: `internal/core/files/service_test.go`
|
||||||
|
|
||||||
- [ ] Define `Service` with a vault dependency that can return the current vault
|
- [x] Define `Service` with a vault dependency that can return the current vault
|
||||||
root and status.
|
root and status.
|
||||||
- [ ] Implement `List(relativeDir string) ([]Entry, error)`.
|
- [x] Implement `List(relativeDir string) ([]Entry, error)`.
|
||||||
- [ ] Implement `Metadata(relativePath string) (Entry, error)`.
|
- [x] Implement `Metadata(relativePath string) (Entry, error)`.
|
||||||
- [ ] Implement `ReadText(relativePath string) (string, error)`.
|
- [x] Implement `ReadText(relativePath string) (string, error)`.
|
||||||
- [ ] Implement `WriteText(relativePath, content string, overwrite bool) (Entry, error)`.
|
- [x] Implement `WriteText(relativePath, content string, overwrite bool) (Entry, error)`.
|
||||||
- [ ] Implement `Mkdir(relativePath string) (Entry, error)`.
|
- [x] Implement `Mkdir(relativePath string) (Entry, error)`.
|
||||||
- [ ] Implement `Move(fromRelativePath, toRelativePath string, overwrite bool) (Entry, error)`.
|
- [x] Implement `Move(fromRelativePath, toRelativePath string, overwrite bool) (Entry, error)`.
|
||||||
- [ ] Implement `Trash(relativePath string) (Entry, error)`.
|
- [x] Implement `Trash(relativePath string) (Entry, error)`.
|
||||||
- [ ] Use the shared path policy for every public method.
|
- [x] Use the shared path policy for every public method.
|
||||||
- [ ] Block `.verstak` paths in every public method.
|
- [x] Block `.verstak` paths in every public method.
|
||||||
- [ ] Add tests for closed vault, list, metadata, text read/write, mkdir, move,
|
- [x] Add tests for closed vault, list, metadata, text read/write, mkdir, move,
|
||||||
trash, overwrite false conflict, overwrite true replace, and reserved path
|
trash, overwrite false conflict, overwrite true replace, and reserved path
|
||||||
rejection.
|
rejection.
|
||||||
- [ ] Run:
|
- [x] Run:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go test ./internal/core/files
|
go test ./internal/core/files
|
||||||
|
|
@ -236,13 +236,13 @@ Expected: all `internal/core/files` tests pass.
|
||||||
- Modify: `internal/core/files/service.go`
|
- Modify: `internal/core/files/service.go`
|
||||||
- Modify: `internal/core/files/service_test.go`
|
- Modify: `internal/core/files/service_test.go`
|
||||||
|
|
||||||
- [ ] Write text content to a temp file in the target directory.
|
- [x] Write text content to a temp file in the target directory.
|
||||||
- [ ] Rename the temp file into the final path only after successful write.
|
- [x] Rename the temp file into the final path only after successful write.
|
||||||
- [ ] Remove temp file on write failure.
|
- [x] Remove temp file on write failure.
|
||||||
- [ ] Add test `TestWriteTextIsAtomicOnFailure` using a controlled failing path
|
- [x] Add test `TestWriteTextIsAtomicOnFailure` using a controlled failing path
|
||||||
or permission-denied directory.
|
or permission-denied directory.
|
||||||
- [ ] Add test `TestWriteTextDoesNotLeaveTempFile`.
|
- [x] Add test `TestWriteTextDoesNotLeaveTempFile`.
|
||||||
- [ ] Run:
|
- [x] Run:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go test ./internal/core/files
|
go test ./internal/core/files
|
||||||
|
|
@ -258,12 +258,12 @@ Expected: all `internal/core/files` tests pass.
|
||||||
- Modify: `main.go`
|
- Modify: `main.go`
|
||||||
- Modify: `internal/api/app_test.go`
|
- Modify: `internal/api/app_test.go`
|
||||||
|
|
||||||
- [ ] Register permissions: `files.read`, `files.write`, `files.delete`.
|
- [x] Register permissions: `files.read`, `files.write`, `files.delete`.
|
||||||
- [ ] Register core capability `verstak/core/files/v1` when vault services are
|
- [x] Register core capability `verstak/core/files/v1` when vault services are
|
||||||
initialized.
|
initialized.
|
||||||
- [ ] Add API guard tests proving each Files bridge method rejects plugins that
|
- [x] Add API guard tests proving each Files bridge method rejects plugins that
|
||||||
are missing the required permission.
|
are missing the required permission.
|
||||||
- [ ] Run:
|
- [x] Run:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go test ./internal/core/permissions ./internal/api
|
go test ./internal/core/permissions ./internal/api
|
||||||
|
|
@ -282,13 +282,13 @@ Expected: permission registry and API tests pass.
|
||||||
- Modify after Wails generation or by hand if generation is unavailable:
|
- Modify after Wails generation or by hand if generation is unavailable:
|
||||||
`frontend/wailsjs/go/api/App.js`
|
`frontend/wailsjs/go/api/App.js`
|
||||||
|
|
||||||
- [ ] Add `files.Service` to `api.App`.
|
- [x] Add `files.Service` to `api.App`.
|
||||||
- [ ] Add plugin-scoped methods listed in "Public Backend Shape".
|
- [x] Add plugin-scoped methods listed in "Public Backend Shape".
|
||||||
- [ ] Use `requirePluginAccess(pluginID, permission)` for every method.
|
- [x] Use `requirePluginAccess(pluginID, permission)` for every method.
|
||||||
- [ ] Return readable errors for closed vault, missing file, reserved path,
|
- [x] Return readable errors for closed vault, missing file, reserved path,
|
||||||
conflict, and missing permission.
|
conflict, and missing permission.
|
||||||
- [ ] Add tests for successful read/write/list/mkdir/move/trash through `App`.
|
- [x] Add tests for successful read/write/list/mkdir/move/trash through `App`.
|
||||||
- [ ] Run:
|
- [x] Run:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go test ./internal/api
|
go test ./internal/api
|
||||||
|
|
@ -305,16 +305,16 @@ Expected: API tests pass.
|
||||||
- Add/modify focused frontend tests under `frontend/e2e/` only if existing test
|
- Add/modify focused frontend tests under `frontend/e2e/` only if existing test
|
||||||
coverage cannot validate the shape outside Playwright.
|
coverage cannot validate the shape outside Playwright.
|
||||||
|
|
||||||
- [ ] Add `api.files.list(relativeDir)`.
|
- [x] Add `api.files.list(relativeDir)`.
|
||||||
- [ ] Add `api.files.metadata(relativePath)`.
|
- [x] Add `api.files.metadata(relativePath)`.
|
||||||
- [ ] Add `api.files.readText(relativePath)`.
|
- [x] Add `api.files.readText(relativePath)`.
|
||||||
- [ ] Add `api.files.writeText(relativePath, content, options)`.
|
- [x] Add `api.files.writeText(relativePath, content, options)`.
|
||||||
- [ ] Add `api.files.mkdir(relativePath)`.
|
- [x] Add `api.files.mkdir(relativePath)`.
|
||||||
- [ ] Add `api.files.move(fromRelativePath, toRelativePath, options)`.
|
- [x] Add `api.files.move(fromRelativePath, toRelativePath, options)`.
|
||||||
- [ ] Add `api.files.trash(relativePath)`.
|
- [x] Add `api.files.trash(relativePath)`.
|
||||||
- [ ] Keep all calls plugin-scoped; plugin code must not pass `pluginId`.
|
- [x] Keep all calls plugin-scoped; plugin code must not pass `pluginId`.
|
||||||
- [ ] Mock readable errors for reserved path and missing permission.
|
- [x] Mock readable errors for reserved path and missing permission.
|
||||||
- [ ] Run:
|
- [x] Run:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd frontend
|
cd frontend
|
||||||
|
|
@ -331,11 +331,11 @@ Expected: frontend build passes.
|
||||||
- Modify: `../verstak-sdk/src/test-utils.ts`
|
- Modify: `../verstak-sdk/src/test-utils.ts`
|
||||||
- Modify: `../verstak-sdk/src/plugin-api.test.ts`
|
- Modify: `../verstak-sdk/src/plugin-api.test.ts`
|
||||||
|
|
||||||
- [ ] Add `files` API TypeScript interfaces matching the frontend API names.
|
- [x] Add `files` API TypeScript interfaces matching the frontend API names.
|
||||||
- [ ] Add mock Files API methods in `createMockPluginAPI`.
|
- [x] Add mock Files API methods in `createMockPluginAPI`.
|
||||||
- [ ] Add contract tests for API shape, text write/read, reserved path error, and
|
- [x] Add contract tests for API shape, text write/read, reserved path error, and
|
||||||
trash result shape.
|
trash result shape.
|
||||||
- [ ] Run:
|
- [x] Run:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ../verstak-sdk
|
cd ../verstak-sdk
|
||||||
|
|
@ -353,36 +353,36 @@ Expected: SDK check, build, and tests pass.
|
||||||
- Modify: `docs/PLUGIN_RUNTIME.md`
|
- Modify: `docs/PLUGIN_RUNTIME.md`
|
||||||
- Modify: `docs/NOTES_FILES_PLUGIN_PLAN.md`
|
- Modify: `docs/NOTES_FILES_PLUGIN_PLAN.md`
|
||||||
|
|
||||||
- [ ] Document Files Core API as functional for Milestone 6a.
|
- [x] Document Files Core API as functional for Milestone 6a.
|
||||||
- [ ] Keep Notes API documented as planned until Milestone 6b or later.
|
- [x] Keep Notes API documented as planned until Milestone 6b or later.
|
||||||
- [ ] Document `.verstak` reserved path policy.
|
- [x] Document `.verstak` reserved path policy.
|
||||||
- [ ] Document slash-only path policy, Windows/UNC rejection, and symlink policy.
|
- [x] Document slash-only path policy, Windows/UNC rejection, and symlink policy.
|
||||||
- [ ] Document text-only write support and deferred binary streaming.
|
- [x] Document text-only write support and deferred binary streaming.
|
||||||
|
|
||||||
## Task 9: Final Verification
|
## Task 9: Final Verification
|
||||||
|
|
||||||
- [ ] Run desktop backend tests:
|
- [x] Run desktop backend tests:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd verstak-desktop
|
cd verstak-desktop
|
||||||
go test ./...
|
go test ./...
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] Run desktop frontend build:
|
- [x] Run desktop frontend build:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd verstak-desktop/frontend
|
cd verstak-desktop/frontend
|
||||||
npm run build
|
npm run build
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] Run desktop e2e:
|
- [x] Run desktop e2e:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd verstak-desktop/frontend
|
cd verstak-desktop/frontend
|
||||||
npm run test:e2e -- --reporter=list
|
npm run test:e2e -- --reporter=list
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] Run official plugins checks:
|
- [x] Run official plugins checks:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd verstak-official-plugins
|
cd verstak-official-plugins
|
||||||
|
|
@ -390,7 +390,7 @@ cd verstak-official-plugins
|
||||||
./scripts/build.sh
|
./scripts/build.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] Run SDK checks:
|
- [x] Run SDK checks:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd verstak-sdk
|
cd verstak-sdk
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue