mirror of
https://github.com/garrytan/gbrain.git
synced 2026-07-27 21:19:18 +00:00
* fix: gbrain auth create dropped the name on the bare (no-flag) form Extract parseAuthCreateArgs; only exclude the --takes-holders value from the positional search when the flag is present (rest[takesIdx+1] resolved to rest[0] when takesIdx === -1, silently dropping the name). Add regression test. * feat: gbrain connect — one-command Claude Code onboarding from a bearer token New connect command prints a paste-ready claude-mcp-add block (or --install wires it + smoke-tests the token via a raw-bearer get_brain_identity probe). Direct HTTP MCP, literal-token default, URL normalization, token header-injection guard, --json redaction, execFileSync (no shell). Wired into CLI_ONLY + CLI_ONLY_SELF_HELP + handleCliOnly. 58 unit + 3 PGLite-E2E cases; e2e-test-map updated. * docs: lead CLAUDE_CODE.md with gbrain connect (remote fast path) + README one-liner Regenerate llms-full.txt for the README change. * refactor: pre-landing review fixes for gbrain connect - DRY: single DEFAULT_PROBE_TIMEOUT_MS + shared isAuthErrorMessage predicate - reuse promptLine (shared stdin lifecycle) for the --install confirm - harden redactToken with a Bearer <value> scrub (defense in depth) - +8 tests: orchestrator guard paths, deterministic timeout, invalid --timeout-ms, Bearer-redaction * fix: adversarial-review hardening for gbrain connect - probe: Promise.race the call against a real timer so a stalled connect()/SSE handshake (signal alone doesn't cover it) can't hang --install indefinitely - probe: close transport even if client.connect() throws - parseArgs: reject a missing/flag-shaped value (e.g. --token --install) - block link-local / cloud-metadata hosts (169.254/fe80:/fd00:ec2::254) — keeps localhost + RFC1918 LAN brains working - non-interactive --install now requires --yes - clearer message when --force removed then add failed +8 tests covering each * fix: codex-review P2s for gbrain connect - POSIX single-quote the rendered claude-mcp-add command so a token with shell metacharacters ($(), backticks) can't trigger command substitution on paste - detect IPv4-mapped IPv6 metadata addresses (::ffff:169.254.x.x / ::ffff:a9fe:*) so they don't bypass the link-local guard +3 tests * chore: bump version and changelog (v0.42.2.0) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: document gbrain connect + connect-probe in CLAUDE.md Key files (v0.42.2.0) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat: gbrain connect — add codex and perplexity agents --agent codex emits 'codex mcp add ... --bearer-token-env-var GBRAIN_REMOTE_TOKEN' (token read from the env var at runtime, never in Codex config; --install runs it). --agent perplexity prints the URL + token for the Settings → Connectors GUI (no --install). Generalized the command file: AGENT_SPECS table, buildCodexMcpAddArgv, cmdString(binary,argv), binary-generic ConnectDeps (hasBinary/runBinary/env), agent-aware buildConnectBlock/buildJson. +25 tests. * docs: codex + perplexity connect paths (new CODEX.md, README, CHANGELOG, CLAUDE.md) Regenerate llms-full.txt for the CLAUDE.md/README edits. * test: real-CLI E2E for connect — drive actual claude + codex against a live server Adds claude-code + codex cases to connect-bearer.test.ts that run the real 'claude mcp add' / 'codex mcp add' through 'gbrain connect --install' against a live 'gbrain serve --http' (sandboxed HOME/CODEX_HOME), then assert via 'claude mcp get' / 'codex mcp get' that the server registered (and codex's token stays out of config). Skips when the binary is absent. Perplexity is GUI-only so it's print-asserted. Regen llms for the CLAUDE.md note. * docs: perplexity OAuth + serve --bind/--public-url footgun (per Perplexity feedback) PERPLEXITY.md now documents the host-side HTTP setup (gbrain serve --http --bind 0.0.0.0 --public-url, the v0.34 ECONNREFUSED footgun) and the OAuth 2.1 client_credentials path (gbrain auth register-client) alongside the legacy bearer token. The 'connect --agent perplexity' output points at the same bind/public-url requirement + PERPLEXITY.md. * feat: gbrain connect --oauth — client-credentials path for perplexity/generic OAuth is the correct path for a third-party cloud connector (Perplexity): instead of a long-lived full-access bearer token, the connector gets Issuer URL + Client ID + Client Secret and mints short-lived scoped tokens. --oauth --register mints a least-privilege client on the host (shells gbrain auth register-client); --oauth --client-id/--client-secret uses an existing one. Rejected for claude-code/codex (bearer) and with --install. Issuer derived from the mcp-url. New E2E proves the full chain: register → connect --oauth → OAuth discovery → /token client_credentials mint → get_brain_identity tool call against a live server. Docs: PERPLEXITY.md leads with OAuth; README + CLAUDE.md updated; +18 unit cases. * docs: add gbrain connect to INSTALL.md MCP section + link CODEX.md The remote-client onboarding command was documented in README/CLAUDE_CODE/CODEX/ PERPLEXITY but missing from INSTALL.md §3 (the natural 'how do I connect a client' home). Add the one-command connect how-to (claude-code/codex/perplexity) and the missing docs/mcp/CODEX.md link. * fix: connect LEARN_INSTRUCTION names put_page, not CLI-only capture The self-orientation block told a connected agent that `capture` is an available MCP tool. It isn't — `capture` is a CLI-only convenience command; the MCP write tool is `put_page`. An agent that followed the instruction hit "unknown tool". Drop capture; put_page was already in the list. Adds a regression block to connect.test.ts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat: serve --http surfaces skill-publishing status (banner + nudge) When mcp.publish_skills is OFF, connected agents can search/write but can't call list_skills/get_skill, so the host's skill catalog is invisible to them. The startup banner now shows a Skills: line, and a stderr nudge fires when off with the paste-ready fix. Pure skillPublishStatus() helper, unit-tested. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test: prove the local stdio MCP funnel end-to-end Spawns real `gbrain serve` (stdio) against a freshly init --pglite brain and drives the official MCP SDK client through initialize -> tools/list -> tools/call (get_brain_identity + search). Pins the advertised core-tool set against what the server actually exposes (asserts capture is NOT advertised). This funnel had zero e2e coverage before. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test: make batch-retry-audit ENOENT case hermetic The 'no-op when audit dir does not exist' case called pruneOldBatchRetryAuditFiles(30) without a GBRAIN_AUDIT_DIR override, so it read the real ~/.gbrain/audit and flaked (kept:1) on any dev machine with a batch-retry-*.jsonl on disk. Point it at a guaranteed-missing temp subdir, matching this file's own hermetic-header contract. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: two-funnel coding-agent onboarding (Claude Code / Codex) New tutorial docs/tutorials/connect-coding-agent.md: Path A (connect to an existing brain) + Path B (start from nothing, local stdio), the brain-first protocol to paste into CLAUDE.md/AGENTS.md, and the four translatable habits. README gains a 'Quick start: Claude Code or Codex' fork separating lightweight retrieval from the full autonomous install. INSTALL.md shows the one-command wire-up at the standalone CLI section. mcp/CLAUDE_CODE + CODEX cross-link the tutorial + note publish_skills + capture-is-CLI-only. Tutorial promoted to Shipped in the tutorials index. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore: changelog + regenerated llms (v0.42.2.0) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: CLAUDE.md Key Files annotation for two-funnel onboarding wave Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
109 lines
5.1 KiB
TypeScript
109 lines
5.1 KiB
TypeScript
// scripts/e2e-test-map.ts
|
|
//
|
|
// Path-glob -> E2E test files map. Used by scripts/select-e2e.ts.
|
|
//
|
|
// CONTRACT: This map can ONLY narrow from "all". When a changed src/ path
|
|
// matches no glob here, the selector falls back to "run all E2E" (fail-closed).
|
|
// You can safely add narrowing entries; you cannot break correctness by missing
|
|
// one. Tune as misses surface (i.e., when ci:local:diff ran more than necessary
|
|
// and you'd like to narrow that surface area).
|
|
//
|
|
// Glob syntax is the minimal subset implemented in select-e2e.ts:
|
|
// - "**" matches any sequence of path segments (including zero)
|
|
// - "*" matches any characters within a single path segment
|
|
// - everything else is literal
|
|
// No brace expansion, no ?, no [ ].
|
|
|
|
export const E2E_TEST_MAP: Record<string, string[]> = {
|
|
// Source-aware ranking, hybrid search, intent classification.
|
|
"src/core/search/**": [
|
|
"test/e2e/search-quality.test.ts",
|
|
"test/e2e/search-exclude.test.ts",
|
|
"test/e2e/search-swamp.test.ts",
|
|
],
|
|
// Tree-sitter chunkers feed code-indexing E2E.
|
|
"src/core/chunkers/**": ["test/e2e/code-indexing.test.ts"],
|
|
// OpenClaw context-engine plugin: engine + entry feed the plugin-shape E2E
|
|
// (mocked SDK) AND the real-loader Tier 2 E2E that spawns openclaw and
|
|
// actually installs the plugin into an isolated --profile.
|
|
"src/core/context-engine.ts": [
|
|
"test/e2e/openclaw-context-engine-plugin.test.ts",
|
|
"test/e2e/openclaw-plugin-load-real.test.ts",
|
|
],
|
|
"src/openclaw-context-engine.ts": [
|
|
"test/e2e/openclaw-context-engine-plugin.test.ts",
|
|
"test/e2e/openclaw-plugin-load-real.test.ts",
|
|
],
|
|
// dream.ts is a thin alias over runCycle in cycle.ts.
|
|
"src/core/cycle.ts": ["test/e2e/cycle.test.ts", "test/e2e/dream.test.ts"],
|
|
// Multi-source sync writes share the per-source bookmark anchor.
|
|
"src/core/sync.ts": ["test/e2e/sync.test.ts", "test/e2e/multi-source.test.ts"],
|
|
// v0.32.8 multi-source bug class regression suite — fires on any cycle
|
|
// phase, extract, integrity, embed, or migrate-engine change.
|
|
"src/core/cycle/extract-takes.ts": ["test/e2e/multi-source-bug-class.test.ts"],
|
|
"src/core/cycle/patterns.ts": ["test/e2e/multi-source-bug-class.test.ts"],
|
|
"src/core/cycle/synthesize.ts": ["test/e2e/multi-source-bug-class.test.ts"],
|
|
"src/commands/embed.ts": ["test/e2e/multi-source-bug-class.test.ts"],
|
|
"src/commands/extract.ts": ["test/e2e/multi-source-bug-class.test.ts"],
|
|
"src/commands/migrate-engine.ts": ["test/e2e/multi-source-bug-class.test.ts"],
|
|
// Any minions queue/worker/handler change exercises all minion E2E.
|
|
"src/core/minions/**": [
|
|
"test/e2e/minions-concurrency.test.ts",
|
|
"test/e2e/minions-resilience.test.ts",
|
|
"test/e2e/minions-shell.test.ts",
|
|
"test/e2e/minions-shell-pglite.test.ts",
|
|
"test/e2e/worker-abort-recovery.test.ts",
|
|
],
|
|
// postgres.js bind paths + JSONB shapes + parity vs PGLite.
|
|
"src/core/postgres-engine.ts": [
|
|
"test/e2e/postgres-bootstrap.test.ts",
|
|
"test/e2e/postgres-jsonb.test.ts",
|
|
"test/e2e/jsonb-roundtrip.test.ts",
|
|
"test/e2e/engine-parity.test.ts",
|
|
"test/e2e/schema-drift.test.ts",
|
|
],
|
|
// PGLite bootstrap path + parity guard.
|
|
"src/core/pglite-engine.ts": [
|
|
"test/e2e/postgres-bootstrap.test.ts",
|
|
"test/e2e/engine-parity.test.ts",
|
|
"test/e2e/schema-drift.test.ts",
|
|
],
|
|
// Schema source of truth: any change must pass the cross-engine drift gate.
|
|
"src/schema.sql": ["test/e2e/schema-drift.test.ts"],
|
|
"src/core/pglite-schema.ts": ["test/e2e/schema-drift.test.ts"],
|
|
"src/core/migrate.ts": ["test/e2e/schema-drift.test.ts", "test/e2e/migrate-chain.test.ts"],
|
|
// MCP stdio + HTTP transports share dispatch.
|
|
"src/mcp/**": ["test/e2e/mcp.test.ts", "test/e2e/http-transport.test.ts"],
|
|
// Integrity batch-load fast path.
|
|
"src/commands/integrity.ts": ["test/e2e/integrity-batch.test.ts"],
|
|
// gbrain connect — raw-bearer MCP smoke probe exercised end-to-end against
|
|
// a real serve --http (PGLite), so changes to either feed it.
|
|
"src/commands/connect.ts": ["test/e2e/connect-bearer.test.ts"],
|
|
"src/core/connect-probe.ts": ["test/e2e/connect-bearer.test.ts"],
|
|
// Upgrade chains migration ledger; touches both runners.
|
|
"src/commands/upgrade.ts": [
|
|
"test/e2e/upgrade.test.ts",
|
|
"test/e2e/migrate-chain.test.ts",
|
|
"test/e2e/migration-flow.test.ts",
|
|
],
|
|
"src/commands/doctor.ts": ["test/e2e/doctor-progress.test.ts"],
|
|
// Knowledge graph layer feeds graph-quality.
|
|
"src/core/link-extraction.ts": ["test/e2e/graph-quality.test.ts"],
|
|
// v0.38 ingestion substrate. POST /ingest lives inside serve-http.ts
|
|
// (per the plan-eng-review E1 decision); the daemon + built-in sources
|
|
// + ingest_capture Minion handler all feed the in-process roundtrip
|
|
// E2E AND the HTTP contract E2E for the webhook route.
|
|
"src/commands/serve-http.ts": [
|
|
"test/e2e/serve-http-ingest-webhook.test.ts",
|
|
"test/e2e/serve-http-oauth.test.ts",
|
|
],
|
|
"src/core/ingestion/**": [
|
|
"test/e2e/ingestion-roundtrip.test.ts",
|
|
"test/e2e/serve-http-ingest-webhook.test.ts",
|
|
],
|
|
"src/core/minions/handlers/ingest-capture.ts": [
|
|
"test/e2e/ingestion-roundtrip.test.ts",
|
|
"test/e2e/serve-http-ingest-webhook.test.ts",
|
|
],
|
|
};
|