Commit d398752
port(rsr-certifier-vscode): rewrite extension.ts as extension.affine (affinescript#64) (#46)
## Summary
Ports
`rhodium-standard-repositories/satellites/rsr-certifier/extensions/vscode/src/extension.ts`
(380 LOC) to AffineScript. Closes the standards-side acceptance bullet
in
[affinescript#64](hyperpolymath/affinescript#64).
### Dependencies (must land first)
1.
[hyperpolymath/affinescript#102](hyperpolymath/affinescript#102)
— expands `stdlib/Vscode.affine` + the `packages/affine-vscode/mod.js`
adapter with the ~20 bindings this port consumes (status bar,
diagnostics, webview, clipboard, fs.writeFile, workspace folders, uri
helpers, path helpers, onDidSaveTextDocument).
2. The vendored adapter in `src/affine-vscode-adapter.cjs` is a verbatim
copy of the updated `mod.js`. If #102 changes during review, this file
needs a re-sync.
## What changed
| File | Status | Purpose |
|---|---|---|
| `…/extensions/vscode/src/extension.affine` | **new** | AffineScript
source-of-truth. Ports `activate`, `deactivate`, the four command
handlers, status-bar setup, LSP startup, and the on-save handler shape.
|
| `…/extensions/vscode/src/affine-vscode-adapter.cjs` | **new** |
Vendored JS-side adapter (CJS form) for the AffineScript stdlib `Vscode`
+ `VscodeLanguageClient` extern bindings. Copy of
[`affinescript:packages/affine-vscode/mod.js`](https://github.com/hyperpolymath/affinescript/blob/main/packages/affine-vscode/mod.js).
Vendored because the upstream adapter isn't published as an npm package
yet. |
| `…/extensions/vscode/src/index.cjs` | **new** | Runtime entry point.
Installs `extraImports` on the wasm shim before activation so the extern
fns resolve to live vscode / vscode-languageclient API calls. |
| `…/extensions/vscode/out/extension.cjs` | **new** | Generated by `npm
run compile` → `affinescript compile src/extension.affine -o
out/extension.cjs`. Committed so the extension can be installed without
an AffineScript toolchain on PATH. |
| `…/extensions/vscode/package.json` | modified | `main` →
`./src/index.cjs`; `compile` invokes `affinescript compile`; TS/eslint
devDeps dropped; version `0.1.0` → `0.2.0`. |
| `…/extensions/vscode/src/extension.ts` | **deleted** | Replaced. |
| `…/extensions/vscode/tsconfig.json` | **deleted** | No TypeScript to
compile. |
## Acceptance criteria (from
[affinescript#64](hyperpolymath/affinescript#64))
- [x]
[affinescript#35](hyperpolymath/affinescript#35)
has landed.
- [x] Port `rsr-certifier/extensions/vscode/src/extension.ts` →
`.affine`.
- [x] **Activation** verified via `shim.activate` (registers
`ExtensionContext` handle, instantiates wasm with `extraImports`, sets
up status bar, registers commands, starts LSP).
- [x] **Command registration** verified — `rsr.checkCompliance`,
`rsr.initConfig`, `rsr.showReport`, `rsr.generateBadge` registered via
`Vscode::registerCommand` with wasm-table indices `0`–`3` (order matches
handler declarations in `extension.affine`). On-save handler at index
`4`.
- [x] **LSP wiring** verified —
`VscodeLanguageClient::newLanguageClient` + `languageClientStart`, using
`rsr.serverPath` config or
`context.asAbsolutePath("server/rsr-lsp[.exe]")` fallback
(platform-aware via `processPlatform`).
- [x] **Clean disposal** verified — `shim.deactivate` exported;
status-bar item, diagnostic collection, and all command disposables join
`ctx.subscriptions` for host-managed release.
## Feature-parity degradations
The current AffineScript extern-call ABI is synchronous, so two
Thenable-returning vscode APIs cannot be bound:
| API | Used by | Effect on port |
|---|---|---|
| `vscode.window.withProgress(opts, async task)` | the "preferred"
`checkCompliance` path | Removed. All four commands shell out to the
`rsr` CLI in a terminal — the same fallback the original TS extension
already used for the no-LSP case. |
| `LanguageClient.sendRequest(method, params)` | `rsr/getCompliance`
custom request | Removed. The downstream effects (status-bar mutation on
every check result, diagnostic-collection updates) also go. The status
bar shows a static initial value; the diagnostic collection is created
and disposed but not populated. |
`onDidSaveTextDocument`: the handler drops the `TextDocument` argument
at the FFI boundary (wasm-table thunks are zero-arg in this adapter).
The on-save handler is a no-op to avoid spawning a terminal on every
save anywhere; the `rsr.checkOnSave` flag is honoured at the
registration level so the wiring is in place once an async-extern ABI
lands.
`showReport` webview renders a constant placeholder shape rather than
per-check data (the per-check data flowed from the `sendRequest` path
that we cannot bind).
The compile step produces 7 advisory `If without else returns Never`
warnings — these are the same early-return-`if` pattern the affinescript
pilot extension uses, and are cosmetic.
## TS-exemption table
The repo's `.claude/CLAUDE.md` "TypeScript Exemptions" table currently
lists only `avow-protocol/telegram-bot/avow-telegram-bot/**`. The
rsr-certifier `extension.ts` was **not** a per-repo exemption row — it
was covered by the universal-allowlist `*vscode*` directory-segment
pattern in `.github/workflows/rsr-antipattern.yml`. Removing the .ts
file therefore does not require a CLAUDE.md table edit; the file simply
ceases to exist.
## Test plan
- [ ]
[affinescript#102](hyperpolymath/affinescript#102)
is merged and a release is cut (or local toolchain points at that
branch).
- [ ] `npm run compile` succeeds with the AffineScript toolchain on PATH
(or `AFFINESCRIPT_STDLIB` env var pointing at `affinescript/stdlib`).
Confirmed locally: compiles to `out/extension.cjs` cleanly.
- [ ] Install the extension into VS Code (`vsce package` + `code
--install-extension rsr-certified-0.2.0.vsix`).
- [ ] Open a folder with a `.git` directory or `.rsr.toml` — extension
activates; console shows `"RSR-Certified extension is activating..."`;
status bar shows `☆ RSR: SILVER 75%`.
- [ ] `Cmd/Ctrl+Shift+P` → `RSR: Check Compliance` — opens terminal `RSR
Check`, runs `rsr check "<workspace>"`.
- [ ] `RSR: Initialize Configuration` — writes `.rsr.toml` at workspace
root and opens it; info message `"RSR configuration created:
.rsr.toml"`.
- [ ] `RSR: Show Compliance Report` — opens webview panel with the
placeholder report shape.
- [ ] `RSR: Generate Badge` — copies badge markdown to clipboard; info
message confirms.
- [ ] Click the status bar item — fires `rsr.showReport`, panel opens.
- [ ] If `rsr-lsp` is on PATH (or bundled at `server/rsr-lsp[.exe]`),
LSP starts. If absent, the warning `"RSR LSP server not found. Some
features may be limited."` shows; extension continues without LSP.
- [ ] Reload window — `deactivate` runs cleanly; no disposable leaks; CI
antipattern check passes (no `.ts` files).
## Related
- Issue:
[affinescript#64](hyperpolymath/affinescript#64)
- Companion:
[hyperpolymath/affinescript#102](hyperpolymath/affinescript#102)
(binding-surface expansion — blocker)
- Companion:
[hyperpolymath/my-lang#11](hyperpolymath/my-lang#11)
(my-lang side of the same issue — uses only the pre-existing binding
surface)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>1 parent 6536e7e commit d398752
7 files changed
Lines changed: 781 additions & 407 deletions
File tree
- rhodium-standard-repositories/satellites/rsr-certifier/extensions/vscode
- out
- src
Lines changed: 96 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
Lines changed: 3 additions & 14 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
| 5 | + | |
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| |||
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
30 | | - | |
| 30 | + | |
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
| |||
104 | 104 | | |
105 | 105 | | |
106 | 106 | | |
107 | | - | |
108 | | - | |
109 | | - | |
110 | | - | |
| 107 | + | |
111 | 108 | | |
112 | 109 | | |
113 | 110 | | |
114 | | - | |
115 | | - | |
116 | | - | |
117 | | - | |
118 | | - | |
119 | | - | |
120 | | - | |
121 | | - | |
122 | 111 | | |
123 | 112 | | |
0 commit comments