reffy-cli 0.6.4 → 0.6.6
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 +10 -10
- package/dist/cli.js +14 -14
- package/dist/doctor.js +6 -6
- package/dist/storage.js +1 -1
- package/package.json +10 -1
package/README.md
CHANGED
|
@@ -23,11 +23,11 @@ reffy bootstrap
|
|
|
23
23
|
|
|
24
24
|
Command summary:
|
|
25
25
|
|
|
26
|
-
- `reffy init`: idempotently creates/updates root `AGENTS.md` managed block and `.
|
|
27
|
-
- `reffy bootstrap`: idempotently runs `init`, ensures `.
|
|
26
|
+
- `reffy init`: idempotently creates/updates root `AGENTS.md` managed block and `.reffy/AGENTS.md`.
|
|
27
|
+
- `reffy bootstrap`: idempotently runs `init`, ensures `.reffy/` structure exists, then reindexes artifacts.
|
|
28
28
|
- `reffy doctor`: diagnoses required Reffy setup and optional tool availability.
|
|
29
|
-
- `reffy reindex`: reconciles `.
|
|
30
|
-
- `reffy validate`: validates `.
|
|
29
|
+
- `reffy reindex`: reconciles `.reffy/manifest.json` with `.reffy/artifacts` by adding missing files and removing stale entries.
|
|
30
|
+
- `reffy validate`: validates `.reffy/manifest.json` against manifest v1 contract.
|
|
31
31
|
- `reffy summarize`: generates a read-only handoff summary from indexed artifacts.
|
|
32
32
|
- `reffy diagram render`: renders Mermaid diagrams as SVG or ASCII, including spec-aware generation from OpenSpec `spec.md`.
|
|
33
33
|
|
|
@@ -48,31 +48,31 @@ reffy summarize --output text
|
|
|
48
48
|
reffy summarize --output json
|
|
49
49
|
reffy diagram render --stdin --format svg < diagram.mmd
|
|
50
50
|
reffy diagram render --input openspec/specs/auth/spec.md --format ascii
|
|
51
|
-
reffy diagram render --input openspec/specs/auth/spec.md --format svg --output .
|
|
51
|
+
reffy diagram render --input openspec/specs/auth/spec.md --format svg --output .reffy/artifacts/auth-spec.svg
|
|
52
52
|
```
|
|
53
53
|
|
|
54
54
|
## Using Reffy With SDD Frameworks (OpenSpec Example)
|
|
55
55
|
|
|
56
56
|
`reffy` is designed to complement spec-driven development workflows rather than replace them. A common pattern is:
|
|
57
57
|
|
|
58
|
-
1. Use Reffy for ideation and context capture in `.
|
|
58
|
+
1. Use Reffy for ideation and context capture in `.reffy/`.
|
|
59
59
|
2. Use an SDD framework (for example [OpenSpec](https://github.com/Fission-AI/OpenSpec)) for formal proposals/specs/tasks.
|
|
60
60
|
3. Keep a clear handoff from exploratory artifacts to formal specs.
|
|
61
61
|
|
|
62
62
|
Reference implementation in this repo:
|
|
63
63
|
|
|
64
64
|
- `AGENTS.md`: contains both managed instruction blocks and encodes sequencing.
|
|
65
|
-
- `AGENTS.md`: Reffy block routes ideation/exploration requests to `@/.
|
|
65
|
+
- `AGENTS.md`: Reffy block routes ideation/exploration requests to `@/.reffy/AGENTS.md`.
|
|
66
66
|
- `AGENTS.md`: OpenSpec block routes planning/proposal/spec requests to `@/openspec/AGENTS.md`.
|
|
67
|
-
- `.
|
|
67
|
+
- `.reffy/AGENTS.md`: defines Reffy as the ideation/context layer and documents handoff expectations to OpenSpec.
|
|
68
68
|
- `openspec/AGENTS.md`: defines OpenSpec as the formal planning/specification workflow after ideation is stable.
|
|
69
|
-
- `src/cli.ts`: `reffy init`/`reffy bootstrap` enforce this integration by idempotently writing the managed Reffy guidance into `AGENTS.md` and `.
|
|
69
|
+
- `src/cli.ts`: `reffy init`/`reffy bootstrap` enforce this integration by idempotently writing the managed Reffy guidance into `AGENTS.md` and `.reffy/AGENTS.md`.
|
|
70
70
|
|
|
71
71
|
Practical connection pattern for any repo:
|
|
72
72
|
|
|
73
73
|
1. Run `reffy init` to install/refresh the Reffy instruction layer.
|
|
74
74
|
2. Keep your SDD framework instructions (for example OpenSpec) in the same root `AGENTS.md`.
|
|
75
|
-
3. During planning, cite only relevant Reffy artifacts from `.
|
|
75
|
+
3. During planning, cite only relevant Reffy artifacts from `.reffy/artifacts/` in your proposal/spec docs.
|
|
76
76
|
4. Continue implementation in your SDD framework's normal review/approval process.
|
|
77
77
|
|
|
78
78
|
## Develop
|
package/dist/cli.js
CHANGED
|
@@ -18,20 +18,20 @@ const REFFY_BLOCK = `<!-- REFFY:START -->
|
|
|
18
18
|
|
|
19
19
|
These instructions are for AI assistants working in this project.
|
|
20
20
|
|
|
21
|
-
Always open \`@/.
|
|
21
|
+
Always open \`@/.reffy/AGENTS.md\` when the request:
|
|
22
22
|
- Mentions early-stage ideation, exploration, brainstorming, or raw notes
|
|
23
23
|
- Needs context before drafting specs or proposals
|
|
24
24
|
- Refers to "reffy", "references", "explore", or "context layer"
|
|
25
25
|
|
|
26
|
-
Use \`@/.
|
|
26
|
+
Use \`@/.reffy/AGENTS.md\` to learn:
|
|
27
27
|
- Reffy workflow and artifact conventions
|
|
28
28
|
- How Reffy and OpenSpec should be sequenced
|
|
29
|
-
- How to store and consume ideation context in \`.
|
|
29
|
+
- How to store and consume ideation context in \`.reffy/\`
|
|
30
30
|
|
|
31
31
|
Keep this managed block so \`reffy init\` can refresh the instructions.
|
|
32
32
|
|
|
33
33
|
<!-- REFFY:END -->`;
|
|
34
|
-
const REFFY_AGENTS_RELATIVE = path.join(".
|
|
34
|
+
const REFFY_AGENTS_RELATIVE = path.join(".reffy", "AGENTS.md");
|
|
35
35
|
const REFFY_AGENTS_CONTENT = `# Reffy Instructions
|
|
36
36
|
|
|
37
37
|
These instructions are for AI assistants working in this project.
|
|
@@ -39,7 +39,7 @@ These instructions are for AI assistants working in this project.
|
|
|
39
39
|
## TL;DR Checklist
|
|
40
40
|
|
|
41
41
|
- Decide whether Reffy ideation is needed for this request.
|
|
42
|
-
- If needed, read existing context in \`.
|
|
42
|
+
- If needed, read existing context in \`.reffy/artifacts/\`.
|
|
43
43
|
- Add/update exploratory artifacts and keep them concise.
|
|
44
44
|
- Run \`reffy reindex\` and \`reffy validate\` after artifact changes.
|
|
45
45
|
- After ideation approval, run \`reffy summarize --output json\` and pick only directly relevant artifacts for proposal citations.
|
|
@@ -60,9 +60,9 @@ You can skip Reffy when the request is:
|
|
|
60
60
|
|
|
61
61
|
## Reffy Workflow
|
|
62
62
|
|
|
63
|
-
1. Read existing artifacts in \`.
|
|
63
|
+
1. Read existing artifacts in \`.reffy/artifacts/\`.
|
|
64
64
|
2. Add or update artifacts to capture exploratory context.
|
|
65
|
-
3. Run \`reffy reindex\` to index newly added files into \`.
|
|
65
|
+
3. Run \`reffy reindex\` to index newly added files into \`.reffy/manifest.json\`.
|
|
66
66
|
4. Run \`reffy validate\` to verify manifest contract compliance.
|
|
67
67
|
|
|
68
68
|
## Relationship To OpenSpec
|
|
@@ -102,7 +102,7 @@ No Reffy references used.
|
|
|
102
102
|
|
|
103
103
|
## Artifact Conventions
|
|
104
104
|
|
|
105
|
-
- Treat \`.
|
|
105
|
+
- Treat \`.reffy/\` as a repository-local guidance and ideation context layer.
|
|
106
106
|
- Keep artifact names clear and stable.
|
|
107
107
|
- Prefer markdown notes for exploratory content.
|
|
108
108
|
- Keep manifests machine-readable and schema-compliant (version 1).
|
|
@@ -153,10 +153,10 @@ function isDirectory(targetPath) {
|
|
|
153
153
|
function discoverRepoRoot(startDir) {
|
|
154
154
|
let current = path.resolve(startDir);
|
|
155
155
|
while (true) {
|
|
156
|
-
if (path.basename(current) === ".
|
|
156
|
+
if (path.basename(current) === ".reffy" && isDirectory(path.join(current, "artifacts"))) {
|
|
157
157
|
return path.dirname(current);
|
|
158
158
|
}
|
|
159
|
-
if (isDirectory(path.join(current, ".
|
|
159
|
+
if (isDirectory(path.join(current, ".reffy"))) {
|
|
160
160
|
return current;
|
|
161
161
|
}
|
|
162
162
|
if (pathExists(path.join(current, "AGENTS.md")) || pathExists(path.join(current, ".git"))) {
|
|
@@ -225,11 +225,11 @@ function usage() {
|
|
|
225
225
|
"Usage: reffy <command> [--repo PATH] [--output text|json]",
|
|
226
226
|
"",
|
|
227
227
|
"Commands:",
|
|
228
|
-
" init Ensure root AGENTS.md block and .
|
|
229
|
-
" bootstrap Run init, ensure .
|
|
228
|
+
" init Ensure root AGENTS.md block and .reffy/AGENTS.md are up to date.",
|
|
229
|
+
" bootstrap Run init, ensure .reffy structure exists, then reindex artifacts.",
|
|
230
230
|
" doctor Diagnose required Reffy setup and optional tool availability.",
|
|
231
|
-
" reindex Scan .
|
|
232
|
-
" validate Validate .
|
|
231
|
+
" reindex Scan .reffy/artifacts and add missing files to manifest.",
|
|
232
|
+
" validate Validate .reffy/manifest.json against manifest v1 contract.",
|
|
233
233
|
" summarize Generate a read-only summary of indexed Reffy artifacts.",
|
|
234
234
|
" diagram Render Mermaid diagrams (supports SVG and ASCII).",
|
|
235
235
|
].join("\n");
|
package/dist/doctor.js
CHANGED
|
@@ -27,7 +27,7 @@ function summarizeChecks(checks) {
|
|
|
27
27
|
}
|
|
28
28
|
export async function runDoctor(repoRoot, options) {
|
|
29
29
|
const checks = [];
|
|
30
|
-
const refsDir = path.join(repoRoot, ".
|
|
30
|
+
const refsDir = path.join(repoRoot, ".reffy");
|
|
31
31
|
const artifactsDir = path.join(refsDir, "artifacts");
|
|
32
32
|
const manifestPath = path.join(refsDir, "manifest.json");
|
|
33
33
|
const rootAgentsPath = path.join(repoRoot, "AGENTS.md");
|
|
@@ -37,14 +37,14 @@ export async function runDoctor(repoRoot, options) {
|
|
|
37
37
|
id: "refs_dir_exists",
|
|
38
38
|
level: "required",
|
|
39
39
|
ok: refsDirExists,
|
|
40
|
-
message: refsDirExists ? ".
|
|
40
|
+
message: refsDirExists ? ".reffy directory found" : ".reffy directory is missing",
|
|
41
41
|
});
|
|
42
42
|
const artifactsDirExists = await pathExists(artifactsDir);
|
|
43
43
|
checks.push({
|
|
44
44
|
id: "artifacts_dir_exists",
|
|
45
45
|
level: "required",
|
|
46
46
|
ok: artifactsDirExists,
|
|
47
|
-
message: artifactsDirExists ? ".
|
|
47
|
+
message: artifactsDirExists ? ".reffy/artifacts directory found" : ".reffy/artifacts directory is missing",
|
|
48
48
|
});
|
|
49
49
|
const rootAgentsExists = await pathExists(rootAgentsPath);
|
|
50
50
|
checks.push({
|
|
@@ -58,7 +58,7 @@ export async function runDoctor(repoRoot, options) {
|
|
|
58
58
|
id: "refs_agents_exists",
|
|
59
59
|
level: "required",
|
|
60
60
|
ok: refsAgentsExists,
|
|
61
|
-
message: refsAgentsExists ? ".
|
|
61
|
+
message: refsAgentsExists ? ".reffy/AGENTS.md found" : ".reffy/AGENTS.md is missing",
|
|
62
62
|
});
|
|
63
63
|
const manifestExists = await pathExists(manifestPath);
|
|
64
64
|
if (!manifestExists) {
|
|
@@ -66,7 +66,7 @@ export async function runDoctor(repoRoot, options) {
|
|
|
66
66
|
id: "manifest_valid",
|
|
67
67
|
level: "required",
|
|
68
68
|
ok: false,
|
|
69
|
-
message: ".
|
|
69
|
+
message: ".reffy/manifest.json is missing",
|
|
70
70
|
});
|
|
71
71
|
}
|
|
72
72
|
else {
|
|
@@ -76,7 +76,7 @@ export async function runDoctor(repoRoot, options) {
|
|
|
76
76
|
level: "required",
|
|
77
77
|
ok: manifestResult.ok,
|
|
78
78
|
message: manifestResult.ok
|
|
79
|
-
? `.
|
|
79
|
+
? `.reffy/manifest.json is valid (artifacts=${String(manifestResult.artifact_count)})`
|
|
80
80
|
: `manifest invalid: ${manifestResult.errors.join("; ")}`,
|
|
81
81
|
});
|
|
82
82
|
}
|
package/dist/storage.js
CHANGED
|
@@ -16,7 +16,7 @@ export class ReferencesStore {
|
|
|
16
16
|
manifestPath;
|
|
17
17
|
constructor(repoRoot) {
|
|
18
18
|
this.repoRoot = repoRoot;
|
|
19
|
-
this.refsDir = path.join(repoRoot, ".
|
|
19
|
+
this.refsDir = path.join(repoRoot, ".reffy");
|
|
20
20
|
this.artifactsDir = path.join(this.refsDir, "artifacts");
|
|
21
21
|
this.manifestPath = path.join(this.refsDir, "manifest.json");
|
|
22
22
|
this.ensureStructure();
|
package/package.json
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "reffy-cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.6",
|
|
4
4
|
"description": "CLI-first, framework-agnostic references workflow for any repo (TypeScript)",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"reffy",
|
|
7
|
+
"openspec",
|
|
8
|
+
"specs",
|
|
9
|
+
"cli",
|
|
10
|
+
"ai",
|
|
11
|
+
"development",
|
|
12
|
+
"sdd"
|
|
13
|
+
],
|
|
5
14
|
"license": "MIT",
|
|
6
15
|
"type": "module",
|
|
7
16
|
"main": "dist/index.js",
|