Skip to content

Commit d2875a5

Browse files
affine-vscode: align docs with --vscode-extension + npm publish manifest (#117)
* Codegen: add --vscode-extension flag to inline extraImports wiring Closes #105. The Node-CJS codegen emitted a shim with an empty extraImports hook that every consumer hand-wired in a separate index.cjs to install the concrete vscode-API bindings. That boilerplate was 100% mechanical and identical across consumers. Add a --vscode-extension codegen flag that inlines the wiring so the generated .cjs is directly loadable as a VS Code extension's `main`: installs exports.extraImports calling the @hyperpolymath/affine-vscode adapter. Sub-flags --vscode-extension-adapter (override the require specifier) and --vscode-extension-no-lc (no language client; pass null) cover the documented variants. Migrate the editors/vscode pilot off the would-be hand-written index.cjs: its compile script now passes --vscode-extension and the regenerated out/extension.cjs carries the inline glue; package.json declares the adapter dependency. https://claude.ai/code/session_01FkzAgzpZFSGxzorVNZ9FUF * docs(affine-vscode): align adapter docs with --vscode-extension (issue #105) The README and mod.js still described the pre-#105 manual hookup and referred to the hook as `_extraImports`. The codegen shim uses `extraImports` and #105 now emits the wiring inline. - Document `--vscode-extension` (and the adapter / no-lc sub-flags) as the recommended path; keep a corrected manual fallback. - Fix the hook name `_extraImports` -> `extraImports`. - Fix the manual example's third argument: the adapter expects the .cjs shim module (it reads `_registerHandle` / `_instance` off it), not a `() => instance` thunk or a bare WebAssembly.Instance. https://claude.ai/code/session_01FkzAgzpZFSGxzorVNZ9FUF * chore: gitignore /_opam/ local opam switch A project-local opam switch (created for a working OCaml toolchain) is a machine-specific environment dir and must not be tracked, mirroring the existing /_build/ ignore. https://claude.ai/code/session_01FkzAgzpZFSGxzorVNZ9FUF * feat(affine-vscode): npm package manifest + tag-driven publish (issue #104) In-repo half of #104 so consumers can `npm install @hyperpolymath/affine-vscode` instead of vendoring mod.js — which is what makes --vscode-extension's default `require("@hyperpolymath/affine-vscode")` resolvable downstream. - packages/affine-vscode/package.json: publish manifest (name, main, PMPL license matching the sibling deno.json, repository.directory, peerDependencies vscode + optional vscode-languageclient, files allowlist, public publishConfig). vscode-languageclient is marked optional to match --vscode-extension-no-lc. - .github/workflows/affine-vscode-publish.yml: publishes on a scoped `affine-vscode-v*` tag (kept distinct from the compiler's `v*` tags), verifies tag==package version, uses runner-provided Node and a runtime $HOME/.npmrc (no committed .npmrc, so the npm/bun blocker stays green). - README: npm-install section as the primary entry point. Out of scope (needs npm org/token + other repos): the @hyperpolymath npm org, first manual publish, and the my-lang / standards consumer ports. https://claude.ai/code/session_01FkzAgzpZFSGxzorVNZ9FUF --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent b5a4109 commit d2875a5

5 files changed

Lines changed: 150 additions & 21 deletions

File tree

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# SPDX-License-Identifier: PMPL-1.0-or-later
2+
# Publishes @hyperpolymath/affine-vscode to npm on a scoped tag push.
3+
#
4+
# This repo is Deno-first (see CLAUDE.md). The npm publish here is a
5+
# deliberate, owner-sanctioned exception (issue #104): the VS Code
6+
# extension host is npm-native and cannot consume the Deno/JSR manifest,
7+
# so AffineScript-authored extensions resolve the adapter via
8+
# `require("@hyperpolymath/affine-vscode")`. Only the publish step touches
9+
# npm; no npm runtime deps are added to the repo and no .npmrc is
10+
# committed (the auth file is written to $HOME at runtime).
11+
#
12+
# Trigger: push a tag matching `affine-vscode-v*` (e.g. affine-vscode-v0.1.0).
13+
# This pattern is intentionally distinct from the `v*` tags used by the
14+
# OCaml compiler Release workflow so the two never collide.
15+
#
16+
# Requires repository secret NPM_TOKEN (an npm automation token with
17+
# publish rights to the @hyperpolymath scope).
18+
19+
name: Publish affine-vscode
20+
21+
on:
22+
push:
23+
tags:
24+
- 'affine-vscode-v*'
25+
26+
permissions:
27+
contents: read
28+
29+
jobs:
30+
publish:
31+
runs-on: ubuntu-latest
32+
steps:
33+
- name: Checkout code
34+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
35+
36+
- name: Verify tag matches package version
37+
working-directory: packages/affine-vscode
38+
run: |
39+
tag="${GITHUB_REF_NAME#affine-vscode-v}"
40+
pkg="$(node -p "require('./package.json').version")"
41+
if [ "$tag" != "$pkg" ]; then
42+
echo "❌ Tag version ($tag) does not match package.json version ($pkg)" >&2
43+
exit 1
44+
fi
45+
echo "✅ Publishing @hyperpolymath/affine-vscode@$pkg"
46+
47+
- name: Configure npm auth
48+
env:
49+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
50+
run: |
51+
if [ -z "${NPM_TOKEN}" ]; then
52+
echo "❌ NPM_TOKEN secret is not set" >&2
53+
exit 1
54+
fi
55+
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > "${HOME}/.npmrc"
56+
57+
- name: Publish to npm
58+
working-directory: packages/affine-vscode
59+
run: npm publish --access public
60+
61+
- name: Clean up npm auth
62+
if: always()
63+
run: rm -f "${HOME}/.npmrc"

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Thumbs.db
1313
# Build
1414
/target/
1515
/_build/
16+
/_opam/
1617
/build/
1718
/dist/
1819
/out/

packages/affine-vscode/README.adoc

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,54 @@ JS-side adapter for the `stdlib/Vscode.affine` and
66
`stdlib/VscodeLanguageClient.affine` binding modules. Issue #35 Phase 2
77
deliverable.
88

9+
== Install
10+
11+
[source,sh]
12+
----
13+
npm install @hyperpolymath/affine-vscode
14+
----
15+
16+
Add it to your extension's `package.json` `dependencies`. `vscode` and
17+
`vscode-languageclient` are peer dependencies (the latter is optional —
18+
omit it with `--vscode-extension-no-lc`).
19+
920
== Usage
1021

11-
In your AffineScript-authored VS Code extension's CJS entry point, after
12-
loading the `.cjs` produced by `affinescript compile extension.affine
13-
-o extension.cjs`, plug this adapter into the Wasm imports:
22+
=== Recommended: `--vscode-extension` (issue #105)
23+
24+
Compile with the `--vscode-extension` flag and the generated `.cjs` is
25+
directly loadable as the extension's `main` — the adapter wiring is
26+
emitted inline, so there is no hand-written entry point to maintain:
27+
28+
[source,sh]
29+
----
30+
affinescript compile src/extension.affine -o out/extension.cjs --vscode-extension
31+
----
32+
33+
Point your extension's `package.json` `main` at the unmodified
34+
`out/extension.cjs` and list `@hyperpolymath/affine-vscode` in
35+
`dependencies`. Sub-flags: `--vscode-extension-adapter <specifier>`
36+
overrides the adapter `require()` target; `--vscode-extension-no-lc`
37+
omits the `vscode-languageclient/node` dependency.
38+
39+
=== Manual wiring (fallback)
40+
41+
If you cannot use the flag, set the shim's `extraImports` hook before the
42+
first `activate`/`deactivate` call so the extern fns resolve to live
43+
vscode APIs. Pass the shim module itself as the third argument — the
44+
adapter reads its handle table and `_instance` lazily:
1445

1546
[source,javascript]
1647
----
1748
const vscode = require("vscode");
1849
const lc = require("vscode-languageclient/node");
1950
const makeBindings = require("@hyperpolymath/affine-vscode");
2051
21-
// The Node-CJS shim emitted by affinescript's compile -o *.cjs path lazily
22-
// instantiates the wasm. Patch its `_extraImports()` hook before the first
23-
// activate/deactivate call so the extern fns resolve to live vscode APIs.
24-
25-
let instance;
26-
const adapter = require("./extension.cjs");
27-
const original = adapter._extraImports || (() => ({}));
28-
adapter._extraImports = () => makeBindings(vscode, lc, () => instance);
52+
const shim = require("./extension.cjs");
53+
shim.extraImports = () => makeBindings(vscode, lc, shim);
2954
30-
// (Real wiring belongs in the codegen — Phase 3 will replace this manual
31-
// hookup with auto-generated glue once `extension.affine` is the source of
32-
// truth for the extension entry point.)
55+
exports.activate = shim.activate;
56+
exports.deactivate = shim.deactivate;
3357
----
3458

3559
== Surface

packages/affine-vscode/mod.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,21 @@
33
//
44
// affine-vscode: JS-side adapter for stdlib/Vscode.affine + stdlib/VscodeLanguageClient.affine.
55
//
6-
// Issue #35 Phase 2 deliverable. Plug this into your Node-CJS extension's
7-
// `_extraImports()` so each `extern fn` declared in the bindings resolves
8-
// to the right vscode API call.
6+
// Issue #35 Phase 2 deliverable. Resolves each `extern fn` declared in the
7+
// bindings to the right vscode API call.
98
//
10-
// Usage from a hand-written .cjs (until Phase 3 automates the wiring):
9+
// Preferred wiring (issue #105): compile with `--vscode-extension` and the
10+
// generated .cjs installs `exports.extraImports` calling this adapter
11+
// automatically — no hand-written entry point.
1112
//
12-
// const vscodeBindings = require("@hyperpolymath/affine-vscode")(
13+
// Manual wiring (fallback), from a hand-written .cjs:
14+
//
15+
// const shim = require("./extension.cjs");
16+
// shim.extraImports = () => require("@hyperpolymath/affine-vscode")(
1317
// require("vscode"),
1418
// require("vscode-languageclient/node"),
15-
// instance, // WebAssembly.Instance, set after instantiate
19+
// shim, // the .cjs shim module (hostShim)
1620
// );
17-
// // Pass vscodeBindings into the Wasm imports map under "env".
1821
//
1922
// The adapter maintains a per-process JS-side handle table keyed by Int
2023
// so opaque handles passed across the FFI boundary survive round-trips.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"name": "@hyperpolymath/affine-vscode",
3+
"version": "0.1.0",
4+
"description": "JS-side adapter for AffineScript's stdlib/Vscode.affine + stdlib/VscodeLanguageClient.affine binding modules. Resolves each extern fn to a real vscode / vscode-languageclient call and maintains the FFI handle table.",
5+
"main": "./mod.js",
6+
"license": "PMPL-1.0-or-later",
7+
"repository": {
8+
"type": "git",
9+
"url": "https://github.com/hyperpolymath/affinescript.git",
10+
"directory": "packages/affine-vscode"
11+
},
12+
"homepage": "https://github.com/hyperpolymath/affinescript/tree/main/packages/affine-vscode",
13+
"bugs": "https://github.com/hyperpolymath/affinescript/issues",
14+
"keywords": [
15+
"affinescript",
16+
"vscode",
17+
"vscode-extension",
18+
"language-server",
19+
"wasm",
20+
"ffi-adapter"
21+
],
22+
"files": [
23+
"mod.js",
24+
"README.adoc"
25+
],
26+
"peerDependencies": {
27+
"vscode": "*",
28+
"vscode-languageclient": "^9.0.0"
29+
},
30+
"peerDependenciesMeta": {
31+
"vscode-languageclient": {
32+
"optional": true
33+
}
34+
},
35+
"publishConfig": {
36+
"access": "public"
37+
}
38+
}

0 commit comments

Comments
 (0)