context-eng 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +272 -0
- package/dist/categories.d.ts +27 -0
- package/dist/categories.js +71 -0
- package/dist/categories.js.map +1 -0
- package/dist/cli-entry.d.ts +2 -0
- package/dist/cli-entry.js +7 -0
- package/dist/cli-entry.js.map +1 -0
- package/dist/cli.d.ts +30 -0
- package/dist/cli.js +327 -0
- package/dist/cli.js.map +1 -0
- package/dist/db.d.ts +40 -0
- package/dist/db.js +158 -0
- package/dist/db.js.map +1 -0
- package/dist/engine.d.ts +149 -0
- package/dist/engine.js +589 -0
- package/dist/engine.js.map +1 -0
- package/dist/harness.d.ts +56 -0
- package/dist/harness.js +358 -0
- package/dist/harness.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/inspect-cli.d.ts +2 -0
- package/dist/inspect-cli.js +96 -0
- package/dist/inspect-cli.js.map +1 -0
- package/dist/inspect.d.ts +33 -0
- package/dist/inspect.js +149 -0
- package/dist/inspect.js.map +1 -0
- package/dist/map.d.ts +39 -0
- package/dist/map.js +106 -0
- package/dist/map.js.map +1 -0
- package/dist/mcp.d.ts +5 -0
- package/dist/mcp.js +348 -0
- package/dist/mcp.js.map +1 -0
- package/dist/migrate.d.ts +7 -0
- package/dist/migrate.js +107 -0
- package/dist/migrate.js.map +1 -0
- package/dist/paths.d.ts +29 -0
- package/dist/paths.js +69 -0
- package/dist/paths.js.map +1 -0
- package/dist/search.d.ts +144 -0
- package/dist/search.js +449 -0
- package/dist/search.js.map +1 -0
- package/dist/secrets.d.ts +28 -0
- package/dist/secrets.js +135 -0
- package/dist/secrets.js.map +1 -0
- package/dist/text.d.ts +22 -0
- package/dist/text.js +153 -0
- package/dist/text.js.map +1 -0
- package/dist/tokens.d.ts +6 -0
- package/dist/tokens.js +15 -0
- package/dist/tokens.js.map +1 -0
- package/dist/typesafe.d.ts +40 -0
- package/dist/typesafe.js +170 -0
- package/dist/typesafe.js.map +1 -0
- package/package.json +51 -0
- package/system_prompts/AGENTS.md +14 -0
- package/system_prompts/CLAUDE.md +14 -0
- package/system_prompts/rules.md +157 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mayank
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
# context-eng
|
|
2
|
+
|
|
3
|
+
Local project memory router for Codex and Claude Code. Memories live in one SQLite database per each category, with SQLite FTS5 for local retrieval and TypeSafe Jev filtering for semantic relevance.
|
|
4
|
+
|
|
5
|
+
## Use
|
|
6
|
+
|
|
7
|
+
Node.js 20 or newer. Run this from an existing project directory, or pass `--project` pointing to one. From a checkout of this repo, `npm install`, `npm run build`, then `npm run init` does the same thing.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx -y context-eng init
|
|
11
|
+
pnpm dlx context-eng init
|
|
12
|
+
context-eng init --project /path/to/repo
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
`init` asks for a TypeSafe API key. The prompt is hidden. Press Enter to skip. A saved key is kept if you press Enter again; type a new key to replace it. The key goes in the OS keychain (macOS Keychain, Windows Credential Manager, or libsecret), not into the project.
|
|
16
|
+
|
|
17
|
+
In a terminal, `init` lists Cursor, Claude Code, and Codex. Installed ones start selected. Space turns one off. Enter writes a user-level MCP server only for the ones left selected. A different existing `context-eng` server needs an explicit yes before replacement. Without a terminal, `init` skips global instructions and editor servers unless you pass `--yes`; `--yes` adds missing servers but never replaces a different one. Restart an app after adding its server.
|
|
18
|
+
|
|
19
|
+
```mermaid
|
|
20
|
+
flowchart TD
|
|
21
|
+
init["context-eng init"] --> key["OS keychain"]
|
|
22
|
+
init --> project["AGENTS.md and CLAUDE.md, only if they exist"]
|
|
23
|
+
init --> pick["select installed apps"]
|
|
24
|
+
pick --> codexRules["~/.codex/AGENTS.md"]
|
|
25
|
+
pick --> cursor["~/.cursor/mcp.json"]
|
|
26
|
+
pick --> claude["~/.claude.json"]
|
|
27
|
+
claude --> claudeRules["~/.claude/CLAUDE.md"]
|
|
28
|
+
pick --> codex["~/.codex/config.toml"]
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
You do not start the server yourself. Cursor, Claude Code, or Codex runs `context-eng mcp`. With no `--project`, the server is global until a tool passes `projectPath` or calls `memory_bind`.
|
|
32
|
+
|
|
33
|
+
### Project and global
|
|
34
|
+
|
|
35
|
+
Two different splits:
|
|
36
|
+
|
|
37
|
+
| | Project | Global |
|
|
38
|
+
| --- | --- | --- |
|
|
39
|
+
| Memory | This repo only, under `~/.context/projects/` | Every repo, under `~/.context/global/` |
|
|
40
|
+
| Instructions | Files inside the repo | Files in your home directory, used by every repo |
|
|
41
|
+
|
|
42
|
+
`memory_search` with `filters.scope` `project`, `global`, or `both` chooses the memory side. The files below are the instruction side.
|
|
43
|
+
|
|
44
|
+
### Files `init` edits
|
|
45
|
+
|
|
46
|
+
Instruction files (`AGENTS.md`, `CLAUDE.md`, and the rule files below) keep your other text. `init` replaces only the block between `<!-- context-eng:start -->` and `<!-- context-eng:end -->`. The MCP config files are updated in place and keep other servers.
|
|
47
|
+
|
|
48
|
+
| File | When | What it does |
|
|
49
|
+
| --- | --- | --- |
|
|
50
|
+
| OS keychain `context-eng` / `typesafe-api-key` | Always | Stores the TypeSafe key for this login |
|
|
51
|
+
| `<project>/AGENTS.md` | Only if that file already exists | Tells Codex, in this repo, to use the memory tools |
|
|
52
|
+
| `<project>/CLAUDE.md` | Only if that file already exists | Tells Claude Code, in this repo, to use the memory tools |
|
|
53
|
+
| `~/.codex/AGENTS.md` | Terminal or `--yes` | Same instructions for every Codex session |
|
|
54
|
+
| `~/.claude/CLAUDE.md` | Claude server added or already matching, or `--claude-only` | Same instructions for every Claude Code project |
|
|
55
|
+
| `~/.cursor/mcp.json` | Cursor selected | Starts the server for every Cursor project. No `--project` |
|
|
56
|
+
| `~/.claude.json` | Claude selected | Same for every Claude Code project. This is the file `claude mcp add --scope user` writes |
|
|
57
|
+
| `~/.codex/config.toml` | Codex selected | Adds `[mcp_servers.context-eng]` only. Codex may later add `[mcp_servers.context-eng.tools.*]` approval lines itself |
|
|
58
|
+
|
|
59
|
+
`<project>` is `--project`, or the current directory when you omit it. It must already exist. Running `init` from `~` uses your home directory as `<project>`. It does not create `~/AGENTS.md` or `~/CLAUDE.md` when those files are absent. Claude's user-level MCP server is in `~/.claude.json`; `init` does not create a project `.mcp.json`.
|
|
60
|
+
|
|
61
|
+
### One app, or only the instruction files
|
|
62
|
+
|
|
63
|
+
These skip the key prompt and the MCP server write. They only update instruction files.
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
context-eng init --codex-only
|
|
67
|
+
context-eng init --cursor-only --scope global
|
|
68
|
+
context-eng init --cursor-only --project /path/to/repo
|
|
69
|
+
context-eng init --claude-only --scope both --project /path/to/repo
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
| Command | Global file | Project file |
|
|
73
|
+
| --- | --- | --- |
|
|
74
|
+
| `--codex-only` | `~/.codex/AGENTS.md` | none |
|
|
75
|
+
| `--cursor-only` | `~/.cursor/rules/context-eng-memory.mdc` | `<project>/.cursor/rules/context-eng-memory.mdc` |
|
|
76
|
+
| `--claude-only` | `~/.claude/CLAUDE.md` | `<project>/.claude/rules/context-eng-memory.md` |
|
|
77
|
+
|
|
78
|
+
`--scope` is `global`, `project`, or `both`. With no `--project`, scope defaults to `global`. With `--project` and no `--scope`, scope defaults to `project`. `project` and `both` need `--project`.
|
|
79
|
+
|
|
80
|
+
`context-eng mcp` reads the keychain key when `TYPESAFE_API_KEY` is unset. Set `TYPESAFE_API_KEY` to override it. Set it empty to force local FTS5 search. `CONTEXT_ENG_HOME` overrides the default `~/.context` storage root.
|
|
81
|
+
|
|
82
|
+
## Search behavior
|
|
83
|
+
|
|
84
|
+
`memory_search` can omit categories to search every category available in the selected scope. Supplying one to four categories narrows the search. Filters are applied before retrieval:
|
|
85
|
+
|
|
86
|
+
- An MCP started without `--project` has no project layout. Global-only search/create and the global portions of map/category discovery still work. Project or both-scope operations return `PROJECT_NOT_BOUND` until you retry that call with `projectPath` or call `memory_bind`; id-based tools require `memory_bind` because they do not accept `projectPath`.
|
|
87
|
+
- With `TYPESAFE_API_KEY`, searches with at most 60 eligible rows and 12,000 eligible tokens send every row to Jev. Larger searches merge FTS5 matches, exact hint-label matches, one conservative typo retry, and priority fill; Jev evaluates the first 90 in batches of 30.
|
|
88
|
+
- Optional `hints.topics`, `hints.tags`, `hints.links`, and `hints.categories` boost candidate selection but never act as hard filters. Exact label matches are preserved in the local fallback.
|
|
89
|
+
- Without the key, or when Jev fails or exceeds its 20-second request deadline (`DEFAULT_JEV_TIMEOUT_MS`, locked), the tool uses local lexical and exact-label retrieval.
|
|
90
|
+
- At most 50 relevant contexts and approximately 4000 tokens are returned after a short retrieval mode/count line.
|
|
91
|
+
|
|
92
|
+
Jev receives only the agent prompt and an array of memory-content strings; category, scope, importance, IDs, and other memory metadata stay local.
|
|
93
|
+
|
|
94
|
+
```mermaid
|
|
95
|
+
sequenceDiagram
|
|
96
|
+
participant You
|
|
97
|
+
participant agent
|
|
98
|
+
participant MCP as memory_search
|
|
99
|
+
participant SQLite
|
|
100
|
+
participant Jev
|
|
101
|
+
|
|
102
|
+
You->>agent: task
|
|
103
|
+
agent->>MCP: query + categories + filters + hints
|
|
104
|
+
MCP->>SQLite: filtered candidates
|
|
105
|
+
SQLite-->>MCP: eligible contexts
|
|
106
|
+
MCP->>Jev: prompt + content strings
|
|
107
|
+
Jev-->>MCP: probability 0 to 1
|
|
108
|
+
MCP-->>agent: notes over 0.5
|
|
109
|
+
agent-->>You: answer using that text
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
```mermaid
|
|
115
|
+
flowchart TD
|
|
116
|
+
search[memory_search] --> filters[apply filters]
|
|
117
|
+
filters --> size{rows ≤ 60 and tokens ≤ 12000?}
|
|
118
|
+
size -->|yes| all[all eligible rows]
|
|
119
|
+
size -->|no| rank[FTS + exact labels + typo retry + fill]
|
|
120
|
+
all --> jev{Jev available?}
|
|
121
|
+
rank --> jev
|
|
122
|
+
jev -->|no or fail| fts[local lexical + exact labels]
|
|
123
|
+
jev -->|yes| cap{candidates > 90?}
|
|
124
|
+
cap -->|no| batch[Jev all in batches of 30]
|
|
125
|
+
cap -->|yes| first[Jev first 90 in batches of 30]
|
|
126
|
+
batch --> gate[Jev keeps over 0.5]
|
|
127
|
+
first --> gate
|
|
128
|
+
gate -->|hits| out[up to 50 notes / ~4000 tokens]
|
|
129
|
+
gate -->|empty| none[no matching memory.]
|
|
130
|
+
first -->|hits remain| msg[append too-large message]
|
|
131
|
+
msg --> out
|
|
132
|
+
fts --> out
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
## Requirements and install
|
|
140
|
+
|
|
141
|
+
Node.js 20 or newer.
|
|
142
|
+
|
|
143
|
+
One command, after this package is published. It asks for the TypeSafe key, then detects Cursor, Claude Code, and Codex. In a terminal the installed ones start selected. Space turns one off, Enter confirms, and init writes a user-level MCP server only for the ones left selected. A different existing `context-eng` setup needs confirmation before replacement. In a non-terminal session, use `--yes` to add missing servers without replacing different ones. That server is `npx -y context-eng mcp` when `npx` is on PATH, otherwise `pnpm dlx context-eng mcp`. Global configs omit `--project`.
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
npx -y context-eng init
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
pnpm dlx context-eng init
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
From this repo:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
npm install
|
|
157
|
+
npm run build
|
|
158
|
+
npm run init
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
## Init and server
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
npm run init
|
|
167
|
+
node dist/cli-entry.js init --project /path/to/repo
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
`context-eng init` asks for a TypeSafe API key in the terminal and stores it in the OS keychain (macOS Keychain, Windows Credential Manager, or libsecret). The prompt is hidden. Press Enter to skip. Run init again to replace a saved key: enter the new key, or press Enter to keep the current one. The key is not written into the project.
|
|
171
|
+
|
|
172
|
+
`context-eng mcp` reads that key when `TYPESAFE_API_KEY` is unset. Set `TYPESAFE_API_KEY` to override the keychain. Set it to an empty value to force local FTS5 search.
|
|
173
|
+
|
|
174
|
+
Run with Jev after the key is saved:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
node dist/cli-entry.js mcp --project /path/to/repo
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Run with `TYPESAFE_API_KEY` empty for local FTS5-only search:
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
TYPESAFE_API_KEY= node dist/cli-entry.js mcp --project /path/to/repo
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Omitting `--project` is supported for a global-only server. It does not resolve or store `process.cwd()` as a project layout; bind explicitly before project access.
|
|
187
|
+
|
|
188
|
+
Project-path resolution elsewhere still uses explicit input, then `CONTEXT_ENG_PROJECT`, then the current working directory. The `mcp` command intentionally treats an omitted `--project` as unbound instead of accepting that fallback as a binding. `CONTEXT_ENG_HOME` overrides the default `~/.context` storage root.
|
|
189
|
+
|
|
190
|
+
## Memory search
|
|
191
|
+
|
|
192
|
+
`query` is required. `projectPath` is required when no project is bound and the scope is `project` or `both` (the default). If the tool returns `PROJECT_NOT_BOUND`, retry the same call with `projectPath`. Categories, filters, hints, sort, and limit are optional.
|
|
193
|
+
|
|
194
|
+
```json
|
|
195
|
+
{
|
|
196
|
+
"projectPath": "/path/to/repo",
|
|
197
|
+
"query": "fix the image export memory leak",
|
|
198
|
+
"categories": ["mistake", "decision"],
|
|
199
|
+
"filters": {
|
|
200
|
+
"scope": "both",
|
|
201
|
+
"minImportance": 0.6,
|
|
202
|
+
"subject": "canvas export",
|
|
203
|
+
"topics": { "values": ["browser memory"], "match": "any" },
|
|
204
|
+
"tags": { "values": ["blob-url"], "match": "all" },
|
|
205
|
+
"links": { "values": ["cli.ts"], "match": "any" },
|
|
206
|
+
"time": { "field": "updated", "preset": "this_month" }
|
|
207
|
+
},
|
|
208
|
+
"hints": {
|
|
209
|
+
"topics": ["browser memory"],
|
|
210
|
+
"tags": ["blob-url"],
|
|
211
|
+
"links": ["cli.ts"],
|
|
212
|
+
"categories": ["mistake"]
|
|
213
|
+
},
|
|
214
|
+
"sort": { "by": "relevance", "order": "desc" },
|
|
215
|
+
"limit": 50
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Omit `categories` to search every category in the selected scope. Omit `projectPath` when the server started with `--project`, you already called `memory_bind`, or `filters.scope` is `global`.
|
|
220
|
+
|
|
221
|
+
Time supports `this_week` (Monday to now), `this_month`, or inclusive ISO-8601 `from`/`to` ranges. Filter topics, tags, and links support `any` or `all` and remove non-matches. Hint topics, tags, links, and categories only influence candidate ordering. Links are opaque cross-references rather than URLs specifically: at most ten values, each at most 64 characters.
|
|
222
|
+
|
|
223
|
+
## Tools
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
| Tool | Contract |
|
|
227
|
+
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
228
|
+
| `memory_search` | `query` is required. Pass `projectPath` when unbound and scope is `project` or `both`; on `PROJECT_NOT_BOUND`, retry with `projectPath`. Other fields are optional. Hints boost without hard filtering. |
|
|
229
|
+
| `memory_create` | Creates a missing custom category on first write. Near-duplicate names require a second call with `confirmNewCategory: true`; built-in durable categories auto-promote and custom categories start in staging. |
|
|
230
|
+
| `memory_list_categories` | Lists global names, and project names when a project is bound. Omission returns global only while unbound. Explicit `scope: "project"` needs `projectPath` or `memory_bind`. |
|
|
231
|
+
| `memory_edit` | Requires `currentCategory`; an optional replacement `category` moves the row between category databases. Creating a near-duplicate destination requires `confirmNewCategory: true`. |
|
|
232
|
+
| `memory_map` | Lists categories, counts, staging, aligned `lines_ids`, and map paths. Accepts `scope` (`both`, `global`, or `project`) and `projectPath`. |
|
|
233
|
+
| `memory_bind` | Binds the server to another project storage catalog. |
|
|
234
|
+
| `memory_promote` | Requires category and ID; moves a staging memory into search. |
|
|
235
|
+
| `memory_demote` | Requires category and ID; moves a searchable memory to staging. |
|
|
236
|
+
| `memory_delete` | Requires category and ID; deletes staging rows only. |
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
## Data layout and migration
|
|
242
|
+
|
|
243
|
+
```text
|
|
244
|
+
~/.context/
|
|
245
|
+
global/
|
|
246
|
+
catalog.db
|
|
247
|
+
categories/<slug>-<hash>.db
|
|
248
|
+
projects/<project-key>/
|
|
249
|
+
catalog.db
|
|
250
|
+
categories/<slug>-<hash>.db
|
|
251
|
+
map.md
|
|
252
|
+
map.json
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
On first open, existing single-database memories are copied into staged category databases, validated, activated, and marked migrated. IDs, timestamps, tags, importance, active state, and staging state are preserved; the legacy database is not deleted.
|
|
256
|
+
|
|
257
|
+
Category names are Unicode-normalized and case-insensitive for lookup. Safe slug-and-hash filenames prevent a category name from becoming a filesystem path. If at least 80% of a new name matches a built-in or same-scope registered category after separators are removed, `memory_create` or a category-changing `memory_edit` returns `NEAR_CATEGORY` without writing. Separator-only variants such as `batch-probe` and `batch_probe` are also treated as matches. The agent can use the suggested category or make a second call with `confirmNewCategory: true`. Built-in categories keep their existing auto-promotion behavior; custom categories have no rename or delete lifecycle in this version.
|
|
258
|
+
|
|
259
|
+
## Checks
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
npm test
|
|
263
|
+
npm run typecheck
|
|
264
|
+
npm run typecheck:test
|
|
265
|
+
npm run lint
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
## Related docs
|
|
271
|
+
|
|
272
|
+
- [Memory tool rules](system_prompts/rules.md) — agent contract for bind, search, write, promote, and delete
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export declare const CATEGORIES: readonly ["instruction", "mistake", "preference", "decision", "constraint", "workflow"];
|
|
2
|
+
/** Categories are extensible; these six names retain their built-in behavior. */
|
|
3
|
+
export type Category = string;
|
|
4
|
+
/** Built-in categories that leave staging immediately on create. */
|
|
5
|
+
export declare const AUTO_PROMOTE: ReadonlySet<string>;
|
|
6
|
+
export declare const SCOPES: readonly ["global", "project"];
|
|
7
|
+
export type Scope = (typeof SCOPES)[number];
|
|
8
|
+
export declare const STAGING = "staging";
|
|
9
|
+
export declare const MAX_TOKENS = 800;
|
|
10
|
+
export declare const MAX_HITS = 50;
|
|
11
|
+
export declare const MAX_READ_TOKENS = 4000;
|
|
12
|
+
export declare const MAX_SEARCH_CATEGORIES = 4;
|
|
13
|
+
export declare const MAX_JEV_CANDIDATES = 30;
|
|
14
|
+
/** Max parallel Jev requests. Candidates after 90 are skipped. */
|
|
15
|
+
export declare const MAX_JEV_BATCHES = 3;
|
|
16
|
+
export declare const MAX_EXHAUSTIVE_SEARCH_ROWS = 60;
|
|
17
|
+
export declare const MAX_EXHAUSTIVE_SEARCH_TOKENS = 12000;
|
|
18
|
+
export declare const MAX_CATEGORY_LENGTH = 64;
|
|
19
|
+
export declare const MAX_FILTER_VALUES = 10;
|
|
20
|
+
export declare const MAX_FILTER_VALUE_LENGTH = 64;
|
|
21
|
+
export declare const NEAR_CATEGORY_SIMILARITY = 0.8;
|
|
22
|
+
export declare function isCategory(value: unknown): value is Category;
|
|
23
|
+
export declare function canonicalCategory(value: string): string;
|
|
24
|
+
export declare function displayCategory(value: string): string;
|
|
25
|
+
/** Returns how much of two category names matches, from 0 to 1. */
|
|
26
|
+
export declare function categoryNameSimilarity(left: string, right: string): number;
|
|
27
|
+
export declare function isScope(value: unknown): value is Scope;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { editDistance } from "./text.js";
|
|
2
|
+
export const CATEGORIES = [
|
|
3
|
+
"instruction",
|
|
4
|
+
"mistake",
|
|
5
|
+
"preference",
|
|
6
|
+
"decision",
|
|
7
|
+
"constraint",
|
|
8
|
+
"workflow",
|
|
9
|
+
];
|
|
10
|
+
/** Built-in categories that leave staging immediately on create. */
|
|
11
|
+
export const AUTO_PROMOTE = new Set([
|
|
12
|
+
"instruction",
|
|
13
|
+
"decision",
|
|
14
|
+
"constraint",
|
|
15
|
+
"mistake",
|
|
16
|
+
]);
|
|
17
|
+
export const SCOPES = ["global", "project"];
|
|
18
|
+
export const STAGING = "staging";
|
|
19
|
+
export const MAX_TOKENS = 800;
|
|
20
|
+
export const MAX_HITS = 50;
|
|
21
|
+
export const MAX_READ_TOKENS = 4000;
|
|
22
|
+
export const MAX_SEARCH_CATEGORIES = 4;
|
|
23
|
+
export const MAX_JEV_CANDIDATES = 30;
|
|
24
|
+
/** Max parallel Jev requests. Candidates after 90 are skipped. */
|
|
25
|
+
export const MAX_JEV_BATCHES = 3;
|
|
26
|
+
export const MAX_EXHAUSTIVE_SEARCH_ROWS = 60;
|
|
27
|
+
export const MAX_EXHAUSTIVE_SEARCH_TOKENS = 12_000;
|
|
28
|
+
export const MAX_CATEGORY_LENGTH = 64;
|
|
29
|
+
export const MAX_FILTER_VALUES = 10;
|
|
30
|
+
export const MAX_FILTER_VALUE_LENGTH = 64;
|
|
31
|
+
export const NEAR_CATEGORY_SIMILARITY = 0.8;
|
|
32
|
+
export function isCategory(value) {
|
|
33
|
+
if (typeof value !== "string")
|
|
34
|
+
return false;
|
|
35
|
+
const normalized = value.normalize("NFKC").trim();
|
|
36
|
+
return (normalized.length > 0 &&
|
|
37
|
+
normalized.length <= MAX_CATEGORY_LENGTH &&
|
|
38
|
+
!hasControlCharacters(normalized));
|
|
39
|
+
}
|
|
40
|
+
function hasControlCharacters(value) {
|
|
41
|
+
for (const character of value) {
|
|
42
|
+
const code = character.charCodeAt(0);
|
|
43
|
+
if (code <= 31 || code === 127)
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
export function canonicalCategory(value) {
|
|
49
|
+
return value.normalize("NFKC").trim().toLocaleLowerCase("en-US");
|
|
50
|
+
}
|
|
51
|
+
export function displayCategory(value) {
|
|
52
|
+
return value.normalize("NFKC").trim();
|
|
53
|
+
}
|
|
54
|
+
/** Returns how much of two category names matches, from 0 to 1. */
|
|
55
|
+
export function categoryNameSimilarity(left, right) {
|
|
56
|
+
const a = comparableCategory(left);
|
|
57
|
+
const b = comparableCategory(right);
|
|
58
|
+
if (a === b)
|
|
59
|
+
return 1;
|
|
60
|
+
if (a.length === 0 || b.length === 0)
|
|
61
|
+
return 0;
|
|
62
|
+
const longest = Math.max(a.length, b.length);
|
|
63
|
+
return 1 - editDistance(a, b, longest) / longest;
|
|
64
|
+
}
|
|
65
|
+
function comparableCategory(value) {
|
|
66
|
+
return canonicalCategory(value).replace(/[^\p{L}\p{N}]+/gu, "");
|
|
67
|
+
}
|
|
68
|
+
export function isScope(value) {
|
|
69
|
+
return typeof value === "string" && SCOPES.includes(value);
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=categories.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"categories.js","sourceRoot":"","sources":["../src/categories.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-entry.js","sourceRoot":"","sources":["../src/cli-entry.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAEhC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC9B,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
declare const RULE_SCOPES: readonly ["global", "project", "both"];
|
|
2
|
+
type RuleScope = (typeof RULE_SCOPES)[number];
|
|
3
|
+
export declare function upsertMarkedBlock(existing: string | null, block: string): string;
|
|
4
|
+
export declare function agentPointerBlock(): string;
|
|
5
|
+
export declare function updateExistingPointer(file: string, block: string): boolean;
|
|
6
|
+
export declare function codexAgentsPath(home?: string): string;
|
|
7
|
+
export declare function writeCodexAgentsPointer(block: string, home?: string): string;
|
|
8
|
+
export declare function globalCursorRulePath(home?: string): string;
|
|
9
|
+
export declare function cursorRulePath(projectPath: string): string;
|
|
10
|
+
export declare function resolveRuleScope(scope: string | undefined, project: string | undefined): RuleScope;
|
|
11
|
+
export declare const resolveCursorRuleScope: typeof resolveRuleScope;
|
|
12
|
+
export declare function writeCursorRuleFile(block: string, file: string): string;
|
|
13
|
+
export declare function writeCursorRule(block: string, projectPath: string): string;
|
|
14
|
+
export declare function writeCursorRules(block: string, opts: {
|
|
15
|
+
scope: RuleScope;
|
|
16
|
+
project?: string;
|
|
17
|
+
home?: string;
|
|
18
|
+
}): string[];
|
|
19
|
+
export declare function globalClaudeAgentsPath(home?: string): string;
|
|
20
|
+
export declare function writeGlobalClaudePointer(block: string, home?: string): string;
|
|
21
|
+
export declare function claudeRulePath(projectPath: string): string;
|
|
22
|
+
export declare function writeClaudeRuleFile(block: string, file: string): string;
|
|
23
|
+
export declare function writeClaudeRule(block: string, projectPath: string): string;
|
|
24
|
+
export declare function writeClaudeRules(block: string, opts: {
|
|
25
|
+
scope: RuleScope;
|
|
26
|
+
project?: string;
|
|
27
|
+
home?: string;
|
|
28
|
+
}): string[];
|
|
29
|
+
export declare function main(): Promise<void>;
|
|
30
|
+
export {};
|