pluribus-context 0.2.0 → 0.3.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/CHANGELOG.md +12 -0
- package/README.md +57 -11
- package/bin/pluribus.js +13 -0
- package/docs/context-drift-audit.md +127 -0
- package/docs/context-file-review.md +102 -0
- package/docs/migrate-existing-context.md +179 -0
- package/docs/quickstart.md +102 -0
- package/docs/release-checklist.md +7 -3
- package/docs/when-to-use-pluribus.md +59 -0
- package/package.json +1 -1
- package/src/commands/audit.js +239 -0
- package/src/index.js +1 -0
- package/src/utils/version.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to Pluribus are documented here.
|
|
4
4
|
|
|
5
|
+
## 0.3.0 — Audit workflow and first-run docs alignment
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Add `pluribus audit`, a read-only command that compares generated tool files with `pluribus.md`, reports missing or drifted outputs, supports `--strict` for CI, and scans existing AI context files when a project has not adopted Pluribus yet.
|
|
10
|
+
- Add first-run docs for quickstart, context drift audit, existing context migration, context-file review, when to use Pluribus versus one-way converters, and issue templates so early users can report install, adapter, security-review, and migration friction with concrete details.
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Align the package README for the npm publish so the npm package page shows the real `npx pluribus-context` install path, npm badge, 60-second smoke test, `audit` workflow, and published-status roadmap.
|
|
15
|
+
- Clarify the temporary source-install path for `pluribus audit` while npm `latest` remains on 0.2.0.
|
|
16
|
+
|
|
5
17
|
## 0.2.0 — Package-ready CLI release
|
|
6
18
|
|
|
7
19
|
Pluribus 0.2.0 is the first npm-ready release of the CLI for keeping intentional AI context in one versioned source and syncing it to the files each tool expects. It supersedes the earlier GitHub-only v0.1.0 alpha release from March.
|
package/README.md
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# Pluribus
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/pluribus-context)
|
|
3
4
|
[](https://x.com/RibeiroCaioCLW)
|
|
4
5
|
[](LICENSE)
|
|
5
6
|
|
|
@@ -72,11 +73,12 @@ And it generates the right files for each tool:
|
|
|
72
73
|
### Install
|
|
73
74
|
|
|
74
75
|
```bash
|
|
75
|
-
#
|
|
76
|
-
|
|
76
|
+
# Run directly from npm
|
|
77
|
+
npx pluribus-context init
|
|
77
78
|
|
|
78
|
-
# Or
|
|
79
|
-
|
|
79
|
+
# Or install globally
|
|
80
|
+
npm install -g pluribus-context
|
|
81
|
+
pluribus --help
|
|
80
82
|
|
|
81
83
|
# Or clone and link locally
|
|
82
84
|
git clone https://github.com/caioribeiroclw-pixel/pluribus.git
|
|
@@ -84,8 +86,29 @@ cd pluribus
|
|
|
84
86
|
npm link
|
|
85
87
|
```
|
|
86
88
|
|
|
89
|
+
### 60-second smoke test
|
|
90
|
+
|
|
91
|
+
Want to see exactly what gets generated before adding it to a real project?
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
mkdir pluribus-demo && cd pluribus-demo
|
|
95
|
+
npx pluribus-context init --name "Ana" --description "A Node.js service" --tools claude,cursor,copilot
|
|
96
|
+
npx pluribus-context validate
|
|
97
|
+
npx pluribus-context sync --dry-run
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
If the preview looks right, run `npx pluribus-context sync` to write the tool-specific files.
|
|
101
|
+
|
|
102
|
+
For a fuller walkthrough, see the [Quickstart](docs/quickstart.md). If your repo already has `CLAUDE.md`, `.cursorrules`, Copilot instructions, or `AGENTS.md`, run a [Context Drift Audit](docs/context-drift-audit.md) first, then follow [Migrate Existing AI Context Files](docs/migrate-existing-context.md). Before committing shared or generated AI instructions, use the [Context File Review Checklist](docs/context-file-review.md). If you're deciding between Pluribus and a one-way rules converter, see [When to use Pluribus](docs/when-to-use-pluribus.md).
|
|
103
|
+
|
|
87
104
|
### Usage
|
|
88
105
|
|
|
106
|
+
> **Version note:** `pluribus audit` requires Pluribus 0.3.0 or newer. If npm still shows `pluribus-context@0.2.0`, use the audit guide manually or run the source install until the npm publish is complete:
|
|
107
|
+
>
|
|
108
|
+
> ```bash
|
|
109
|
+
> npx --package github:caioribeiroclw-pixel/pluribus#main pluribus audit
|
|
110
|
+
> ```
|
|
111
|
+
|
|
89
112
|
**1. Initialize your context file**
|
|
90
113
|
|
|
91
114
|
```bash
|
|
@@ -156,7 +179,21 @@ If you use remote imports and want to refresh the lock/cache while validating:
|
|
|
156
179
|
pluribus validate --update-imports
|
|
157
180
|
```
|
|
158
181
|
|
|
159
|
-
**5.
|
|
182
|
+
**5. Audit generated files before syncing**
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
pluribus audit
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
This is read-only. It compares existing generated files with what `pluribus.md` would produce, reports missing or drifted outputs, and can run in CI with `--strict`:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
pluribus audit --strict
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
If your project does not have `pluribus.md` yet, `pluribus audit` scans for known AI context files (`CLAUDE.md`, `.cursorrules`, Copilot instructions, `AGENTS.md`, Windsurf, Continue, Zed) so you know what to migrate.
|
|
195
|
+
|
|
196
|
+
**6. Sync to all your tools**
|
|
160
197
|
|
|
161
198
|
```bash
|
|
162
199
|
pluribus sync
|
|
@@ -253,7 +290,7 @@ See `spec/skills-format.md` for the skill file format.
|
|
|
253
290
|
- [x] Remote composable contexts MVP (explicit `--update-imports`, public GitHub/HTTPS, safety limits)
|
|
254
291
|
- [x] Remote imports hardening (lockfile/cache/digest offline mode, optional GitHub auth, and CI coverage)
|
|
255
292
|
- [ ] CI/CD: auto-sync on commit
|
|
256
|
-
- [
|
|
293
|
+
- [x] Published to npm as [`pluribus-context`](https://www.npmjs.com/package/pluribus-context)
|
|
257
294
|
|
|
258
295
|
## Building in Public
|
|
259
296
|
|
|
@@ -261,10 +298,18 @@ I'm documenting every step of building Pluribus — the decisions, the trade-off
|
|
|
261
298
|
|
|
262
299
|
Follow along: [@RibeiroCaioCLW](https://x.com/RibeiroCaioCLW)
|
|
263
300
|
|
|
264
|
-
If you've felt this pain,
|
|
301
|
+
If you've felt this pain, tell me about your setup. What tools do you use? How do you manage context today? What's broken?
|
|
302
|
+
|
|
303
|
+
- [Quickstart feedback](https://github.com/caioribeiroclw-pixel/pluribus/issues/new?template=quickstart-feedback.yml) — if install, validate, or dry-run felt confusing
|
|
304
|
+
- [Bug report](https://github.com/caioribeiroclw-pixel/pluribus/issues/new?template=bug-report.yml) — if a command failed or generated the wrong output
|
|
305
|
+
- [Tool integration request](https://github.com/caioribeiroclw-pixel/pluribus/issues/new?template=integration-request.yml) — if another AI tool should be supported
|
|
265
306
|
|
|
266
307
|
## Docs
|
|
267
308
|
|
|
309
|
+
- [Quickstart](docs/quickstart.md) — first install, validation, dry-run preview, and common friction
|
|
310
|
+
- [Migrate Existing AI Context Files](docs/migrate-existing-context.md) — move from `CLAUDE.md`, `.cursorrules`, Copilot instructions, or `AGENTS.md` to one source of truth
|
|
311
|
+
- [When to use Pluribus](docs/when-to-use-pluribus.md) — choose between sync, one-way conversion, and tool-native context files
|
|
312
|
+
- [Context File Review Checklist](docs/context-file-review.md) — review AI instructions as supply-chain artifacts before committing generated context
|
|
268
313
|
- [OpenClaw Integration](docs/openclaw-integration.md) — how Pluribus generates `AGENTS.md` for OpenClaw
|
|
269
314
|
- [Composable Contexts](docs/composable-contexts.md) — local/remote imports, merge behavior, and safety rules
|
|
270
315
|
- [Remote Composable Context Imports](docs/remote-composable-context-imports.md) — design notes for lockfile/cache/auth hardening
|
|
@@ -279,11 +324,12 @@ If you've felt this pain, [open an issue](https://github.com/caioribeiroclw-pixe
|
|
|
279
324
|
|
|
280
325
|
This project is just getting started. The best way to help right now:
|
|
281
326
|
|
|
282
|
-
1.
|
|
283
|
-
2.
|
|
284
|
-
3.
|
|
327
|
+
1. Try the 60-second smoke test above in a throwaway directory
|
|
328
|
+
2. ⭐ Star the repo if the problem resonates
|
|
329
|
+
3. 🗣️ [Open a quickstart feedback issue](https://github.com/caioribeiroclw-pixel/pluribus/issues/new?template=quickstart-feedback.yml) if anything felt confusing
|
|
330
|
+
4. 📣 Share with someone who maintains 3+ AI context files
|
|
285
331
|
|
|
286
|
-
Looking for first contributions? Check out the [open issues](https://github.com/caioribeiroclw-pixel/pluribus/issues). The next good contributions are
|
|
332
|
+
Looking for first contributions? Check out the [open issues](https://github.com/caioribeiroclw-pixel/pluribus/issues). The next good contributions are CI/CD workflow examples, real-world adapter feedback, and install/quickstart friction reports.
|
|
287
333
|
|
|
288
334
|
## License
|
|
289
335
|
|
package/bin/pluribus.js
CHANGED
|
@@ -9,6 +9,7 @@ import { runInit } from '../src/commands/init.js'
|
|
|
9
9
|
import { runSync } from '../src/commands/sync.js'
|
|
10
10
|
import { runValidate } from '../src/commands/validate.js'
|
|
11
11
|
import { runWatch } from '../src/commands/watch.js'
|
|
12
|
+
import { runAudit } from '../src/commands/audit.js'
|
|
12
13
|
import { parseArgs } from '../src/utils/args.js'
|
|
13
14
|
import { VERSION } from '../src/utils/version.js'
|
|
14
15
|
|
|
@@ -22,6 +23,7 @@ COMMANDS
|
|
|
22
23
|
init Create a pluribus.md file in the current directory
|
|
23
24
|
sync Read pluribus.md and generate tool-specific output files
|
|
24
25
|
validate Validate pluribus.md before syncing
|
|
26
|
+
audit Compare generated tool files with pluribus.md without writing
|
|
25
27
|
watch Watch pluribus.md and auto-sync after changes
|
|
26
28
|
help Show this help message
|
|
27
29
|
|
|
@@ -40,6 +42,12 @@ OPTIONS (validate)
|
|
|
40
42
|
--source Path to pluribus.md (default: ./pluribus.md)
|
|
41
43
|
--update-imports Refresh remote github:/https:// imports before validating
|
|
42
44
|
|
|
45
|
+
OPTIONS (audit)
|
|
46
|
+
--source Path to pluribus.md (default: ./pluribus.md)
|
|
47
|
+
--tools Override which tools to audit (comma-separated)
|
|
48
|
+
--update-imports Refresh remote github:/https:// imports before auditing
|
|
49
|
+
--strict Exit non-zero when generated files are missing or drifted
|
|
50
|
+
|
|
43
51
|
OPTIONS (watch)
|
|
44
52
|
--source Path to pluribus.md (default: ./pluribus.md)
|
|
45
53
|
--tools Override which tools to sync (comma-separated)
|
|
@@ -55,6 +63,8 @@ EXAMPLES
|
|
|
55
63
|
pluribus sync --tools claude,openclaw
|
|
56
64
|
pluribus sync --update-imports
|
|
57
65
|
pluribus validate
|
|
66
|
+
pluribus audit
|
|
67
|
+
pluribus audit --strict
|
|
58
68
|
pluribus watch --tools claude,cursor
|
|
59
69
|
|
|
60
70
|
DOCS
|
|
@@ -91,6 +101,9 @@ async function main() {
|
|
|
91
101
|
case 'watch':
|
|
92
102
|
await runWatch(parsedArgs)
|
|
93
103
|
break
|
|
104
|
+
case 'audit':
|
|
105
|
+
await runAudit(parsedArgs)
|
|
106
|
+
break
|
|
94
107
|
default:
|
|
95
108
|
console.error(`❌ Unknown command: "${command}"`)
|
|
96
109
|
console.log(`Run \`pluribus help\` for usage.`)
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Context Drift Audit
|
|
2
|
+
|
|
3
|
+
Use this before adopting Pluribus when you are not sure whether your AI context files have already drifted.
|
|
4
|
+
|
|
5
|
+
The goal is not to make every tool identical. The goal is to separate shared project facts from tool-specific behavior so the shared parts can live in `pluribus.md` and be regenerated deliberately.
|
|
6
|
+
|
|
7
|
+
> **Version note:** the `pluribus audit` command requires Pluribus 0.3.0 or newer. If npm still serves `pluribus-context@0.2.0`, follow the manual checklist below or run from the GitHub source until the npm publish is complete:
|
|
8
|
+
>
|
|
9
|
+
> ```bash
|
|
10
|
+
> npx --package github:caioribeiroclw-pixel/pluribus#main pluribus audit
|
|
11
|
+
> ```
|
|
12
|
+
|
|
13
|
+
## 1. Find AI context surfaces
|
|
14
|
+
|
|
15
|
+
From the project root:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
find . -maxdepth 4 \( \
|
|
19
|
+
-name 'CLAUDE.md' -o \
|
|
20
|
+
-name '.cursorrules' -o \
|
|
21
|
+
-path './.cursor/rules/*.mdc' -o \
|
|
22
|
+
-path './.github/copilot-instructions.md' -o \
|
|
23
|
+
-name 'AGENTS.md' -o \
|
|
24
|
+
-path './.windsurf/rules/*.md' -o \
|
|
25
|
+
-path './.continue/rules/*.md' -o \
|
|
26
|
+
-name '.rules' \
|
|
27
|
+
\) -print
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
If this returns zero or one file, Pluribus may still be useful for future portability, but context drift is probably not your immediate pain.
|
|
31
|
+
|
|
32
|
+
## 2. Compare shared facts
|
|
33
|
+
|
|
34
|
+
For each file, scan for facts that should be identical everywhere:
|
|
35
|
+
|
|
36
|
+
- project purpose and product constraints;
|
|
37
|
+
- stack, runtime versions, package manager, and framework choices;
|
|
38
|
+
- test/lint/build commands;
|
|
39
|
+
- architecture boundaries and ownership rules;
|
|
40
|
+
- security or privacy constraints;
|
|
41
|
+
- review expectations and generated-file warnings.
|
|
42
|
+
|
|
43
|
+
Drift usually shows up as small contradictions: one file says Node 20, another says Node 22; one mentions Vitest, another mentions Jest; one has a security constraint the others never see.
|
|
44
|
+
|
|
45
|
+
## 3. Split shared context from tool-specific context
|
|
46
|
+
|
|
47
|
+
Move stable shared context into `pluribus.md`:
|
|
48
|
+
|
|
49
|
+
```markdown
|
|
50
|
+
# Identity
|
|
51
|
+
This repo is <project>. Its goal is <goal>.
|
|
52
|
+
|
|
53
|
+
# Stack
|
|
54
|
+
- Runtime: Node.js 22
|
|
55
|
+
- Package manager: npm
|
|
56
|
+
- Tests: npm test
|
|
57
|
+
|
|
58
|
+
# Conventions
|
|
59
|
+
- Prefer small focused changes.
|
|
60
|
+
- Run tests before publishing.
|
|
61
|
+
|
|
62
|
+
# Goals
|
|
63
|
+
- Keep AI tools aligned on the same project rules.
|
|
64
|
+
|
|
65
|
+
# Constraints
|
|
66
|
+
- Do not expose secrets, tokens, or private infrastructure details.
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Keep tool-specific behavior outside the shared layer when it truly belongs to one tool: Cursor glob/frontmatter semantics, Claude-only slash-command notes, local MCP setup, or IDE-specific UI instructions.
|
|
70
|
+
|
|
71
|
+
## 4. Audit and preview the regenerated files
|
|
72
|
+
|
|
73
|
+
Run the read-only audit first:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
npx pluribus-context audit
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
If `pluribus.md` exists, this compares generated tool files with the source and reports anything missing or drifted. If `pluribus.md` does not exist yet, it scans for known AI context files so you know what to migrate.
|
|
80
|
+
|
|
81
|
+
Then run a dry-run before writing anything:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
npx pluribus-context validate
|
|
85
|
+
npx pluribus-context sync --dry-run
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Read the previews and ask two questions:
|
|
89
|
+
|
|
90
|
+
1. Did every generated file receive the shared facts it needs?
|
|
91
|
+
2. Did anything tool-specific get flattened into a place where it does not belong?
|
|
92
|
+
|
|
93
|
+
If the answer to either question is no, edit `pluribus.md` or keep that behavior in a tool-native file before syncing.
|
|
94
|
+
|
|
95
|
+
## 5. Add a lightweight drift check
|
|
96
|
+
|
|
97
|
+
After adoption, the simplest check is:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
npx pluribus-context audit --strict
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
That catches three common failure modes without writing files:
|
|
104
|
+
|
|
105
|
+
- someone edited a generated file directly;
|
|
106
|
+
- someone changed `pluribus.md` but forgot to regenerate outputs;
|
|
107
|
+
- a configured output file is missing.
|
|
108
|
+
|
|
109
|
+
Use `sync --dry-run` to inspect the fix, then `sync` to update generated files.
|
|
110
|
+
|
|
111
|
+
## What this does not check
|
|
112
|
+
|
|
113
|
+
`pluribus audit` is intentionally narrow: it checks whether the files generated from `pluribus.md` are current, missing, or drifted. It is not a general-purpose linter for whether your instructions still match the repository.
|
|
114
|
+
|
|
115
|
+
That distinction matters:
|
|
116
|
+
|
|
117
|
+
- use `pluribus audit` when you want to know whether `CLAUDE.md`, Cursor rules, Copilot instructions, `AGENTS.md`, Windsurf, Continue, or Zed outputs are still in sync with the same source of truth;
|
|
118
|
+
- use repo-specific checks, tests, or AI-context linters when you want to find stale commands, dead paths, outdated architecture notes, or conflicting nested instruction files;
|
|
119
|
+
- use both if your risk is bigger than copy-paste drift: first keep generated files aligned, then validate that the shared instructions are still true.
|
|
120
|
+
|
|
121
|
+
Pluribus solves output drift across tools. It does not prove that the canonical context is correct.
|
|
122
|
+
|
|
123
|
+
## Decision rule
|
|
124
|
+
|
|
125
|
+
Adopt Pluribus if the audit finds repeated shared facts across two or more tools and at least one contradiction, stale command, or copy-paste maintenance burden.
|
|
126
|
+
|
|
127
|
+
Do not adopt it just to replace one healthy context file. A single accurate `CLAUDE.md` or `AGENTS.md` is better than an unnecessary abstraction.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Context File Review Checklist
|
|
2
|
+
|
|
3
|
+
AI context files are part of the software supply chain.
|
|
4
|
+
|
|
5
|
+
Files like `CLAUDE.md`, `.cursorrules`, Copilot instructions, `AGENTS.md`, Windsurf rules, Continue rules, and Zed rules are not just notes for humans. Agents read them before acting. Some teams also let agents edit them. Treat shared context with the same review discipline you apply to scripts, CI config, and dependency manifests.
|
|
6
|
+
|
|
7
|
+
Use this checklist before adopting Pluribus, before committing generated context files, or before reviewing a PR that changes AI instructions.
|
|
8
|
+
|
|
9
|
+
## 1. Separate public project context from private operating context
|
|
10
|
+
|
|
11
|
+
Good shared context:
|
|
12
|
+
|
|
13
|
+
- project purpose and architecture;
|
|
14
|
+
- stack, package manager, and supported runtime versions;
|
|
15
|
+
- build, test, lint, and release commands;
|
|
16
|
+
- coding conventions and review expectations;
|
|
17
|
+
- security and privacy constraints that are safe to publish.
|
|
18
|
+
|
|
19
|
+
Do not put these in generated/shared context files:
|
|
20
|
+
|
|
21
|
+
- API keys, tokens, cookies, passwords, recovery codes, or auth URLs;
|
|
22
|
+
- private customer data or internal incident details;
|
|
23
|
+
- unreleased strategy that should not leave the team;
|
|
24
|
+
- local machine paths that reveal sensitive infrastructure;
|
|
25
|
+
- instructions to bypass tests, reviews, permissions, or safety checks.
|
|
26
|
+
|
|
27
|
+
If a rule needs private detail, store the detail somewhere else and reference the policy at a high level.
|
|
28
|
+
|
|
29
|
+
## 2. Review instructions as executable influence
|
|
30
|
+
|
|
31
|
+
A context file can change agent behavior as strongly as code can change runtime behavior. Review diffs for:
|
|
32
|
+
|
|
33
|
+
- new commands agents are told to run;
|
|
34
|
+
- new files or directories agents are told to read or write;
|
|
35
|
+
- weakened test, lint, security, or review expectations;
|
|
36
|
+
- tool-specific instructions copied into the wrong tool;
|
|
37
|
+
- stale paths, package managers, or deployment commands;
|
|
38
|
+
- broad instructions like "always", "never", or "ignore" that might have unintended scope.
|
|
39
|
+
|
|
40
|
+
Prefer concrete, verifiable rules over taste statements. "Run `npm test` before release" is better than "be careful".
|
|
41
|
+
|
|
42
|
+
## 3. Keep generated files visibly generated
|
|
43
|
+
|
|
44
|
+
When Pluribus writes tool-specific files, it includes generated-file metadata. Keep that warning intact.
|
|
45
|
+
|
|
46
|
+
The review rule is simple:
|
|
47
|
+
|
|
48
|
+
- edit `pluribus.md` or imported source files for shared context;
|
|
49
|
+
- regenerate outputs with `pluribus sync`;
|
|
50
|
+
- avoid hand-editing generated files unless the file is intentionally tool-native and outside Pluribus.
|
|
51
|
+
|
|
52
|
+
If someone edits a generated file directly, expect drift.
|
|
53
|
+
|
|
54
|
+
## 4. Use dry-run before writing
|
|
55
|
+
|
|
56
|
+
Preview generated outputs before changing a real repo:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npx pluribus-context validate
|
|
60
|
+
npx pluribus-context sync --dry-run
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Read the preview like a PR diff. Confirm that shared facts appear where they should and that private or tool-specific details did not get flattened into every output.
|
|
64
|
+
|
|
65
|
+
## 5. Add a drift check to review or CI
|
|
66
|
+
|
|
67
|
+
For repos that commit generated AI context files, add a lightweight check:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npx pluribus-context sync
|
|
71
|
+
git diff --exit-code -- \
|
|
72
|
+
CLAUDE.md \
|
|
73
|
+
.cursorrules \
|
|
74
|
+
.github/copilot-instructions.md \
|
|
75
|
+
AGENTS.md \
|
|
76
|
+
.windsurf/rules/pluribus.md \
|
|
77
|
+
.continue/rules/pluribus.md \
|
|
78
|
+
.rules
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
This catches two risky cases:
|
|
82
|
+
|
|
83
|
+
- `pluribus.md` changed but generated files were not updated;
|
|
84
|
+
- generated files changed directly and no longer match the source of truth.
|
|
85
|
+
|
|
86
|
+
## 6. Decide what should stay tool-native
|
|
87
|
+
|
|
88
|
+
Not every instruction belongs in shared context. Keep tool-native files when a rule depends on one tool's semantics, such as:
|
|
89
|
+
|
|
90
|
+
- Cursor `.mdc` glob/frontmatter behavior;
|
|
91
|
+
- Claude-only slash command notes;
|
|
92
|
+
- IDE UI preferences;
|
|
93
|
+
- local MCP or extension setup that other tools cannot use;
|
|
94
|
+
- experimental prompts that should not affect the whole team.
|
|
95
|
+
|
|
96
|
+
Pluribus is for stable intentional context that should stay aligned across tools, not for forcing every tool to behave identically.
|
|
97
|
+
|
|
98
|
+
## Decision rule
|
|
99
|
+
|
|
100
|
+
Commit and sync shared context when it is safe, stable, reviewable, and useful across two or more tools.
|
|
101
|
+
|
|
102
|
+
Keep it out of Pluribus when it is secret, local-only, highly experimental, or meaningful to just one tool.
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# Migrate Existing AI Context Files
|
|
2
|
+
|
|
3
|
+
Use this guide when your project already has one or more AI instruction files and you want Pluribus to become the source of truth without losing working context.
|
|
4
|
+
|
|
5
|
+
Typical starting point:
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
CLAUDE.md
|
|
9
|
+
.cursorrules
|
|
10
|
+
.github/copilot-instructions.md
|
|
11
|
+
AGENTS.md
|
|
12
|
+
.windsurf/rules/pluribus.md
|
|
13
|
+
.continue/rules/pluribus.md
|
|
14
|
+
.rules
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Goal:
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
pluribus.md # edit this
|
|
21
|
+
CLAUDE.md # generated
|
|
22
|
+
.cursorrules # generated
|
|
23
|
+
.github/copilot-instructions.md
|
|
24
|
+
AGENTS.md
|
|
25
|
+
...
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 1. Inventory what exists
|
|
29
|
+
|
|
30
|
+
From the project root:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
find . -maxdepth 3 \( \
|
|
34
|
+
-name 'CLAUDE.md' -o \
|
|
35
|
+
-name '.cursorrules' -o \
|
|
36
|
+
-path './.github/copilot-instructions.md' -o \
|
|
37
|
+
-name 'AGENTS.md' -o \
|
|
38
|
+
-path './.windsurf/rules/pluribus.md' -o \
|
|
39
|
+
-path './.continue/rules/pluribus.md' -o \
|
|
40
|
+
-name '.rules' \
|
|
41
|
+
\) -print
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Read the files and separate three kinds of content:
|
|
45
|
+
|
|
46
|
+
1. **Project facts** — stack, architecture, commands, deployment model.
|
|
47
|
+
2. **Conventions** — style, testing expectations, review rules, naming patterns.
|
|
48
|
+
3. **Tool-specific quirks** — instructions that only make sense for one tool.
|
|
49
|
+
|
|
50
|
+
Move project facts and shared conventions into `pluribus.md`. Keep tool-specific quirks as adapter feedback or custom skill work, not as duplicated generic context.
|
|
51
|
+
|
|
52
|
+
## 2. Scaffold `pluribus.md`
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npx pluribus-context init \
|
|
56
|
+
--name "Your project" \
|
|
57
|
+
--description "What this repo does" \
|
|
58
|
+
--tools claude,cursor,copilot,openclaw
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Edit `pluribus.md` and paste the shared context into the scaffolded sections.
|
|
62
|
+
|
|
63
|
+
A practical first pass:
|
|
64
|
+
|
|
65
|
+
```markdown
|
|
66
|
+
# Identity
|
|
67
|
+
I am working on <project>. The goal is <goal>.
|
|
68
|
+
|
|
69
|
+
# Stack
|
|
70
|
+
- Runtime: Node.js 22
|
|
71
|
+
- Language: TypeScript
|
|
72
|
+
- Test command: npm test
|
|
73
|
+
|
|
74
|
+
# Conventions
|
|
75
|
+
- Prefer small focused changes.
|
|
76
|
+
- Add tests for behavior changes.
|
|
77
|
+
- Keep generated files out of manual edits.
|
|
78
|
+
|
|
79
|
+
# Goals
|
|
80
|
+
- Keep AI tools aligned on the same project rules.
|
|
81
|
+
|
|
82
|
+
# Constraints
|
|
83
|
+
- Do not introduce new production dependencies without a clear reason.
|
|
84
|
+
- Do not expose secrets, tokens, or private infrastructure details.
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## 3. Preview before overwriting anything
|
|
88
|
+
|
|
89
|
+
Run a dry-run first:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
npx pluribus-context validate
|
|
93
|
+
npx pluribus-context sync --dry-run
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Check the preview for each target tool. If the generated files would lose important instructions, move that missing context into `pluribus.md` and run the dry-run again.
|
|
97
|
+
|
|
98
|
+
## 4. Replace generated files deliberately
|
|
99
|
+
|
|
100
|
+
When the preview looks right:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
npx pluribus-context sync
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Review the diff carefully:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
git diff -- CLAUDE.md .cursorrules .github/copilot-instructions.md AGENTS.md
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Recommended commit shape:
|
|
113
|
+
|
|
114
|
+
1. Commit `pluribus.md` and generated files together.
|
|
115
|
+
2. In the commit message, say that generated AI context files now come from Pluribus.
|
|
116
|
+
3. Tell teammates to edit `pluribus.md`, not the generated outputs.
|
|
117
|
+
|
|
118
|
+
## 5. Add a guardrail for drift
|
|
119
|
+
|
|
120
|
+
For local work:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
npx pluribus-context watch
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
For CI or pre-commit flows, use a dry-run/check pattern first. Pluribus does not ship a dedicated CI command yet, but you can still detect drift by syncing in CI and checking whether git changed:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
npx pluribus-context sync
|
|
130
|
+
git diff --exit-code -- CLAUDE.md .cursorrules .github/copilot-instructions.md AGENTS.md
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
If this fails, someone edited a generated file directly or changed `pluribus.md` without regenerating outputs.
|
|
134
|
+
|
|
135
|
+
## 6. Use imports for team/org context
|
|
136
|
+
|
|
137
|
+
If several repos share the same conventions, keep shared context in one file and import it:
|
|
138
|
+
|
|
139
|
+
```markdown
|
|
140
|
+
# @import ./shared/team-context.md
|
|
141
|
+
# @import ./shared/security-constraints.md
|
|
142
|
+
|
|
143
|
+
# Identity
|
|
144
|
+
This repo is the billing service.
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
For cross-repo shared context, use explicit remote imports and pin them with `--update-imports`:
|
|
148
|
+
|
|
149
|
+
```markdown
|
|
150
|
+
# @import github:your-org/ai-context/shared/team-context.md@main
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Then:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
npx pluribus-context sync --update-imports
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Commit `pluribus.lock.json` so future syncs are deterministic. Do not commit `.pluribus/cache/remote/`; it is a local regenerable cache.
|
|
160
|
+
|
|
161
|
+
## Migration checklist
|
|
162
|
+
|
|
163
|
+
- [ ] Existing AI context files inventoried.
|
|
164
|
+
- [ ] Shared project facts and conventions moved into `pluribus.md`.
|
|
165
|
+
- [ ] `validate` passes.
|
|
166
|
+
- [ ] `sync --dry-run` preview reviewed.
|
|
167
|
+
- [ ] Generated files written and reviewed with `git diff`.
|
|
168
|
+
- [ ] Team knows to edit `pluribus.md`, not generated outputs.
|
|
169
|
+
- [ ] Optional drift check added to CI/pre-commit.
|
|
170
|
+
|
|
171
|
+
## Feedback wanted
|
|
172
|
+
|
|
173
|
+
If migration from an existing `CLAUDE.md`, `.cursorrules`, or Copilot instructions file loses important semantics, open a [quickstart feedback issue](https://github.com/caioribeiroclw-pixel/pluribus/issues/new?template=quickstart-feedback.yml) with:
|
|
174
|
+
|
|
175
|
+
1. which source file you migrated from;
|
|
176
|
+
2. which generated target felt wrong;
|
|
177
|
+
3. the smallest sanitized example of the missing instruction.
|
|
178
|
+
|
|
179
|
+
That is the fastest path to improving the adapters.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Quickstart
|
|
2
|
+
|
|
3
|
+
Use this when you want to try Pluribus without touching a real project yet.
|
|
4
|
+
|
|
5
|
+
Pluribus takes one intentional context file (`pluribus.md`) and generates the tool-specific files your AI tools expect: `CLAUDE.md`, `.cursorrules`, Copilot instructions, `AGENTS.md`, Windsurf/Continue rules, and Zed `.rules`.
|
|
6
|
+
|
|
7
|
+
Already have one or more of those files? See [Migrate Existing AI Context Files](migrate-existing-context.md) before replacing anything.
|
|
8
|
+
|
|
9
|
+
## 1. Create a disposable demo project
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
mkdir pluribus-demo
|
|
13
|
+
cd pluribus-demo
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## 2. Scaffold context from npm
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npx pluribus-context init \
|
|
20
|
+
--name "Ana" \
|
|
21
|
+
--description "A Node.js service" \
|
|
22
|
+
--tools claude,cursor,copilot
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
This creates `pluribus.md`. Open it and replace the scaffolded notes with real project context when you are ready.
|
|
26
|
+
|
|
27
|
+
## 3. Validate before writing generated files
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npx pluribus-context validate
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Validation checks for missing required sections, duplicate top-level sections, broken imports, and unsupported tool names.
|
|
34
|
+
|
|
35
|
+
## 4. Preview generated outputs
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npx pluribus-context sync --dry-run
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
You should see previews for the selected tools. For the command above, Pluribus targets:
|
|
42
|
+
|
|
43
|
+
| Tool | Generated file |
|
|
44
|
+
| --- | --- |
|
|
45
|
+
| Claude Code | `CLAUDE.md` |
|
|
46
|
+
| Cursor | `.cursorrules` |
|
|
47
|
+
| GitHub Copilot | `.github/copilot-instructions.md` |
|
|
48
|
+
|
|
49
|
+
## 5. Audit before writing or in CI
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npx pluribus-context audit
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Before generated files exist, audit reports them as missing. After sync, it becomes a read-only drift check. Use `--strict` in CI when you want missing or drifted generated files to fail the build.
|
|
56
|
+
|
|
57
|
+
## 6. Write the files when the preview looks right
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npx pluribus-context sync
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Commit `pluribus.md` as the source of truth. Commit generated files if your team wants each tool to work immediately after clone; otherwise regenerate them in local setup/CI.
|
|
64
|
+
|
|
65
|
+
## 7. Keep files fresh while editing
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npx pluribus-context watch
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`watch` re-runs `sync` after edits to `pluribus.md` with a small debounce, so tool-specific files do not drift during normal work.
|
|
72
|
+
|
|
73
|
+
## Using shared or org-level context
|
|
74
|
+
|
|
75
|
+
For reusable team conventions, import shared Markdown before local project sections:
|
|
76
|
+
|
|
77
|
+
```markdown
|
|
78
|
+
# @import ./shared/team-context.md
|
|
79
|
+
# @import ./shared/security-constraints.md
|
|
80
|
+
|
|
81
|
+
# Identity
|
|
82
|
+
I am Ana, building Conduit — a Node.js job runner.
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Local sections apply after imports, so project-specific context can override shared context. See [Composable Contexts](composable-contexts.md) for local and remote import details.
|
|
86
|
+
|
|
87
|
+
## Common friction
|
|
88
|
+
|
|
89
|
+
- **`pluribus` command not found after `npx`:** use `npx pluribus-context ...` for one-off runs, or install globally with `npm install -g pluribus-context` and then run `pluribus ...`.
|
|
90
|
+
- **Remote imports fail without `--update-imports`:** network refresh is explicit. Run `npx pluribus-context sync --update-imports` to refresh and pin remote content, then normal `sync` uses the lock/cache offline.
|
|
91
|
+
- **Private GitHub imports fail:** set `GH_TOKEN`/`GITHUB_TOKEN` or log in with `gh auth login`. Pluribus never writes tokens to `pluribus.lock.json` or cache files.
|
|
92
|
+
- **Generated files look wrong:** edit `pluribus.md`, run `validate`, then use `audit` and `sync --dry-run` before writing files.
|
|
93
|
+
|
|
94
|
+
## Feedback wanted
|
|
95
|
+
|
|
96
|
+
If the quickstart fails or the generated files do not match how your team actually uses AI tools, open an issue with:
|
|
97
|
+
|
|
98
|
+
1. the command you ran;
|
|
99
|
+
2. which tool file felt wrong;
|
|
100
|
+
3. what you expected Pluribus to generate instead.
|
|
101
|
+
|
|
102
|
+
That feedback is more useful than generic feature requests because it shows where the context format or adapters are not matching real workflows.
|
|
@@ -47,14 +47,15 @@ Before publishing, install the exact tarball that `npm pack` creates into a temp
|
|
|
47
47
|
npm run release:smoke
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
The script packs the current checkout, installs that tarball into a temporary project, runs `pluribus --version`, `--help`, `init`, `validate`, `sync --dry-run`,
|
|
50
|
+
The script packs the current checkout, installs that tarball into a temporary project, runs `pluribus --version`, `--help`, `init`, `validate`, `audit`, `sync --dry-run`, a real `sync`, and `audit --strict`, then checks that generated output includes the package version from `package.json`. It also removes the temporary project and generated tarball on exit.
|
|
51
51
|
|
|
52
52
|
Expected results:
|
|
53
53
|
|
|
54
54
|
- `pluribus --version` matches `package.json`.
|
|
55
55
|
- `pluribus --help` shows the same version.
|
|
56
56
|
- generated files mention the same Pluribus version.
|
|
57
|
-
- `validate` and `sync --dry-run` work from the installed package, not the repo checkout.
|
|
57
|
+
- `validate`, `audit`, and `sync --dry-run` work from the installed package, not the repo checkout.
|
|
58
|
+
- `audit --strict` passes after generated files are written.
|
|
58
59
|
|
|
59
60
|
## 4. Publish
|
|
60
61
|
|
|
@@ -64,13 +65,16 @@ Only publish after npm auth is active and the dry run is clean:
|
|
|
64
65
|
npm publish --access public
|
|
65
66
|
```
|
|
66
67
|
|
|
67
|
-
Then verify:
|
|
68
|
+
Then verify the registry entry and the install path users will see:
|
|
68
69
|
|
|
69
70
|
```bash
|
|
70
71
|
npm view pluribus-context version dist.tarball
|
|
72
|
+
npm view pluribus-context readme | grep -E 'npx pluribus-context|60-second smoke test|Published to npm'
|
|
71
73
|
npx pluribus-context --help
|
|
72
74
|
```
|
|
73
75
|
|
|
76
|
+
The npm README is captured at publish time. If the GitHub README changed after the previous publish, confirm the npm package page no longer contains stale pre-release markers such as `once published` before starting distribution.
|
|
77
|
+
|
|
74
78
|
## 5. GitHub release
|
|
75
79
|
|
|
76
80
|
After npm publish succeeds:
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# When to use Pluribus
|
|
2
|
+
|
|
3
|
+
Pluribus is for keeping intentional AI context in sync across tools.
|
|
4
|
+
|
|
5
|
+
Use it when you already have, or expect to have, more than one context surface for the same project:
|
|
6
|
+
|
|
7
|
+
- `CLAUDE.md` for Claude Code
|
|
8
|
+
- `.cursorrules` or `.cursor/rules/*.mdc` for Cursor
|
|
9
|
+
- `.github/copilot-instructions.md` for GitHub Copilot
|
|
10
|
+
- `AGENTS.md` for OpenClaw or Codex-style agents
|
|
11
|
+
- Windsurf, Continue, Zed, or other workspace rule files
|
|
12
|
+
|
|
13
|
+
The core bet is simple: if multiple AI tools need the same project facts, conventions, and constraints, those facts should be reviewed once and generated many times.
|
|
14
|
+
|
|
15
|
+
## Use Pluribus if
|
|
16
|
+
|
|
17
|
+
- You use two or more AI coding tools in the same repo.
|
|
18
|
+
- You maintain project conventions by copy-pasting between context files.
|
|
19
|
+
- You want context changes to be visible in git review.
|
|
20
|
+
- You want a dry-run before overwriting generated tool files.
|
|
21
|
+
- Your team has shared conventions that should apply across many repos.
|
|
22
|
+
- You want remote/shared context pinned with a lockfile before syncing.
|
|
23
|
+
|
|
24
|
+
## You may not need it if
|
|
25
|
+
|
|
26
|
+
- You only use one AI tool and one context file.
|
|
27
|
+
- Your context is entirely tool-specific and should not be shared.
|
|
28
|
+
- You need chat memory, retrieval, vector search, or agent orchestration.
|
|
29
|
+
- You want a one-time migration and do not plan to keep files synchronized.
|
|
30
|
+
|
|
31
|
+
## Pluribus vs one-way converters
|
|
32
|
+
|
|
33
|
+
A one-way converter is useful when you want to translate one tool's rule format into another tool's file once.
|
|
34
|
+
|
|
35
|
+
Pluribus is different: it treats `pluribus.md` as the source of truth and regenerates the tool files from that source whenever the context changes.
|
|
36
|
+
|
|
37
|
+
| Need | Better fit |
|
|
38
|
+
|---|---|
|
|
39
|
+
| Convert existing Cursor rules into `CLAUDE.md` once | One-way converter |
|
|
40
|
+
| Keep Claude, Cursor, Copilot, OpenClaw, Windsurf, Continue, and Zed context aligned over time | Pluribus |
|
|
41
|
+
| Preserve tool-specific metadata exactly as-is | Tool-native files or a converter |
|
|
42
|
+
| Review shared project context in PRs and regenerate generated files | Pluribus |
|
|
43
|
+
| Share org/team conventions across repos with pinned imports | Pluribus |
|
|
44
|
+
|
|
45
|
+
## Recommended migration path
|
|
46
|
+
|
|
47
|
+
1. Inventory your existing context files.
|
|
48
|
+
2. Move shared project facts and conventions into `pluribus.md`.
|
|
49
|
+
3. Keep genuinely tool-specific behavior in tool-native files or custom skills.
|
|
50
|
+
4. Run `pluribus sync --dry-run` and inspect the output.
|
|
51
|
+
5. Commit `pluribus.md`, generated files, and `pluribus.lock.json` if remote imports are used.
|
|
52
|
+
|
|
53
|
+
For the step-by-step version, see [Migrate Existing AI Context Files](migrate-existing-context.md).
|
|
54
|
+
|
|
55
|
+
## Mental model
|
|
56
|
+
|
|
57
|
+
Pluribus is not trying to make every AI tool identical.
|
|
58
|
+
|
|
59
|
+
It is trying to keep the stable, intentional parts of your project context from drifting while still letting each tool keep its own interface and strengths.
|
package/package.json
CHANGED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pluribus audit — inspect AI context files and report sync drift.
|
|
3
|
+
*
|
|
4
|
+
* The command is intentionally read-only. With a pluribus.md source present it
|
|
5
|
+
* renders the expected tool files and compares them with what is on disk. When
|
|
6
|
+
* pluribus.md is not present, it scans for known context files to help users
|
|
7
|
+
* decide whether they need a migration pass before adopting Pluribus.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import * as fs from 'fs'
|
|
11
|
+
import * as path from 'path'
|
|
12
|
+
import { parsePluribusFile, validateSections, REQUIRED_SECTIONS } from '../utils/parser.js'
|
|
13
|
+
import { resolveImportsAsync } from '../utils/imports.js'
|
|
14
|
+
import { renderTemplate, parseSkillFile } from '../utils/renderer.js'
|
|
15
|
+
import { BUILT_IN_SKILLS, SUPPORTED_TOOLS } from '../skills/built-in.js'
|
|
16
|
+
|
|
17
|
+
const TOOLS_COMMENT_RE = /<!--\s*pluribus:tools:\s*([^-]+)\s*-->/
|
|
18
|
+
const KNOWN_CONTEXT_FILES = [
|
|
19
|
+
...new Set([
|
|
20
|
+
...Object.values(BUILT_IN_SKILLS).flatMap((skill) => skill.outputFiles),
|
|
21
|
+
'.cursor/rules',
|
|
22
|
+
'.github/instructions',
|
|
23
|
+
'AGENTS.md',
|
|
24
|
+
'CLAUDE.md',
|
|
25
|
+
]),
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @param {Record<string, string | boolean>} args
|
|
30
|
+
*/
|
|
31
|
+
export async function runAudit(args) {
|
|
32
|
+
const sourceArg = typeof args.source === 'string' ? args.source : null
|
|
33
|
+
const toolsArg = typeof args.tools === 'string' ? args.tools : null
|
|
34
|
+
const updateImports = Boolean(args['update-imports'])
|
|
35
|
+
const strict = Boolean(args.strict)
|
|
36
|
+
const cwd = process.cwd()
|
|
37
|
+
const sourcePath = sourceArg
|
|
38
|
+
? path.resolve(cwd, sourceArg)
|
|
39
|
+
: path.join(cwd, 'pluribus.md')
|
|
40
|
+
const displaySource = path.relative(cwd, sourcePath) || 'pluribus.md'
|
|
41
|
+
|
|
42
|
+
if (!fs.existsSync(sourcePath)) {
|
|
43
|
+
const found = scanKnownContextFiles(cwd)
|
|
44
|
+
console.log(`ℹ️ No ${displaySource} found.`)
|
|
45
|
+
|
|
46
|
+
if (found.length > 0) {
|
|
47
|
+
console.log('')
|
|
48
|
+
console.log('Found existing AI context surface(s):')
|
|
49
|
+
for (const file of found) {
|
|
50
|
+
console.log(` • ${file}`)
|
|
51
|
+
}
|
|
52
|
+
console.log('')
|
|
53
|
+
console.log('Use these as migration inputs for `pluribus init`, then run `pluribus audit` again.')
|
|
54
|
+
} else {
|
|
55
|
+
console.log('')
|
|
56
|
+
console.log('No known AI context files found in this directory.')
|
|
57
|
+
console.log('Run `pluribus init` to create a source file, then `pluribus sync --dry-run`.')
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
console.log('Docs: https://github.com/caioribeiroclw-pixel/pluribus/blob/main/docs/migrate-existing-context.md')
|
|
61
|
+
if (strict) process.exit(1)
|
|
62
|
+
return
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
let rawContent
|
|
66
|
+
try {
|
|
67
|
+
rawContent = fs.readFileSync(sourcePath, 'utf8')
|
|
68
|
+
} catch (err) {
|
|
69
|
+
console.error(`❌ Could not read ${sourcePath}: ${err.message}`)
|
|
70
|
+
process.exit(1)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const errors = []
|
|
74
|
+
let resolvedContent
|
|
75
|
+
try {
|
|
76
|
+
const projectDir = path.dirname(sourcePath)
|
|
77
|
+
const resolved = await resolveImportsAsync(sourcePath, {
|
|
78
|
+
rootDir: projectDir,
|
|
79
|
+
allowRemote: updateImports,
|
|
80
|
+
lockfilePath: path.join(projectDir, 'pluribus.lock.json'),
|
|
81
|
+
cacheDir: path.join(projectDir, '.pluribus', 'cache', 'remote'),
|
|
82
|
+
updateLockfile: updateImports,
|
|
83
|
+
})
|
|
84
|
+
resolvedContent = resolved.content
|
|
85
|
+
} catch (err) {
|
|
86
|
+
errors.push(`Could not resolve imports: ${err.message}`)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const sections = resolvedContent ? parsePluribusFile(resolvedContent) : {}
|
|
90
|
+
const validation = validateSections(sections)
|
|
91
|
+
for (const error of validation.errors) {
|
|
92
|
+
errors.push(error)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const tools = getTools(rawContent, toolsArg)
|
|
96
|
+
const unknownTools = tools.filter((tool) => !SUPPORTED_TOOLS.includes(tool))
|
|
97
|
+
if (unknownTools.length > 0) {
|
|
98
|
+
errors.push(`Unknown tool(s): ${unknownTools.join(', ')}. Supported: ${SUPPORTED_TOOLS.join(', ')}`)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (errors.length > 0) {
|
|
102
|
+
console.error(`❌ Cannot audit ${displaySource}:`)
|
|
103
|
+
for (const error of errors) {
|
|
104
|
+
console.error(` • ${error}`)
|
|
105
|
+
}
|
|
106
|
+
console.error(`\n Complete required sections (${REQUIRED_SECTIONS.join(', ')}) and re-run.`)
|
|
107
|
+
process.exit(1)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
console.log(`🔎 Auditing ${displaySource} → ${tools.join(', ')}`)
|
|
111
|
+
console.log('')
|
|
112
|
+
|
|
113
|
+
const results = []
|
|
114
|
+
for (const toolId of tools) {
|
|
115
|
+
const skill = loadSkill(cwd, toolId)
|
|
116
|
+
if (!skill) {
|
|
117
|
+
results.push({ toolId, status: 'error', file: '(skill)', message: 'Skill not found' })
|
|
118
|
+
continue
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const missingRequired = skill.required.filter((required) => {
|
|
122
|
+
const sectionName = Object.keys(sections).find((name) => name.toLowerCase() === required.toLowerCase())
|
|
123
|
+
return !sectionName || !sections[sectionName]?.trim()
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
if (missingRequired.length > 0) {
|
|
127
|
+
results.push({
|
|
128
|
+
toolId,
|
|
129
|
+
status: 'error',
|
|
130
|
+
file: '(sections)',
|
|
131
|
+
message: `Missing required section(s) for ${toolId}: ${missingRequired.join(', ')}`,
|
|
132
|
+
})
|
|
133
|
+
continue
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
let rendered
|
|
137
|
+
try {
|
|
138
|
+
rendered = renderTemplate(skill.template, sections, path.relative(cwd, sourcePath) || 'pluribus.md')
|
|
139
|
+
} catch (err) {
|
|
140
|
+
results.push({ toolId, status: 'error', file: '(template)', message: err.message })
|
|
141
|
+
continue
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
for (const outputFile of skill.outputFiles) {
|
|
145
|
+
const outputPath = path.join(cwd, outputFile)
|
|
146
|
+
if (!fs.existsSync(outputPath)) {
|
|
147
|
+
results.push({ toolId, status: 'missing', file: outputFile })
|
|
148
|
+
continue
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const existing = fs.readFileSync(outputPath, 'utf8')
|
|
152
|
+
if (normalizeGeneratedMetadata(existing) === normalizeGeneratedMetadata(rendered)) {
|
|
153
|
+
results.push({ toolId, status: 'current', file: outputFile })
|
|
154
|
+
} else {
|
|
155
|
+
results.push({ toolId, status: 'drift', file: outputFile })
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
for (const result of results) {
|
|
161
|
+
const label = `[${result.toolId}] ${result.file}`
|
|
162
|
+
if (result.status === 'current') {
|
|
163
|
+
console.log(` ✅ ${label} is current`)
|
|
164
|
+
} else if (result.status === 'missing') {
|
|
165
|
+
console.log(` ⚠️ ${label} is missing`)
|
|
166
|
+
} else if (result.status === 'drift') {
|
|
167
|
+
console.log(` ⚠️ ${label} differs from generated output`)
|
|
168
|
+
} else {
|
|
169
|
+
console.log(` ❌ ${label}: ${result.message}`)
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const summary = results.reduce((acc, result) => {
|
|
174
|
+
acc[result.status] = (acc[result.status] || 0) + 1
|
|
175
|
+
return acc
|
|
176
|
+
}, {})
|
|
177
|
+
|
|
178
|
+
console.log('')
|
|
179
|
+
console.log(`Summary: ${summary.current || 0} current, ${summary.drift || 0} drifted, ${summary.missing || 0} missing, ${summary.error || 0} error(s).`)
|
|
180
|
+
|
|
181
|
+
const hasProblem = (summary.drift || 0) + (summary.missing || 0) + (summary.error || 0) > 0
|
|
182
|
+
if (hasProblem) {
|
|
183
|
+
console.log('Run `pluribus sync --dry-run` to preview fixes, then `pluribus sync` to update generated files.')
|
|
184
|
+
} else {
|
|
185
|
+
console.log('✅ Generated context files are in sync.')
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if ((strict && hasProblem) || (summary.error || 0) > 0) {
|
|
189
|
+
process.exit(1)
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function getTools(rawContent, toolsArg) {
|
|
194
|
+
if (toolsArg) {
|
|
195
|
+
return splitTools(toolsArg)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const match = rawContent.match(TOOLS_COMMENT_RE)
|
|
199
|
+
if (match) {
|
|
200
|
+
return splitTools(match[1])
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return [...SUPPORTED_TOOLS]
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function splitTools(value) {
|
|
207
|
+
return String(value)
|
|
208
|
+
.split(',')
|
|
209
|
+
.map((tool) => tool.trim().toLowerCase())
|
|
210
|
+
.filter(Boolean)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function loadSkill(cwd, toolId) {
|
|
214
|
+
const localSkillPath = path.join(cwd, 'pluribus', 'skills', `${toolId}.md`)
|
|
215
|
+
if (fs.existsSync(localSkillPath)) {
|
|
216
|
+
const parsed = parseSkillFile(fs.readFileSync(localSkillPath, 'utf8'))
|
|
217
|
+
return {
|
|
218
|
+
id: toolId,
|
|
219
|
+
outputFiles: parsed.output,
|
|
220
|
+
template: parsed.template,
|
|
221
|
+
required: parsed.sections.required,
|
|
222
|
+
optional: parsed.sections.optional,
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return BUILT_IN_SKILLS[toolId]
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function scanKnownContextFiles(cwd) {
|
|
230
|
+
return KNOWN_CONTEXT_FILES
|
|
231
|
+
.filter((relativePath) => fs.existsSync(path.join(cwd, relativePath)))
|
|
232
|
+
.sort()
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function normalizeGeneratedMetadata(content) {
|
|
236
|
+
return content
|
|
237
|
+
.replace(/Generated by Pluribus ([^\s]+) on \d{4}-\d{2}-\d{2}/g, 'Generated by Pluribus $1 on <date>')
|
|
238
|
+
.replace(/generated by Pluribus ([^\s]+) on \d{4}-\d{2}-\d{2}/g, 'generated by Pluribus $1 on <date>')
|
|
239
|
+
}
|
package/src/index.js
CHANGED
|
@@ -6,6 +6,7 @@ export { runInit } from './commands/init.js'
|
|
|
6
6
|
export { runSync } from './commands/sync.js'
|
|
7
7
|
export { runValidate } from './commands/validate.js'
|
|
8
8
|
export { runWatch } from './commands/watch.js'
|
|
9
|
+
export { runAudit } from './commands/audit.js'
|
|
9
10
|
export { parsePluribusFile, validateSections } from './utils/parser.js'
|
|
10
11
|
export { renderTemplate } from './utils/renderer.js'
|
|
11
12
|
export { BUILT_IN_SKILLS, SUPPORTED_TOOLS } from './skills/built-in.js'
|
package/src/utils/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '0.
|
|
1
|
+
export const VERSION = '0.3.0'
|