80 Commits

Author SHA1 Message Date
Mert Koseoglu 10ce5fb468 fix(v1.0.108): #415 hook destruction + #411 mcp path + #414 win hook resilience
#415 — settings.json data loss (CRITICAL)
- pretooluse.mjs: REMOVED destructive `entries.filter(...!some(isCtxMode))` block
  that wiped co-located user SessionStart hooks on every PreToolUse fire
  (gated by per-version marker, fired once per machine per version)
- src/adapters/claude-code/index.ts: replaced entry-level filter at the
  "allCovered" branch with inner-hook level strip + empty-entry prune;
  user-owned siblings now preserved
- Safe block at lines 357-385 (stale-path cleanup with `isAnyContextModeHook`
  guard) intentionally untouched

#411 — cached .mcp.json points to previous version
- src/cli.ts upgrade(): write `${CLAUDE_PLUGIN_ROOT}/start.mjs` literal
  placeholder instead of `resolve(pluginRoot, "start.mjs")` absolute path.
  Prior absolute path baked-in OLD version dir at write time → broken once
  #181 lazy cleanup removed that dir → MCP reconnect failed
- Matches Anthropic canonical pattern (claude-mem, our own
  .claude-plugin/plugin.json:23-29)

#414 — Windows hook crashes (cjs/loader:1479 + silent fail)
- NEW hooks/run-hook.mjs: universal crash-resilient wrapper. Installs
  uncaughtException + unhandledRejection handlers BEFORE handler invocation.
  Dynamic-imports side-effect modules (suppress-stderr, ensure-deps) inside
  try/catch — static top-level imports threw at parse time and bypassed all
  catch blocks (architect's critical finding)
- 5 hook entries (sessionstart, userpromptsubmit, pretooluse, posttooluse,
  precompact) refactored to one-line `runHook(async () => {...})` pattern.
  No top-level static side-effect imports remain
- Logs to ~/.claude/context-mode/hook-errors.log before exit 0 — silent
  ghost hooks no longer possible
- scripts/postinstall.mjs: also normalize hooks.json at install time (was
  only normalized on MCP boot — but hooks fire independently of MCP)

#408 — better-sqlite3 binding missing on Windows
- Merged PR #410 by @ousamabenyounes (5/6 prior PRs merged) via squash:
  3-layer self-heal in scripts/heal-better-sqlite3.mjs (prebuild-install
  via process.execPath → npm install fallback → actionable stderr).
  Wired into postinstall, ensure-deps, and cli doctor hint
- All CI green (3 OS matrix)

Tests:
- 4 new behavioral run-hook tests (subprocess + poisoned-import staging)
- 2 new co-location preservation tests for #415
- Inverted .mcp.json placeholder test for #411
- Updated cli.test.ts anchors for new runHook architecture
- 9 pre-existing failures unrelated (8 opencode adapter + 1 continuity
  parallel-spawn flake — both pass in isolation, fail before this commit)

Verified by direct repro: /tmp/repro-415.sh exit=1 (bug eliminated),
all hooks crash-safe via `node hooks/X.mjs </dev/null` smoke test.
2026-05-04 18:01:00 +03:00
Ben Younes 5432575ae3 fix(install): self-heal missing better-sqlite3 binding on Windows (#408) (#410)
Closes #408. 3-layer self-heal (prebuild-install via process.execPath → npm install fallback → actionable stderr). Wired into postinstall + ensure-deps + cli doctor hint.

Co-authored-by: ousamabenyounes <ousama.benyounes@gmail.com>
2026-05-04 17:43:18 +03:00
Mert Koseoglu 8641fb8504 fix(cache): address agent army review — 7 security and correctness fixes
Agent review found critical issues in the initial cache self-heal:

1. CRITICAL: Layer 4 global hook was dead code — now registers in
   ~/.claude/settings.json SessionStart (Claude Code doesn't auto-discover hooks)
2. HIGH: Path traversal — installPath now validated inside plugin cache root
   via resolve(rp).startsWith(cacheRoot + sep) in all 4 code paths
3. HIGH: server.ts bundle mode — symlink target used wrong dir, now uses
   pluginRoot pattern (package.json existence check)
4. HIGH: Dangling symlink — lstatSync + unlinkSync before symlinkSync
   prevents EEXIST when broken symlink already exists
5. MEDIUM: Tests asserted .sh but code deploys .mjs — fixed
6. LOW: Dead lstatSync import removed, unlinkSync in static imports
7. LOW: Exact key match (=== "context-mode@context-mode") instead of includes()

13 TDD tests now cover: dangling symlink, path traversal, exact match,
settings.json registration, and all previous behaviors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-26 14:21:02 +03:00
Mert Koseoglu 69a7eca138 fix(cache): remove duplicate postinstall block + replace bash hook with pure Node.js
- postinstall.mjs: removed duplicate self-heal block (was copy-pasted twice)
- Global heal hook: replaced #!/usr/bin/env bash with #!/usr/bin/env node
  Bash dependency caused issues on Windows (no bash) and macOS with SIP/MDM
  security policies that restrict shell execution. Pure Node.js works everywhere.
- Auto-cleans old .sh hook if present, deploys .mjs version
- Windows: uses junction type for symlinks (no admin required)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-26 14:20:43 +03:00
Mert Koseoglu 8d84097307 fix(cache): 4-layer self-heal for plugin cache mismatch (anthropics/claude-code#46915)
Claude Code auto-update can leave installed_plugins.json pointing to a
non-existent directory, breaking all hooks. This adds 4 defense layers:

1. start.mjs startup: reverse heal — symlink from broken registry path to our dir
2. server.ts first tool call: mid-session heal — catches auto-update during session
3. postinstall.mjs: backward symlink on new install for stale registry
4. start.mjs auto-deploy: global SessionStart hook at ~/.claude/hooks/ that
   survives total plugin cache breakage

9 TDD tests verify heal behavior with real filesystem fixtures.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-26 13:55:39 +03:00
Murat Aslan 6b1775736a fix(openclaw): register MCP sidecar on install so ctx_* tools surface to agent (#339)
* fix(openclaw): register MCP sidecar on install so ctx_* tools surface to agent

context-mode's ctx_* tools live in server.bundle.mjs and are exposed over
stdio MCP. Other adapters (Claude Code, Codex, Cursor) spawn the bundle via
their platform's mcpServers config. The OpenClaw install script wrote
plugins.allow / plugins.entries to openclaw.json but never added
mcp.servers.context-mode, so the gateway never spawned the sidecar and
the agent never saw the ctx_* tool list — while openclaw plugins list,
openclaw doctor, and scripts/ctx-debug.sh all reported healthy state.

Changes
- scripts/lib/register-openclaw-config.mjs (new): extracts step 5 of the
  install script into a testable helper. Writes plugins.allow / .entries /
  cleans legacy plugins.load.paths (existing behavior) and additionally
  registers mcp.servers.context-mode pointing at
  <pluginRoot>/server.bundle.mjs. Idempotent: re-running is a no-op;
  stale server paths are refreshed.
- scripts/install-openclaw-plugin.sh: step 5 delegates to the helper.
- tests/plugins/openclaw.test.ts: 5 unit tests for the helper (MCP entry
  presence, idempotency, stale-path refresh, plugins.allow/entries contract,
  legacy plugins.load.paths cleanup).
- docs/adapters/openclaw.md: new troubleshooting entry documenting the MCP
  sidecar requirement and the manual openclaw mcp set recovery command.

Verification
- npm run typecheck: clean
- vitest tests/plugins/openclaw.test.ts tests/adapters/openclaw.test.ts:
  117/117 pass (baseline 112 + 5 new)
- Live: on OpenClaw 2026.4.22 + context-mode 1.0.89, after the fix the
  agent tool inventory includes context-mode__ctx_execute,
  context-mode__ctx_search, context-mode__ctx_fetch_and_index, and the
  rest of the ctx_* surface (OpenClaw prefixes MCP-sourced tools with
  the server name).

Debugging walkthrough (initial wrong diagnosis, cross-check with
@benzntech, server.ts trace that surfaced the registerTool calls,
final resolution):
https://gist.github.com/murataslan1/cd7b27577fcb535d56fe318c2339b400

Companion to issue #45 (follow-up comment:
https://github.com/mksglu/context-mode/issues/45#issuecomment-4313313422).

Pre-existing test failures in tests/hooks/integration.test.ts (Security
Policy Enforcement) are present on main too (reproduced by git-stashing
this PR and re-running), so they are not caused by this change. They
appear related to the PreToolUse relaxation commits (415ce57, 2731ca2,
ece3abb) and are out of scope here.

Scope is limited to OpenClaw adapter files and install path; hooks,
src/server.ts, the session layer, and all non-OpenClaw adapter tests
are untouched.

* fix(openclaw): prefix ctx_* names in AGENTS.md so the model invokes MCP variants

Complements the previous commit. With the MCP sidecar registered, OpenClaw
surfaces the plugin's tools as context-mode__ctx_* (server-name prefix is
automatically applied by OpenClaw's MCP aggregator). The routing guidance
injected via AGENTS.md still referenced the unprefixed names (ctx_execute,
ctx_search, ...), which left the model to bridge the naming gap on its own.

UI QA on OpenClaw 2026.4.22 + context-mode 1.0.89 confirmed this was costly
in practice: the model would invoke context-mode__ctx_fetch_and_index first
(good), but then redundantly fall back to the built-in web_fetch for the
raw content, and skip context-mode__ctx_search entirely in favor of a
web_fetch + ctx_execute combo. The unprefixed guidance made the built-ins
look like the closer match when under pressure.

This commit rewrites all 14 ctx_* mentions in configs/openclaw/AGENTS.md
to use the context-mode__ctx_* form the model actually sees. Sanity check:

  $ grep -c 'context-mode__ctx_' configs/openclaw/AGENTS.md   # 14
  $ grep -cE '\bctx_[a-z]' configs/openclaw/AGENTS.md         # 0

Scope is still OpenClaw-only — configs/pi/AGENTS.md and every other
adapter's AGENTS.md are untouched, because those platforms don't apply
the server-name prefix.

Tests unchanged; this is a system-prompt text-only change. typecheck and
the full tests/plugins/openclaw.test.ts + tests/adapters/openclaw.test.ts
suite still pass (117/117).

* fix(openclaw): preserve unrelated MCP server fields; add edge-case tests

Addressing the review points from Codex's independent CLI review of PR #339:

1. The helper previously did a full reset of mcp.servers["context-mode"] on
   every path refresh, which would silently drop user-supplied custom fields
   (env, cwd, timeout, anything OpenClaw adds in a future release). It now
   spreads the existing entry and only overwrites the two fields the helper
   owns (command + args).

2. Added two edge-case tests in tests/plugins/openclaw.test.ts:
   - "preserves unrelated fields on the existing mcp.servers entry when
     refreshing the path" — seeds env/cwd/timeout on the old entry, bumps
     pluginRoot, asserts all three survive alongside the new args[0].
   - "throws a useful error when the runtime config is not valid JSON" —
     exercises the previously-uncovered parse-error path.

Test count 117/117 → 119/119 on `tests/plugins/openclaw.test.ts` +
`tests/adapters/openclaw.test.ts`. Typecheck still clean.

Scope unchanged — still inside OpenClaw adapter/install/tests.

---------

Co-authored-by: Murat Aslan <murataslan1@users.noreply.github.com>
2026-04-25 19:01:24 +03:00
Mert Koseoglu 6c4dd7a939 docs: pin Codex ≤0.116.0 for exec-mode MCP, add version check to debug script
- README + platform-support.md: document exec-mode regression (v0.118.0),
  pin workaround, link to openai/codex#16685
- ctx-debug.sh: detect Codex CLI version, warn if ≥0.118.0
- Issue #45: murataslan1 promoted to QA Lead (Codex CLI), added Known
  Platform Issues table, added k1lgor (Windows)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 19:50:46 +03:00
Mert Koseoglu e5002c08c6 refactor(debug): JSON-only output, no markdown file
- Output is now a single JSON file at /tmp/ctx-debug-<ts>.json
- JSONL accumulator replaces markdown generation (check/kv/warn/detail → JSONL)
- Config file contents properly JSON-escaped via node (was broken tr pipe)
- Terminal shows only: pass/fail summary + JSON path + copy hint
- Converted remaining printf checks to check()/warn() calls
- No flags needed — runs all 18 sections by default

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 19:00:44 +03:00
Mert Koseoglu bc219da04f fix(debug): fix 6 failing sections in ctx-debug.sh v2
- Set NODE_PATH to plugin node_modules (require('better-sqlite3') now works)
- Set CLAUDE_PLUGIN_ROOT for hook execution tests
- Replace server import with dep resolution (import starts MCP transport, hangs)
- Fix grep -c integer parse: tr -d whitespace, fallback defaults
- Replace bare timeout with timed() helper (macOS gtimeout fallback)
- Fix WARN_N grep pattern (unicode emoji → text patterns)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 17:59:29 +03:00
Mert Koseoglu 949e0b849f feat(debug): ctx-debug.sh v2 — 18 sections, temp file output, JSON
Major DX overhaul:
- No flags — runs all 18 sections automatically
- Output goes to temp files (/tmp/ctx-debug-<ts>.md + .json)
- Terminal shows compact summary: pass/fail counts + failed items only
- Copy hint per platform (pbcopy/xclip/clip)

New sections (65% → 90% issue coverage):
- Section 13: Hook execution — PreToolUse deny/passthrough, SessionStart routing
- Section 14: MCP server startup — module import test
- Section 15: SQLite concurrency — WAL mode, orphaned journals, concurrent writes
- Section 16: Adapter validation — detectPlatform + validateHooks + checkPluginRegistration
- Section 17: Sandbox environment — env denylist, CA certs, TMPDIR writable
- Section 18: Network/TLS — HTTPS connectivity, proxy detection, Snap confinement, disk space

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 17:53:39 +03:00
Mert Koseoglu 9dd788e583 fix(debug): fix BSD sed backreference + integer parse on macOS
- mysql/redis/https patterns had \3 but only 2 capture groups → \2
- Session DB count: use wc -l instead of grep -c (avoid multiline parse)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 17:40:07 +03:00
Mert Koseoglu 04182a3f88 fix(debug): fix 6 critical issues in ctx-debug.sh
- Redaction: add postgres/mongodb/mysql/redis/https connection string patterns
  (was leaking Supabase passwords in Cursor mcp.json)
- CWD: use git root instead of pwd for project-level config detection
- Adapter detection: scan config dirs (~/.claude, ~/.cursor, etc.) in addition
  to env vars — script now works from terminal outside a session
- Process check: exclude context-mode-dashboard, esbuild, wrangler, workerd
- Hook registration: verify PreToolUse/PostToolUse/PreCompact/SessionStart
  are all registered (not just file existence)
- Session DBs: check all adapter session dirs, not just ~/.claude/

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 17:35:56 +03:00
Mert Koseoglu 4eba5aaf0a feat: add cross-platform debug script + update issue/PR templates
- Add scripts/ctx-debug.sh: 609-line diagnostic script covering 12 sections
  (system info, runtimes, better-sqlite3 ABI, adapter detection, config files
  for all 12 adapters with redaction, hook validation with stale path detection,
  FTS5 test, executor test, process check, session DBs, env vars)
- Update bug_report.yml: require debug script output, 12 adapter dropdown,
  9 OS options (Apple Silicon/Intel, Ubuntu/Debian/Fedora/Arch, Git Bash/WSL/PowerShell)
- Add feature_request.yml: new feature request template
- Update PULL_REQUEST_TEMPLATE.md: 112 → 47 lines, all 12 adapters, Windows path notes
- Update CONTRIBUTING.md: reference debug script, fix stale slash command names
- Update README.md: add debug script to utility commands
- Fix #223: include stderr in doctor server test FAIL output

Based on analysis of 90 issues + 100 PRs by 20 parallel agents.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 17:29:20 +03:00
Mert Koseoglu cd9cd83612 fix: use openclaw.json as single source of truth in installer
Removed runtime/openclaw.runtime.json fallback entirely.
OpenClaw uses openclaw.json as the single config file since v2026.3.28+.
Source: https://docs.openclaw.ai/tools/plugin

- RUNTIME_JSON → OPENCLAW_JSON (no fallback, no backwards compat)
- Updated docs/adapters/openclaw.md references
- Zero legacy runtime.json references remaining in codebase

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 16:33:36 +03:00
Victor P aa55232488 fix: support openclaw.json in installer script
Co-authored-by: Fix PR <you@example.com>
2026-04-03 16:33:36 +03:00
Mert Koseoglu 815de2b56d fix: marketplace sync, OpenCode hooks, routing guard, OpenClaw env vars (#156 #158 #159 #160)
## Issue #158 — start.mjs unconditionally writes CLAUDE.md
- Added hook-capable platform guard: skip routing file write when
  CLAUDE_SESSION_ID, GEMINI_PROJECT_DIR, OPENCODE, OPENCLAW_HOME,
  or OPENCLAW_CLI env vars are present (sessionStart hook handles it)

## Issue #159 — OpenCode hook interface mismatch
- Fixed opencode-plugin.ts: two-param (input, output) hook signature
  matching upstream @opencode-ai/plugin API
- Field mapping: tool_name→input.tool, tool_input→output.args,
  tool_output→output.output, is_error removed
- Arg mutation now correctly targets output.args (read by OpenCode)
- Updated adapter index.ts and all tests

## Issue #160 — Marketplace sync: cli.bundle.mjs missing
- ctx_doctor: runs diagnostics in-process (no CLI dependency)
- ctx_upgrade: temp .mjs file fallback when CLI missing (cross-platform)
- start.mjs: CLI self-heal shim (cli.bundle.mjs from build/cli.js)
- session-loaders.mjs: bundle-first with build/session fallback
- Skills: prefer MCP tool, Bash as fallback

## Additional fixes
- Replaced fabricated OPENCLAW_PROJECT_DIR with real OPENCLAW_CLI env var
  (verified against openclaw/openclaw source: src/infra/openclaw-exec-env.ts)
- postinstall.mjs: improved nvm4w detection, isSafeWindowsPath guard
- Removed dead basename import from session-loaders.mjs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 04:42:05 +03:00
Mert Koseoglu 182fc47287 fix: improve nvm4w postinstall — detect all shim locations, fix stale shims (#156)
- Replace deprecated `npm bin -g` with `npm config get prefix`
- Use `where context-mode.cmd` to find ALL shim locations (including
  stale ones at C:\nvm4w\nodejs\)
- Create directory junctions at every shim location where node_modules
  doesn't exist, so stale .cmd shims can resolve the package
- Rewrite stale shims that reference old `build\cli.js` → `cli.bundle.mjs`

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 16:57:33 +03:00
Mert Koseoglu 4c319eb4ab fix: inline ensureNativeCompat into start.mjs & add nvm4w junction fix (#156)
- Move ensureNativeCompat from native-abi.mjs directly into start.mjs
  to prevent missing-file errors when marketplace updater skips new files
- Delete native-abi.mjs (no longer needed as separate module)
- Add scripts/postinstall.mjs with Windows nvm4w directory junction fix:
  detects when npm bin dir and node_modules are on different paths and
  creates a junction so the .cmd shim can resolve the package
- Update tests: extract function from start.mjs source at test time
  via temp module to avoid code duplication

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 16:49:16 +03:00
Mert Koseoglu 7ac0c451ef fix: include Pi extension in version-sync targets
The .pi/extensions/context-mode/package.json had a hardcoded version
that wasn't synced by the version lifecycle hook. Now included in both
the sync script targets and git add staging.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 20:52:59 +03:00
Mert Koseoglu 6599b63405 fix(openclaw): env var passthrough, printf portability, and docs alignment
- Install script now respects $OPENCLAW_STATE_DIR env var as fallback:
  ${1:-${OPENCLAW_STATE_DIR:-/openclaw}}
- Replace echo '\n' with printf in postinstall for POSIX portability
- Update README.md and CONTRIBUTING.md to reference npm run install:openclaw
  as the primary install method (aligns with docs/adapters/openclaw.md)

Refs #123

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 20:52:58 +03:00
Pedro Almeida 54e0246c83 feat(openclaw): improve install UX with preflight guards and npm alias (#147)
* feat(openclaw): add preflight guards to install script

Checks for node in PATH, OPENCLAW_STATE_DIR existence, and
runtime/openclaw.runtime.json before proceeding.

Refs #123

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(openclaw): replace Python with node -e for runtime.json registration

Removes the python3 dependency from the install script. The node -e
replacement preserves all four operations: read JSON, deduplicate
load.paths, add to allow, add to entries.

Refs #123

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(openclaw): add install:openclaw alias and conditional postinstall hint

npm run install:openclaw runs the install script. The postinstall
hint only prints when OPENCLAW_STATE_DIR is set, avoiding noise for
non-OpenClaw users.

Refs #123

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(openclaw): update install section with npm alias and troubleshooting

References npm run install:openclaw as the primary method. Adds
prerequisites and troubleshooting for the common runtime.json and
state dir issues reported in #123.

Refs #123

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(openclaw): trailing newline in runtime.json + align docs error strings

Appends \n to JSON.stringify output for POSIX compliance. Updates
troubleshooting docs to match the actual script error messages.

Refs #123

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 20:52:58 +03:00
Pedro Almeida e09a103e37 test: add OpenClaw E2E synthetic test + CI workflow (#136)
* test: add OpenClaw E2E synthetic test + CI workflow

Adds a programmatic hook lifecycle test that runs against the real built
plugin and SQLite DB — no gateway process needed. Validated on Raspberry
Pi 5 (aarch64), Node v22.22.1, OpenClaw 2026.3.13: 39/39 checks passed.

- scripts/test-openclaw-e2e.sh — fires all 10 hooks in sequence via a
  recording API proxy, verifies session_events, session_resume, and
  openclaw_session_map are populated in real SQLite
- .github/workflows/openclaw-e2e.yml — CI job on ubuntu + macos,
  pinned to OpenClaw v2026.3.2, with install verification and artifact
  upload on failure

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(ci): remove npm cache from setup-node — repo uses bun.lock not package-lock.json

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* ci: update install stats

* ci: update install stats

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-19 20:52:58 +03:00
Mert Koseoglu eb8717aa8a refactor: single source of truth for version (package.json)
- src/server.ts reads version from package.json via createRequire
- scripts/version-sync.mjs syncs to all 5 JSON manifests
- npm `version` lifecycle hook auto-runs sync + stages files
- Fixed OpenClaw manifests: 1.0.20/1.0.21 → 1.0.23
- Bump to 1.0.23

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 16:55:44 +03:00
Pedro Almeida 71013e2bb9 refactor(openclaw): address round 2 PR #122 review feedback
- Extract OpenClawSessionDB subclass with openclaw_session_map table
- Revert shared session/db.ts to 2-param ensureSession signature
- Remove bundle files, lockfile, and stats.json from git tracking
- Remove internal planning/spec docs from PR
- Remove deploy script and package.json deploy entry
- Document minimum OpenClaw version (>2026.1.29) in adapter docs
- Fix .gitignore to list bundle files explicitly (tests assert names)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 20:58:12 +01:00
Pedro Almeida 550d51fc96 feat(openclaw): DB singleton, deploy script, and sessionId snapshot
- Share a single SessionDB across all register() calls via module-level
  singleton, reducing connection overhead with concurrent agents
- Add npm run deploy script (build + clear jiti cache + restart gateway)
- Snapshot sessionId in before_prompt_build handler for consistency

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 01:13:31 +01:00
Pedro Almeida 8bc1162ebd feat(openclaw): add user message capture, command lifecycle hooks, and tool name mapping
- Register before_model_resolve hook to capture user decisions, roles,
  intents, and large data pastes via extractUserEvents() — mirrors the
  UserPromptSubmit hook that Claude Code has but OpenClaw lacked
- Register command:reset and command:stop hooks for session cleanup
  (previously only command:new was registered)
- Add OPENCLAW_TOOL_MAP to translate OpenClaw lowercase tool names
  (exec, read, write, edit, glob, grep) to Claude Code PascalCase
  equivalents that extractEvents() can recognize
- Add generic tool_call fallback event for unrecognized OpenClaw tools
- Accept both result/output and error/isError field variants defensively
  to handle both OpenClaw v2+ and older gateway builds
- Add TDD tests for all new hooks

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 05:12:57 +01:00
Pedro Almeida 625ac42eb8 Fix OpenClaw plugin: sync register(), remove skills path, add install script
Dogfooding at /openclaw revealed three issues:

- register() was async — OpenClaw silently discards the returned Promise,
  so no hooks were ever registered. Fix: sync register() with an eager
  initPromise that hook handlers await internally.

- "skills" key in openclaw.plugin.json resolved to the global extension
  dir (/openclaw/extensions/<id>/skills), not the plugin source. Removed.

- Added scripts/install-openclaw-plugin.sh: one-shot installer that builds,
  rebuilds better-sqlite3 for system Node, creates a real extension directory
  (OpenClaw does not follow dir symlinks), registers in runtime.json, and
  restarts the gateway.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 21:53:48 +01:00
Mert Koseoglu 49e0d7f135 refactor: flatten monorepo to src/ and add adapter pattern for multi-platform hooks
Migrate from 3-package monorepo (shared, session, core) to flat src/ structure.
Add HookAdapter interface with Claude Code adapter implementation for future
multi-platform support (Gemini CLI, OpenCode, Copilot CLI, Cursor per #46).

- Move packages/*/src/ → src/ and src/session/
- Replace @context-mode/* imports with relative paths
- Add src/adapters/types.ts (HookAdapter interface, normalized event types)
- Add src/adapters/claude-code/ (adapter, hooks, config modules)
- Refactor CLI to use adapter pattern instead of hardcoded logic
- Remove packages/, tsconfig.base.json, scripts/fix-imports.mjs
- Simplify to single tsconfig.json (no project references)
- All 492 tests pass

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 01:34:46 +03:00
Mert Koseoglu 649d2ab8bc refactor: migrate source of truth from root src/ to packages/core/
- packages/core/src/ is now the single source of truth for MCP server code
- store.ts imports loadDatabase, applyWALPragmas, PreparedStatement from @context-mode/shared/db-base
- store.ts imports IndexResult, SearchResult, StoreStats from @context-mode/shared/types
- executor.ts imports smartTruncate from @context-mode/shared/truncate
- executor.ts imports ExecResult from @context-mode/shared/types
- Root tsconfig.json converted to project references orchestrator (tsc -b)
- fix-imports.mjs rewrites both build/ and packages/session/dist/
- CI simplified to single typecheck + build step
- Deleted root src/ (-4,959 lines of duplication)
- All 492 tests pass

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 21:26:24 +03:00
Mert Koseoglu af03f7100e feat: session continuity — full event capture, zero-truncation injection, and user prompt tracking
Session Continuity captures 14 event categories (file, rule, decision, task,
git, env, cwd, error, mcp, subagent, skill, intent, role, data) plus user
prompts via PostToolUse and UserPromptSubmit hooks.

Key changes:
- Add PostToolUse hook with extractEvents() pipeline (14 extractors)
- Add PreCompact hook that builds priority-sorted resume snapshots
- Add UserPromptSubmit hook to capture every user prompt for seamless
  continuation after compact
- Rewrite SessionStart injection: zero-truncation, full event data grouped
  by category in <session_events> XML, <last_user_prompt> for exact
  continuation, behavioral directives telling LLM to index into context-mode
- Add marketing DISPLAY TO USER table on compact/startup showing what was
  preserved with counts and data previews
- Enhance /ctx-stats with Session Continuity section: 4-column table with
  "I remember..." previews and "Why it matters" hints, --continue note
- Fix sdb.close() bug in stats (was called before previewRows query)
- Add MCP tool extraction (extractMcp) and CLAUDE.md content capture
- Add packages/session (extract, snapshot, db) and packages/shared
- Add session test suite (db, extract, snapshot, pipeline)
- Add per-package .gitignore for dist/
- Update CONTRIBUTING.md with dev-mode guide

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 21:05:48 +03:00