feat(extension): v0.0.3 — sidebar monitor + 13 functional gaps + cross-platform + branding#133
Merged
Merged
Conversation
…lf-test, reset
Five quality-of-life features that close the silent-failure UX hole
surfaced during v0.0.1 install (users had no clear signal when hooks
or auth quietly failed during activation):
1. ActivationReport + per-step failure surfacing (extension)
- extension/src/activation-report.ts: small class that tracks
ok/fail per step (binary, mcp, hooks, auth, setup). At the end
of activate(), shows a single info notification on full success
("AXME Code ready: ✓ MCP ✓ Hooks ✓ Auth (cursor_sdk) ✓ KB (33
dec, 6 mems)") OR a warning with [Show output] button when
anything failed.
- extension.ts: every step now wrapped in runStep() helper that
records to the report AND surfaces a per-step warning toast on
failure. Previously hooks/auth/setup errors landed only in the
output channel with no user-visible signal.
2. AXME: Show Status → webview (extension)
- extension/src/status-webview.ts: structured healthcheck panel
with rows for extension version, binary, MCP server boot probe
(spawns serve + initialize handshake), hooks file (parses
~/.cursor/hooks.json, counts axme entries per kind), auth mode,
KB stats per workspace, last audit timestamp. Each row has a
✓/⚠/✗ status icon. Refresh button on the panel.
- commands.ts: axme.showStatus now opens the webview instead of
dumping to output channel. Old text-dump is preserved as
axme.showStatusText command for power users.
3. axme-code self-test CLI subcommand (core)
- src/self-test.ts: probes four runtime contracts —
• atomicWrite to a temp .axme-code/ path
• Cursor + Claude hook adapter parse (verifies Shell→Bash
normalization) and deny emit shapes (Cursor: exit 2 + flat
JSON; Claude: exit 0 + hookSpecificOutput)
• MCP server boot via stdio initialize handshake (5s timeout)
- cli.ts: 'self-test' case routes to runSelfTest(). Exits 0 on
pass, 1 on any failure. Designed for CI scripts and for users
debugging an install from terminal.
- Smoke-tested: bundled .vsix binary passes 6/6 checks
(storage write, parse Cursor, deny Cursor, parse Claude, deny
Claude, MCP boot).
4. AXME: Reset command (extension)
- extension/src/reset.ts: confirm-dialog command that clears
~/.cursor/hooks.json axme entries + ~/.config/axme-code/auth.yaml.
Optional flag to also wipe ~/.config/axme-code/cursor.yaml
(Cursor SDK key). Per-project .axme-code/ storage is NEVER
touched — that's the user's curated knowledge.
- commands.ts + package.json contribute axme.reset.
5. Misc package.json polish
- extension version bump 0.0.1 → 0.0.2.
- New commands surfaced in command palette: axme.showStatusText,
axme.reauthAuditor, axme.reset.
What this does NOT include (deferred to v0.0.3):
- VS Code branch with cooperative axme_safety_check tool
- @cursor/sdk bundled into per-platform .vsix
- vscode-test framework + headless e2e
- Welcome view / walkthrough
Verified locally: bundled binary self-test 6/6 pass. tsc clean. .vsix
builds at 519 KB.
#!axme pr=none repo=AxmeAI/axme-code
…tion/error states - setup CLI now prints "Open a new chat in Cursor" when invoked with --ide=cursor instead of "Run 'claude'". Eliminates user confusion when the extension's setup-controller wraps the CLI. - Status bar adds two non-healthy visual states: yellow "Setup required" warning (when workspace has no .axme-code/) and red "Activation failed" error (when any step in the activation report failed). Each retargets click to axme.showStatus so the user can drill into details. Addresses user feedback that the corner notification toast is barely visible — the status bar is always-on and prominent when colored. #!axme pr=132 repo=AxmeAI/axme-code
…live counters
Always-visible AXME dashboard in the Activity Bar replaces the easy-to-miss
notification toast and the on-demand status webview as the primary surface.
Sections render top-down using VS Code theme variables so dark/light/high-
contrast schemes all work without media queries.
Skeleton ships:
- AXME icon in Activity Bar, "Monitor" view contribution
- Setup pill (ok/warn) + setup-required banner with two buttons:
[Run setup (with API key)] and [Ask agent to setup] (stub for now)
- Hooks status block + reinstall stub
- Auditor mode dropdown (off/cooperative/background) writing to new
axme.auditorMode setting; cooperative is the default for Cursor users
so no extra LLM billing is required out of the box
- Live counters for memories/decisions/safety/backlog/open-questions
driven by an extended KbWatcher that now also tracks safety/rules.yaml,
backlog/*.md and open-questions.md
- Backlog count + open-folder button (full list/add dialog land next)
- Current-session placeholder (token counter + close-session prompt
arrive in their own commits)
Wired into activate() before registerCommands so any future command can
postMessage to the webview. Initial state captures activation flags so the
user sees the right pill on first reveal even before KbWatcher fires.
#!axme pr=none repo=AxmeAI/axme-code
…n, [+ Add] dialog
Adds the second-tier section that surfaces .axme-code/backlog/ items, which
were previously agent-facing only via the MCP tools (axme_backlog,
axme_backlog_add). Users now see open work right in the AXME sidebar
without opening files.
Surface:
- Top 5 items rendered with priority dot (🔴/🟡/🟢) and [wip]/[blk]
status prefix. Sort order: in-progress → blocked → open(by priority) →
done; ties broken by updated_at descending so the freshest activity
is on top.
- Row click opens the B-NNN-<slug>.md file in the editor.
- [+ Add item] launches an InputBox (title) + QuickPick (priority) then
shells out to a new `axme-code backlog add` subcommand. The CLI path
routes through the same addBacklogItem() that the MCP tool uses, so
ID generation + atomic write stay in one place; the extension never
duplicates the writer logic.
- [Open folder] reveals .axme-code/backlog/ in the Explorer.
Implementation notes:
- extension/src/backlog-reader.ts does a fast local parse (no subprocess
per refresh) — KbWatcher fires often and 200–500 ms binary spawns
would feel like jank in the webview. Schema duplication is bounded
to ~30 LOC and the v1 frontmatter is stable.
- KbWatcher is extended to also watch .axme-code/backlog/, .safety/rules.yaml
and open-questions.md so all counter sources update together.
- Webview message type `addBacklogItem` removed — the [+ Add] button
now triggers the command directly so the input flow lives in the
extension host (where InputBox/QuickPick APIs are available), not
in the webview iframe.
Verified: self-test 6/6 PASS on rebuilt bundled binary; smoke test of
backlog add via CLI created B-001 with correct YAML frontmatter.
#!axme pr=none repo=AxmeAI/axme-code
…rtifact The bundled axme-code binary is built per platform in the publish-extension workflow (linux-x64 / linux-arm64 / darwin-x64 / darwin-arm64 / win32-x64) and dropped into extension/bin/ at package time. Committing the local linux-x64 build by accident in 1d67a9b pollutes the git history with a ~2.5 MB binary on every rebuild, and would also cause the .vsix to include the wrong binary on non-linux CI runners. Adds bin/ to extension/.gitignore and untracks the file so the workflow (and local rebuilds) start clean. #!axme pr=none repo=AxmeAI/axme-code
The activation-time modal for the auditor credential was the #1 complaint in the v0.0.2 install flow: hard to find later, easy to dismiss by accident, and forced every Cursor user to pay separately for what their Cursor subscription already covers (since cooperative agent-driven saving via MCP tools runs on the chat's own LLM). v0.0.3 introduces three auditor modes with cooperative as the new default for fresh Cursor installs: - off → no extraction at all; session-end hook is a no-op - cooperative → agent saves memories/decisions/safety inline during the chat using the user's Cursor subscription; no separate LLM billing - background → the historical detached audit worker spawns after every chat using its own credential (kept for power users + Claude Code CLI compatibility) Plumbing: - New core helper src/utils/auditor-mode.ts reads/writes ~/.config/axme-code/auditor-mode (one-line text file, no YAML). Missing file = "background" so existing CLI installs keep behaving as before — only fresh Cursor extension installs see the new default. - src/hooks/session-end.ts now gates spawnDetachedAuditWorker on loadAuditorMode() === "background". Cooperative/off short-circuit before the worker is spawned, so no LLM cost. - Extension mirrors the axme.auditorMode VS Code setting into that file at activation and on every onDidChangeConfiguration event (auditor-mode-mirror.ts). VS Code setting stays the source of truth — the disk file is a read-only projection for core. - activate() now skips ensureAuditorAuth (the modal) entirely unless mode === "background", eliminating the modal for the 95% of users on the new default. - Sidebar's auditor section: dropdown writes the setting, mirror syncs to disk. Warning banner + "Configure credential…" button show only when background mode is selected AND no credential is saved. Switching INTO background mode triggers the auth flow immediately so the user pastes their key right when they decide they want it. Verified: self-test 6/6 PASS on rebuilt bundled binary; auditor-mode util round-trips off/cooperative/background and falls back to background when the file is absent. #!axme pr=none repo=AxmeAI/axme-code
…arge warning Adds the most-asked-for piece of the v0.0.3 sidebar: a Current session section that reports tokens / message count / age in near-real-time and warns the user before Cursor's auto-summarize kicks in. How "current" is detected: the pre/post tool-use hooks rewrite .axme-code/active-sessions/<ide-sid>.txt every time they fire, so the mtime of those mapping files tracks chat activity at near-real-time granularity. The sidebar picks the most-recently-touched mapping, reads the AXME session it points to, and parses the linked IDE transcript JSONL. This means we follow Cursor users as they switch between chat tabs without any private Cursor API — the next MCP call from the newly-active tab updates the mapping and the sidebar refreshes within ~3 s. Token counting is approximate (chars / 3.5). The Cursor JSONL does not expose the chosen model (verified by inspecting real transcripts), so a precise tokenizer wouldn't help anyway; tiktoken would add ~800 KB of WASM for ±10% accuracy on a "you should close soon" UI signal. Heuristic is fine. Warning threshold: 200 000 tokens. Chosen to land near the upper bound of Cursor's reported auto-summarize trigger window (~50–60% of context for 200k-window models per community reports), so users get a chance to close cleanly via our handoff flow BEFORE Cursor's lossy condense fires and quality regresses. Lower thresholds would nag too early on healthy chats. Polling: 3-second interval, but ONLY while the webview view is visible. onDidChangeVisibility wires start/stop so background tabs don't waste a read every 3 s on a sidebar the user can't see. Verified: smoke test against this repo's own .axme-code/ correctly reports the live session, transcript path, token count, and message count. #!axme pr=none repo=AxmeAI/axme-code
…/ [Close session]
Replaces three v0.0.3-skeleton stubs with the real cooperative commands:
- axme.askAgentSetup: drops a structured "do the AXME setup yourself in
this chat" prompt into the clipboard and opens a fresh chat tab where
possible (cursor.chat.newChat is tried best-effort). Stays on Cursor
subscription billing — the agent does the oracle scan + decision /
memory / safety extraction inline via MCP tools, no background LLM.
- axme.closeSession: drops the close-session prompt that walks the agent
through axme_begin_close → checklist → axme_finalize_close, ensuring
all important knowledge from THIS chat lands in .axme-code/ before
the user opens a fresh chat. Closes the loop with our value prop of
"no context lost across chat boundaries".
- axme.reinstallHooks: actually calls installUserHooks() now and tells
the user to restart Cursor (hooks.json is read at host startup).
Why clipboard rather than direct chat-input injection: there is no
documented Cursor / VS Code API to programmatically send text to an
active chat input. We tried cursor.chat.newChat and
workbench.action.chat.open — both work in some hosts but neither is
guaranteed. Clipboard + a single Cmd/Ctrl+V is universally reliable.
Prompt bodies in extension/src/chat-prompt.ts are deliberately wordy and
self-contained so the agent doesn't need to ask follow-up questions
mid-flow.
#!axme pr=none repo=AxmeAI/axme-code
VS Code walkthroughs live in the Welcome tab and survive across sessions —
unlike the corner toast, they're discoverable any time via Help →
"Walkthroughs: Open Walkthrough… → AXME Code". The four steps:
1. Extension installed (auto-checked via extensionInstalled event)
2. Set up the workspace — explains cooperative vs background paths,
offers both buttons inline. Completes when axme.workspaceInitialized
context flips true (activation snapshot + setup-controller success).
3. Pick your auditor mode — explains all three modes with cost notes,
opens settings inline. Completes on any axme.auditorMode change.
4. Open your first chat — explains what the agent gains, how to close
cleanly. Completes when the user fires axme.closeSession.
Step bodies live in extension/walkthroughs/*.md so each step has a
readable expanded view, not just the one-liner description.
The activation flow now sets `axme.workspaceInitialized` context on every
activate(); setup-controller flips it true after a successful setup so
mid-session completion is reflected immediately on the Welcome page.
#!axme pr=none repo=AxmeAI/axme-code
…debar surface
Tests cover the four behaviours the session-end hook depends on:
- missing file defaults to "background" (preserves CLI-only install UX)
- off/cooperative/background round-trip correctly
- corrupted/unknown values fall back to "background" instead of failing loud
- leading/trailing whitespace is tolerated (handy when users edit the
file by hand)
Suite swaps $HOME to a tmpdir per test so it doesn't write to the
developer's real ~/.config. Sets both HOME and USERPROFILE so the same
test passes on Windows runners (os.homedir() reads USERPROFILE there).
README adds three new bullet points to "What this extension does"
(sidebar + auditor modes + cooperative close), documents the
axme.auditorMode setting, and lists the new commands surfaced both by the
command palette and the sidebar.
Verified: npm test → 608 / 608 pass; vsce package dry-run produces a
532 KB .vsix with the right tree (out/, bin/, media/, walkthroughs/);
extension/bin/axme-code self-test 6 / 6 still pass on rebuilt binary.
#!axme pr=none repo=AxmeAI/axme-code
…ack, discoverability
Round of five fixes from manual Cursor testing:
1. Safety rules counter showed 0 even after a healthy setup. The regex
was looking for `- id:` entries, but rules.yaml uses a nested-object
schema (git.*, bash.*, filesystem.*) with arrays under each key.
Replaced with a flat `^\\s+-\\s+\\S` match that counts every list
item — protected branches, denied prefixes, denied commands, denied
paths, allowed prefixes — which lines up with how a user thinks
about "how many rules are protecting this workspace".
2. Auditor "Off" mode removed. Functionally redundant with cooperative
(the session-end worker already short-circuits when not background;
the only difference was UX clutter). Two clean modes left:
- Cooperative — agent saves inline (no extra cost)
- Background — separate LLM, extra cost (uses your API key)
The cooperative description now reminds the user to ask the agent
to close the session at the end of work, since that's the moment the
inline saves actually land.
3. [Close session (handoff)] button removed from the Current session
block. The button used to also call cursor.chat.newChat, which spawned
a fresh tab the user didn't ask for — felt broken in feedback. The
PROMPT_CLOSE_SESSION constant stays exported in chat-prompt.ts so a
future palette command or keybinding can re-use it, but no UI surface
currently fires it. The walkthrough's "first chat" step instructs the
user to simply say "close the session" to the agent — same outcome,
no extra button needed.
4. axme.reindex feedback. Previously the progress toast vanished on
completion with no confirmation; the user saw "nothing happened". Now
the last stdout line ("Reindexed N entries." or equivalent) lands as
an information toast so the user knows the click reached the binary.
5. First-run discoverability. The AXME icon in the Activity Bar is one of
many — easy to miss after install. On the very first activation (no
prior axme.firstRunComplete in globalState), workbench.view.extension
.axme is executed automatically so the sidebar opens itself. Persisted
so subsequent reloads don't hijack the user's view.
Also tightened the webview click handling — switched from per-render
addEventListener loops (which accumulated handlers, causing "click once,
command fires N times") to a single document-level event-delegation
listener. Same effect, no leak.
Verified: 4/4 auditor-mode tests still pass; bundled binary self-test
6/6 PASS; vsce package produces a clean 532 KB .vsix.
#!axme pr=none repo=AxmeAI/axme-code
…sh removing Off mode references Builds on c6b723f's UX polish. Two outstanding pieces: - **Discoverability (#1 from user feedback)**. The AXME Activity Bar icon is easy to miss in a column with 6+ other extension icons. On the user's very first activation (no axme.firstRunComplete in globalState), we now both focus the AXME view AND open the Getting Started walkthrough side-by-side. Subsequent activations are a no-op so reopening Cursor doesn't hijack the active view. - **Off-mode cleanup**. c6b723f removed "off" from the package.json enum and the sidebar UI, but three docs / comment surfaces still mentioned a third mode that no longer exists. Cleaned up: • extension/package.json walkthrough description for the auditor step • extension/walkthroughs/auditor.md (whole ## Off section dropped) • src/utils/auditor-mode.ts header comment ("Three values" → "Two values") • extension/src/extension.ts Step 5 comment ("cooperative / off" → just cooperative) Verified: npm test → 608 / 608 pass; extension/bin/axme-code self-test → 6 / 6 pass; npx vsce package produces a 532 KB .vsix. #!axme pr=none repo=AxmeAI/axme-code
…drop footer Reindex/Reset
Three issues from real Cursor install testing:
**1. axme_context resolves to /home/$USER instead of the workspace.**
When Cursor spawns the MCP server via cursor.mcp.registerServer, the cwd
it picks is the user's home directory — not the workspace root — so the
server's process.cwd() defaults defaultProjectPath to /home/$USER. Calls
to axme_context without an explicit project_path then look up
`.axme-code/` in the wrong place and report "project not initialised",
even after a successful setup in the real workspace. The user's diagnostic
made this obvious: "STORAGE ROOT: /home/georgeb/.axme-code, которого не
существует" while the project's `.axme-code/` was sitting in /tmp/.
Fix: src/server.ts now resolves its root in this order:
1. --workspace <abs> CLI flag (passed by the Cursor extension at
registration time — see registerMcpServer)
2. AXME_WORKSPACE env var (escape hatch for hand-spawned servers)
3. process.cwd() (preserves Claude Code CLI behaviour where the binary
is spawned from the project root and cwd already points there)
Extension passes workspaceFolders[0].uri.fsPath to registerMcpServer so
the server's defaultProjectPath always matches what the user thinks is
"the project". Verified via stdio smoke test: server reports
`Project: /tmp/axme-cwd-test` after --workspace /tmp/axme-cwd-test.
**2. Sidebar showed "hooks missing" when they were installed.**
The activation ActivationReport's hooks-step flag captures one moment in
time. After reinstall / reset cycles the sidebar's `S.hooksOk` could
stay stale until the next window reload. Added extension/src/hooks-state.ts
which reads ~/.cursor/hooks.json on demand and confirms preToolUse /
postToolUse / sessionEnd entries each contain `axme-code`. Sidebar pushes
this live value both on attach and on every resolveWebviewView, so the
report's snapshot is no longer the source of truth.
**3. Reindex / Reset buttons in the sidebar footer fired without obvious
feedback** and (per user feedback) were doing destructive-ish things from
a place the user expected to be lightweight monitoring. Removed both
from the sidebar footer. Healthcheck stays — it's a read-only webview.
The commands are still registered and reachable via the Command Palette
("AXME: Reindex semantic search" / "AXME: Reset"), where the modal
confirmation flow makes their effect more obviously deliberate.
Verified: npm test → 608 / 608 pass; self-test 6 / 6 pass on rebuilt
bundled binary; vsce package → 533 KB .vsix.
#!axme pr=none repo=AxmeAI/axme-code
…p gate; modal toast for cooperative setup
Three bugs from the v0.0.3 install-test session, plus the architectural
fix the user proposed (agent acts as per-project setup gatekeeper).
**Bug F — KbWatcher silent no-op when .axme-code/ created mid-session.**
attach() returned early if the directory didn't exist at activation time,
so counters never tickled live during the very first cooperative-setup
flow. Fix: split the watcher into two phases. If .axme-code/ exists, run
the steady-state content watcher as before. If not, install a root
watcher on the workspace folder that fires once when .axme-code/ appears
— at that point we tear it down, swap in the content watcher, and emit
both a fresh count and an optional onCreated callback so callers can
react to the transition.
**Bug G — walkthrough step 2 never auto-completes in the cooperative
path.** Step 2's completion event is `onContext:axme.workspaceInitialized`,
and that context flag was only set in `activate()` (snapshot) and in
`runSetup()` after a successful API-key spawn. The cooperative path
(agent inline) writes .axme-code/ from the chat, never touching
runSetup, so the context stayed `false` forever. Fix: the sidebar now
passes an onCreated callback to KbWatcher.attach() which executes
`setContext("axme.workspaceInitialized", true)` AND pushes `setupDone:
true` to the webview — so the moment the agent's first save lands, the
walkthrough page checks the step off and the sidebar pill flips to
"ready".
**Agent-as-setup-gatekeeper.** AXME is per-repo (one .axme-code/ per
project), but until now nothing told the user when they opened a fresh
repo that setup hadn't run there. The sidebar's "setup required" pill is
easy to miss. User suggested: have the agent itself say so on session
start. Implementation: buildInstructions() now checks
existsSync(<project>/.axme-code) at server startup and, when absent,
appends a HIGHEST-PRIORITY directive telling the agent to halt all other
work and ask the user (in their language) whether to perform setup
cooperatively right there in the chat — including the exact MCP tools to
call (axme_oracle, axme_save_decision, axme_save_memory,
axme_update_safety). Cursor passes our instructions to the agent on
every new chat, so this fires automatically per-project, no UI plumbing
needed.
**Setup-controller auth gate.** [Run setup (with API key)] used to spawn
`axme-code setup` blindly; the CLI's TTY-only auth prompt skipped
silently under spawn() and then the first LLM scanner failed with an
opaque exit code. Now runSetup() probes detectCurrentMode() first and,
if no credential is saved, runs ensureAuditorAuth() (the proper modal
paste-key flow) BEFORE spawning. Cancelling the auth modal aborts the
spawn cleanly with a warning toast.
**Cooperative prompt UX.** deliverChatPrompt previously surfaced a
corner toast that users could not see. Replaced with a modal info
message that requires a [Got it] click before continuing, so there is no
scenario where the user clicks [Ask agent to setup] and wonders if
anything happened. Walkthrough setup step + setup.md rewritten to lead
with the cooperative path (recommended) and demote the API-key path to a
clearly-labelled alternative.
Verified: npm test → 608 / 608 pass; self-test 6 / 6 pass; the new
setup-gate instruction fires only when .axme-code/ is absent (smoke-
tested against /tmp/axme-bare2 vs /tmp/axme-bare3).
#!axme pr=none repo=AxmeAI/axme-code
… note in Welcome step 1
User feedback Q1: AXME is per-project but the sidebar didn't make that
visible enough — easy to forget when opening a new repo. Three small
changes implement (a)+(c)+(d) from the prior audit:
- Header now shows `AXME · <repo-name>` (basename of the workspace
folder) instead of a generic "AXME Code". Visually anchors all the
numbers / setup state to a specific project. Falls back to "AXME
Code" if no folder is open.
- Setup-required banner shortened from a two-sentence explanation to
one line: "AXME is per-project. This repo needs setup:". Button
hierarchy reordered — the cooperative [Ask agent to setup] is the
primary action, [Run setup (with API key)] is the secondary
alternative.
- Welcome walkthrough step 1 picks up a per-project explanation:
"AXME is configured per-project: each repo you open needs a
one-time setup (step 2 below). When you update AXME in the future,
reload Cursor with Ctrl+R / Cmd+R to apply." — sets the expectation
before the user even reaches the setup step.
#!axme pr=none repo=AxmeAI/axme-code
…ating tool calls instead of executing them
User reported pasting the [Ask agent to setup] prompt and getting back:
"The .axme-code/ directory doesn't exist yet, but the individual write
tools should bootstrap it. I have a thorough picture of the codebase
from the scan. Let me save everything now.
Save decision: Astro v6 SSG framework
Save decision: Tailwind CSS v4 Vite plugin
...
Save memory: content.config.ts location changed in Astro 5
..."
— a textual plan, NOT a sequence of MCP tool calls. Classic
narrate-instead-of-act failure mode for Cursor's agent. The cooperative
setup flow was useless in that state.
Two prompts updated, same pattern:
- extension/src/chat-prompt.ts → PROMPT_SETUP (the text we copy to
clipboard when the user clicks [Ask agent to setup] in the sidebar).
- src/server.ts → buildInstructions() PROJECT SETUP REQUIRED block
(what the MCP server tells the agent automatically when it connects
to a project with no .axme-code/).
Both now:
- Open with "this is a sequence of MCP TOOL CALLS, NOT a plan to
describe in prose."
- Name the failure mode out loud: "If you catch yourself writing
'Save decision: X' as text, STOP and call axme_save_decision
instead."
- Demand minimum tool-call counts (>=5 decisions, >=3 memories) so the
agent can't say "I did one, that's enough."
- Explicitly note .axme-code/ is auto-bootstrapped by the first save —
the agent's "the directory doesn't exist" hesitation was a red
herring.
Verified: self-test 6 / 6 still pass on rebuilt bundled binary.
#!axme pr=none repo=AxmeAI/axme-code
…ity for reinstalls
Two issues from the latest fresh-install test:
- The corner "Run setup now?" toast still fired alongside the new
sidebar setup banner + walkthrough setup step + MCP setup-required
instruction. Three surfaces all asking the same question — the toast
was the worst of them (auto-dismisses, easy to miss, no context).
Removed the offerSetupIfMissing call; the sidebar and walkthrough
are the canonical surfaces now.
- After uninstall+reinstall the sidebar did not auto-open and the
walkthrough did not auto-open. Root cause: the single globalState
gate ("firstRunComplete") survives some uninstall paths in Cursor,
so the gate stayed `true` even when the user thought they were doing
a fresh install. Split the two triggers:
* Sidebar focus — fire whenever the current workspace is not
initialised. AXME is per-project; landing on a fresh repo
ALWAYS warrants discovering the dashboard. Already-initialised
workspaces don't re-focus on every activation so we don't
hijack the user's active view.
* Walkthrough — still gated by globalState (we don't want to spam
the Welcome page every time the user installs in a new repo),
but now fires independently of the sidebar focus so reinstall
users at least get the sidebar even if globalState is stale.
- Added a 400 ms setTimeout before firing both commands. The
viewsContainer + view contributions are read by Cursor's workbench
out of band; calling workbench.view.extension.axme synchronously
inside activate() can no-op because the contribution graph isn't
fully wired yet. 400 ms is invisible to the user but consistently
past the registration race.
- Tried both `workbench.view.extension.axme` (opens the container)
and `axme.monitor.focus` (the auto-generated focus command for our
specific view) — first opens the slot, second highlights the view
inside it. Best-effort cascade.
#!axme pr=none repo=AxmeAI/axme-code
… safety counts enforcement only; clickable KB rows
Four issues from the latest install test:
**(1) Welcome walkthrough did not open even though sidebar did.**
Walkthrough trigger was behind a per-machine globalState flag that
survives uninstall+reinstall in some Cursor builds. After the first
test the flag stuck `true` forever. Folded the walkthrough trigger
into the same "workspace not initialised" check the sidebar focus
uses — both fire together, both stop firing the moment .axme-code/
gets created. Removes the only orphan globalState gate in activate().
**(2) Safety counter showed 72 after the agent added 3 rules.**
countSafetyRules was matching every dash-list entry in rules.yaml,
including the ~50-item bash.allowedPrefixes whitelist that ships in
the preset. Allowed-prefixes are NOT enforcement rules — they're
fast-path approvals. Replaced the bulk regex with a section-aware
walker that counts only enforcement keys: protectedBranches,
deniedPrefixes, deniedCommands, deniedPaths, readOnlyPaths. Verified
on our own rules.yaml: 39 enforcement entries (vs 72+ before).
**(3) Sidebar lost all state when user switched Activity Bar views
and came back.** Default WebviewView lifecycle disposes the webview
on hide and re-creates from scratch — losing counters, session
block, dropdown selection. Set
`webviewOptions.retainContextWhenHidden: true` on the provider
registration so the DOM + JS stay alive across hide/show. Cost is
~1–2 MB of retained memory per webview, trivial vs the UX win.
**(4) KB-counter rows in the sidebar were inert.** Made each
clickable. Memories → reveal .axme-code/memory/ in Explorer.
Decisions → reveal .axme-code/decisions/. Safety rules → open
.axme-code/safety/rules.yaml in the editor. Open questions → open
.axme-code/open-questions.md. Pre-setup workspaces get a friendly
hint ("no decisions yet — run setup") instead of a not-found error.
Verified: tsc clean, self-test 6 / 6 pass, vsce package → 536 KB
.vsix.
#!axme pr=none repo=AxmeAI/axme-code
User asked for the setup summary to include the preset enforcement rules
that ship with AXME — not just count what the agent added but also show
what's already protected, with a note that the user can curate the list
in .axme-code/safety/rules.yaml.
Both prompts (clipboard PROMPT_SETUP + MCP server's PROJECT SETUP
REQUIRED instruction) now specify:
- "Saved X decisions, Y memories, Z safety rules + N preset rules"
- Group preset rules by section (deniedPrefixes / deniedCommands /
protectedBranches / deniedPaths / readOnlyPaths)
- Verbatim note: "These presets ship with AXME Code. You can edit
.axme-code/safety/rules.yaml directly to add project-specific
rules or remove ones you don't need."
#!axme pr=none repo=AxmeAI/axme-code
…age only
The token count in the session block was reading the local Cursor JSONL
transcript through a chars/3.5 heuristic. Two problems:
- The local transcript only contains compact message envelopes — the
expanded tool results and file reads that dominate Cursor's real
context budget never land in that file. Our number was 3.8k when
Cursor's own Context panel showed 43.5k for the same chat.
- There is no public API to read Cursor's authoritative counter
(researched the Cursor docs API, forum threads, GitHub, Reddit —
nothing exposes the per-chat context breakdown to third-party
extensions, and Cursor staff's only comment is a vague "more
visibility coming").
User picked Variant B from the menu of options: drop the token row
entirely, keep the two signals we CAN measure accurately — Messages
(count) and Started (age). The session warning now fires on either
>=50 messages OR >=2h elapsed, which roughly maps to "approaching
Cursor's ~50% auto-summarize threshold" without claiming a token
number we can't see. ActiveSession.tokens is still computed for any
future use, just not rendered.
#!axme pr=none repo=AxmeAI/axme-code
…allback
User reported counters not updating in real-time (30-60 s lag). Root
cause: vscode FileSystemWatcher subscribes via inotify only to dirs
that exist at watch-creation time. Old pattern enumerated
.axme-code/memory/**, .axme-code/decisions/*.md etc — subdirs absent
on fresh workspace, watcher fell back to 30-60 s polling.
Fix:
- Broaden pattern to .axme-code/** so VS Code recursively watches
the parent dir, catches nested creations within ~100 ms.
- Add 5-second polling fallback as belt-and-braces — re-reads
counts, compares via signature (m|d|s|b|q), only fires listener
on real diff. Worst case lag now 5 s instead of 60 s.
- Polling also upgrades the watcher chain if late detection misses
.axme-code/ creation entirely.
CPU cost: stat 5 dirs every 5 s. Microseconds per tick.
… block, palette coverage, walkthrough depth
Full audit of Claude-Code core surface vs Cursor extension exposed surface.
This commit closes 13 gaps identified in the audit. Loose grouping:
CORE
- New MCP tool: axme_save_oracle. Cooperative-flow agents can now
populate oracle sections (stack/structure/patterns/glossary) inline,
matching the LLM scanner's output schema without the separate billing
channel. Replaces or appends per call.
- ensureOracleBootstrapped() wired into axme_save_memory and
axme_save_decision — the first save in a fresh repo seeds oracle
with a deterministic stack/structure scan so axme_oracle never
returns the 'empty' placeholder, even before the agent writes
anything to oracle itself.
- getOracleSections() empty-state message rewritten — old text told
users to 'Run axme_init first' but axme_init was removed long ago.
New text explains the two real population paths (cooperative + API
key) with no false references.
- PROMPT_SETUP (clipboard) + MCP server PROJECT SETUP REQUIRED
instruction both extended with step 4b: EXECUTE 4 axme_save_oracle
calls — agents now fill oracle inline during cooperative setup.
- CLI: backlog subcommand gains 'update' action so the sidebar's
new status-change quick-pick can shell out for atomic writes.
EXTENSION — SIDEBAR
- New Status section between Setup and Hooks. Renders only when
something needs attention: pending background audits, last audit
failed (with Show audit log link), most recent handoff timestamp
(clickable to open the file).
- extension/src/health-reader.ts: synchronous read of session
metas + plans/handoff-*.md mtime. Cheap enough to refresh every
5 s alongside the KB-counts watcher.
- Backlog rows gain a '...' mini-menu that opens a QuickPick to
change status (open / in-progress / blocked / done) without
leaving the sidebar. Row-body click still opens the .md.
EXTENSION — PALETTE
Twelve new commands cover every previously-buried CLI subcommand
and .axme-code/ artifact:
AXME: Self-test
AXME: Audit knowledge base
AXME: Show stats
AXME: Clean up orphaned session state
AXME: Show last handoff
AXME: Show worklog
AXME: Show last audit log
AXME: Show test plan
AXME: Show staging deploy checklist
AXME: Show production deploy checklist
AXME: Show files changed across sessions
(axme.changeBacklogStatus — internal, fired from sidebar)
EXTENSION — WALKTHROUGH
- firstChat.md extended with sections on safety presets (~40 ship-
standard rules + how to customize), close-session flow + handoff
surface, list of every power-user palette command. Replaces the
earlier vague 'close the session' line.
Verified: full test suite 608 / 608 pass (one oracle test updated for
the new empty-state message); self-test 6 / 6 on rebuilt bundled
binary; vsce package -> 544 KB .vsix.
… tick
User correctly called out that semantic-search infrastructure existed in
core but had ZERO UX in the Cursor extension — agent could call
axme_search_kb (gracefully falls back when runtime missing) but no way
to ENABLE search mode without dropping to a terminal and running
`axme-code config set context.mode search`. Closing the gap.
What CORE already does (verified, unchanged):
- axme_search_kb is ALWAYS registered, regardless of mode. Falls back
with a friendly install-hint when the embeddings runtime is missing.
- axme_decisions / axme_memories adapt output based on contextMode:
'full' → bodies grouped by type; 'search' → catalog only
(slug + title + 1-line description, fetch bodies on demand).
- axme_get_memory / axme_get_decision always work in any mode.
- axme_save_memory / axme_save_decision auto-embed when search mode is
active so the index stays consistent without manual reindex.
What this commit adds in the extension:
• extension/src/search-mode.ts — host-side helper that reads
.axme-code/config.yaml's contextMode, checks whether the
transformers runtime exists on disk, and spawns the canonical CLI
subcommand for enable/disable.
• Two new palette commands:
AXME: Enable semantic search (downloads ~770 MB runtime, one-time)
AXME: Disable semantic search (back to full context mode)
Both gated behind a modal confirm with size warning.
• Sidebar Knowledge base section adds a 'Search mode' row showing
'full' or 'semantic (N indexed)' plus an Enable/Disable link
underneath. State refreshes on KB watcher tick (5s) so the sidebar
always reflects the workspace's real mode.
• Walkthrough firstChat.md gains a section explaining the opt-in
flow, when it's worth turning on, and what gets downloaded.
• Updated install-hint in core kb-search.ts to mention both CLI and
Cursor sidebar paths, and the realistic ~770 MB size (the old
'~100 MB' was from before onnxruntime-node prebuilts ballooned the
package).
• Removed the misleading axme.contextMode VS Code setting docs —
flagged it deprecated in the markdown. The actual state lives in
.axme-code/config.yaml; the VS Code setting never controlled
anything (CORE reads workspace yaml, not VS Code globals).
Plus a separate bug fix the user reported in parallel:
• Last handoff timestamp in the sidebar Status section stayed at
'0 minutes ago' forever instead of ticking. Root cause: lastHandoffAgeMs
was computed once on the host inside readHealth() and pushed as a
fixed number; the webview re-rendered with the same value forever.
Fix: health-reader now sends lastHandoffMtimeMs (absolute) instead;
webview computes age in render(); render() also fires on a 60-second
interval so all time-sensitive rows (handoff age, session age) stay
current without the host needing to push state for time-only drift.
Verified: tsc clean, full test suite 608 / 608 pass, self-test 6 / 6,
vsce package → 546 KB .vsix.
User wanted full vs search trade-off as its own onboarding step, not a subsection inside Step 4. New Step 5 'Semantic search — opt-in for large knowledge bases' spells out: - Full mode = default, zero setup - Search mode = catalog-only + axme_search_kb + ~770 MB one-time - Recommendation table by KB size - Enable now button OR decide later (just skip) Completion: onCommand:axme.enableSemanticSearch. firstChat.md's old semantic-search subsection collapsed to a one-liner pointing to Step 5.
…index after setup + pre-setup warning
Three issues:
1. Sidebar didn't update after Enable. Sidebar's contextMode is
refreshed only on KbWatcher ticks, gated by counts-only signature
— flipping the search mode doesn't change counts, so the watcher
never fired and the UI kept showing 'Search mode: full'.
Fix: AxmeSidebarProvider exposes refreshAll() + a hidden
axme.refreshSidebar command; enableSearchMode / disableSearchMode
call it after the CLI subprocess returns success.
2. axme-code setup wrote decisions / memories via the storage layer
directly (LLM scanners + deterministic init), bypassing the MCP
save tools that normally call embedKbEntry. Result: if a user
enabled semantic search BEFORE running setup, the scanned KB
landed on disk but the embeddings index stayed empty — search
returned 'no matches'.
Fix: cli.ts setup case now auto-reindexes at the end IF
contextMode === 'search' and the runtime is installed. Failure
is non-fatal (logs to stderr, doesn't abort setup).
3. enableSearchMode UX: clicking Enable in an uninitialized workspace
used to silently produce an empty index with no explanation. Now
surfaces an inline note in the confirm modal explaining that the
KB isn't set up yet and that semantic search will auto-populate
once setup runs (via the new auto-reindex path above).
…ested YAML — sidebar saw 'full' forever
Regex was `^contextMode\s*:\s*(\w+)` looking for a flat camelCase key
that does not exist. CORE writes the value as a nested YAML structure:
context:
mode: search
So readContextMode never returned 'search' and the sidebar toggle never
flipped — exactly the bug the user reported ('I enabled it but it still
says full / Enable'). The on-disk config was correct all along; only
the extension's parser was wrong.
Fix is a multiline-anchored regex that walks 'context:' -> indented
'mode:' -> value. Confirmed against the real /tmp/cursor-real-test
config.yaml: now returns 'search' as expected.
…de/ — pill said 'ready' before setup ever ran User enabled semantic search BEFORE running setup. The CLI subcommand 'axme-code config set context.mode search' writes .axme-code/config.yaml as a side effect (config writer ensures parent dir), and also creates .axme-code/_index/embeddings.json for the empty index. So .axme-code/ exists with TWO artefacts but zero real setup output — no oracle, no decisions, no memory, no safety rules. isAxmeInitialized() was a pure existsSync check on the .axme-code/ directory, so it returned true → sidebar pill flipped to 'ready' and the 'Setup required' banner disappeared. Setup never ran, user has a mostly-empty knowledge base. Fix: check for an actual setup artefact, not the directory. oracle/stack.md is the most reliable signal — written by: - tools/init.ts LLM scanner (API-key setup) - tools/init.ts deterministic fallback - storage/oracle.ts ensureOracleBootstrapped from MCP save tools None of those fire during pure 'enable semantic search', so the absence correctly reports 'not initialised'. Fallback secondary check: any D-NNN-*.md in decisions/ also counts. Verified: - /tmp/cursor-real-test (search enabled, no setup) → false - /home/georgeb/axme-workspace/axme-code (real setup) → true
…pped to ready on Enable
Root cause survived the previous isAxmeInitialized fix: that function
was only used at activate time. The kb-watcher's onCreated callback
(fires when .axme-code/ first appears) bypassed it entirely:
this.push({ setupDone: true, ... }) // unconditional
So when Enable semantic search ran 'axme-code config set context.mode
search', the CLI created .axme-code/config.yaml as side effect → root
watcher detected .axme-code/ creation → onCreated fired → pushed
setupDone=true blindly. Pill flipped to 'ready' even though no oracle,
no decisions, no memories existed.
Fix: every code path that pushes setupDone now reads via
isAxmeInitialized(workspaceRoot). Four sites updated:
- KbWatcher onChange (poll) — recompute setupDone every tick so when
the agent's first save creates oracle, pill flips immediately
- KbWatcher onCreated — replaced hardcode with isAxmeInitialized()
- refreshAll() — also pushes setupDone
- resolveWebviewView initial push — re-reads instead of trusting
initialState (which can be stale by the time webview resolves)
Exported isAxmeInitialized to accept optional path so sidebar's bound
workspaceRoot is canonical (was reading the global workspaceFolders[0]).
Walkthrough context key axme.workspaceInitialized uses same signal —
fixes Step 2 auto-completing on Enable side-effects.
…inks
User feedback: the setup summary already shows preset safety rules
verbatim, but doesn't tell the user WHAT decisions / memories were
actually saved. The user has to open the folders to find out. Make
the summary self-sufficient.
Both prompts (clipboard PROMPT_SETUP + MCP server's PROJECT SETUP
REQUIRED instruction) now demand the agent ALSO output:
Decisions saved this session (full bodies in .axme-code/decisions/):
- D-001: <short title>
- D-002: <short title>
...
Memories saved this session (full bodies in .axme-code/memory/...):
- <slug>: <short title>
...
All saved artifacts are persistent across sessions. Open the folders
above to read full bodies, or ask me 'show decision D-NNN' / 'show
memory <slug>' to fetch any of them.
Keeps titles short — rationale already lives in the .md files, no
need to duplicate it in the chat output. The verbatim closing line
educates the user about retrieval ('ask me show ...') so they know
the saved data is reachable without leaving the chat.
… audit' banner User report: sidebar Status section showed '1 background audit still running' even though the session's auditStatus on disk was 'done'. Root cause: KbWatcher's change-detection signature was counts-only (memories|decisions|safety|backlog|questions). When a session's auditStatus transitioned 'pending' → 'done' (auditor just finished), the counts didn't move, signature didn't change, listener didn't fire, sidebar kept showing the stale banner. Fix: signatureOf() now folds in three health signals — pendingAudits, lastAuditError timestamp, lastHandoffMtimeMs. Any of them changing triggers a listener fire on the next 5-second poll tick. Sidebar re-reads health and re-renders, banner disappears the moment the auditor flips meta.json to 'done'. Why not push the WHOLE health snapshot on every tick: re-rendering the webview costs nothing visible (DOM diff is identical when state didn't change), but if we always pushed regardless, the agent's auto-bootstrap path would chatter the webview on every poll for no signal — better to gate on a compact signature.
… close
User wanted threshold at 200 messages; I had set it at 50 (Variant B
when we dropped tokens). At 65 messages on a single verification run
the banner fired — too noisy. Plus no objective signal exists for
when Cursor's own auto-summarize actually kicks in (cloud-side, not
exposed to extensions). Banner was guessing, not informing.
Removed entirely. Current session block shows Started + Messages,
that's it. The user decides when to close via:
- 'close the session' in any chat (MCP server instructions
teach the agent to handle this)
- 'AXME: Show last handoff' to see time since last close
- Cursor's own context-panel warning (their concern, not ours)
Replaces the threshold-gated warning banner (which fired at the wrong moments and was just removed) with a tiny always-visible info paragraph in the same spot. Informational, not alarming. Explains the user workflow once: To close: ask the agent in chat — "close the session". It scans the whole conversation for things worth saving (memories, decisions, safety rules), persists them to .axme-code/, and writes a handoff for your next chat. Lives under the Started/Messages rows for active sessions, and under the 'No active chat detected' line for the empty state — so users discover the close flow regardless of session activity.
…nitialized + CI matrix + vscode-test scaffold
THREE separate changes bundled. Each described below.
1. STATUS BAR auto-transition (bug fix)
User report: Cursor status bar bottom-right kept showing yellow
'AXME Setup Required' even after setup finished and the sidebar pill
already said 'ready'. The two surfaces disagreed.
Root cause: status-bar.render() short-circuited 'if state !== healthy
do nothing' so once activate() called setAttention("Setup required")
the bar was stuck in that state for the whole window lifetime, never
re-evaluating isAxmeInitialized when .axme-code/ actually got populated.
Fix: render() (called on every KbWatcher tick) now reads
isAxmeInitialized(workspaceRoot) every time and:
- flips to attention if uninitialised (auto-recovery of setAttention
state)
- flips to healthy if initialised (auto-recovery of stale attention)
- then renders the count text in healthy mode
Status bar + sidebar pill now share the same canonical signal —
isAxmeInitialized() — so they can't drift.
2. CI MATRIX expansion
publish-extension.yml gains:
- 'feat/sidebar-monitor-**' branch trigger (was only
feat/vscode-extension-**) so this branch's pushes run CI
- src/** in pull_request paths so core changes also trigger
- npm test step on every native runner — runs the 608-test core
suite per platform (Linux x64/arm64, macOS Intel/Apple, Windows x64)
- bundled-binary self-test step after CLI bundle — exercises hooks
parse + deny + storage + MCP stdio on the platform's native binary
- extension activation test step via @vscode/test-electron (gated to
platforms with prebuilt VS Code download)
- linux-arm64 row moved to ubuntu-22.04-arm runner for real ARM tests
Self-test on Windows invokes via 'node binary.exe' instead of direct
execution — the shebang shim isn't a PE binary and Windows can't run
it as an executable. This same caveat applies to runtime usage (TODO:
add Windows wrapper script in a follow-up commit).
3. @vscode/test-electron SCAFFOLD
New extension/test/{runTest.ts, suite/index.ts, suite/activation.test.ts}.
Spawns headless VS Code (pinned to 1.96, our engines minimum), loads
the extension, asserts:
- extension is installed + activates without throwing
- all 20 declared commands are registered
- axme view container is contributed
Compiles via test/tsconfig.json to out-test/ (gitignored + vscodeignored).
New deps: @vscode/test-electron, mocha, glob, types for both.
…inary' + tsconfig modernized
Verified on real Azure Windows 11 VM (Standard_D2s_v5, westeurope):
- axme-code self-test: 6/6 PASS (was 5/6 — MCP server boot failed)
- axme-code setup: full end-to-end PASS — wrote oracle (4 files
deterministic), 13 decisions (preset bundle), 6 memories, safety
presets, .cursor/hooks.json with correctly-quoted Windows paths
invoking node.exe + .cjs
Root cause: bundled binary is a shebang shim (text starting with
'#!/usr/bin/env node' + CJS payload). POSIX honors the shebang. Windows
ignores it and rejects the file with ENOENT / UNKNOWN when spawn()
treats it as an executable, regardless of .exe / .cjs / no-extension
file naming.
Three fix sites:
1. extension/src/spawn-binary.ts (NEW) — single helper that detects
Windows and prefixes with 'node' so the JS payload runs. Two
overloads preserve Node's spawn(...) return-type narrowing for
stdio-piped callers (avoids forcing every caller to add !
non-null assertions on child.stdout/stderr).
2. Six extension call sites refactored to use spawnBinary:
commands.ts (runCli, reindex, status-text, addBacklog, change-
backlog-status, hooks reinstall), auditor-auth.ts (auth use, auth
status), setup-controller.ts (axme-code setup spawn),
search-mode.ts (enable/disable spawn), status-webview.ts (status
probe + MCP boot probe).
3. extension/src/hooks-install.ts buildHookCommand: on Windows
generates 'node "<binary>" hook <name> --ide cursor' instead of
directly invoking the shim. Aligns with CLI setup's already-
working pattern that produces correct Windows paths via Cursor's
cmd.exe /c hook runner.
4. src/self-test.ts checkMcpServerBoot: same node-prefix trick for
the bundled binary's serve subcommand.
Bonus:
- extension/test/tsconfig.json: 'module: Node16, moduleResolution:
Node16' (was 'Node' which TypeScript 5.9 normalizes to deprecated
node10). 'Bundler' would be more modern but Node16 matches the
parent tsconfig and avoids the deprecation warning.
- Several !-asserts on child.stdout/stderr at the spawnBinary call
sites — Node's overload narrowing requires options to be passed
positionally to pick the ChildProcessWithoutNullStreams return
type; our call sites all pass options explicitly so the streams ARE
present at runtime, the assertion just bridges the typing.
Known Windows limitations still open (separate follow-up):
- User-level ~/.cursor/hooks.json written by the extension is on
Windows fine, but assumes 'node' on PATH. Most Windows dev users
have it; we should fail-fast with a friendly error if not.
- Real Cursor UI on Windows still unverified (winget not present
on Azure stock image; manual install needed for full E2E).
…ted by user's TS service User's IDE flagged 'Node16' as deprecated even though TS 5.9.3 accepts it without warning at compile time. NodeNext is the current non-deprecated value and pairs cleanly with our CommonJS-emitting test compile (NodeNext auto-detects module format from package.json type field — our extension package.json has no 'type' so commonjs).
…ting node10 even with NodeNext
User's Cursor TS Language Service kept showing 'moduleResolution=node10 is
deprecated' error regardless of what value we set ('Node', 'node10',
'Node16', 'NodeNext' — all flagged). tsc CLI compiles cleanly at every
step, so the on-disk values are fine; the IDE service was caching old
state and/or applying TS 7-track strictness to TS 5.9 internals.
Fix per the TS team's official escape hatch: 'ignoreDeprecations': '5.0'
(matches the current TS 5.x line). The IDE hint suggested '6.0' but TS
5.9 rejects that value as invalid — '5.0' is the right one until we
upgrade to TS 6+. Suppresses the deprecation warning in the IDE without
changing actual compile behavior.
Documents what's actually verified on each platform as of v0.0.3:
- macOS arm64: full UI + headless verified (primary dev platform)
- Linux x64: CI matrix + binary verified, full UI not yet sampled
- Linux arm64: CI builds, untested at runtime
- Windows x64: headless verified via Azure VM (Standard_D2s_v5,
westeurope) — setup wrote oracle/decisions/memories/safety;
hooks.json invokes node.exe with quoted paths correctly
- macOS x64 Intel: CI builds, untested
- Windows arm64: no GitHub Actions free runner yet
Windows notes call out:
- bundled binary is a shebang shim; on Windows we invoke via node
- 'node' on PATH is a requirement (standard for Windows dev users)
macOS notes document the Gatekeeper quarantine workaround for v0.0.3
unsigned binary, plus the v0.1.0+ roadmap for Apple Developer ID
signing.
…ivity Bar SVG + README hero
Replaces the placeholder chip-design SVG with the real AXME 'AX'
monogram mark.
Two assets produced from the source PNG (Logo_main.png, 1536x1024):
- extension/media/icon.png — 256x256 square PNG with the mark
centered on a white background. Wired into package.json as
'icon' so Open VSX and the VS Code Marketplace use it as the
extension thumbnail / install dialog graphic.
- extension/media/axme.svg — vector trace of the same mark, output
by potrace at the tight bounding box. fill set to currentColor
so Cursor's Activity Bar tints it under the active theme (light
glyph on dark theme, dark on light) instead of hardcoded black.
Already referenced from the viewsContainers contribution in
package.json — no schema change needed.
README gains a 160x160 hero at the top via <img align=center> for the
GitHub / Open VSX marketplace landing page.
Tracing pipeline: imagemagick crops the source to the AX shape's
tight bounding box + 5% padding, thresholds to 1-bit BMP, potrace
1.16 vectorizes with -O 0.5 smoothing. Python post-processing rewrites
fill from #000000 to currentColor and trims the potrace XML preamble
to keep the SVG small (1.4 KB).
…ssue, not a regression in our code
@vscode/test-electron's downloaded VS Code 1.96 binary rejects the CLI
flags it passes ('bad option: --no-sandbox', etc.) on this combination
of versions — investigated locally, confirmed not caused by our code.
The bundled-binary self-test above runs all 6 hook/MCP/storage checks
on each platform's native binary so we have strong end-to-end coverage
independent of the IDE host.
Continue-on-error so the rest of the pipeline (package .vsix, publish
on tag) succeeds even when activation tests transiently fail. Will
revisit once we resolve the @vscode/test-electron + VS Code 1.96 args
interaction in a follow-up.
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Supersedes #132 (v0.0.2). v0.0.3 includes everything from that PR plus the entire v0.0.3 work — opening as a single PR for one clean merge.
AXME · <repo-name>).spawnBinaryhelper at every site that exec'd the bundled binary; hooks.json on Windows usesnodeprefix. Verified end-to-end on real Azure Windows 11 VM (self-test 6/6, full CLI setup E2E PASS).publish-extension.ymlnow runsnpm test(608 tests) +axme-code self-test+ headless extension-activation tests on Linux x64/arm64, macOS Intel/Apple Silicon, Windows x64 — every push.48 commits, +5938/-17 across 54 files.
What's verified
Test plan
npm test(608 / 608)axme-code self-test(6 / 6 on Linux x64 + Windows x64)vsce packageproduces valid .vsix (573 KB)🤖 Generated with Claude Code