Skip to content

Commit 1b15648

Browse files
authored
Merge pull request #130 from AxmeAI/feat/vscode-extension-20260510
feat(extension): Cursor-only extension v0.0.1 (full axme-code in Cursor, 1-click install)
2 parents e705953 + 7014546 commit 1b15648

24 files changed

Lines changed: 1513 additions & 10 deletions
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
name: Publish extension
2+
3+
# Build a platform-specific .vsix on every push to the extension branch
4+
# (artifact-only, no publish). Publish to Open VSX only when a human pushes
5+
# a tag matching `extension-v*` — agents must never push tags per D-024.
6+
7+
on:
8+
push:
9+
branches:
10+
- feat/vscode-extension-**
11+
tags:
12+
- "extension-v*"
13+
pull_request:
14+
paths:
15+
- "extension/**"
16+
- ".github/workflows/publish-extension.yml"
17+
workflow_dispatch:
18+
19+
permissions:
20+
contents: read
21+
22+
jobs:
23+
build:
24+
name: Build .vsix (${{ matrix.target }})
25+
runs-on: ${{ matrix.runner }}
26+
strategy:
27+
fail-fast: false
28+
matrix:
29+
include:
30+
- target: linux-x64
31+
runner: ubuntu-latest
32+
binary_name: axme-code-linux-x64
33+
extension_bin: axme-code
34+
- target: linux-arm64
35+
runner: ubuntu-latest
36+
binary_name: axme-code-linux-arm64
37+
extension_bin: axme-code
38+
- target: darwin-x64
39+
runner: macos-13
40+
binary_name: axme-code-darwin-x64
41+
extension_bin: axme-code
42+
- target: darwin-arm64
43+
runner: macos-latest
44+
binary_name: axme-code-darwin-arm64
45+
extension_bin: axme-code
46+
- target: win32-x64
47+
runner: windows-latest
48+
binary_name: axme-code-windows-x64.exe
49+
extension_bin: axme-code.exe
50+
steps:
51+
- uses: actions/checkout@v4
52+
53+
- uses: actions/setup-node@v4
54+
with:
55+
node-version: 20
56+
cache: npm
57+
58+
- name: Install core deps
59+
run: npm install
60+
61+
- name: Build core
62+
run: npm run build
63+
64+
- name: Bundle core CLI to a single platform-specific file
65+
shell: bash
66+
run: |
67+
mkdir -p extension/bin
68+
# Bundle dist/cli.mjs into a single CJS file with all deps inlined
69+
# EXCEPT @cursor/sdk. claude-agent-sdk is always required (used by
70+
# LLM scanners during setup and by the session auditor); it must
71+
# be inside the binary so Node doesn't try to resolve it from a
72+
# node_modules/ dir that doesn't ship with the .vsix.
73+
#
74+
# @cursor/sdk stays external because (a) it carries ~15 MB of
75+
# platform-specific native binaries that bloat the .vsix, and
76+
# (b) the AgentSdk factory's fallback gracefully degrades to the
77+
# Claude path on MODULE_NOT_FOUND. v0.0.1 users use Claude for
78+
# the auditor; Cursor SDK as a first-class in-extension option
79+
# is a v0.0.2 follow-up.
80+
#
81+
# WHY CJS, not ESM: the output is a shebang script with no file
82+
# extension (Windows uses .exe — see matrix.extension_bin).
83+
# Without ".mjs" extension AND without a sibling package.json
84+
# declaring "type":"module", Node loads the file as CJS and
85+
# ESM import statements throw at runtime.
86+
npx esbuild dist/cli.mjs \
87+
--bundle \
88+
--platform=node \
89+
--target=node20 \
90+
--format=cjs \
91+
--external:@cursor/sdk \
92+
--outfile=extension/bin/axme-code.cjs
93+
# Wrap in a shebang shim so it's executable as a binary.
94+
{
95+
printf '#!/usr/bin/env node\n'
96+
cat extension/bin/axme-code.cjs
97+
} > extension/bin/${{ matrix.extension_bin }}
98+
rm extension/bin/axme-code.cjs
99+
chmod +x extension/bin/${{ matrix.extension_bin }} || true
100+
101+
- name: Install extension deps
102+
working-directory: extension
103+
run: npm install
104+
105+
- name: Build extension bundle
106+
working-directory: extension
107+
run: npm run build
108+
109+
- name: Package .vsix
110+
working-directory: extension
111+
run: npx vsce package --target ${{ matrix.target }} --no-dependencies -o ../axme-code-${{ matrix.target }}.vsix
112+
113+
- uses: actions/upload-artifact@v4
114+
with:
115+
name: axme-code-${{ matrix.target }}
116+
path: axme-code-${{ matrix.target }}.vsix
117+
retention-days: 14
118+
119+
publish:
120+
name: Publish to Open VSX
121+
needs: build
122+
if: startsWith(github.ref, 'refs/tags/extension-v')
123+
runs-on: ubuntu-latest
124+
steps:
125+
- uses: actions/checkout@v4
126+
- uses: actions/setup-node@v4
127+
with:
128+
node-version: 20
129+
130+
- name: Download all .vsix artifacts
131+
uses: actions/download-artifact@v4
132+
with:
133+
path: vsix
134+
merge-multiple: true
135+
136+
- name: Publish per-target to Open VSX
137+
env:
138+
OVSX_TOKEN: ${{ secrets.OVSX_TOKEN }}
139+
run: |
140+
set -euo pipefail
141+
for target in linux-x64 linux-arm64 darwin-x64 darwin-arm64 win32-x64; do
142+
file="vsix/axme-code-${target}.vsix"
143+
if [ ! -f "$file" ]; then
144+
echo "Warning: $file missing; skipping $target."
145+
continue
146+
fi
147+
echo "Publishing $file (target=$target)"
148+
npx ovsx publish "$file" --target "$target" --pat "$OVSX_TOKEN"
149+
done
150+
151+
- name: Attach .vsix files to GitHub Release
152+
env:
153+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
154+
run: |
155+
set -euo pipefail
156+
# Create release if missing, then attach all 5 .vsix files for
157+
# sideload distribution alongside Open VSX.
158+
tag="${GITHUB_REF#refs/tags/}"
159+
gh release view "$tag" >/dev/null 2>&1 || \
160+
gh release create "$tag" --title "$tag" --notes "Extension $tag — six platform-specific .vsix files attached. See README for install instructions."
161+
for f in vsix/axme-code-*.vsix; do
162+
gh release upload "$tag" "$f" --clobber
163+
done

README.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,21 @@ Decisions enforce verification requirements: agent must run tests and show proof
8080

8181
## Quick Start
8282

83-
**Requires [Claude Code](https://docs.anthropic.com/en/docs/claude-code) (CLI or VS Code extension).**
83+
AXME Code supports three IDE paths today, ranked by lowest install friction:
8484

85-
### Option 1: Claude Code plugin (recommended)
85+
### Option 0: Cursor extension (1-click install — recommended for Cursor users)
86+
87+
For **Cursor 0.42+** users — install the `AXME Code` extension from the Extensions panel (Open VSX). The extension bundles the binary, registers the MCP server programmatically (no manual Enable click), installs user-level safety hooks at `~/.cursor/hooks.json` (apply to every project on your machine), and offers a one-click "Run setup" notification the first time you open a project without `.axme-code/`.
88+
89+
```
90+
Cursor → Extensions → search "AXME Code" → Install
91+
```
92+
93+
Or sideload the .vsix attached to the [latest release](https://github.com/AxmeAI/axme-code/releases) (`Extensions → ... menu → "Install from VSIX..."`).
94+
95+
On first activation a modal asks for an LLM credential for the session auditor: paste an Anthropic API key, a Cursor SDK key (cursor.com → Integrations), or skip the auditor. If `claude` CLI is logged in (`claude login`), the extension auto-uses your Claude subscription — no paste needed.
96+
97+
### Option 1: Claude Code plugin (recommended for Claude Code users)
8698

8799
In Claude Code, run:
88100

extension/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules/
2+
out/
3+
*.vsix
4+
package-lock.json

extension/.vscodeignore

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
.vscode/**
2+
.vscode-test/**
3+
src/**
4+
**/*.map
5+
**/*.ts
6+
**/tsconfig.json
7+
**/.eslintrc*
8+
**/.gitignore
9+
**/build.mjs
10+
**/node_modules/**
11+
.github/**
12+
.git/**
13+
**/*.vsix

extension/README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# AXME Code
2+
3+
Persistent memory, decisions, and safety guardrails for AI coding agents — Cursor, GitHub Copilot, Cline, Continue, Roo Code, Windsurf, and any VS Code chat agent that respects the Language Model API.
4+
5+
## What this extension does
6+
7+
- Registers `axme-code` as an MCP server so the agent has access to the project knowledge base — `axme_context`, `axme_save_memory`, `axme_save_decision`, `axme_safety`, and ~15 more tools.
8+
- Installs safety hooks at the user level (`~/.cursor/hooks.json`) so dangerous operations (force-push to main, `rm -rf` on protected paths, secret-file edits) are blocked **before** the agent runs them.
9+
- Auto-spawns the session auditor at chat end — extracts non-obvious patterns / decisions / safety rules from your conversation and saves them to `.axme-code/` for the next session to load.
10+
11+
## Requirements
12+
13+
- Cursor 0.42+ **or** VS Code 1.96+ (Copilot Agent Mode, Cline, Continue, Roo Code, Windsurf — anything that consumes MCP servers via the standard discovery API).
14+
- The `axme-code` CLI installed on your `$PATH`. Get it: `curl -fsSL https://raw.githubusercontent.com/AxmeAI/axme-code/main/install.sh | bash`. The extension auto-detects it on activation; if your install is non-standard, set `axme.binaryPath` in settings.
15+
16+
## Settings
17+
18+
| Setting | Default | Description |
19+
| --- | --- | --- |
20+
| `axme.binaryPath` | `""` | Absolute path to the `axme-code` binary. Leave empty for auto-detect. |
21+
| `axme.contextMode` | `"full"` | `full` loads every memory into agent context. `search` uses semantic search at scale. |
22+
| `axme.enableHooks` | `true` | Register safety hooks. Turn off if you don't want machine-wide guardrails. |
23+
24+
## Commands
25+
26+
- **AXME: Set up workspace** — runs `axme-code setup` against the current workspace folder.
27+
- **AXME: Open dashboard** — opens the worklog / decisions / memories view.
28+
- **AXME: Reindex semantic search** — rebuilds the embeddings index.
29+
- **AXME: Show status** — shows session count, audit health, recent worklog entries.
30+
31+
## How this differs from the CLI install
32+
33+
The `axme-code` CLI alone writes `.cursor/mcp.json` and `.cursor/hooks.json` per project. Cursor 0.42+ requires a manual **Enable** click in Settings → MCP for any new project-level server (security feature). This extension registers MCP via Cursor's extension API directly, bypassing the per-project Enable gate — install the extension once, every project just works.
34+
35+
## License
36+
37+
MIT — see [LICENSE](https://github.com/AxmeAI/axme-code/blob/main/LICENSE).

extension/build.mjs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* Bundle the AXME Code VS Code extension entry point.
3+
*
4+
* VS Code extensions are loaded as CommonJS, with `vscode` provided by the
5+
* host (must stay external). Everything else is inlined into a single file
6+
* so the .vsix has no node_modules at runtime — that keeps the artifact
7+
* small (well under 1 MB) and avoids platform-specific binary surprises.
8+
*/
9+
10+
import { build, context } from "esbuild";
11+
import { readFileSync } from "fs";
12+
13+
const watch = process.argv.includes("--watch");
14+
15+
const pkg = JSON.parse(readFileSync("package.json", "utf-8"));
16+
17+
const buildOptions = {
18+
entryPoints: ["src/extension.ts"],
19+
bundle: true,
20+
platform: "node",
21+
target: "node20",
22+
format: "cjs",
23+
external: ["vscode"],
24+
outfile: "out/extension.js",
25+
sourcemap: true,
26+
define: {
27+
__EXTENSION_VERSION__: JSON.stringify(pkg.version),
28+
},
29+
};
30+
31+
if (watch) {
32+
const ctx = await context(buildOptions);
33+
await ctx.watch();
34+
console.log("Watching extension/...");
35+
} else {
36+
await build(buildOptions);
37+
console.log(`Built extension v${pkg.version} → out/extension.js`);
38+
}

extension/package.json

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
{
2+
"name": "axme-code",
3+
"displayName": "AXME Code",
4+
"description": "Persistent memory, decisions, and safety guardrails for Cursor, GitHub Copilot, Cline, Continue, Roo Code, Windsurf, and VS Code chat agents",
5+
"version": "0.0.1",
6+
"publisher": "AxmeAI",
7+
"repository": {
8+
"type": "git",
9+
"url": "https://github.com/AxmeAI/axme-code.git",
10+
"directory": "extension"
11+
},
12+
"homepage": "https://github.com/AxmeAI/axme-code",
13+
"bugs": {
14+
"url": "https://github.com/AxmeAI/axme-code/issues"
15+
},
16+
"license": "MIT",
17+
"engines": {
18+
"vscode": "^1.96.0"
19+
},
20+
"categories": [
21+
"AI",
22+
"Other"
23+
],
24+
"keywords": [
25+
"ai",
26+
"agent",
27+
"cursor",
28+
"copilot",
29+
"cline",
30+
"mcp",
31+
"memory",
32+
"safety"
33+
],
34+
"main": "./out/extension.js",
35+
"activationEvents": [
36+
"onStartupFinished"
37+
],
38+
"contributes": {
39+
"configuration": {
40+
"title": "AXME Code",
41+
"properties": {
42+
"axme.binaryPath": {
43+
"type": "string",
44+
"default": "",
45+
"markdownDescription": "Absolute path to the `axme-code` binary. Leave empty to auto-detect via `$PATH`, `~/.local/bin/axme-code`, or platform standards. Override only if you have a non-standard install."
46+
},
47+
"axme.contextMode": {
48+
"type": "string",
49+
"enum": [
50+
"full",
51+
"search"
52+
],
53+
"default": "full",
54+
"markdownDescription": "Knowledge-base loading mode. `full` loads every memory + decision into agent context (default, simple). `search` loads only catalog + uses semantic search (saves tokens at scale; requires the search-mode runtime — install via `axme-code config set context.mode search`)."
55+
},
56+
"axme.enableHooks": {
57+
"type": "boolean",
58+
"default": true,
59+
"markdownDescription": "Register safety hooks (`preToolUse` / `postToolUse` / `sessionEnd`) at activation. When ON, force-pushes / dangerous bash / file-write violations are blocked across every project on this machine."
60+
}
61+
}
62+
},
63+
"commands": [
64+
{
65+
"command": "axme.setup",
66+
"title": "AXME: Set up workspace (writes .axme-code/ + hooks)",
67+
"category": "AXME"
68+
},
69+
{
70+
"command": "axme.openDashboard",
71+
"title": "AXME: Open dashboard (worklog + decisions + memories)",
72+
"category": "AXME"
73+
},
74+
{
75+
"command": "axme.reindex",
76+
"title": "AXME: Reindex semantic search",
77+
"category": "AXME"
78+
},
79+
{
80+
"command": "axme.showStatus",
81+
"title": "AXME: Show status",
82+
"category": "AXME"
83+
}
84+
]
85+
},
86+
"scripts": {
87+
"build": "node build.mjs",
88+
"watch": "node build.mjs --watch",
89+
"package": "vsce package --no-dependencies",
90+
"publish:ovsx": "ovsx publish --pat $OVSX_TOKEN"
91+
},
92+
"devDependencies": {
93+
"@types/node": "^22.0.0",
94+
"@types/vscode": "^1.96.0",
95+
"@vscode/vsce": "^3.2.0",
96+
"esbuild": "^0.25.0",
97+
"ovsx": "^0.10.0",
98+
"typescript": "^5.9.0"
99+
}
100+
}

0 commit comments

Comments
 (0)