@codified/cli 0.3.5 → 0.3.7

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.
Files changed (106) hide show
  1. package/README.md +115 -0
  2. package/dist/commands/add.d.ts +3 -0
  3. package/dist/commands/add.d.ts.map +1 -0
  4. package/dist/commands/add.js +163 -0
  5. package/dist/commands/add.js.map +1 -0
  6. package/dist/commands/bootstrap.d.ts.map +1 -0
  7. package/dist/commands/bootstrap.js +141 -0
  8. package/dist/commands/bootstrap.js.map +1 -0
  9. package/dist/commands/check.d.ts +3 -0
  10. package/dist/commands/check.d.ts.map +1 -0
  11. package/dist/commands/check.js +332 -0
  12. package/dist/commands/check.js.map +1 -0
  13. package/dist/commands/cleanup.d.ts +3 -0
  14. package/dist/commands/cleanup.d.ts.map +1 -0
  15. package/dist/commands/cleanup.js +166 -0
  16. package/dist/commands/cleanup.js.map +1 -0
  17. package/dist/commands/collect.d.ts +26 -0
  18. package/dist/commands/collect.d.ts.map +1 -0
  19. package/dist/commands/collect.js +269 -0
  20. package/dist/commands/collect.js.map +1 -0
  21. package/dist/commands/connect.d.ts +3 -0
  22. package/dist/commands/connect.d.ts.map +1 -0
  23. package/dist/commands/connect.js +321 -0
  24. package/dist/commands/connect.js.map +1 -0
  25. package/dist/commands/explain.d.ts +3 -0
  26. package/dist/commands/explain.d.ts.map +1 -0
  27. package/dist/commands/explain.js +527 -0
  28. package/dist/commands/explain.js.map +1 -0
  29. package/dist/commands/export.d.ts +3 -0
  30. package/dist/commands/export.d.ts.map +1 -0
  31. package/dist/commands/export.js +59 -0
  32. package/dist/commands/export.js.map +1 -0
  33. package/dist/commands/gaps.d.ts +3 -0
  34. package/dist/commands/gaps.d.ts.map +1 -0
  35. package/dist/commands/gaps.js +315 -0
  36. package/dist/commands/gaps.js.map +1 -0
  37. package/dist/commands/graph.d.ts +3 -0
  38. package/dist/commands/graph.d.ts.map +1 -0
  39. package/dist/commands/graph.js +293 -0
  40. package/dist/commands/graph.js.map +1 -0
  41. package/dist/commands/import-cmd.d.ts +3 -0
  42. package/dist/commands/import-cmd.d.ts.map +1 -0
  43. package/dist/commands/import-cmd.js +199 -0
  44. package/dist/commands/import-cmd.js.map +1 -0
  45. package/dist/commands/init.d.ts.map +1 -0
  46. package/dist/commands/init.js +215 -0
  47. package/dist/commands/init.js.map +1 -0
  48. package/dist/commands/project.d.ts +3 -0
  49. package/dist/commands/project.d.ts.map +1 -0
  50. package/dist/commands/project.js +179 -0
  51. package/dist/commands/project.js.map +1 -0
  52. package/dist/commands/reset.d.ts +3 -0
  53. package/dist/commands/reset.d.ts.map +1 -0
  54. package/dist/commands/reset.js +157 -0
  55. package/dist/commands/reset.js.map +1 -0
  56. package/dist/commands/search.d.ts +3 -0
  57. package/dist/commands/search.d.ts.map +1 -0
  58. package/dist/commands/search.js +183 -0
  59. package/dist/commands/search.js.map +1 -0
  60. package/dist/commands/start.d.ts.map +1 -0
  61. package/dist/commands/start.js +205 -0
  62. package/dist/commands/start.js.map +1 -0
  63. package/dist/commands/status.d.ts.map +1 -0
  64. package/dist/commands/status.js +242 -0
  65. package/dist/commands/status.js.map +1 -0
  66. package/dist/commands/timeline.d.ts +3 -0
  67. package/dist/commands/timeline.d.ts.map +1 -0
  68. package/dist/commands/timeline.js +424 -0
  69. package/dist/commands/timeline.js.map +1 -0
  70. package/dist/commands/triage.d.ts +3 -0
  71. package/dist/commands/triage.d.ts.map +1 -0
  72. package/dist/commands/triage.js +336 -0
  73. package/dist/commands/triage.js.map +1 -0
  74. package/dist/commands/up.d.ts +3 -0
  75. package/dist/commands/up.d.ts.map +1 -0
  76. package/dist/commands/up.js +312 -0
  77. package/dist/commands/up.js.map +1 -0
  78. package/dist/commands/watch.d.ts +3 -0
  79. package/dist/commands/watch.d.ts.map +1 -0
  80. package/dist/commands/watch.js +224 -0
  81. package/dist/commands/watch.js.map +1 -0
  82. package/dist/index.d.ts +2 -0
  83. package/dist/index.d.ts.map +1 -0
  84. package/dist/index.js +636 -506
  85. package/dist/index.js.map +1 -0
  86. package/dist/lib/config.d.ts +52 -0
  87. package/dist/lib/config.d.ts.map +1 -0
  88. package/dist/lib/config.js +142 -0
  89. package/dist/lib/config.js.map +1 -0
  90. package/dist/lib/docker.d.ts +23 -0
  91. package/dist/lib/docker.d.ts.map +1 -0
  92. package/dist/lib/docker.js +84 -0
  93. package/dist/lib/docker.js.map +1 -0
  94. package/dist/lib/migrate.d.ts +9 -0
  95. package/dist/lib/migrate.d.ts.map +1 -0
  96. package/dist/lib/migrate.js +97 -0
  97. package/dist/lib/migrate.js.map +1 -0
  98. package/dist/lib/paths.d.ts +9 -0
  99. package/dist/lib/paths.d.ts.map +1 -0
  100. package/dist/lib/paths.js +28 -0
  101. package/dist/lib/paths.js.map +1 -0
  102. package/dist/lib/prompt.d.ts +14 -0
  103. package/dist/lib/prompt.d.ts.map +1 -0
  104. package/dist/lib/prompt.js +87 -0
  105. package/dist/lib/prompt.js.map +1 -0
  106. package/package.json +4 -2
@@ -0,0 +1,269 @@
1
+ // codify collect — mine the graph for evidence that addresses gaps
2
+ import { Command } from "commander";
3
+ import { loadProjectConfig } 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 RED = "\x1b[31m";
9
+ const GREEN = "\x1b[32m";
10
+ const YELLOW = "\x1b[33m";
11
+ const CYAN = "\x1b[36m";
12
+ const MAGENTA = "\x1b[35m";
13
+ const WHITE = "\x1b[37m";
14
+ function typeColor(type) {
15
+ const colors = {
16
+ Decision: "\x1b[33m", // yellow
17
+ Feature: "\x1b[32m", // green
18
+ Metric: "\x1b[36m", // cyan
19
+ CustomerSignal: "\x1b[35m", // magenta
20
+ CodeArtifact: "\x1b[34m", // blue
21
+ Discussion: "\x1b[37m", // white
22
+ Gap: "\x1b[31m", // red
23
+ Study: "\x1b[36m", // cyan
24
+ Person: "\x1b[33m", // yellow
25
+ };
26
+ return `${colors[type] ?? DIM}${type}${RESET}`;
27
+ }
28
+ function truncate(str, maxLen) {
29
+ if (str.length <= maxLen)
30
+ return str;
31
+ return str.slice(0, maxLen - 3) + "...";
32
+ }
33
+ /**
34
+ * Extract keywords from a title string.
35
+ * Splits on whitespace, filters out words <= 2 chars and common stop words.
36
+ */
37
+ function extractKeywords(title) {
38
+ const stopWords = new Set([
39
+ "the", "and", "for", "with", "that", "this", "from", "are", "was", "were",
40
+ "has", "had", "have", "not", "but", "can", "will", "been", "its", "all",
41
+ "use", "used", "using", "into", "about", "over", "also", "does", "did",
42
+ ]);
43
+ return title
44
+ .split(/\s+/)
45
+ .map((w) => w.replace(/[^a-zA-Z0-9_-]/g, ""))
46
+ .filter((w) => w.length > 2 && !stopWords.has(w.toLowerCase()));
47
+ }
48
+ /**
49
+ * Core graph-mining logic: search for evidence nodes relevant to an affected node,
50
+ * create evidence_for edges, and return results.
51
+ *
52
+ * Exported so triage.ts can reuse it inline.
53
+ */
54
+ export async function collectEvidenceForGap(pool, gapId, affectedNodes) {
55
+ const evidenceNodes = [];
56
+ let edgesCreated = 0;
57
+ // Collect IDs already connected to the gap (to exclude them from results)
58
+ const connectedResult = await pool.query(`SELECT DISTINCT CASE
59
+ WHEN e.source_id = $1 THEN e.target_id
60
+ ELSE e.source_id
61
+ END as id
62
+ FROM edges e
63
+ WHERE e.source_id = $1 OR e.target_id = $1`, [gapId]);
64
+ const connectedIds = new Set(connectedResult.rows.map((r) => r.id));
65
+ connectedIds.add(gapId); // also exclude the gap itself
66
+ for (const affected of affectedNodes) {
67
+ const keywords = extractKeywords(affected.title);
68
+ if (keywords.length === 0)
69
+ continue;
70
+ // Build ILIKE conditions — AND keywords together for relevance
71
+ const conditions = [
72
+ "superseded_by IS NULL",
73
+ "layer = ANY($1)",
74
+ "type != 'Gap'",
75
+ ];
76
+ const params = [["permanent", "draft"]];
77
+ let paramIdx = 2;
78
+ const keywordConditions = keywords.map((kw) => {
79
+ params.push(`%${kw}%`);
80
+ const idx = paramIdx++;
81
+ return `(properties::text ILIKE $${idx} OR metadata::text ILIKE $${idx})`;
82
+ });
83
+ conditions.push(`(${keywordConditions.join(" AND ")})`);
84
+ // Exclude nodes already connected to the gap
85
+ const excludeIds = Array.from(connectedIds);
86
+ if (excludeIds.length > 0) {
87
+ conditions.push(`id != ALL($${paramIdx++})`);
88
+ params.push(excludeIds);
89
+ }
90
+ params.push(10); // limit
91
+ const sql = `SELECT id, type, properties, metadata
92
+ FROM nodes
93
+ WHERE ${conditions.join(" AND ")}
94
+ ORDER BY freshness DESC
95
+ LIMIT $${paramIdx}`;
96
+ const result = await pool.query(sql, params);
97
+ for (const node of result.rows) {
98
+ const props = node.properties ?? {};
99
+ const meta = node.metadata ?? {};
100
+ const title = props.title ?? meta.title ??
101
+ props.name ?? meta.name ?? node.id.slice(0, 12);
102
+ evidenceNodes.push({
103
+ id: node.id,
104
+ type: node.type,
105
+ title,
106
+ targetNodeId: affected.id,
107
+ });
108
+ // Create evidence_for edge: found node -> affected node
109
+ try {
110
+ await pool.query(`INSERT INTO edges (id, type, source_id, target_id, confidence, weight, properties, created_at)
111
+ VALUES (gen_random_uuid(), 'evidence_for', $1, $2, 0.7, 0.5, '{"source": "graph-mining"}', now())
112
+ ON CONFLICT DO NOTHING`, [node.id, affected.id]);
113
+ edgesCreated++;
114
+ }
115
+ catch {
116
+ // Edge already exists or constraint violation — skip
117
+ }
118
+ // Track this node so we don't link it again for another affected node of the same gap
119
+ connectedIds.add(node.id);
120
+ }
121
+ }
122
+ return { evidenceNodes, edgesCreated };
123
+ }
124
+ // --- Command definition ---
125
+ export const collectCommand = new Command("collect")
126
+ .description("Mine the graph for evidence that addresses gaps")
127
+ .option("--gap <gapId>", "Collect evidence for a specific gap ID")
128
+ .option("--limit <n>", "Number of gaps to process (default: 5)", "5")
129
+ .action(async (opts) => {
130
+ try {
131
+ await loadProjectConfig();
132
+ const { getPool, closePool } = await import("@codify/graph");
133
+ const pool = getPool();
134
+ try {
135
+ await pool.query("SELECT 1");
136
+ }
137
+ catch {
138
+ console.error(" ERROR: Cannot connect to PostgreSQL. Run 'codify init' first.\n");
139
+ process.exit(1);
140
+ }
141
+ // Determine which gaps to process
142
+ let gapsSql;
143
+ let gapsParams;
144
+ if (opts.gap) {
145
+ // Specific gap
146
+ gapsSql = `SELECT id, properties, metadata
147
+ FROM nodes
148
+ WHERE id = $1 AND type = 'Gap' AND superseded_by IS NULL`;
149
+ gapsParams = [opts.gap];
150
+ }
151
+ else {
152
+ // Top N unresolved gaps by severity, then freshness
153
+ const limit = parseInt(opts.limit, 10);
154
+ if (isNaN(limit) || limit < 1) {
155
+ console.error("\n ERROR: --limit must be a positive integer.\n");
156
+ process.exit(1);
157
+ }
158
+ gapsSql = `SELECT id, properties, metadata
159
+ FROM nodes
160
+ WHERE type = 'Gap'
161
+ AND superseded_by IS NULL
162
+ AND COALESCE(properties->>'status', 'detected') NOT IN ('resolved', 'wont_fix')
163
+ ORDER BY
164
+ CASE properties->>'severity'
165
+ WHEN 'critical' THEN 0
166
+ WHEN 'high' THEN 1
167
+ WHEN 'medium' THEN 2
168
+ WHEN 'low' THEN 3
169
+ ELSE 4
170
+ END ASC,
171
+ freshness DESC
172
+ LIMIT $1`;
173
+ gapsParams = [limit];
174
+ }
175
+ const gapsResult = await pool.query(gapsSql, gapsParams);
176
+ const gaps = gapsResult.rows;
177
+ console.log(`\n ${BOLD}Codify — Collect Evidence for Gaps${RESET}\n`);
178
+ if (gaps.length === 0) {
179
+ if (opts.gap) {
180
+ console.error(` ERROR: Gap "${opts.gap}" not found or already resolved.\n`);
181
+ }
182
+ else {
183
+ console.log(" No unresolved gaps found. Nothing to collect.\n");
184
+ }
185
+ await closePool();
186
+ return;
187
+ }
188
+ let totalEdgesCreated = 0;
189
+ let gapsWithEvidence = 0;
190
+ for (const gap of gaps) {
191
+ const props = gap.properties ?? {};
192
+ const title = props.title ?? props.description?.slice(0, 60) ?? "(untitled)";
193
+ const description = props.description ?? "";
194
+ // Get affected nodes for this gap
195
+ const affectedResult = await pool.query(`SELECT n.id, n.type, n.properties, n.metadata
196
+ FROM nodes n
197
+ JOIN edges e ON (e.source_id = n.id OR e.target_id = n.id)
198
+ WHERE (e.source_id = $1 OR e.target_id = $1)
199
+ AND n.id != $1
200
+ AND n.superseded_by IS NULL
201
+ GROUP BY n.id, n.type, n.properties, n.metadata`, [gap.id]);
202
+ const affectedNodes = affectedResult.rows.map((r) => {
203
+ const p = r.properties ?? {};
204
+ const m = r.metadata ?? {};
205
+ return {
206
+ id: r.id,
207
+ type: r.type,
208
+ title: p.title ?? m.title ??
209
+ p.name ?? m.name ?? "(untitled)",
210
+ };
211
+ });
212
+ // Print gap header
213
+ const affectedDesc = affectedNodes.length > 0
214
+ ? affectedNodes.map((n) => `${n.type} "${truncate(n.title, 40)}"`).join(", ")
215
+ : "no affected nodes";
216
+ console.log(` ${YELLOW}Gap:${RESET} ${BOLD}${title}${RESET}`);
217
+ if (description) {
218
+ console.log(` ${DIM}${truncate(description, 80)}${RESET}`);
219
+ }
220
+ console.log(` ${DIM}Affected: ${affectedDesc}${RESET}`);
221
+ console.log(` Searching graph for evidence...`);
222
+ if (affectedNodes.length === 0) {
223
+ console.log(` ${DIM}No affected nodes to search for.${RESET}\n`);
224
+ continue;
225
+ }
226
+ // Run the graph mining
227
+ const { evidenceNodes, edgesCreated } = await collectEvidenceForGap(pool, gap.id, affectedNodes);
228
+ if (evidenceNodes.length > 0) {
229
+ console.log(` ${GREEN}Found ${evidenceNodes.length} relevant node${evidenceNodes.length === 1 ? "" : "s"}:${RESET}`);
230
+ for (const ev of evidenceNodes) {
231
+ console.log(` ${GREEN}+${RESET} ${typeColor(ev.type)}: ${WHITE}"${truncate(ev.title, 60)}"${RESET}`);
232
+ }
233
+ console.log(` Created ${edgesCreated} evidence edge${edgesCreated === 1 ? "" : "s"}.`);
234
+ // Update gap status to evidence_found
235
+ await pool.query(`UPDATE nodes
236
+ SET properties = jsonb_set(properties, '{status}', '"evidence_found"'),
237
+ updated_at = now()
238
+ WHERE id = $1
239
+ AND COALESCE(properties->>'status', 'detected') = 'detected'`, [gap.id]);
240
+ totalEdgesCreated += edgesCreated;
241
+ gapsWithEvidence++;
242
+ }
243
+ else {
244
+ console.log(` ${DIM}No new evidence found.${RESET}`);
245
+ }
246
+ console.log("");
247
+ }
248
+ // Summary
249
+ console.log(` ${BOLD}Summary:${RESET} ${totalEdgesCreated} evidence edge${totalEdgesCreated === 1 ? "" : "s"} created for ${gapsWithEvidence} of ${gaps.length} gap${gaps.length === 1 ? "" : "s"}.`);
250
+ console.log("");
251
+ await closePool();
252
+ }
253
+ catch (err) {
254
+ const message = err instanceof Error ? err.message : String(err);
255
+ if (message.includes("ECONNREFUSED")) {
256
+ console.error("\n ERROR: Cannot connect to Codify services.");
257
+ console.error(" Run 'codify init' to start the infrastructure.\n");
258
+ }
259
+ else if (message.includes("ANTHROPIC_API_KEY")) {
260
+ console.error("\n ERROR: ANTHROPIC_API_KEY not set.");
261
+ console.error(" Export your API key: export ANTHROPIC_API_KEY=sk-...\n");
262
+ }
263
+ else {
264
+ console.error(`\n ERROR: ${message}\n`);
265
+ }
266
+ process.exit(1);
267
+ }
268
+ });
269
+ //# sourceMappingURL=collect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collect.js","sourceRoot":"","sources":["../../src/commands/collect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const connectCommand: Command;
3
+ //# sourceMappingURL=connect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/commands/connect.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuWpC,eAAO,MAAM,cAAc,SAOI,CAAC"}
@@ -0,0 +1,321 @@
1
+ // codify connect — manage external data source connections
2
+ //
3
+ // Subcommands:
4
+ // codify connect slack --token xoxb-... --channels C01234,C05678
5
+ // codify connect github --token ghp-... --repos owner/repo1,owner/repo2
6
+ // codify connect linear --api-key lin_... --team TEAM
7
+ // codify connect notion --token ntn_... --databases db_id1,db_id2
8
+ // codify connect list — show all connected sources with last sync time
9
+ // codify connect remove <id> — disconnect a source
10
+ import { Command } from "commander";
11
+ import { existsSync, readFileSync } from "node:fs";
12
+ import { resolve } from "node:path";
13
+ import { loadProjectConfig, loadConnectors, addConnector, removeConnector, } from "../lib/config.js";
14
+ // ── Security warning ──────────────────────────────────────────────────
15
+ function printCredentialWarning() {
16
+ console.log(" \x1b[33mWARN: Token stored in .codify/config.json (plaintext).\x1b[0m");
17
+ // Check if .codify is gitignored
18
+ const gitignorePath = resolve(process.cwd(), ".gitignore");
19
+ let isGitignored = false;
20
+ try {
21
+ if (existsSync(gitignorePath)) {
22
+ const content = readFileSync(gitignorePath, "utf-8");
23
+ isGitignored = content.split("\n").some((line) => line.trim() === ".codify" || line.trim() === ".codify/" || line.trim() === ".codify/*");
24
+ }
25
+ }
26
+ catch { /* ignore */ }
27
+ if (!isGitignored) {
28
+ console.log(" \x1b[33mWARN: .codify/ is NOT in .gitignore. Add it to prevent credential leaks.\x1b[0m");
29
+ }
30
+ }
31
+ // ── Validation helpers ────────────────────────────────────────────────
32
+ function validateToken(token, prefix, name) {
33
+ if (!token) {
34
+ console.error(`\n ERROR: --token is required for ${name}.\n`);
35
+ process.exit(1);
36
+ }
37
+ if (prefix && !token.startsWith(prefix)) {
38
+ console.error(`\n ERROR: ${name} token should start with "${prefix}".\n`);
39
+ process.exit(1);
40
+ }
41
+ }
42
+ function parseCommaSeparated(value, flag) {
43
+ if (!value) {
44
+ console.error(`\n ERROR: ${flag} is required.\n`);
45
+ process.exit(1);
46
+ }
47
+ return value.split(",").map((s) => s.trim()).filter(Boolean);
48
+ }
49
+ /**
50
+ * Verify a connector by authenticating with the real service.
51
+ * Uses the same connector implementations from @codify/agents.
52
+ */
53
+ async function verifyConnector(type, credentials) {
54
+ await loadProjectConfig();
55
+ const { getPool } = await import("@codify/graph");
56
+ const pool = getPool();
57
+ try {
58
+ await pool.query("SELECT 1");
59
+ }
60
+ catch {
61
+ console.error(" ERROR: Cannot connect to PostgreSQL. Run 'codify init' first.\n");
62
+ process.exit(1);
63
+ }
64
+ const { createIngestService } = await import("@codify/agents");
65
+ const ingest = await createIngestService({
66
+ minerBatchSize: 10,
67
+ enableDedup: true,
68
+ autoPromoteThreshold: 0.7,
69
+ });
70
+ // Build the auth config that the connector expects
71
+ const authConfig = { type };
72
+ switch (type) {
73
+ case "slack": {
74
+ authConfig.token = credentials.token;
75
+ authConfig.credentials = {
76
+ token: credentials.token,
77
+ channels: credentials.channels.join(","),
78
+ };
79
+ break;
80
+ }
81
+ case "github": {
82
+ const repos = credentials.repos;
83
+ // Verify each repo — connect the first one for validation
84
+ const [first] = repos;
85
+ const [owner, repo] = first.split("/");
86
+ authConfig.token = credentials.token;
87
+ authConfig.credentials = { owner, repo };
88
+ break;
89
+ }
90
+ case "linear": {
91
+ authConfig.token = credentials.apiKey;
92
+ const linearCreds = {
93
+ token: credentials.apiKey,
94
+ };
95
+ if (credentials.team) {
96
+ linearCreds.teams = String(credentials.team);
97
+ }
98
+ authConfig.credentials = linearCreds;
99
+ break;
100
+ }
101
+ case "notion": {
102
+ authConfig.token = credentials.token;
103
+ authConfig.credentials = {
104
+ token: credentials.token,
105
+ };
106
+ break;
107
+ }
108
+ }
109
+ // This calls the real API to authenticate
110
+ await ingest.registry.connect(type, authConfig);
111
+ }
112
+ // ── Subcommand: slack ─────────────────────────────────────────────────
113
+ const slackSubcommand = new Command("slack")
114
+ .description("Connect a Slack workspace")
115
+ .requiredOption("--token <token>", "Slack Bot OAuth token (xoxb-...)")
116
+ .requiredOption("--channels <ids>", "Comma-separated channel IDs (e.g., C01234,C05678)")
117
+ .action(async (opts) => {
118
+ try {
119
+ console.log("\n Codify Connect — Slack\n");
120
+ validateToken(opts.token, "xoxb-", "Slack");
121
+ const channels = parseCommaSeparated(opts.channels, "--channels");
122
+ console.log(` Verifying Slack token and channel access...`);
123
+ await verifyConnector("slack", { token: opts.token, channels });
124
+ const entry = addConnector({
125
+ type: "slack",
126
+ credentials: { token: opts.token, channels },
127
+ });
128
+ console.log(`\n Connected! ID: ${entry.id}`);
129
+ console.log(` Channels: ${channels.join(", ")}`);
130
+ printCredentialWarning();
131
+ console.log(`\n Run 'codify watch' to start syncing Slack messages.\n`);
132
+ }
133
+ catch (err) {
134
+ const message = err instanceof Error ? err.message : String(err);
135
+ console.error(`\n ERROR: ${message}\n`);
136
+ process.exit(1);
137
+ }
138
+ });
139
+ // ── Subcommand: github ────────────────────────────────────────────────
140
+ const githubSubcommand = new Command("github")
141
+ .description("Connect GitHub repositories")
142
+ .requiredOption("--token <token>", "GitHub personal access token (ghp_...)")
143
+ .requiredOption("--repos <repos>", "Comma-separated repos (e.g., owner/repo1,owner/repo2)")
144
+ .action(async (opts) => {
145
+ try {
146
+ console.log("\n Codify Connect — GitHub\n");
147
+ validateToken(opts.token, "ghp_", "GitHub");
148
+ const repos = parseCommaSeparated(opts.repos, "--repos");
149
+ // Validate repo format
150
+ for (const repo of repos) {
151
+ if (!repo.includes("/")) {
152
+ console.error(`\n ERROR: Invalid repo format "${repo}". Expected owner/repo.\n`);
153
+ process.exit(1);
154
+ }
155
+ }
156
+ console.log(` Verifying GitHub token and repo access...`);
157
+ await verifyConnector("github", { token: opts.token, repos });
158
+ const entry = addConnector({
159
+ type: "github",
160
+ credentials: { token: opts.token, repos },
161
+ });
162
+ console.log(`\n Connected! ID: ${entry.id}`);
163
+ console.log(` Repos: ${repos.join(", ")}`);
164
+ printCredentialWarning();
165
+ console.log(`\n Run 'codify watch' to start syncing GitHub data.\n`);
166
+ }
167
+ catch (err) {
168
+ const message = err instanceof Error ? err.message : String(err);
169
+ console.error(`\n ERROR: ${message}\n`);
170
+ process.exit(1);
171
+ }
172
+ });
173
+ // ── Subcommand: linear ────────────────────────────────────────────────
174
+ const linearSubcommand = new Command("linear")
175
+ .description("Connect a Linear workspace")
176
+ .requiredOption("--api-key <key>", "Linear Personal API key (lin_api_...)")
177
+ .option("--team <team>", "Linear team key to filter (e.g., ENG)")
178
+ .action(async (opts) => {
179
+ try {
180
+ console.log("\n Codify Connect — Linear\n");
181
+ if (!opts.apiKey) {
182
+ console.error("\n ERROR: --api-key is required for Linear.\n");
183
+ process.exit(1);
184
+ }
185
+ const credentials = { apiKey: opts.apiKey };
186
+ if (opts.team) {
187
+ credentials.team = opts.team;
188
+ }
189
+ console.log(` Verifying Linear API key...`);
190
+ await verifyConnector("linear", credentials);
191
+ const entry = addConnector({
192
+ type: "linear",
193
+ credentials,
194
+ });
195
+ console.log(`\n Connected! ID: ${entry.id}`);
196
+ if (opts.team) {
197
+ console.log(` Team: ${opts.team}`);
198
+ }
199
+ printCredentialWarning();
200
+ console.log(`\n Run 'codify watch' to start syncing Linear data.\n`);
201
+ }
202
+ catch (err) {
203
+ const message = err instanceof Error ? err.message : String(err);
204
+ console.error(`\n ERROR: ${message}\n`);
205
+ process.exit(1);
206
+ }
207
+ });
208
+ // ── Subcommand: notion ────────────────────────────────────────────────
209
+ const notionSubcommand = new Command("notion")
210
+ .description("Connect a Notion workspace")
211
+ .requiredOption("--token <token>", "Notion Internal Integration Token (ntn_...)")
212
+ .option("--databases <ids>", "Comma-separated database IDs to scope (optional)")
213
+ .action(async (opts) => {
214
+ try {
215
+ console.log("\n Codify Connect — Notion\n");
216
+ validateToken(opts.token, "ntn_", "Notion");
217
+ const credentials = { token: opts.token };
218
+ if (opts.databases) {
219
+ const databases = parseCommaSeparated(opts.databases, "--databases");
220
+ credentials.databases = databases;
221
+ }
222
+ console.log(` Verifying Notion token...`);
223
+ await verifyConnector("notion", credentials);
224
+ const entry = addConnector({
225
+ type: "notion",
226
+ credentials,
227
+ });
228
+ console.log(`\n Connected! ID: ${entry.id}`);
229
+ if (credentials.databases) {
230
+ console.log(` Databases: ${credentials.databases.join(", ")}`);
231
+ }
232
+ printCredentialWarning();
233
+ console.log(`\n Run 'codify watch' to start syncing Notion pages.\n`);
234
+ }
235
+ catch (err) {
236
+ const message = err instanceof Error ? err.message : String(err);
237
+ console.error(`\n ERROR: ${message}\n`);
238
+ process.exit(1);
239
+ }
240
+ });
241
+ // ── Subcommand: list ──────────────────────────────────────────────────
242
+ const listSubcommand = new Command("list")
243
+ .description("Show all connected data sources")
244
+ .action(() => {
245
+ const connectors = loadConnectors();
246
+ console.log("\n Codify — Connected Sources\n");
247
+ if (connectors.length === 0) {
248
+ console.log(" No connectors configured.");
249
+ console.log("\n Add one with:");
250
+ console.log(" codify connect slack --token xoxb-... --channels C01234");
251
+ console.log(" codify connect github --token ghp-... --repos owner/repo");
252
+ console.log(" codify connect linear --api-key lin_api_... --team ENG");
253
+ console.log(" codify connect notion --token ntn_... --databases db_id\n");
254
+ return;
255
+ }
256
+ for (const c of connectors) {
257
+ const syncDisplay = c.lastSyncAt
258
+ ? new Date(c.lastSyncAt).toLocaleString()
259
+ : "never";
260
+ const scope = formatScope(c);
261
+ console.log(` ${c.id}`);
262
+ console.log(` Type: ${c.type}`);
263
+ console.log(` Scope: ${scope}`);
264
+ console.log(` Added: ${new Date(c.addedAt).toLocaleString()}`);
265
+ console.log(` Last sync: ${syncDisplay}`);
266
+ console.log("");
267
+ }
268
+ console.log(` Total: ${connectors.length} connector${connectors.length === 1 ? "" : "s"}`);
269
+ console.log(`\n Remove with: codify connect remove <id>\n`);
270
+ });
271
+ /**
272
+ * Format the scope/target of a connector for display.
273
+ */
274
+ function formatScope(entry) {
275
+ switch (entry.type) {
276
+ case "slack": {
277
+ const channels = entry.credentials.channels;
278
+ return Array.isArray(channels) ? channels.join(", ") : String(channels);
279
+ }
280
+ case "github": {
281
+ const repos = entry.credentials.repos;
282
+ return Array.isArray(repos) ? repos.join(", ") : String(repos);
283
+ }
284
+ case "linear": {
285
+ const team = entry.credentials.team;
286
+ return team ? String(team) : "all teams";
287
+ }
288
+ case "notion": {
289
+ const dbs = entry.credentials.databases;
290
+ if (dbs && Array.isArray(dbs) && dbs.length > 0)
291
+ return dbs.join(", ");
292
+ return "all accessible pages";
293
+ }
294
+ default:
295
+ return "unknown";
296
+ }
297
+ }
298
+ // ── Subcommand: remove ────────────────────────────────────────────────
299
+ const removeSubcommand = new Command("remove")
300
+ .description("Disconnect a data source")
301
+ .argument("<id>", "Connector ID (from 'codify connect list')")
302
+ .action((id) => {
303
+ const removed = removeConnector(id);
304
+ if (!removed) {
305
+ console.error(`\n ERROR: Connector "${id}" not found.`);
306
+ console.error(" Run 'codify connect list' to see available connectors.\n");
307
+ process.exit(1);
308
+ }
309
+ console.log(`\n Disconnected: ${removed.id} (${removed.type})`);
310
+ console.log(` Credentials removed from .codify/config.json\n`);
311
+ });
312
+ // ── Main connect command ──────────────────────────────────────────────
313
+ export const connectCommand = new Command("connect")
314
+ .description("Connect external data sources (Slack, GitHub, Linear, Notion)")
315
+ .addCommand(slackSubcommand)
316
+ .addCommand(githubSubcommand)
317
+ .addCommand(linearSubcommand)
318
+ .addCommand(notionSubcommand)
319
+ .addCommand(listSubcommand)
320
+ .addCommand(removeSubcommand);
321
+ //# sourceMappingURL=connect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect.js","sourceRoot":"","sources":["../../src/commands/connect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const explainCommand: Command;
3
+ //# sourceMappingURL=explain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explain.d.ts","sourceRoot":"","sources":["../../src/commands/explain.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkHpC,eAAO,MAAM,cAAc,SAwevB,CAAC"}