@ctxo/cli 0.13.0 → 0.14.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/README.md +20 -4
- package/dist/chunk-2Q76LH2H.js +186 -0
- package/dist/chunk-2Q76LH2H.js.map +1 -0
- package/dist/chunk-72CEQEQD.js +53 -0
- package/dist/chunk-72CEQEQD.js.map +1 -0
- package/dist/chunk-7HSA5JVP.js +1049 -0
- package/dist/chunk-7HSA5JVP.js.map +1 -0
- package/dist/chunk-G4BMKCKG.js +76 -0
- package/dist/chunk-G4BMKCKG.js.map +1 -0
- package/dist/chunk-L2CAUER6.js +508 -0
- package/dist/chunk-L2CAUER6.js.map +1 -0
- package/dist/chunk-LAX6VVBU.js +98 -0
- package/dist/chunk-LAX6VVBU.js.map +1 -0
- package/dist/chunk-SRQZDGFZ.js +128 -0
- package/dist/chunk-SRQZDGFZ.js.map +1 -0
- package/dist/{chunk-DT3ZH4AU.js → chunk-X4TVFJ4C.js} +6 -1
- package/dist/chunk-X4TVFJ4C.js.map +1 -0
- package/dist/{chunk-BYX3UFBJ.js → chunk-ZL36YS2V.js} +785 -1624
- package/dist/chunk-ZL36YS2V.js.map +1 -0
- package/dist/{cli-router-RR4CM62C.js → cli-router-AZCDNX5R.js} +982 -506
- package/dist/cli-router-AZCDNX5R.js.map +1 -0
- package/dist/index.js +13 -2874
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +747 -0
- package/dist/internal.js +13 -0
- package/dist/{json-index-reader-OXTRTGE6.js → json-index-reader-DBW32TCN.js} +6 -4
- package/dist/json-index-reader-DBW32TCN.js.map +1 -0
- package/dist/mcp-server-6YG2QE6E.js +2604 -0
- package/dist/mcp-server-6YG2QE6E.js.map +1 -0
- package/dist/module-host-KNMKS62R.js +13 -0
- package/dist/module-host-KNMKS62R.js.map +1 -0
- package/dist/module-loader-B3LYF3W7.js +14 -0
- package/dist/module-loader-B3LYF3W7.js.map +1 -0
- package/dist/plugin-discovery-XRXI3IJF.js +13 -0
- package/dist/plugin-discovery-XRXI3IJF.js.map +1 -0
- package/llms-full.txt +105 -1
- package/llms.txt +21 -1
- package/package.json +15 -4
- package/dist/chunk-BYX3UFBJ.js.map +0 -1
- package/dist/chunk-DT3ZH4AU.js.map +0 -1
- package/dist/cli-router-RR4CM62C.js.map +0 -1
- /package/dist/{json-index-reader-OXTRTGE6.js.map → internal.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
discoverPlugins,
|
|
4
|
+
resolvePackageCandidates,
|
|
5
|
+
resolvePluginPackageJson
|
|
6
|
+
} from "./chunk-2Q76LH2H.js";
|
|
7
|
+
import "./chunk-5DSKZJNN.js";
|
|
8
|
+
export {
|
|
9
|
+
discoverPlugins,
|
|
10
|
+
resolvePackageCandidates,
|
|
11
|
+
resolvePluginPackageJson
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=plugin-discovery-XRXI3IJF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/llms-full.txt
CHANGED
|
@@ -13,6 +13,9 @@ ctxo index --check # CI gate: fail if index stale (writes nothing, re
|
|
|
13
13
|
ctxo index --commit HEAD # Re-index the files one commit changed (what the post-commit hook runs)
|
|
14
14
|
ctxo index --files a.ts b.ts # Re-index only these files (alias: --file <path>)
|
|
15
15
|
ctxo # Start MCP server (stdio transport)
|
|
16
|
+
ctxo install domain # opt-in domain knowledge layer (@ctxo/domain)
|
|
17
|
+
ctxo init --domain # registry skeleton, fold guard hooks, skill, domain config
|
|
18
|
+
ctxo verify-domain --since origin/main # CI gate for contexts, cards, rule IDs, boundaries
|
|
16
19
|
```
|
|
17
20
|
|
|
18
21
|
MCP client configuration:
|
|
@@ -29,7 +32,7 @@ Ctxo is a pnpm workspace monorepo:
|
|
|
29
32
|
- `@ctxo/cli` (packages/cli) - CLI entry, composition root, MCP server, tool handlers
|
|
30
33
|
- `@ctxo/plugin-api` (packages/plugin-api) - `CtxoLanguagePlugin` protocol interface (v1 and v2)
|
|
31
34
|
- `@ctxo/lang-typescript` - ts-morph (full tier) plugin for TS/JS
|
|
32
|
-
- `@ctxo/lang-go` - tree-sitter
|
|
35
|
+
- `@ctxo/lang-go` - ctxo-go-analyzer (full tier, Go 1.22+) + tree-sitter plugin for Go
|
|
33
36
|
- `@ctxo/lang-csharp` - Roslyn plugin for C# (attribute annotations; SQL edges at known call sites when `@ctxo/lang-sql` is installed)
|
|
34
37
|
- `@ctxo/lang-java` - tree-sitter Java plugin (syntax tier); full tier via `@ctxo/lang-java-analyzer` companion package (JRE 11+ required)
|
|
35
38
|
- `@ctxo/lang-sql` (packages/lang-sql) - T-SQL plugin for `.sql` files, protocol v2 (`ctxo install sql`, alias `tsql`)
|
|
@@ -125,6 +128,8 @@ Parameters:
|
|
|
125
128
|
|
|
126
129
|
Returns: deadSymbols (with confidence 1.0/0.9/0.7 and reason), deadFiles, unusedExports, scaffolding markers. Symbols in .sql files are never reported (their consumers may live outside the index).
|
|
127
130
|
|
|
131
|
+
Test files are decided by the shared test-file classifier (the default test globs, such as `**/*.test.*`, `**/*_test.go` and `**/src/test/**`, plus files where a test-framework annotation marks a symbol). Unless includeTests is set they are left out: test symbols are never reported, and production code called only from tests is not dead.
|
|
132
|
+
|
|
128
133
|
When to use: Cleanup, refactoring, confirming code is truly unused.
|
|
129
134
|
Instead of: find_importers (specific symbol reverse lookup).
|
|
130
135
|
|
|
@@ -444,6 +449,105 @@ When the helper cannot restore or build during `ctxo index`, the C# plugin falls
|
|
|
444
449
|
|
|
445
450
|
---
|
|
446
451
|
|
|
452
|
+
## Language Parity: TypeScript, Java and Go (unreleased, #156 PR 1C)
|
|
453
|
+
|
|
454
|
+
`@ctxo/lang-typescript`, `@ctxo/lang-java` (with `@ctxo/lang-java-analyzer`) and `@ctxo/lang-go` do what `@ctxo/lang-csharp` does: annotations, tests as symbols with edges, and data edges for constant SQL at known call sites. Feature doc: docs/features/domain-knowledge.md ("Language parity"). Design record: the ADR-017 addendum.
|
|
455
|
+
|
|
456
|
+
### Capability matrix
|
|
457
|
+
|
|
458
|
+
| Language | Annotations (always on) | Test symbols | SQL at call sites (needs `@ctxo/lang-sql`) |
|
|
459
|
+
|---|---|---|---|
|
|
460
|
+
| C# | attributes, both tiers | test methods | Roslyn tier |
|
|
461
|
+
| TypeScript/JS | decorators | describe/it/test blocks | always (one tier) |
|
|
462
|
+
| Java | JDT: constant values; tree-sitter: strings only | test methods under src/test/java | JDT full tier only |
|
|
463
|
+
| Go | struct tags, both tiers | `_test.go` functions and methods (full tier) | analyzer full tier only |
|
|
464
|
+
|
|
465
|
+
### Known APIs
|
|
466
|
+
|
|
467
|
+
- TypeScript/JS (receiver must trace to the npm module): pg `query` (also `{ text }`); mysql2 `query`, `execute` (also `{ sql }`); mssql `query` (call or tagged template), `execute` (a procedure name); `knex.raw`; Prisma `$queryRaw`, `$executeRaw` (tagged template, interpolations become `@p0`, `@p1`) and `$queryRawUnsafe`, `$executeRawUnsafe`; TypeORM `query`; Sequelize `query`; better-sqlite3 `prepare`, `exec`.
|
|
468
|
+
- Java: JDBC `Connection.prepareStatement`, `prepareCall`, `Statement.execute*`; Spring `JdbcTemplate`, `NamedParameterJdbcTemplate` and their `*Operations` interfaces (`query*`, `update`, `batchUpdate`, `execute`); `EntityManager.createNativeQuery` (javax and jakarta); `@Query(value = ..., nativeQuery = true)`; MyBatis `@Select`, `@Insert`, `@Update`, `@Delete`. A JDBC escape `{call name(...)}` gives an `executes` edge.
|
|
469
|
+
- Go: `database/sql` `Query`, `QueryRow`, `Exec`, `Prepare` and their `Context` forms on DB, Tx, Conn, Stmt; sqlx `Select`, `Get`, `Queryx`, `NamedExec`, `MustExec` (methods and package functions); pgx v4 and v5 `Query`, `QueryRow`, `Exec`, including pgxpool; gorm `Raw`, `Exec`. The SQL is the argument bound to the callee's first `string` parameter.
|
|
470
|
+
- Out of scope in every language: ORM and query-builder calls (knex chains, Prisma model calls, TypeORM repositories, JPQL and Spring Data derived queries, gorm model calls).
|
|
471
|
+
|
|
472
|
+
### Constants and matching
|
|
473
|
+
|
|
474
|
+
- TypeScript: string literals, templates without substitutions, `+` and templates of constants, `const` bindings in the file or behind a relative import. Receiver provenance follows imports, `require`, type annotations and initializers, destructuring, constructor parameter properties and `this` members (through `extends` too), return types, `import('M').T`, `export *` barrels and dynamic `import()`, at most 8 steps. Relative modules missing from memory are read from disk (`.ts/.tsx/.js/.jsx`, inside the project root), so the post-commit hook, `--files` and watch give the same edges as a full run. Edges start at the innermost exported function, method of an exported class, exported variable or test block.
|
|
475
|
+
- Java: JDT constant evaluation (literals, static final fields, concatenation, text blocks). The owner matches the receiver's static type, the binding's declaring class or any supertype; without a binding, the declared type through the imports. Edges start at the enclosing method or constructor.
|
|
476
|
+
- Go: constants per `go/types`; the callee's method object (pointer stripped) names the owner. A closure belongs to its enclosing function.
|
|
477
|
+
- Non-constant SQL is counted (debug logs and the analyzers' `sql: { constant, nonConstant }` summary), never guessed, and never stored in the index.
|
|
478
|
+
|
|
479
|
+
### Annotation formats
|
|
480
|
+
|
|
481
|
+
- TypeScript: `name` is the rightmost identifier (`@nest.Injectable()` gives `Injectable`); `args` are string literal arguments; `named` holds string properties of object-literal arguments. Property decorators go on the class with `named.member` (`{ name: 'Column', named: { member: 'memberId', name: 'member_id' } }`). Accessor and parameter decorators are ignored.
|
|
482
|
+
- Java: simple name; `value` to `args`, other members to `named`; declared values only; strings, numbers, booleans, enum constants as `Type.MEMBER`, class literals as the qualified name; arrays flattened in `args` and joined with `,` in `named`. Java keeps a member named `member`.
|
|
483
|
+
- Go: `{ name: 'tag', named: { member: '<Field>', <key>: '<value>' } }` per tagged field, on the struct; `reflect.StructTag` rules, first key wins.
|
|
484
|
+
- Every language drops a key named `type` (`named.type` stays reserved).
|
|
485
|
+
|
|
486
|
+
### Test-block naming (TypeScript)
|
|
487
|
+
|
|
488
|
+
Title path joined with ` > `; whitespace collapsed; runs of `:` collapsed and a trailing `:` dropped; empty title `(untitled)`; cut at 200 characters; a repeated path (or one equal to an exported function name) gets ` #2`, ` #3`; children use their parent's final name. Example ID: `src/loans/loan-policy.test.ts::LoanPolicy > renewal > extends by seven days::function`. `index.tests` extras do not reach plugins.
|
|
489
|
+
|
|
490
|
+
### Effects and limits
|
|
491
|
+
|
|
492
|
+
- Tests count as blast-radius dependents (the gate may fire more often on well-tested symbols); symbol-level communities shift once; Go full-tier runs type-check test packages; JDT `calls`/`uses` edges stay type-level.
|
|
493
|
+
- find_dead_code: shared test-file classifier (default globs plus test-annotated files); test symbols are never dead, production code called only from tests is not dead (Go included); production code under `test/` or `src/test/` folders and test-annotated files are left out of the analysis.
|
|
494
|
+
- A Java file with a `@Test` method counts as a test file anywhere.
|
|
495
|
+
- Limits: TypeScript misses union-typed receivers (`Pool | null`), getters returning a pool, namespace imports of relative modules and numeric constants in templates. Java's tree-sitter tier keeps strings only and evaluates no constants; MyBatis `<script>` and `${}` pass through as written; without a binding, subclass receivers, `super.update(...)` and `batchUpdate` array literals are missed. Go's tree-sitter tier decodes interpreted tag literals with JSON rules and reads exported structs only; build-tagged test files are not loaded, so the full tier gives them no symbols; sqlc-style interfaces, method values and method expressions give no call sites; sqlx `...Context` forms are not listed.
|
|
496
|
+
- Corpus: `packages/sql-extract/corpus/<case>.<ts|java|go>.fixture` with `mode` `typescript`, `java` or `go`, run only by the matching plugin.
|
|
497
|
+
|
|
498
|
+
---
|
|
499
|
+
|
|
500
|
+
## Domain Knowledge Layer: `@ctxo/domain` (unreleased, #156 PR 2B)
|
|
501
|
+
|
|
502
|
+
An opt-in package that lets a team name its bounded contexts and keep markdown cards in step with code. Ctxo supplies structure, linkage, verification and retrieval; it never writes domain text or fetches external documentation. Feature doc: docs/features/domain-knowledge.md ("Named contexts and the domain package", "Ctxo domain conventions v1"). Design record: docs/architecture/ADR/adr-018-domain-knowledge-layer.md.
|
|
503
|
+
|
|
504
|
+
### Install and loading
|
|
505
|
+
|
|
506
|
+
- `ctxo install domain` installs `@ctxo/domain` at the CLI's version (globally when the project has no `package.json`; `npm i -g @ctxo/cli @ctxo/domain @ctxo/lang-sql` is the supported path for such repositories). `ctxo init --domain` also sets it up.
|
|
507
|
+
- The CLI loads the package from the project's `node_modules`, then from next to itself, through `@ctxo/cli/internal` (types only, plus `createModuleHost`). Only a copy at the same `major.minor` loads; `@ctxo/cli` and `@ctxo/domain` share one version.
|
|
508
|
+
- Without the package: no domain commands, fields or hooks. A known domain command name (`verify-domain`, `contexts-touched`, `domain`) prints an install hint and exits 1; `ctxo domain-guard-hook` exits 0 without output; `ctxo --help` ends with one install hint line. With the package and no registry: the commands print a hint and exit 0 and no `context` fields appear.
|
|
509
|
+
|
|
510
|
+
### Registry and cards
|
|
511
|
+
|
|
512
|
+
- `docs/domain/contexts.yaml` (`domain.registry`): `version: 1`, `contexts[]` with `id` (kebab-case, permanent), `name`, `card` (optional only at rung fear), `paths` (globs), `rung` (fear, pinned, named, bounded, boring), `rulePrefix`, `contracts` (target context to allowed target files); `unowned.allow`, `glossary` (`docs/domain/glossary.md`), `contextMap` (`docs/domain/context-map.md`, a table with Context and Rung columns that must agree with the registry).
|
|
513
|
+
- A file belongs to at most one context. Unowned files warn by default (`domain.coverage.unowned: error` to fail).
|
|
514
|
+
- Card: five H2 headings in order (Language; Rules and invariants; Boundary contracts; Decisions; Open questions). Rules are `### <ID> <title>` under Rules and invariants, with optional `Tests:`, `Code:` and `Untested:` lines. A rule needs a test link, a `Tests:` line or an `Untested:` line.
|
|
515
|
+
- Rule IDs match `domain.rules.idPattern` (default `^[A-Z][A-Z0-9]*-\d+$`), are permanent and unique across cards, and use the context's `rulePrefix` when it has one. A test links to a rule through `[Trait("Rule", "LEND-03")]` (keys in `domain.tests.ruleTraitKeys`), `Category` / `TestCategory` / `Tag` values, `rule: LEND-03` comments, test titles that start with an ID, or the card's `Tests:` line. Tracker prefixes (`domain.rules.trackerPrefixes`) never link from plain text.
|
|
516
|
+
|
|
517
|
+
### Commands
|
|
518
|
+
|
|
519
|
+
- `ctxo contexts-touched [--since <ref>] [--committed | --staged] [--json] [--check]`: contexts whose paths hold a changed non-test file, with status `card-changed`, `acknowledged` (a `Domain-Unchanged` trailer in the range), `unresolved` or `no-card`. `--check` exits 1 on unresolved; 2 on registry problems, a missing base (CI needs `fetch-depth: 0`) or git failure.
|
|
520
|
+
- `ctxo verify-domain [--since <ref>] [--boundaries by-rung|report] [--json]`: checks 1 registry and config, 2 cards present, 3 path globs match, 4a single owner, 4b unowned files, 5 card headings, 6 rule IDs and test links, 7 card links and anchors, 8 generated loader rules, 9 context map rungs, 10 boundaries, 11 fold since a ref (with `--since`). Exit 0 (warnings allowed), 1 errors, 2 missing index, git failure or internal error. `--json` writes `{ registry, checks, summary, exitCode }` to stdout; stdout is empty on exit 2 and with no registry.
|
|
521
|
+
- `ctxo domain rules --write | --check`: one pointer file per context with a card: `.claude/rules/ctxo-context-<id>.md` (front matter `paths`) and, when `.cursor/` exists, `.cursor/rules/ctxo-context-<id>.mdc`. Marker `<!-- generated by ctxo domain rules; do not edit -->`. `--check` exits 1 on missing, outdated, stale and blocked files (a hand-written file at a generated path; rename or delete it).
|
|
522
|
+
- `ctxo domain discover [--json] [--write]`: card rule prefixes, tracker-like keys in commit subjects and branch names (5 or more is proposed as a tracker prefix), test trait keys, uncovered test folders; `--write` merges the proposal into `.ctxo/config.yaml`.
|
|
523
|
+
- `ctxo init --domain [--boundaries <by-rung|report>]` or `--only domain`: config defaults, registry skeleton, discovery with confirmation, loader rules, guard hooks (SessionStart, Stop, TaskCompleted) and the `ctxo-domain-fold` skill (Claude Code and Cursor).
|
|
524
|
+
|
|
525
|
+
### Fold guard and trailer
|
|
526
|
+
|
|
527
|
+
- `ctxo domain-guard-hook` judges only the commits of the current session (`startHead..HEAD`, recorded at SessionStart, intersected with the branch range from `domain.guard.base`, `origin/HEAD`, `main` or `master`; unpushed commits on the default branch). It blocks once per fingerprint (HEAD plus unresolved IDs): `Stop` prints `{"decision":"block","reason":...}` and exits 0, `TaskCompleted` prints to stderr and exits 2. `stop_hook_active` and every internal error allow.
|
|
528
|
+
- Trailer: `Domain-Unchanged: <id>[, <id>...] [(reason)]`, read with `git log --format=%(trailers:key=Domain-Unchanged,valueonly)` over the evaluated range only. A card change in the range also resolves a context. An empty commit with the trailer is fine.
|
|
529
|
+
|
|
530
|
+
### Boundaries, drift and fields
|
|
531
|
+
|
|
532
|
+
- `ctxo index` writes `.ctxo/index/domain/contexts.json`, `boundaries.json` and `history/` (10 per-commit entries), each with a `ctxoArtifact` marker that the index reader skips.
|
|
533
|
+
- Edges between contexts are allowed when the target file matches the source context's `contracts.<target>`; otherwise a violation: an error for `blockingRungs` (default bounded, boring) in `by-rung` mode, else a warning (`report` mode: always a warning). Edges from test files and to unowned files are skipped.
|
|
534
|
+
- Additive fields: `context` (set when exactly one context owns the file) on search_symbols results, get_blast_radius impacted symbols, find_importers importers, get_logic_slice roots and get_pr_impact changed symbols; `contextBoundaryViolations` (capped at 50, with `contextBoundaryViolationsTotal`) on get_pr_impact; `contextDrift` (`crossShare`, `trend`, `movedFiles`, `distinctCommits`, `confidence`) on get_why_context.
|
|
535
|
+
|
|
536
|
+
### Doctor and global installs
|
|
537
|
+
|
|
538
|
+
- `domain_registry`, `domain_agent_setup` and `domain_conventions` (all pass or warn; a repo with neither `.claude/` nor `.cursor/` is checked as Claude Code and carries a standing agent-setup warning until `ctxo init --only domain`).
|
|
539
|
+
- `install_copies` (every project): warns, never fails, when hooks call `ctxo` and none is on PATH, or an npx-pinned MCP entry differs from the global CLI the hooks run. `ctxo init` from a global install writes MCP entries that call the global `ctxo`.
|
|
540
|
+
|
|
541
|
+
### Config
|
|
542
|
+
|
|
543
|
+
`domain:` keys and defaults: `registry: docs/domain/contexts.yaml`, `coverage.unowned: warn`, `boundaries.enforce: by-rung`, `boundaries.blockingRungs: [bounded, boring]`, `rules.idPattern: ^[A-Z][A-Z0-9]*-\d+$`, `rules.trackerPrefixes: []`, `tests.ruleTraitKeys: [Rule]`, `guard.enabled: true`, `guard.base` (unset), `guard.subagents: false`. An invalid key falls back to its default and verify-domain check 1 reports it.
|
|
544
|
+
|
|
545
|
+
### Adoption ladder
|
|
546
|
+
|
|
547
|
+
level 0: install and index; 1: registry with paths; 2: cards; 3: rule IDs and test links, through card `Tests:` lines, test names or framework tags; 4: contracts and shadow-spec resolutions. No level requires code changes.
|
|
548
|
+
|
|
549
|
+
---
|
|
550
|
+
|
|
447
551
|
## Safe-Edit Guard (v0.8+)
|
|
448
552
|
|
|
449
553
|
The safe-edit guard closes the loop between MCP tool availability and agent compliance. An agent with access to get_blast_radius can still skip it. The guard makes skipping impossible for high-impact symbols on Claude Code.
|
package/llms.txt
CHANGED
|
@@ -18,10 +18,11 @@ ctxo # Start MCP server (stdio)
|
|
|
18
18
|
- `@ctxo/cli` - CLI + MCP server (formerly `ctxo-mcp`)
|
|
19
19
|
- `@ctxo/plugin-api` - `CtxoLanguagePlugin` interface, protocol v1 and v2 (`SUPPORTED_API_VERSIONS = ['1', '2']`; v2 adds data kinds, annotations, facts on request and host capabilities)
|
|
20
20
|
- `@ctxo/lang-typescript` - ts-morph full-tier plugin
|
|
21
|
-
- `@ctxo/lang-go` - tree-sitter
|
|
21
|
+
- `@ctxo/lang-go` - ctxo-go-analyzer (full tier, Go 1.22+) + tree-sitter plugin
|
|
22
22
|
- `@ctxo/lang-csharp` - Roslyn plugin (attribute annotations; SQL edges at known call sites when `@ctxo/lang-sql` is installed)
|
|
23
23
|
- `@ctxo/lang-java` - tree-sitter Java plugin (syntax tier built-in; full tier via `@ctxo/lang-java-analyzer` companion, requires JRE 11+)
|
|
24
24
|
- `@ctxo/lang-sql` - T-SQL plugin for `.sql` files (protocol v2): tables, views, procedures, functions and their reads/writes/executes
|
|
25
|
+
- `@ctxo/domain` - opt-in domain knowledge layer (ADR-018): named contexts, cards, the fold guard and the `verify-domain` CI gate; loaded by the CLI through `@ctxo/cli/internal`, shares one version with `@ctxo/cli`
|
|
25
26
|
- `@ctxo/sql-extract` - zero-dependency T-SQL tokenizer and recognizers (a library, not a plugin; the one dependency plugins may take besides `@ctxo/plugin-api`)
|
|
26
27
|
|
|
27
28
|
Language adapters ship as separate npm packages and are discovered by scanning the project `package.json` for `@ctxo/lang-*` or `ctxo-lang-*` dependencies.
|
|
@@ -55,6 +56,25 @@ Language adapters ship as separate npm packages and are discovered by scanning t
|
|
|
55
56
|
- Safe to delete? -> find_importers
|
|
56
57
|
- Preparing a context map? -> get_architectural_overlay(mode: "contexts")
|
|
57
58
|
|
|
59
|
+
## Unreleased: domain knowledge layer, `@ctxo/domain` (#156, PR 2B)
|
|
60
|
+
|
|
61
|
+
- Install: `ctxo install domain` (globally when the project has no `package.json`), then `ctxo init --domain`. Opt-in: without the package, no commands, fields or hooks, and a known domain command name prints an install hint and exits 1 (`ctxo domain-guard-hook` exits 0 without output). With the package but no registry, the domain commands print a hint and exit 0 and no `context` fields appear.
|
|
62
|
+
- Registry `docs/domain/contexts.yaml`: contexts with `id`, `name`, `card`, `paths`, `rung` (fear, pinned, named, bounded, boring), `rulePrefix`, `contracts`; `unowned.allow`, `glossary`, `contextMap`. A card has five H2 headings (Language; Rules and invariants; Boundary contracts; Decisions; Open questions) and rules as `### LEND-03 title` with optional `Tests:`, `Code:` and `Untested:` lines.
|
|
63
|
+
- Commands: `ctxo contexts-touched [--since <ref>] [--committed | --staged] [--json] [--check]`; `ctxo verify-domain [--since <ref>] [--boundaries by-rung|report] [--json]` (exit 0, 1 or 2; `--json` stdout is empty on exit 2 and with no registry); `ctxo domain rules --write | --check`; `ctxo domain discover [--json] [--write]`; `ctxo init --domain [--boundaries <mode>]` and `--only domain`.
|
|
64
|
+
- Fold guard (Claude Code): `ctxo domain-guard-hook` on SessionStart, Stop and TaskCompleted blocks once when the session's commits changed a context without a card change; resolve with a card commit or the trailer `Domain-Unchanged: <id>[, <id>] (reason)`.
|
|
65
|
+
- Config `domain:` in `.ctxo/config.yaml`: `registry`, `coverage.unowned` (warn | error), `boundaries.enforce` (by-rung | report) and `blockingRungs`, `rules.idPattern` and `trackerPrefixes`, `tests.ruleTraitKeys`, `guard.enabled`, `guard.base`, `guard.subagents`.
|
|
66
|
+
- Additive fields with `@ctxo/domain` and a registry: `context` on search_symbols, get_blast_radius, find_importers, get_logic_slice and get_pr_impact entries; `contextBoundaryViolations` on get_pr_impact; `contextDrift` on get_why_context. `ctxo index` writes `.ctxo/index/domain/`.
|
|
67
|
+
- Doctor: `domain_registry`, `domain_agent_setup`, `domain_conventions`, and `install_copies` (MCP entry and hooks start the same copy). Feature doc: docs/features/domain-knowledge.md ("Ctxo domain conventions v1").
|
|
68
|
+
|
|
69
|
+
## Unreleased: language parity for TypeScript, Java and Go (#156, PR 1C)
|
|
70
|
+
|
|
71
|
+
- Capability matrix (annotations / test symbols / SQL at call sites, the last only with `@ctxo/lang-sql` installed): C# attributes / test methods / ADO.NET, Dapper, SqlBulkCopy, EF Core raw SQL (Roslyn tier); TypeScript decorators / test blocks / pg, mysql2, mssql, knex.raw, Prisma raw, TypeORM, Sequelize, better-sqlite3; Java annotations (JDT constant values, tree-sitter strings only) / test methods under src/test/java / JDBC, Spring JdbcTemplate, JPA native queries, native @Query, MyBatis (JDT full tier); Go struct tags (both tiers) / `_test.go` functions (full tier) / database/sql, sqlx, pgx, gorm raw (analyzer full tier).
|
|
72
|
+
- Annotation formats: TypeScript `@Injectable()` gives `{ name: 'Injectable' }`; a property decorator `@Column({ name: 'member_id' }) memberId` gives `{ name: 'Column', named: { member: 'memberId', name: 'member_id' } }` on the class. Java: the `value` member goes to `args`, other members to `named`, enum constants as `Type.MEMBER`. Go: each tagged field gives `{ name: 'tag', named: { member: 'LoanID', json: 'loan_id', gorm: 'column:loan_id' } }` on its struct. C# caps everywhere (20 per symbol, 10 args, 10 named, 200 chars); a key named `type` is dropped; `named.member` is reserved only in TypeScript and Go.
|
|
73
|
+
- TypeScript test blocks: in files matching `**/__tests__/**`, `**/*.test.*`, `**/*.spec.*`, `**/test/**`, `**/tests/**`, each describe/it/test block is a `function` symbol named by its title path, for example `src/loans/loan-policy.test.ts::LoanPolicy > renewal > extends by seven days::function`, annotated `{ name: 'test' }`, with its own callback's edges; a repeated path gets ` #2`, ` #3`.
|
|
74
|
+
- SQL at call sites: constant SQL only, parsed by `@ctxo/sql-extract`, edges to the same 2-part targets as C# and `.sql` files (`dbo.loans::table`). TypeScript ties the receiver to the listed npm module through a provenance walk (at most 8 steps); Java matches the receiver type, its supertypes or the imports; Go matches the callee's method object. Java and Go need their full tier.
|
|
75
|
+
- Tests now count as blast-radius dependents, so the safe-edit gate may fire more often on well-tested symbols. find_dead_code uses the shared test-file classifier: test symbols are never dead and Go functions called only from tests are no longer reported.
|
|
76
|
+
- The first re-index after upgrading rewrites committed index JSON for TypeScript, Java and Go files once; run a full `ctxo index`. The three plugins stay on protocol '1', so older CLIs keep loading them.
|
|
77
|
+
|
|
58
78
|
## New in v0.13
|
|
59
79
|
|
|
60
80
|
### Tiered agent rules, granular init, agent-setup doctor checks (#159)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ctxo/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "MCP server delivering dependency-aware, history-enriched context for codebases",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -19,6 +19,17 @@
|
|
|
19
19
|
],
|
|
20
20
|
"main": "dist/index.js",
|
|
21
21
|
"types": "dist/index.d.ts",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"import": "./dist/index.js"
|
|
26
|
+
},
|
|
27
|
+
"./internal": {
|
|
28
|
+
"types": "./dist/internal.d.ts",
|
|
29
|
+
"import": "./dist/internal.js"
|
|
30
|
+
},
|
|
31
|
+
"./package.json": "./package.json"
|
|
32
|
+
},
|
|
22
33
|
"keywords": [
|
|
23
34
|
"mcp",
|
|
24
35
|
"context",
|
|
@@ -54,10 +65,10 @@
|
|
|
54
65
|
"typescript-eslint": "^8.71.1",
|
|
55
66
|
"vitest": "^5.0.1",
|
|
56
67
|
"@ctxo/lang-csharp": "0.9.0",
|
|
57
|
-
"@ctxo/lang-go": "0.
|
|
58
|
-
"@ctxo/lang-java": "0.10.1",
|
|
68
|
+
"@ctxo/lang-go": "0.10.0",
|
|
59
69
|
"@ctxo/lang-sql": "0.1.0",
|
|
60
|
-
"@ctxo/lang-
|
|
70
|
+
"@ctxo/lang-java": "0.11.0",
|
|
71
|
+
"@ctxo/lang-typescript": "0.9.0"
|
|
61
72
|
},
|
|
62
73
|
"repository": {
|
|
63
74
|
"type": "git",
|