@codified/cli 0.3.5 → 0.3.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/dist/commands/add.d.ts +3 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +163 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/bootstrap.d.ts.map +1 -0
- package/dist/commands/bootstrap.js +141 -0
- package/dist/commands/bootstrap.js.map +1 -0
- package/dist/commands/check.d.ts +3 -0
- package/dist/commands/check.d.ts.map +1 -0
- package/dist/commands/check.js +332 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/cleanup.d.ts +3 -0
- package/dist/commands/cleanup.d.ts.map +1 -0
- package/dist/commands/cleanup.js +166 -0
- package/dist/commands/cleanup.js.map +1 -0
- package/dist/commands/collect.d.ts +26 -0
- package/dist/commands/collect.d.ts.map +1 -0
- package/dist/commands/collect.js +269 -0
- package/dist/commands/collect.js.map +1 -0
- package/dist/commands/connect.d.ts +3 -0
- package/dist/commands/connect.d.ts.map +1 -0
- package/dist/commands/connect.js +321 -0
- package/dist/commands/connect.js.map +1 -0
- package/dist/commands/explain.d.ts +3 -0
- package/dist/commands/explain.d.ts.map +1 -0
- package/dist/commands/explain.js +527 -0
- package/dist/commands/explain.js.map +1 -0
- package/dist/commands/export.d.ts +3 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +59 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/gaps.d.ts +3 -0
- package/dist/commands/gaps.d.ts.map +1 -0
- package/dist/commands/gaps.js +315 -0
- package/dist/commands/gaps.js.map +1 -0
- package/dist/commands/graph.d.ts +3 -0
- package/dist/commands/graph.d.ts.map +1 -0
- package/dist/commands/graph.js +293 -0
- package/dist/commands/graph.js.map +1 -0
- package/dist/commands/import-cmd.d.ts +3 -0
- package/dist/commands/import-cmd.d.ts.map +1 -0
- package/dist/commands/import-cmd.js +199 -0
- package/dist/commands/import-cmd.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +215 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/project.d.ts +3 -0
- package/dist/commands/project.d.ts.map +1 -0
- package/dist/commands/project.js +179 -0
- package/dist/commands/project.js.map +1 -0
- package/dist/commands/reset.d.ts +3 -0
- package/dist/commands/reset.d.ts.map +1 -0
- package/dist/commands/reset.js +157 -0
- package/dist/commands/reset.js.map +1 -0
- package/dist/commands/search.d.ts +3 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +183 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +205 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +242 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/timeline.d.ts +3 -0
- package/dist/commands/timeline.d.ts.map +1 -0
- package/dist/commands/timeline.js +424 -0
- package/dist/commands/timeline.js.map +1 -0
- package/dist/commands/triage.d.ts +3 -0
- package/dist/commands/triage.d.ts.map +1 -0
- package/dist/commands/triage.js +336 -0
- package/dist/commands/triage.js.map +1 -0
- package/dist/commands/up.d.ts +3 -0
- package/dist/commands/up.d.ts.map +1 -0
- package/dist/commands/up.js +312 -0
- package/dist/commands/up.js.map +1 -0
- package/dist/commands/watch.d.ts +3 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +224 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +574 -491
- package/dist/index.js.map +1 -0
- package/dist/lib/config.d.ts +52 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +142 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/docker.d.ts +23 -0
- package/dist/lib/docker.d.ts.map +1 -0
- package/dist/lib/docker.js +84 -0
- package/dist/lib/docker.js.map +1 -0
- package/dist/lib/migrate.d.ts +9 -0
- package/dist/lib/migrate.d.ts.map +1 -0
- package/dist/lib/migrate.js +97 -0
- package/dist/lib/migrate.js.map +1 -0
- package/dist/lib/paths.d.ts +9 -0
- package/dist/lib/paths.d.ts.map +1 -0
- package/dist/lib/paths.js +28 -0
- package/dist/lib/paths.js.map +1 -0
- package/dist/lib/prompt.d.ts +14 -0
- package/dist/lib/prompt.d.ts.map +1 -0
- package/dist/lib/prompt.js +87 -0
- package/dist/lib/prompt.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import-cmd.d.ts","sourceRoot":"","sources":["../../src/commands/import-cmd.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,aAAa,SAuNtB,CAAC"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
// codify import — import a context graph from a JSON backup file
|
|
2
|
+
// Named import-cmd.ts because "import" is a reserved word in JS.
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
import { readFileSync } from "node:fs";
|
|
5
|
+
import { resolve } from "node:path";
|
|
6
|
+
import { loadProjectConfig } from "../lib/config.js";
|
|
7
|
+
export const importCommand = new Command("import")
|
|
8
|
+
.description("Import a context graph from a JSON backup file")
|
|
9
|
+
.argument("<file>", "Path to the JSON export file")
|
|
10
|
+
.option("--merge", "Add new nodes/edges, skip existing (ON CONFLICT DO NOTHING)")
|
|
11
|
+
.option("--replace", "Wipe the graph first, then import all data")
|
|
12
|
+
.action(async (file, opts) => {
|
|
13
|
+
try {
|
|
14
|
+
// Read and validate the JSON file
|
|
15
|
+
const filePath = resolve(process.cwd(), file);
|
|
16
|
+
let raw;
|
|
17
|
+
try {
|
|
18
|
+
raw = readFileSync(filePath, "utf-8");
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
console.error(`\n ERROR: Cannot read file: ${filePath}\n`);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
let data;
|
|
25
|
+
try {
|
|
26
|
+
data = JSON.parse(raw);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
console.error(`\n ERROR: Invalid JSON in file: ${filePath}\n`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
if (!Array.isArray(data.nodes) || !Array.isArray(data.edges)) {
|
|
33
|
+
console.error(`\n ERROR: Invalid export file. Must contain "nodes" and "edges" arrays.\n`);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
const nodes = data.nodes;
|
|
37
|
+
const edges = data.edges;
|
|
38
|
+
await loadProjectConfig();
|
|
39
|
+
const { getPool, closePool } = await import("@codify/graph");
|
|
40
|
+
const pool = getPool();
|
|
41
|
+
try {
|
|
42
|
+
await pool.query("SELECT 1");
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
console.error(" ERROR: Cannot connect to PostgreSQL. Run 'codify init' first.\n");
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
const client = await pool.connect();
|
|
49
|
+
try {
|
|
50
|
+
await client.query("BEGIN");
|
|
51
|
+
// --replace mode: wipe graph first
|
|
52
|
+
if (opts.replace) {
|
|
53
|
+
console.log("\n Replacing graph — truncating existing data...");
|
|
54
|
+
await client.query("TRUNCATE TABLE edges CASCADE");
|
|
55
|
+
await client.query("TRUNCATE TABLE nodes CASCADE");
|
|
56
|
+
console.log(" Truncated nodes and edges.");
|
|
57
|
+
}
|
|
58
|
+
// Determine conflict strategy
|
|
59
|
+
const isUpsert = !opts.merge && !opts.replace;
|
|
60
|
+
const isMerge = !!opts.merge;
|
|
61
|
+
// ── Import nodes ───────────────────────────────────────────────
|
|
62
|
+
console.log(`\n Importing ${nodes.length} nodes...`);
|
|
63
|
+
for (const node of nodes) {
|
|
64
|
+
const values = [
|
|
65
|
+
node.id,
|
|
66
|
+
node.type,
|
|
67
|
+
node.layer,
|
|
68
|
+
node.branch_id ?? null,
|
|
69
|
+
node.confidence,
|
|
70
|
+
node.freshness,
|
|
71
|
+
node.properties ? JSON.stringify(node.properties) : "{}",
|
|
72
|
+
node.metadata ? JSON.stringify(node.metadata) : "{}",
|
|
73
|
+
node.tags ?? [],
|
|
74
|
+
node.source_system ?? "manual",
|
|
75
|
+
node.source_reference ?? "",
|
|
76
|
+
node.source_agent_id ?? null,
|
|
77
|
+
node.source_reliability ?? 0.7,
|
|
78
|
+
node.superseded_by ?? null,
|
|
79
|
+
node.version ?? 1,
|
|
80
|
+
node.created_at,
|
|
81
|
+
node.updated_at,
|
|
82
|
+
];
|
|
83
|
+
if (opts.replace || isMerge) {
|
|
84
|
+
// For replace mode: straight insert (table was truncated)
|
|
85
|
+
// For merge mode: insert, skip on conflict
|
|
86
|
+
const conflictClause = isMerge ? "ON CONFLICT (id) DO NOTHING" : "";
|
|
87
|
+
await client.query(`INSERT INTO nodes (
|
|
88
|
+
id, type, layer, branch_id, confidence, freshness,
|
|
89
|
+
properties, metadata, tags, source_system, source_reference,
|
|
90
|
+
source_agent_id, source_reliability, superseded_by, version,
|
|
91
|
+
created_at, updated_at
|
|
92
|
+
) VALUES (
|
|
93
|
+
$1, $2, $3, $4, $5, $6,
|
|
94
|
+
$7::jsonb, $8::jsonb, $9, $10, $11,
|
|
95
|
+
$12, $13, $14, $15,
|
|
96
|
+
$16, $17
|
|
97
|
+
) ${conflictClause}`, values);
|
|
98
|
+
}
|
|
99
|
+
else if (isUpsert) {
|
|
100
|
+
// Default upsert mode
|
|
101
|
+
await client.query(`INSERT INTO nodes (
|
|
102
|
+
id, type, layer, branch_id, confidence, freshness,
|
|
103
|
+
properties, metadata, tags, source_system, source_reference,
|
|
104
|
+
source_agent_id, source_reliability, superseded_by, version,
|
|
105
|
+
created_at, updated_at
|
|
106
|
+
) VALUES (
|
|
107
|
+
$1, $2, $3, $4, $5, $6,
|
|
108
|
+
$7::jsonb, $8::jsonb, $9, $10, $11,
|
|
109
|
+
$12, $13, $14, $15,
|
|
110
|
+
$16, $17
|
|
111
|
+
) ON CONFLICT (id) DO UPDATE SET
|
|
112
|
+
type = EXCLUDED.type,
|
|
113
|
+
layer = EXCLUDED.layer,
|
|
114
|
+
branch_id = EXCLUDED.branch_id,
|
|
115
|
+
confidence = EXCLUDED.confidence,
|
|
116
|
+
freshness = EXCLUDED.freshness,
|
|
117
|
+
properties = EXCLUDED.properties,
|
|
118
|
+
metadata = EXCLUDED.metadata,
|
|
119
|
+
tags = EXCLUDED.tags,
|
|
120
|
+
source_system = EXCLUDED.source_system,
|
|
121
|
+
source_reference = EXCLUDED.source_reference,
|
|
122
|
+
source_agent_id = EXCLUDED.source_agent_id,
|
|
123
|
+
source_reliability = EXCLUDED.source_reliability,
|
|
124
|
+
superseded_by = EXCLUDED.superseded_by,
|
|
125
|
+
version = EXCLUDED.version,
|
|
126
|
+
created_at = EXCLUDED.created_at,
|
|
127
|
+
updated_at = EXCLUDED.updated_at`, values);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// ── Import edges ───────────────────────────────────────────────
|
|
131
|
+
console.log(` Importing ${edges.length} edges...`);
|
|
132
|
+
for (const edge of edges) {
|
|
133
|
+
const values = [
|
|
134
|
+
edge.id,
|
|
135
|
+
edge.type,
|
|
136
|
+
edge.source_id,
|
|
137
|
+
edge.target_id,
|
|
138
|
+
edge.confidence,
|
|
139
|
+
edge.weight,
|
|
140
|
+
edge.properties ? JSON.stringify(edge.properties) : "{}",
|
|
141
|
+
edge.evidence ?? null,
|
|
142
|
+
edge.branch_id ?? null,
|
|
143
|
+
edge.created_at,
|
|
144
|
+
];
|
|
145
|
+
if (opts.replace || isMerge) {
|
|
146
|
+
const conflictClause = isMerge ? "ON CONFLICT (id) DO NOTHING" : "";
|
|
147
|
+
await client.query(`INSERT INTO edges (
|
|
148
|
+
id, type, source_id, target_id, confidence, weight,
|
|
149
|
+
properties, evidence, branch_id, created_at
|
|
150
|
+
) VALUES (
|
|
151
|
+
$1, $2, $3, $4, $5, $6,
|
|
152
|
+
$7::jsonb, $8, $9, $10
|
|
153
|
+
) ${conflictClause}`, values);
|
|
154
|
+
}
|
|
155
|
+
else if (isUpsert) {
|
|
156
|
+
await client.query(`INSERT INTO edges (
|
|
157
|
+
id, type, source_id, target_id, confidence, weight,
|
|
158
|
+
properties, evidence, branch_id, created_at
|
|
159
|
+
) VALUES (
|
|
160
|
+
$1, $2, $3, $4, $5, $6,
|
|
161
|
+
$7::jsonb, $8, $9, $10
|
|
162
|
+
) ON CONFLICT (id) DO UPDATE SET
|
|
163
|
+
type = EXCLUDED.type,
|
|
164
|
+
source_id = EXCLUDED.source_id,
|
|
165
|
+
target_id = EXCLUDED.target_id,
|
|
166
|
+
confidence = EXCLUDED.confidence,
|
|
167
|
+
weight = EXCLUDED.weight,
|
|
168
|
+
properties = EXCLUDED.properties,
|
|
169
|
+
evidence = EXCLUDED.evidence,
|
|
170
|
+
branch_id = EXCLUDED.branch_id,
|
|
171
|
+
created_at = EXCLUDED.created_at`, values);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
await client.query("COMMIT");
|
|
175
|
+
const mode = opts.replace ? "(replace)" : opts.merge ? "(merge)" : "(upsert)";
|
|
176
|
+
console.log(`\n Import complete ${mode}. ${nodes.length} nodes, ${edges.length} edges.\n`);
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
await client.query("ROLLBACK");
|
|
180
|
+
throw err;
|
|
181
|
+
}
|
|
182
|
+
finally {
|
|
183
|
+
client.release();
|
|
184
|
+
}
|
|
185
|
+
await closePool();
|
|
186
|
+
}
|
|
187
|
+
catch (err) {
|
|
188
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
189
|
+
if (message.includes("ECONNREFUSED")) {
|
|
190
|
+
console.error("\n ERROR: Cannot connect to Codify services.");
|
|
191
|
+
console.error(" Run 'codify init' to start the infrastructure.\n");
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
console.error(`\n ERROR: ${message}\n`);
|
|
195
|
+
}
|
|
196
|
+
process.exit(1);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
//# sourceMappingURL=import-cmd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import-cmd.js","sourceRoot":"","sources":["../../src/commands/import-cmd.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBpC,eAAO,MAAM,WAAW,SAkOpB,CAAC"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
// codify init — interactive wizard for setting up Codify
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import { existsSync, mkdirSync, writeFileSync, readFileSync } from "node:fs";
|
|
4
|
+
import { resolve } from "node:path";
|
|
5
|
+
import { homedir } from "node:os";
|
|
6
|
+
import { execSync } from "node:child_process";
|
|
7
|
+
import { getMigrationsDir } from "../lib/paths.js";
|
|
8
|
+
import { promptSecret } from "../lib/prompt.js";
|
|
9
|
+
import { isDockerInstalled, isDockerRunning, setupDockerAssets, startDockerServices, waitForPostgres, } from "../lib/docker.js";
|
|
10
|
+
import { runMigrations } from "../lib/migrate.js";
|
|
11
|
+
export const initCommand = new Command("init")
|
|
12
|
+
.description("Initialize Codify for the current project")
|
|
13
|
+
.option("--skip-docker", "Skip Docker setup (use external services)")
|
|
14
|
+
.option("--yes", "Non-interactive mode (use env vars, skip prompts)")
|
|
15
|
+
.action(async (opts) => {
|
|
16
|
+
try {
|
|
17
|
+
const cwd = process.cwd();
|
|
18
|
+
const configDir = resolve(cwd, ".codify");
|
|
19
|
+
const dockerDir = resolve(configDir, "docker");
|
|
20
|
+
console.log("\n Codify — Living Context Graph for AI-Native Teams\n");
|
|
21
|
+
// ── Step 1: Pre-flight checks ──────────────────────────────────
|
|
22
|
+
console.log(" [1/6] Pre-flight checks");
|
|
23
|
+
// Check Node version
|
|
24
|
+
const nodeVersion = parseInt(process.versions.node.split(".")[0], 10);
|
|
25
|
+
if (nodeVersion < 22) {
|
|
26
|
+
console.error(` ✗ Node.js v${process.versions.node} (requires >= 22.0.0)`);
|
|
27
|
+
console.error(" Install Node 22+: https://nodejs.org/\n");
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
console.log(` ✓ Node.js v${process.versions.node}`);
|
|
31
|
+
if (!opts.skipDocker) {
|
|
32
|
+
// Check Docker installed
|
|
33
|
+
if (!isDockerInstalled()) {
|
|
34
|
+
console.error(" ✗ Docker is not installed");
|
|
35
|
+
console.error(" Install Docker Desktop: https://docs.docker.com/get-docker/\n");
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
// Check Docker running
|
|
39
|
+
if (!isDockerRunning()) {
|
|
40
|
+
console.error(" ✗ Docker is not running");
|
|
41
|
+
console.error(" Start Docker Desktop and try again.\n");
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
console.log(" ✓ Docker is running");
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
console.log(" - Docker check skipped (--skip-docker)");
|
|
48
|
+
}
|
|
49
|
+
// ── Step 2: API key setup ──────────────────────────────────────
|
|
50
|
+
console.log("\n [2/6] API key setup");
|
|
51
|
+
let anthropicApiKey = process.env.ANTHROPIC_API_KEY ?? "";
|
|
52
|
+
if (anthropicApiKey) {
|
|
53
|
+
console.log(" ✓ ANTHROPIC_API_KEY already set in environment");
|
|
54
|
+
}
|
|
55
|
+
else if (opts.yes) {
|
|
56
|
+
console.error(" ✗ ANTHROPIC_API_KEY not set. Set it in your environment for --yes mode.\n");
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
console.log(" Codify uses Claude to understand your codebase.");
|
|
61
|
+
anthropicApiKey = await promptSecret(" Enter your Anthropic API key: ");
|
|
62
|
+
if (!anthropicApiKey) {
|
|
63
|
+
console.error(" ✗ API key is required. Get one at https://console.anthropic.com/\n");
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
if (!anthropicApiKey.startsWith("sk-ant-")) {
|
|
67
|
+
console.error(" ✗ Invalid API key format (should start with sk-ant-)\n");
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
process.env.ANTHROPIC_API_KEY = anthropicApiKey;
|
|
71
|
+
console.log(" ✓ API key set for this session");
|
|
72
|
+
console.log(" TIP: Add to your shell profile for persistence:");
|
|
73
|
+
console.log(` echo 'export ANTHROPIC_API_KEY=${anthropicApiKey.slice(0, 10)}...' >> ~/.zshrc`);
|
|
74
|
+
}
|
|
75
|
+
// ── Step 3: Start infrastructure ───────────────────────────────
|
|
76
|
+
console.log("\n [3/6] Starting infrastructure");
|
|
77
|
+
const databaseUrl = process.env.DATABASE_URL ?? "postgresql://codify:codify@localhost:5432/codify";
|
|
78
|
+
const natsUrl = process.env.NATS_URL ?? "nats://localhost:4222";
|
|
79
|
+
if (!opts.skipDocker) {
|
|
80
|
+
console.log(" Starting PostgreSQL (with graph + vector extensions), NATS, and Redis...");
|
|
81
|
+
console.log(" (First run builds the PostgreSQL image — this may take a few minutes)\n");
|
|
82
|
+
// Copy Docker assets from npm package to .codify/docker/
|
|
83
|
+
setupDockerAssets(dockerDir);
|
|
84
|
+
try {
|
|
85
|
+
await startDockerServices(dockerDir);
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
console.error(" ✗ Failed to start Docker services:", err.message);
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
console.log(" ✓ PostgreSQL on :5432");
|
|
92
|
+
console.log(" ✓ NATS on :4222");
|
|
93
|
+
console.log(" ✓ Redis on :6379");
|
|
94
|
+
// Wait for PostgreSQL to be ready
|
|
95
|
+
console.log(" Waiting for PostgreSQL to accept connections...");
|
|
96
|
+
const pgReady = await waitForPostgres(dockerDir);
|
|
97
|
+
if (!pgReady) {
|
|
98
|
+
console.error(" ✗ PostgreSQL did not become ready within 120s\n");
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
console.log(" ✓ PostgreSQL is ready");
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
console.log(" - Docker setup skipped (--skip-docker)");
|
|
105
|
+
console.log(" Ensure PostgreSQL and NATS are running externally.");
|
|
106
|
+
}
|
|
107
|
+
// ── Step 4: Database migrations ────────────────────────────────
|
|
108
|
+
console.log("\n [4/6] Database migrations");
|
|
109
|
+
try {
|
|
110
|
+
const migrationsDir = getMigrationsDir();
|
|
111
|
+
const result = await runMigrations(databaseUrl, migrationsDir);
|
|
112
|
+
const total = result.applied.length + result.skipped.length;
|
|
113
|
+
if (result.applied.length > 0) {
|
|
114
|
+
console.log(` ✓ Schema applied (${result.applied.length} migration${result.applied.length > 1 ? "s" : ""} applied, ${result.skipped.length} already up-to-date)`);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
console.log(` ✓ Schema up-to-date (${total} migration${total > 1 ? "s" : ""})`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
console.error(" ✗ Migration failed:", err.message);
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
124
|
+
// ── Step 5: Project config ─────────────────────────────────────
|
|
125
|
+
console.log("\n [5/6] Project config");
|
|
126
|
+
mkdirSync(configDir, { recursive: true });
|
|
127
|
+
const configPath = resolve(configDir, "config.json");
|
|
128
|
+
const config = {
|
|
129
|
+
version: process.env.CLI_VERSION ?? "0.0.0",
|
|
130
|
+
database: databaseUrl,
|
|
131
|
+
nats: natsUrl,
|
|
132
|
+
projectRoot: cwd,
|
|
133
|
+
createdAt: new Date().toISOString(),
|
|
134
|
+
};
|
|
135
|
+
// NOTE: API key is NOT persisted to disk. It must be set via environment variable.
|
|
136
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
137
|
+
console.log(" ✓ .codify/config.json created");
|
|
138
|
+
// Add .codify/ to .gitignore
|
|
139
|
+
const gitignorePath = resolve(cwd, ".gitignore");
|
|
140
|
+
if (existsSync(gitignorePath)) {
|
|
141
|
+
const gitignore = readFileSync(gitignorePath, "utf-8");
|
|
142
|
+
if (!gitignore.includes(".codify")) {
|
|
143
|
+
writeFileSync(gitignorePath, gitignore.trimEnd() + "\n.codify/\n", "utf-8");
|
|
144
|
+
console.log(" ✓ .codify/ added to .gitignore");
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
writeFileSync(gitignorePath, ".codify/\n", "utf-8");
|
|
149
|
+
console.log(" ✓ .gitignore created with .codify/");
|
|
150
|
+
}
|
|
151
|
+
// ── Step 6: Claude Code integration ────────────────────────────
|
|
152
|
+
console.log("\n [6/6] Claude Code integration");
|
|
153
|
+
// Resolve full paths so MCP works even with nvm (Claude Code
|
|
154
|
+
// spawns processes without a login shell, so nvm's PATH isn't set).
|
|
155
|
+
const nodePath = process.execPath; // e.g. /Users/x/.nvm/versions/node/v22.../bin/node
|
|
156
|
+
const codifyPath = resolve(process.argv[1]); // e.g. /Users/x/.nvm/versions/node/v22.../bin/codify
|
|
157
|
+
// Use `claude mcp add` — the official way to register MCP servers.
|
|
158
|
+
// This writes to the correct config file regardless of Claude Code version.
|
|
159
|
+
try {
|
|
160
|
+
// Remove existing entry first (ignore errors if it doesn't exist)
|
|
161
|
+
try {
|
|
162
|
+
execSync('claude mcp remove codify -s user', { stdio: "ignore" });
|
|
163
|
+
}
|
|
164
|
+
catch { }
|
|
165
|
+
const redisUrl = process.env.REDIS_URL ?? "redis://localhost:6379";
|
|
166
|
+
const envFlags = `-e DATABASE_URL=${databaseUrl} -e NATS_URL=${natsUrl} -e REDIS_URL=${redisUrl}`;
|
|
167
|
+
execSync(`claude mcp add codify ${envFlags} -s user -- ${nodePath} ${codifyPath} start`, { stdio: "ignore" });
|
|
168
|
+
console.log(" ✓ MCP server registered via claude mcp add");
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
// Fallback: claude CLI not installed — write to ~/.claude.json
|
|
172
|
+
console.log(" claude CLI not found, writing config manually...");
|
|
173
|
+
const mcpServerConfig = {
|
|
174
|
+
command: nodePath,
|
|
175
|
+
args: [codifyPath, "start"],
|
|
176
|
+
cwd,
|
|
177
|
+
env: {
|
|
178
|
+
DATABASE_URL: databaseUrl,
|
|
179
|
+
NATS_URL: natsUrl,
|
|
180
|
+
REDIS_URL: "redis://localhost:6379",
|
|
181
|
+
},
|
|
182
|
+
};
|
|
183
|
+
const claudeJsonPath = resolve(homedir(), ".claude.json");
|
|
184
|
+
let config = {};
|
|
185
|
+
if (existsSync(claudeJsonPath)) {
|
|
186
|
+
try {
|
|
187
|
+
config = JSON.parse(readFileSync(claudeJsonPath, "utf-8"));
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
// corrupt file, start fresh
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (!config.mcpServers || typeof config.mcpServers !== "object") {
|
|
194
|
+
config.mcpServers = {};
|
|
195
|
+
}
|
|
196
|
+
config.mcpServers.codify = mcpServerConfig;
|
|
197
|
+
writeFileSync(claudeJsonPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
198
|
+
console.log(" ✓ MCP config written to ~/.claude.json");
|
|
199
|
+
}
|
|
200
|
+
// ── Done ───────────────────────────────────────────────────────
|
|
201
|
+
console.log("\n Ready! Next: codify bootstrap\n");
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
205
|
+
if (message.includes("ECONNREFUSED")) {
|
|
206
|
+
console.error("\n ERROR: Cannot connect to Codify services.");
|
|
207
|
+
console.error(" Make sure Docker is running and try again.\n");
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
console.error(`\n ERROR: ${message}\n`);
|
|
211
|
+
}
|
|
212
|
+
process.exit(1);
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/commands/project.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC,eAAO,MAAM,cAAc,SAQzB,CAAC"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
// codify project — multi-project management
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import { loadProjectConfig, readRawConfig, writeRawConfig, getProjectId, DEFAULT_PROJECT_ID } from "../lib/config.js";
|
|
4
|
+
// --- Color helpers (ANSI escape codes) ---
|
|
5
|
+
const RESET = "\x1b[0m";
|
|
6
|
+
const BOLD = "\x1b[1m";
|
|
7
|
+
const DIM = "\x1b[2m";
|
|
8
|
+
const CYAN = "\x1b[36m";
|
|
9
|
+
const GREEN = "\x1b[32m";
|
|
10
|
+
// --- Command definition ---
|
|
11
|
+
export const projectCommand = new Command("project")
|
|
12
|
+
.description("Manage projects (create, list, switch, current)")
|
|
13
|
+
.addHelpText("after", `
|
|
14
|
+
Examples:
|
|
15
|
+
codify project create alpha Create a new project and switch to it
|
|
16
|
+
codify project list List all projects with node counts
|
|
17
|
+
codify project switch default Switch to a different project
|
|
18
|
+
codify project current Show the active project
|
|
19
|
+
`);
|
|
20
|
+
// --- Subcommand: create ---
|
|
21
|
+
projectCommand
|
|
22
|
+
.command("create")
|
|
23
|
+
.argument("<name>", "Name for the new project")
|
|
24
|
+
.option("--description <desc>", "Optional project description")
|
|
25
|
+
.description("Create a new project and switch to it")
|
|
26
|
+
.action(async (name, opts) => {
|
|
27
|
+
try {
|
|
28
|
+
await loadProjectConfig();
|
|
29
|
+
const { getPool, closePool } = await import("@codify/graph");
|
|
30
|
+
const pool = getPool();
|
|
31
|
+
try {
|
|
32
|
+
await pool.query("SELECT 1");
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
console.error(" ERROR: Cannot connect to PostgreSQL. Run 'codify init' first.\n");
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
// Check if project already exists
|
|
39
|
+
const existing = await pool.query("SELECT id FROM projects WHERE name = $1", [name]);
|
|
40
|
+
if (existing.rows.length > 0) {
|
|
41
|
+
console.error(`\n ERROR: Project '${name}' already exists.\n`);
|
|
42
|
+
await closePool();
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
// Insert new project
|
|
46
|
+
const desc = opts.description ?? null;
|
|
47
|
+
const result = await pool.query("INSERT INTO projects (name, description) VALUES ($1, $2) RETURNING id", [name, desc]);
|
|
48
|
+
const projectId = result.rows[0].id;
|
|
49
|
+
// Switch to the new project
|
|
50
|
+
const config = readRawConfig() ?? {};
|
|
51
|
+
config.projectId = projectId;
|
|
52
|
+
config.projectName = name;
|
|
53
|
+
writeRawConfig(config);
|
|
54
|
+
console.log(`\n Created project '${CYAN}${name}${RESET}' and switched to it.`);
|
|
55
|
+
console.log(` ${DIM}id: ${projectId}${RESET}\n`);
|
|
56
|
+
await closePool();
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
60
|
+
if (message.includes("ECONNREFUSED")) {
|
|
61
|
+
console.error("\n ERROR: Cannot connect to Codify services.");
|
|
62
|
+
console.error(" Run 'codify init' to start the infrastructure.\n");
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
console.error(`\n ERROR: ${message}\n`);
|
|
66
|
+
}
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
// --- Subcommand: list ---
|
|
71
|
+
projectCommand
|
|
72
|
+
.command("list")
|
|
73
|
+
.description("List all projects with node counts")
|
|
74
|
+
.action(async () => {
|
|
75
|
+
try {
|
|
76
|
+
await loadProjectConfig();
|
|
77
|
+
const { getPool, closePool } = await import("@codify/graph");
|
|
78
|
+
const pool = getPool();
|
|
79
|
+
try {
|
|
80
|
+
await pool.query("SELECT 1");
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
console.error(" ERROR: Cannot connect to PostgreSQL. Run 'codify init' first.\n");
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
const activeId = getProjectId();
|
|
87
|
+
const result = await pool.query(`SELECT p.id, p.name, COUNT(n.id) AS node_count, p.created_at
|
|
88
|
+
FROM projects p
|
|
89
|
+
LEFT JOIN nodes n ON n.project_id = p.id AND n.superseded_by IS NULL
|
|
90
|
+
GROUP BY p.id, p.name, p.created_at
|
|
91
|
+
ORDER BY p.created_at ASC`);
|
|
92
|
+
console.log(`\n ${BOLD}Projects:${RESET}\n`);
|
|
93
|
+
for (const row of result.rows) {
|
|
94
|
+
const isActive = row.id === activeId;
|
|
95
|
+
const marker = isActive ? `${GREEN}*${RESET}` : " ";
|
|
96
|
+
const nameStr = isActive ? `${BOLD}${row.name}${RESET}` : row.name;
|
|
97
|
+
const count = parseInt(row.node_count, 10);
|
|
98
|
+
const date = new Date(row.created_at).toISOString().slice(0, 10);
|
|
99
|
+
const activeSuffix = isActive ? ` ${DIM}<- active${RESET}` : "";
|
|
100
|
+
console.log(` ${marker} ${nameStr.padEnd(isActive ? row.name.length + 8 : 20)} ${DIM}(${count} node${count === 1 ? "" : "s"}, created ${date})${RESET}${activeSuffix}`);
|
|
101
|
+
}
|
|
102
|
+
console.log("");
|
|
103
|
+
await closePool();
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
107
|
+
if (message.includes("ECONNREFUSED")) {
|
|
108
|
+
console.error("\n ERROR: Cannot connect to Codify services.");
|
|
109
|
+
console.error(" Run 'codify init' to start the infrastructure.\n");
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
console.error(`\n ERROR: ${message}\n`);
|
|
113
|
+
}
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
// --- Subcommand: switch ---
|
|
118
|
+
projectCommand
|
|
119
|
+
.command("switch")
|
|
120
|
+
.argument("<name>", "Name of the project to switch to")
|
|
121
|
+
.description("Switch to a different project")
|
|
122
|
+
.action(async (name) => {
|
|
123
|
+
try {
|
|
124
|
+
await loadProjectConfig();
|
|
125
|
+
const { getPool, closePool } = await import("@codify/graph");
|
|
126
|
+
const pool = getPool();
|
|
127
|
+
try {
|
|
128
|
+
await pool.query("SELECT 1");
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
console.error(" ERROR: Cannot connect to PostgreSQL. Run 'codify init' first.\n");
|
|
132
|
+
process.exit(1);
|
|
133
|
+
}
|
|
134
|
+
const result = await pool.query("SELECT id FROM projects WHERE name = $1", [name]);
|
|
135
|
+
if (result.rows.length === 0) {
|
|
136
|
+
console.error(`\n ERROR: Project '${name}' not found.`);
|
|
137
|
+
console.error(" Run 'codify project list' to see available projects.\n");
|
|
138
|
+
await closePool();
|
|
139
|
+
process.exit(1);
|
|
140
|
+
}
|
|
141
|
+
const projectId = result.rows[0].id;
|
|
142
|
+
const config = readRawConfig() ?? {};
|
|
143
|
+
config.projectId = projectId;
|
|
144
|
+
config.projectName = name;
|
|
145
|
+
writeRawConfig(config);
|
|
146
|
+
console.log(`\n Switched to project '${CYAN}${name}${RESET}'.\n`);
|
|
147
|
+
await closePool();
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
151
|
+
if (message.includes("ECONNREFUSED")) {
|
|
152
|
+
console.error("\n ERROR: Cannot connect to Codify services.");
|
|
153
|
+
console.error(" Run 'codify init' to start the infrastructure.\n");
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
console.error(`\n ERROR: ${message}\n`);
|
|
157
|
+
}
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
// --- Subcommand: current ---
|
|
162
|
+
projectCommand
|
|
163
|
+
.command("current")
|
|
164
|
+
.description("Show the active project")
|
|
165
|
+
.action(async () => {
|
|
166
|
+
try {
|
|
167
|
+
await loadProjectConfig();
|
|
168
|
+
const config = readRawConfig();
|
|
169
|
+
const projectId = config?.projectId ?? DEFAULT_PROJECT_ID;
|
|
170
|
+
const projectName = config?.projectName ?? "default";
|
|
171
|
+
console.log(`\n Active project: ${BOLD}${projectName}${RESET} ${DIM}(${projectId})${RESET}\n`);
|
|
172
|
+
}
|
|
173
|
+
catch (err) {
|
|
174
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
175
|
+
console.error(`\n ERROR: ${message}\n`);
|
|
176
|
+
process.exit(1);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
//# sourceMappingURL=project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/commands/project.ts"],"names":[],"mappings":"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"}
|