cfsa-antigravity 5.0.0 → 6.0.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 +1 -7
- package/bin/cli.mjs +1 -21
- package/package.json +2 -2
- package/template/.claude/README.md +1 -2
- package/template/.codex/README.md +1 -2
- package/template/.memory/.obsidian/app.json +1 -2
- package/template/.memory/README.md +0 -1
- package/template/.memory/pipeline/kit-sync.md +3 -3
- package/template/docs/README.md +0 -18
- package/template/docs/kit-architecture.md +1 -2
- package/template/docs/progress-state-catalog.md +0 -1
- package/template/.memory/migrate/README.md +0 -9
- package/template/.memory/migrate/migrate-legacy.mjs +0 -152
package/README.md
CHANGED
|
@@ -29,7 +29,6 @@ npx cfsa-antigravity init --agent claude,factory
|
|
|
29
29
|
| `cfsa-antigravity init --dry-run` | Preview what would be installed |
|
|
30
30
|
| `cfsa-antigravity init --path ./dir` | Install into specific directory |
|
|
31
31
|
| `cfsa-antigravity init --memory` | Scaffold unified `.memory/` + MCP integration |
|
|
32
|
-
| `cfsa-antigravity init --migrate-memory` | Scaffold unified memory and import legacy runtime memory |
|
|
33
32
|
|
|
34
33
|
### Available runtimes
|
|
35
34
|
|
|
@@ -54,8 +53,7 @@ Every install now scaffolds a shared `.memory/` root at the project level. It is
|
|
|
54
53
|
├── schema/ # machine-readable index/chunk artifacts
|
|
55
54
|
├── mcp-server/ # shared project-local MCP daemon + per-runtime client entrypoints
|
|
56
55
|
├── runtime/ # daemon pid/state files
|
|
57
|
-
|
|
58
|
-
└── migrate/ # legacy memory import helpers
|
|
56
|
+
└── hooks/ # Claude hook entrypoints
|
|
59
57
|
```
|
|
60
58
|
|
|
61
59
|
The installer ships the shared memory runtime into `.memory/`, including the project-local MCP server under `.memory/mcp-server/`. Tool-specific MCP client config is intentionally **not** managed by the kit — users wire their own `.mcp.json` / editor settings for the tools they actually use. The daemon writes workspace-local runtime state into `.memory/runtime/`, and clients resolve that state before proxying requests so one workspace does not silently talk to another workspace's daemon. The semantic index writes retrieval artifacts into `.memory/schema/semantic-index.json` plus `.memory/schema/semantic-manifest.json`.
|
|
@@ -150,10 +148,6 @@ A fresh `init` now installs:
|
|
|
150
148
|
|
|
151
149
|
Tool-specific MCP client config (such as `.mcp.json`) is user-managed and documented above.
|
|
152
150
|
|
|
153
|
-
Use `--migrate-memory` when upgrading an older installation that still has runtime-local memory you want imported into `.memory/`.
|
|
154
|
-
|
|
155
|
-
If migration finds a knowledge-file destination with different existing contents, it preserves both versions by writing a `.conflict-YYYY-MM-DD.md` sibling file for manual reconciliation.
|
|
156
|
-
|
|
157
151
|
## Documentation
|
|
158
152
|
|
|
159
153
|
| Document | Contents |
|
package/bin/cli.mjs
CHANGED
|
@@ -200,7 +200,6 @@ ${c.bold}Init Options:${c.reset}
|
|
|
200
200
|
--dry-run Preview what would be copied without making changes
|
|
201
201
|
--quiet Suppress output (for CI/CD — installs all runtimes)
|
|
202
202
|
--memory Scaffold unified .memory/ and MCP integration
|
|
203
|
-
--migrate-memory Scaffold .memory/ and migrate legacy runtime memory
|
|
204
203
|
|
|
205
204
|
${c.bold}Examples:${c.reset}
|
|
206
205
|
${c.dim}# Interactive — pick which runtimes to install${c.reset}
|
|
@@ -225,7 +224,7 @@ ${c.bold}Examples:${c.reset}
|
|
|
225
224
|
|
|
226
225
|
// --- Parse Arguments ---
|
|
227
226
|
function parseArgs(args) {
|
|
228
|
-
const parsed = { command: null, agents: null, force: false, dryRun: false, path: null, quiet: false, memory: false,
|
|
227
|
+
const parsed = { command: null, agents: null, force: false, dryRun: false, path: null, quiet: false, memory: false, json: false };
|
|
229
228
|
|
|
230
229
|
let i = 0;
|
|
231
230
|
while (i < args.length) {
|
|
@@ -272,10 +271,6 @@ function parseArgs(args) {
|
|
|
272
271
|
case "--memory":
|
|
273
272
|
parsed.memory = true;
|
|
274
273
|
break;
|
|
275
|
-
case "--migrate-memory":
|
|
276
|
-
parsed.memory = true;
|
|
277
|
-
parsed.migrateMemory = true;
|
|
278
|
-
break;
|
|
279
274
|
case "--json":
|
|
280
275
|
parsed.json = true;
|
|
281
276
|
break;
|
|
@@ -424,18 +419,6 @@ function installMemoryScaffold(targetDir, opts) {
|
|
|
424
419
|
info(`MCP client configuration is user-managed; see the README for tool-specific setup and the initial graph compile step.`);
|
|
425
420
|
}
|
|
426
421
|
|
|
427
|
-
async function migrateMemory(targetDir) {
|
|
428
|
-
const migratePath = join(targetDir, ".memory", "migrate", "migrate-legacy.mjs");
|
|
429
|
-
if (!existsSync(migratePath)) {
|
|
430
|
-
error("Unified memory migration script not found after scaffold.");
|
|
431
|
-
exit(1);
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
const migrationModule = await import(pathToFileURL(migratePath).href);
|
|
435
|
-
const result = migrationModule.migrateLegacyMemory({ projectRoot: targetDir });
|
|
436
|
-
info(`Migrated legacy memory (${result.migratedCount} item(s))`);
|
|
437
|
-
}
|
|
438
|
-
|
|
439
422
|
// --- Install runtimes ---
|
|
440
423
|
function installRuntimes(runtimes, targetDir, opts) {
|
|
441
424
|
let totalCopied = 0;
|
|
@@ -569,9 +552,6 @@ async function cmdInit(opts) {
|
|
|
569
552
|
const { totalCopied, totalSkipped } = installRuntimes(selected, targetDir, opts);
|
|
570
553
|
|
|
571
554
|
installMemoryScaffold(targetDir, opts);
|
|
572
|
-
if (opts.migrateMemory && !opts.dryRun) {
|
|
573
|
-
await migrateMemory(targetDir);
|
|
574
|
-
}
|
|
575
555
|
|
|
576
556
|
if (!opts.dryRun) {
|
|
577
557
|
const compilePath = join(targetDir, ".memory", "pipeline", "compile.mjs");
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cfsa-antigravity",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0",
|
|
4
4
|
"description": "CFSA Pipeline — Constraint-First Specification Architecture for AI agents. Production-grade from line one.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"changeset": "changeset",
|
|
7
7
|
"version": "changeset version",
|
|
8
8
|
"prebuild": "./scripts/build-template.sh",
|
|
9
9
|
"build": "./scripts/build-template.sh",
|
|
10
|
-
"check": "./scripts/check-template-integrity.sh && node ./scripts/check-memory-mcp.mjs && node ./scripts/check-
|
|
10
|
+
"check": "./scripts/check-template-integrity.sh && node ./scripts/check-memory-mcp.mjs && node ./scripts/check-vault-contract.mjs && node ./scripts/check-e2e-harness.mjs",
|
|
11
11
|
"prepare": "husky || true"
|
|
12
12
|
},
|
|
13
13
|
"bin": {
|
|
@@ -24,8 +24,7 @@ Project root canonical memory / Obsidian vault:
|
|
|
24
24
|
├── wiki/ # Compiled patterns, decisions, blockers, and knowledge
|
|
25
25
|
├── schema/ # Machine-readable retrieval artifacts
|
|
26
26
|
├── mcp-server/ # Shared memory MCP server
|
|
27
|
-
|
|
28
|
-
└── migrate/ # Legacy memory import helpers
|
|
27
|
+
└── hooks/ # Claude hook entrypoints
|
|
29
28
|
```
|
|
30
29
|
|
|
31
30
|
The `.memory/` directory is the canonical project memory layer and is designed to function as an Obsidian-friendly vault inside the project. `.claude/memory/` exists only for Claude-native bridge guidance and session-specific conventions.
|
|
@@ -24,8 +24,7 @@ Project root canonical memory / Obsidian vault:
|
|
|
24
24
|
├── wiki/ # Compiled patterns, decisions, blockers, and knowledge
|
|
25
25
|
├── schema/ # Machine-readable retrieval artifacts
|
|
26
26
|
├── mcp-server/ # Shared memory MCP server
|
|
27
|
-
|
|
28
|
-
└── migrate/ # Legacy memory import helpers
|
|
27
|
+
└── hooks/ # Optional hook entrypoints
|
|
29
28
|
```
|
|
30
29
|
|
|
31
30
|
The `.memory/` directory is the canonical project memory layer and is designed to function as an Obsidian-friendly vault inside the project.
|
|
@@ -7,7 +7,6 @@ Source files for the unified `.memory/` scaffold that `npm run build` copies int
|
|
|
7
7
|
- `pipeline/progress/` — canonical pipeline progress scaffold shared by all runtimes
|
|
8
8
|
- `mcp-server/` — stdio MCP server exposing memory tools
|
|
9
9
|
- `hooks/` — Claude Code hook entrypoints
|
|
10
|
-
- `migrate/` — legacy memory migration
|
|
11
10
|
- `schema/` — JSON schemas for compiled memory records
|
|
12
11
|
|
|
13
12
|
## Extension pattern
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# Kit Sync State
|
|
2
2
|
|
|
3
3
|
upstream: https://github.com/RepairYourTech/cfsa-antigravity
|
|
4
|
-
last_synced_commit:
|
|
5
|
-
last_synced_at: 2026-05-06T14:
|
|
6
|
-
kit_version:
|
|
4
|
+
last_synced_commit: ed50ceb28f7722945520e5bda7376fe87040be64
|
|
5
|
+
last_synced_at: 2026-05-06T14:36:37Z
|
|
6
|
+
kit_version: 6.0.0
|
|
7
7
|
installed_runtimes:
|
|
8
8
|
- agents
|
|
9
9
|
- codex
|
package/template/docs/README.md
CHANGED
|
@@ -186,24 +186,6 @@ After installing or updating the `.memory` runtime in an existing project:
|
|
|
186
186
|
3. Verify graph/index artifacts exist under `.memory/schema/` and `.memory/wiki/`.
|
|
187
187
|
4. Open Obsidian at `.memory/`.
|
|
188
188
|
|
|
189
|
-
If you are upgrading an older project with siloed runtime-local memory, run:
|
|
190
|
-
|
|
191
|
-
```bash
|
|
192
|
-
npx cfsa-antigravity init --migrate-memory
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
### Migration conflicts
|
|
196
|
-
|
|
197
|
-
When migration imports runtime-local knowledge files into `.memory/wiki/knowledge/`, an existing destination with different contents is preserved and a sibling conflict file is written:
|
|
198
|
-
|
|
199
|
-
```text
|
|
200
|
-
.memory/wiki/knowledge/<name>.conflict-YYYY-MM-DD.md
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
Resolve conflicts by comparing the imported `.conflict-*.md` file with the canonical target file, merging the content you want to keep, then deleting the conflict file once resolved.
|
|
204
|
-
|
|
205
|
-
Structured legacy files like old `decisions.md`, `patterns.md`, and `blockers.md` are imported through the raw memory pipeline so compile can preserve them in the unified wiki outputs.
|
|
206
|
-
|
|
207
189
|
### Semantic backend
|
|
208
190
|
|
|
209
191
|
The shared memory system now supports a stronger local semantic mode:
|
|
@@ -45,8 +45,7 @@ The kit ships multiple runtime trees in this repository:
|
|
|
45
45
|
├── schema/
|
|
46
46
|
├── mcp-server/ # shared daemon + per-runtime client entrypoints
|
|
47
47
|
├── runtime/ # daemon pid/state files
|
|
48
|
-
|
|
49
|
-
└── migrate/
|
|
48
|
+
└── hooks/
|
|
50
49
|
```
|
|
51
50
|
|
|
52
51
|
`.agents/`, `.codex/`, `.claude/`, and `.factory/` implement the same CFSA pipeline for different agent environments. Codex uses the `.codex/` runtime plus the root `CODEX.md` guidance file. Each runtime owns its own execution assets. Shared project state lives under `.memory/`.
|
|
@@ -51,7 +51,6 @@ These paths may appear only as legacy migration source paths.
|
|
|
51
51
|
|
|
52
52
|
Old runtime progress paths are intentionally retained in:
|
|
53
53
|
|
|
54
|
-
- `memory-src/migrate/migrate-legacy.mjs`
|
|
55
54
|
- `docs/kit-architecture.md`
|
|
56
55
|
|
|
57
56
|
Those references describe migration inputs only. They are not instructions for active workflow state.
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import { existsSync } from "node:fs";
|
|
2
|
-
import { basename, join } from "node:path";
|
|
3
|
-
import { createHash } from "node:crypto";
|
|
4
|
-
import { ensureMemoryScaffold, getFileText, getMemoryRoot, setFileText, slugify } from "../pipeline/utils.mjs";
|
|
5
|
-
import { flushEntry } from "../pipeline/flush.mjs";
|
|
6
|
-
import { compileMemory } from "../pipeline/compile.mjs";
|
|
7
|
-
|
|
8
|
-
const LEGACY_MAP = [
|
|
9
|
-
{ source: ".claude/memory/patterns.md", target: "wiki/patterns.md" },
|
|
10
|
-
{ source: ".claude/memory/decisions.md", target: "wiki/decisions.md" },
|
|
11
|
-
{ source: ".claude/memory/blockers.md", target: "wiki/blockers.md" },
|
|
12
|
-
{ source: ".claude/progress/memory", targetDir: "wiki/knowledge", runtime: "claude-progress" },
|
|
13
|
-
{ source: ".codex/progress/memory", targetDir: "wiki/knowledge", runtime: "codex-progress" },
|
|
14
|
-
{ source: ".agents/progress/memory", targetDir: "wiki/knowledge", runtime: "agent-progress" },
|
|
15
|
-
{ source: ".factory/memory", targetDir: "wiki/knowledge", runtime: "factory-memory" },
|
|
16
|
-
{ source: ".factory/progress/memory", targetDir: "wiki/knowledge", runtime: "factory-progress" },
|
|
17
|
-
];
|
|
18
|
-
|
|
19
|
-
function hashText(text) {
|
|
20
|
-
return createHash("sha256").update(text).digest("hex");
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function structuredTypeFromTarget(target) {
|
|
24
|
-
if (target.includes("patterns.md")) return "pattern";
|
|
25
|
-
if (target.includes("decisions.md")) return "decision";
|
|
26
|
-
if (target.includes("blockers.md")) return "blocker";
|
|
27
|
-
return "knowledge";
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function stripMarkdownHeading(text) {
|
|
31
|
-
return text
|
|
32
|
-
.split("\n")
|
|
33
|
-
.filter((line, index) => !(index === 0 && line.startsWith("# ")))
|
|
34
|
-
.join("\n")
|
|
35
|
-
.trim();
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function importStructuredRecord(mapping, content, memoryRoot, migratedAt) {
|
|
39
|
-
const normalized = stripMarkdownHeading(content);
|
|
40
|
-
if (!normalized) {
|
|
41
|
-
return { status: "skipped", reason: "empty" };
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const result = flushEntry({
|
|
45
|
-
type: structuredTypeFromTarget(mapping.target),
|
|
46
|
-
agent: "migration",
|
|
47
|
-
source: mapping.source,
|
|
48
|
-
title: `${structuredTypeFromTarget(mapping.target)} import`,
|
|
49
|
-
text: normalized,
|
|
50
|
-
metadata: {
|
|
51
|
-
migratedAt,
|
|
52
|
-
legacySource: mapping.source,
|
|
53
|
-
importMode: "structured-file"
|
|
54
|
-
},
|
|
55
|
-
sessionId: "legacy-migration"
|
|
56
|
-
}, { memoryRoot });
|
|
57
|
-
|
|
58
|
-
return { status: "created", destination: result.path };
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function writeKnowledgeImport(destination, content, sourceLabel, runtime, migratedAt) {
|
|
62
|
-
const existingText = getFileText(destination, "");
|
|
63
|
-
if (existingText.trim() && hashText(existingText) === hashText(content)) {
|
|
64
|
-
return { status: "skipped", destination, reason: "identical" };
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (existingText.trim()) {
|
|
68
|
-
const conflictDestination = destination.replace(/\.md$/, `.conflict-${migratedAt.slice(0, 10)}.md`);
|
|
69
|
-
setFileText(conflictDestination, content);
|
|
70
|
-
return { status: "conflict", destination: conflictDestination, runtime, source: sourceLabel };
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
setFileText(destination, content);
|
|
74
|
-
return { status: "created", destination, runtime, source: sourceLabel };
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export function migrateLegacyMemory(options = {}) {
|
|
78
|
-
const projectRoot = options.projectRoot ?? process.cwd();
|
|
79
|
-
const memoryRoot = options.memoryRoot ?? getMemoryRoot(projectRoot);
|
|
80
|
-
ensureMemoryScaffold(memoryRoot);
|
|
81
|
-
|
|
82
|
-
const migrated = [];
|
|
83
|
-
const skipped = [];
|
|
84
|
-
const conflicts = [];
|
|
85
|
-
const migratedAt = new Date().toISOString();
|
|
86
|
-
|
|
87
|
-
for (const mapping of LEGACY_MAP) {
|
|
88
|
-
const absoluteSource = join(projectRoot, mapping.source);
|
|
89
|
-
if (!existsSync(absoluteSource)) {
|
|
90
|
-
continue;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (mapping.target) {
|
|
94
|
-
const content = getFileText(absoluteSource, "");
|
|
95
|
-
if (!content.trim()) {
|
|
96
|
-
continue;
|
|
97
|
-
}
|
|
98
|
-
const result = importStructuredRecord(mapping, content, memoryRoot, migratedAt);
|
|
99
|
-
if (result.status === "skipped") {
|
|
100
|
-
skipped.push({ from: mapping.source, to: mapping.target, reason: result.reason });
|
|
101
|
-
} else {
|
|
102
|
-
migrated.push({ from: mapping.source, to: mapping.target, status: result.status });
|
|
103
|
-
}
|
|
104
|
-
continue;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const entries = ["patterns.md", "decisions.md", "blockers.md"].map((name) => join(absoluteSource, name)).filter((path) => existsSync(path));
|
|
108
|
-
for (const entryPath of entries) {
|
|
109
|
-
const text = getFileText(entryPath, "");
|
|
110
|
-
if (!text.trim()) {
|
|
111
|
-
continue;
|
|
112
|
-
}
|
|
113
|
-
const fileName = `${slugify(mapping.runtime)}-${slugify(basename(entryPath, ".md"))}.md`;
|
|
114
|
-
const destination = join(memoryRoot, mapping.targetDir, fileName);
|
|
115
|
-
const sourceLabel = `${mapping.source}/${basename(entryPath)}`;
|
|
116
|
-
const content = [
|
|
117
|
-
"---",
|
|
118
|
-
`source: ${sourceLabel}`,
|
|
119
|
-
`runtime: ${mapping.runtime}`,
|
|
120
|
-
`migrated_at: ${migratedAt}`,
|
|
121
|
-
"---",
|
|
122
|
-
"",
|
|
123
|
-
text.trim(),
|
|
124
|
-
"",
|
|
125
|
-
].join("\n");
|
|
126
|
-
const result = writeKnowledgeImport(destination, content, sourceLabel, mapping.runtime, migratedAt);
|
|
127
|
-
if (result.status === "skipped") {
|
|
128
|
-
skipped.push({ from: entryPath, to: destination, reason: result.reason });
|
|
129
|
-
} else if (result.status === "conflict") {
|
|
130
|
-
conflicts.push({ from: entryPath, to: result.destination });
|
|
131
|
-
} else {
|
|
132
|
-
migrated.push({ from: entryPath, to: destination, status: result.status });
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const compileResult = compileMemory({ projectRoot, memoryRoot });
|
|
138
|
-
return {
|
|
139
|
-
ok: true,
|
|
140
|
-
migratedCount: migrated.length,
|
|
141
|
-
skippedCount: skipped.length,
|
|
142
|
-
conflictCount: conflicts.length,
|
|
143
|
-
migrated,
|
|
144
|
-
skipped,
|
|
145
|
-
conflicts,
|
|
146
|
-
compileResult,
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
151
|
-
console.log(JSON.stringify(migrateLegacyMemory(), null, 2));
|
|
152
|
-
}
|