Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,34 @@
## [Unreleased] — 1.0.0 (stable API)

First stable line: the CLI surface, MCP tool surface, and manifest schema are
now considered stable and versioned under SemVer. Released as a **major** because
the vendor-file output format changed (see Changed).

### Added
- `pack --budget <n>` to override the manifest token budget per run, and
`pack --exact` to count tokens with the bundled `gpt-tokenizer` (cl100k)
instead of the `chars/4` estimate.
- `lint` now warns about fragments whose content alone exceeds the budget
(they can never be packed).
- `build --target <name...>` to compile only selected vendors
(`claude`, `gemini`, `agents`, `cursor`).
- `agenticscope schema` — generate `schema/manifest.schema.json` from the zod
schema for TOML editor autocomplete/validation.
- `agenticscope mcp-config` — print ready-to-paste MCP server config per host
(Claude Desktop, Cursor, generic).
- MCP server **HTTP transport**: `agenticscope-mcp --http [port]` serves over
Streamable HTTP for remote/hosted use, alongside the default stdio transport.

### Changed
- **BREAKING:** vendor files are now rendered per vendor. `CLAUDE.md`/`GEMINI.md`/
`AGENTS.md` get vendor-specific markdown preambles and `.cursorrules` is a plain
instruction file (no markdown H1). The old single `# Agent context for <name>`
header is gone. Re-run `agenticscope build` to regenerate.

### Security
- MCP `project` arguments are scope-guarded to the workspace root; paths that
escape it (`../…`, absolute paths outside) are rejected.

## [0.2.1](https://github.com/jessn-dev/agentic-scope/compare/v0.2.0...v0.2.1) (2026-06-24)


Expand Down
35 changes: 24 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@

**A directory-as-context standard plus a read-only MCP server that gives any AI agent live, structured awareness of your workspace — without burning your tokens re-reading everything.**

> **Status:** Draft 0.1.0 · **License:** MIT · **Requires:** Node.js ≥ 22
[![npm version](https://img.shields.io/npm/v/agenticscope.svg)](https://www.npmjs.com/package/agenticscope)
[![CI](https://github.com/jessn-dev/agentic-scope/actions/workflows/ci.yml/badge.svg)](https://github.com/jessn-dev/agentic-scope/actions/workflows/ci.yml)
[![license](https://img.shields.io/npm/l/agenticscope.svg)](./LICENSE)
[![node](https://img.shields.io/node/v/agenticscope.svg)](https://nodejs.org)

> **License:** MIT · **Requires:** Node.js ≥ 22 · Published to npm with [provenance](https://docs.npmjs.com/generating-provenance-statements).

---

Expand Down Expand Up @@ -155,9 +160,13 @@ agenticscope pack "refactor handler" -p src/api/handler.ts -p src/db/schema.sql
| Command | Does |
| :--- | :--- |
| `agenticscope init [dir]` | Scaffold a manifest + `.scope/` tree |
| `agenticscope lint [dir]` | Validate the manifest; flag missing paths, dupe ids, dead fragments |
| `agenticscope build [dir]` | Compile `.scope/` into all vendor files |
| `agenticscope pack <task...>` | Resolve a task into a budgeted context block (`-d` dir, `-p` paths, `--raw`) |
| `agenticscope lint [dir]` | Validate the manifest; flag missing paths, dupe ids, dead fragments, and fragments too big for the budget |
| `agenticscope build [dir]` | Compile `.scope/` into vendor files (`-t, --target claude\|gemini\|agents\|cursor` to pick a subset) |
| `agenticscope pack <task...>` | Resolve a task into a budgeted context block (`-d` dir, `-p` paths, `-b, --budget` override, `--exact` tokenizer, `--raw`) |
| `agenticscope schema [dir]` | Generate `schema/manifest.schema.json` for TOML editor autocomplete (`-o` out path) |
| `agenticscope mcp-config` | Print ready-to-paste MCP config (`--workspace`, `--host claude\|cursor\|generic`) |

**Exact token counts.** `pack` estimates tokens with a fast `chars/4` heuristic by default. Pass `--exact` to use the bundled `gpt-tokenizer` (cl100k) for precise counts when a budget is tight.

### Wire up the MCP server

Expand All @@ -176,7 +185,15 @@ Point any MCP-capable host at the server and give it your workspace root. The ho
}
```

The same server works in **Gemini (Gemini CLI)**, **ChatGPT / OpenAI agents**, **Cursor**, **Zed**, and **Windsurf** — each just has its own config file. You can also set the workspace with the `AGENTICSCOPE_WORKSPACE` environment variable instead of `--workspace`.
The same server works in **Gemini (Gemini CLI)**, **ChatGPT / OpenAI agents**, **Cursor**, **Zed**, and **Windsurf** — each just has its own config file. You can also set the workspace with the `AGENTICSCOPE_WORKSPACE` environment variable instead of `--workspace`, or run `agenticscope mcp-config --host cursor` to print a ready-to-paste block.

**Stdio by default; HTTP for remote/hosted use.** Desktop hosts launch the server over stdio. To run it as a shared service, start it over Streamable HTTP:

```bash
agenticscope-mcp --http 3000 --workspace ~/Documents # serves POST/GET http://localhost:3000/mcp
```

**Safe by construction.** Every tool is read-only, errors return a clean `isError` result instead of crashing the host, and `project` arguments are **scope-guarded** to the workspace root — a client can't coax the server into reading `/etc` or `../../secrets`.

Once connected, I ask things like *"what's in flight across my workspace?"* and the host calls `list_plans` + `git_status` and answers from structured data — **no file dumps, no token burn.** That's the whole point delivered.

Expand Down Expand Up @@ -216,16 +233,12 @@ agenticscope/
└── sample-workspace/ # a working .scope/ project to try the commands against
```

## Changelog

See [CHANGELOG.md](CHANGELOG.md) for what shipped, what I fixed, and what others contributed.

## Contributing

Contributions are welcome.

- **Found a bug or have an idea?** Open an issue: https://github.com/jessn-dev/agentic-scope/issues
- **Sending a pull request?** Fork, branch, run `npm run typecheck && npm test` before you push, and describe the change. I record merged PRs in the Changelog above.
- **Sending a pull request?** Fork, branch, run `npm run typecheck && npm test` before you push, and describe the change. Releases and merged changes are recorded in [CHANGELOG.md](CHANGELOG.md).
- **Local setup:**
```bash
npm install
Expand All @@ -237,7 +250,7 @@ Contributions are welcome.

## Status & roadmap

This is an early draft (0.1.0). The standard and the MCP tool surface come first; expect the resolver and tooling to keep evolving. Feedback, forks, and competing designs are all welcome — I want a better way to feed agents context, not a walled garden.
The `1.0` line marks a stable CLI + MCP tool surface and manifest schema. The standard and tooling will keep evolving; breaking changes are released as new majors. Feedback, forks, and competing designs are all welcome — I want a better way to feed agents context, not a walled garden.

---

Expand Down
107 changes: 55 additions & 52 deletions context.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# agenticscope — project context

Working notes: what exists, what's left. Last updated 2026-06-23.
Working notes: what exists, what's left. Last updated 2026-06-24.

## What this is
A directory-as-context standard + a read-only MCP server that gives AI agents
Expand All @@ -10,72 +10,75 @@ vendor-folder sprawl, and zero workspace-level awareness.

- **Stack:** TypeScript (ESM, NodeNext), Node >= 22.
- **Repo:** https://github.com/jessn-dev/agentic-scope
- **npm:** `agenticscope` (name reserved; `0.1.0` published, `0.2.0` pending publish).
- **npm:** `agenticscope` `0.1.0`, `0.2.0`, `0.2.1` published (provenance, OIDC).
- **Two bins:** `agenticscope` (CLI), `agenticscope-mcp` (MCP server).

## Release pipeline (working)
- Push to `main` → `.github/workflows/release.yml` runs semantic-release
(Conventional Commits → version/CHANGELOG/tag/GitHub release), then a
**top-level** `npm publish` via **npm OIDC Trusted Publishing** (no token).
- Node 24 in CI (npm 11.x, needed for OIDC). Key gotchas, all solved:
Trusted Publisher must match `jessn-dev` / `agentic-scope` / `release.yml` /
blank env; setup-node's `_authToken` placeholder is stripped from the npmrc;
publish must be top-level (semantic-release's exec env shadows OIDC).
- `ci.yml` runs typecheck + test + build on PRs.

## Done

### Core (`src/core/`)
- `types.ts` — zod schemas. Fragment fields: `id`, `type` (rule|knowledge|spec|persona),
`path`, `triggers` (globs→paths), `keywords` (words→text), `priority`, `always`.
Scope: `version`, `budget`, `name`, `precedence` ("type" | "priority").
- `manifest.ts` — load/parse/validate `agenticscope.toml` (smol-toml + zod).
- `tokens.ts` — dependency-free `chars/4` estimator.
- `fragments.ts` — `matchTriggers` (glob vs keyword split, false-positive fixed),
`pack` (precedence ordering + hard budget cap + skip reasons), `renderPack`.
- `vendor.ts` — `compile`/`build` → CLAUDE.md, GEMINI.md, AGENTS.md, .cursorrules.
- `types.ts` — zod schemas (Fragment, Manifest, precedence).
- `manifest.ts` — load/parse/validate `agenticscope.toml`.
- `tokens.ts` — `chars/4` estimator; `{ exact: true }` uses `gpt-tokenizer` (lazy).
- `fragments.ts` — `matchTriggers`, `pack` (budget override + exact opt), `renderPack`,
`oversizedFragments` (lint helper).
- `vendor.ts` — per-vendor `compile`/`build`, `resolveTargets` (target selection).
- `schema.ts` — JSON Schema generation from zod (`zod-to-json-schema`).

### CLI (`src/cli.ts`)
- `init` (scaffold), `lint` (validate + dead-fragment/dup checks), `build`, `pack`.
- `init`, `lint` (+ oversized-fragment warning), `build` (`--target`),
`pack` (`--budget`, `--exact`, `-p`, `--raw`), `schema`, `mcp-config`.
- `--version` reads from package.json (no drift).

### MCP server (`src/mcp/`)
- `server.ts` — stdio transport, 6 tools, all wrapped in `guard()` → clean `isError`.
- Tools: `list_projects`, `list_subagents`, `list_plans`, `git_status`,
`grep_memory`, `pack_context`.
- `workspace.ts` (scan depth-1 for projects), `git.ts` (read-only simple-git),
`grep.ts` (pure-Node grep over `.scope/memory/`).
- `server.ts` — `createServer()` factory; stdio transport (default) **and**
`--http [port]` Streamable HTTP transport for remote/hosted use.
- 6 tools, all `guard()`-wrapped → clean `isError`.
- `scope.ts` — path-scope guard: `project` args restricted to the workspace root.
- `pack_context` accepts a `budget` override.

### Tests + CI
- Vitest, 18 tests passing (manifest, match, pack, vendor, grep). `npm test`.
- `.github/workflows/ci.yml` — typecheck + test + build on push/PR.
- `.github/workflows/publish.yml` — tag `v*` → `npm publish --provenance`
(needs `NPM_TOKEN` repo secret w/ bypass-2FA; NOT set yet).
- Vitest, **34 tests passing** (manifest, match, pack, budget, vendor, tokens,
schema, scope, grep). `npm test`.

### Docs / meta
- README: full spec, usage, MCP config, Changelog, Contributing. Active first-person voice.
- LICENSE (MIT, Jesse B Ngolab), `.gitignore` (ignores generated vendor files + .idea).
- `examples/sample-workspace/api/` — working demo project.
- package.json metadata (author/repo/bugs/homepage) filled.
- README: full spec + usage, badges (npm/CI/license/node), new commands/flags,
HTTP transport, security note. CHANGELOG.md (semantic-release-managed).
- `schema/manifest.schema.json` generated and committed.

## State
- Local: bumped to `0.2.0`, commit + tag `v0.2.0` created.
- `0.2.0` NOT yet published to npm, and the bump commit/tag may not be pushed.

## TODO

### Immediate (finish the 0.2.0 release)
- [ ] `npm publish --otp=XXXXXX` (blocked on 2FA OTP — needs the human).
- [ ] `git push && git push --tags`.
- [ ] (optional) Add `NPM_TOKEN` secret so tag pushes auto-publish.
- **`develop` carries the 1.0.0 work** (all of the former backlog below).
- Merging `develop` → `main` is intended to cut a **major (1.0.0)** release.
semantic-release needs a `BREAKING CHANGE:` footer (or `feat!:`) on at least
one commit to bump to 1.0.0 — the vendor-output format change is the break.

### Tier 3 — next features (agreed backlog)
- [ ] #5 done? precedence config shipped. (priority-vs-type configurable — DONE)
- [ ] #6 `--budget` override on `pack`; lint warning when one fragment > budget.
- [ ] #7 Generate `schema/manifest.schema.json` from zod for TOML autocomplete
(the `schema/` dir + package keyword exist but the file is empty).
- [ ] #8 Per-vendor formatting (Cursor vs Claude idioms) + `--target` flag on build.
- [ ] #9 `agenticscope mcp-config` — print ready-to-paste MCP JSON per host.
- [ ] #10 Optional exact tokenizer (gpt-tokenizer, pure JS) behind a flag.
## Backlog — DONE in this 1.0.0 cycle
- [x] #6 `pack --budget` override + lint warning for oversized fragments.
- [x] #7 `schema/manifest.schema.json` generated from zod (+ `schema` command).
- [x] #8 per-vendor formatting + `build --target`.
- [x] #9 `agenticscope mcp-config`.
- [x] #10 optional exact tokenizer (`gpt-tokenizer`) behind `--exact`.
- [x] #12 MCP HTTP transport (`--http`).
- [x] #13 MCP path-scope guard.
- [x] README badges (npm/CI/license/node).

### Tier 4 — distribution / hardening
- [ ] #11 Separate CHANGELOG.md (keep-a-changelog) + README badges (npm/CI/license).
- [ ] #12 HTTP transport for MCP (currently stdio-only) for remote/hosted use.
- [ ] #13 Path-scope guard: restrict MCP `project` args to within the workspace root.
## Future ideas (not started)
- Watch mode for `build` (recompile on `.scope/` change).
- Stateful HTTP MCP sessions (current HTTP mode is stateless per-request).
- Per-fragment include/exclude globs beyond a single `path`.

### Known issues / notes
- Dev-only audit vulns in `vite-node` (via vitest). Prod deps: 0 vulns. Shipped
package is `dist/` only, so users are unaffected. Clearing needs a breaking
vitest major bump — deferred.
- `list_subagents` / `list_plans` require an absolute `project` path argument;
consider accepting a project name resolved against the workspace.
- Token counts are estimates (chars/4); budgets are approximate by design.
## Known issues / notes
- Dev-only audit vulns in `vite-node` (via vitest). Prod deps clean; shipped
package is `dist/` only. Clearing needs a breaking vitest bump — deferred.
- Token counts default to estimates (`chars/4`); use `--exact` / `exact: true`
for precise counts. Budgets are approximate by design otherwise.
- `context.md` is untracked working notes (not committed to any branch).
14 changes: 11 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,12 @@
"dependencies": {
"@modelcontextprotocol/sdk": "^1.12.0",
"commander": "^12.1.0",
"gpt-tokenizer": "^2.9.0",
"picomatch": "^4.0.2",
"simple-git": "^3.27.0",
"smol-toml": "^1.3.1",
"zod": "^3.23.8"
"zod": "^3.23.8",
"zod-to-json-schema": "^3.24.1"
},
"devDependencies": {
"@semantic-release/changelog": "^6.0.3",
Expand Down
95 changes: 95 additions & 0 deletions schema/manifest.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
{
"$ref": "#/definitions/AgenticscopeManifest",
"definitions": {
"AgenticscopeManifest": {
"type": "object",
"properties": {
"scope": {
"type": "object",
"properties": {
"version": {
"type": "string",
"default": "0.1.0"
},
"budget": {
"type": "integer",
"exclusiveMinimum": 0,
"default": 4000
},
"name": {
"type": "string"
},
"precedence": {
"type": "string",
"enum": [
"type",
"priority"
],
"default": "type"
}
},
"additionalProperties": false
},
"fragment": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"type": {
"type": "string",
"enum": [
"rule",
"knowledge",
"spec",
"persona"
]
},
"path": {
"type": "string",
"minLength": 1
},
"triggers": {
"type": "array",
"items": {
"type": "string"
},
"default": []
},
"keywords": {
"type": "array",
"items": {
"type": "string"
},
"default": []
},
"priority": {
"type": "integer",
"default": 50
},
"always": {
"type": "boolean",
"default": false
}
},
"required": [
"id",
"type",
"path"
],
"additionalProperties": false
},
"default": []
}
},
"required": [
"scope"
],
"additionalProperties": false
}
},
"$schema": "http://json-schema.org/draft-07/schema#"
}
Loading
Loading