project-context-ai 1.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.
Files changed (93) hide show
  1. package/dist/cli.d.ts +3 -0
  2. package/dist/cli.d.ts.map +1 -0
  3. package/dist/cli.js +313 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/context/hasher.d.ts +7 -0
  6. package/dist/context/hasher.d.ts.map +1 -0
  7. package/dist/context/hasher.js +44 -0
  8. package/dist/context/hasher.js.map +1 -0
  9. package/dist/context/store.d.ts +7 -0
  10. package/dist/context/store.d.ts.map +1 -0
  11. package/dist/context/store.js +62 -0
  12. package/dist/context/store.js.map +1 -0
  13. package/dist/detect-ide.d.ts +9 -0
  14. package/dist/detect-ide.d.ts.map +1 -0
  15. package/dist/detect-ide.js +83 -0
  16. package/dist/detect-ide.js.map +1 -0
  17. package/dist/generators/claude.d.ts +3 -0
  18. package/dist/generators/claude.d.ts.map +1 -0
  19. package/dist/generators/claude.js +32 -0
  20. package/dist/generators/claude.js.map +1 -0
  21. package/dist/generators/codex.d.ts +3 -0
  22. package/dist/generators/codex.d.ts.map +1 -0
  23. package/dist/generators/codex.js +39 -0
  24. package/dist/generators/codex.js.map +1 -0
  25. package/dist/generators/copilot.d.ts +3 -0
  26. package/dist/generators/copilot.d.ts.map +1 -0
  27. package/dist/generators/copilot.js +32 -0
  28. package/dist/generators/copilot.js.map +1 -0
  29. package/dist/generators/cursor.d.ts +3 -0
  30. package/dist/generators/cursor.d.ts.map +1 -0
  31. package/dist/generators/cursor.js +39 -0
  32. package/dist/generators/cursor.js.map +1 -0
  33. package/dist/generators/gemini.d.ts +3 -0
  34. package/dist/generators/gemini.d.ts.map +1 -0
  35. package/dist/generators/gemini.js +32 -0
  36. package/dist/generators/gemini.js.map +1 -0
  37. package/dist/generators/index.d.ts +5 -0
  38. package/dist/generators/index.d.ts.map +1 -0
  39. package/dist/generators/index.js +40 -0
  40. package/dist/generators/index.js.map +1 -0
  41. package/dist/generators/template.d.ts +9 -0
  42. package/dist/generators/template.d.ts.map +1 -0
  43. package/dist/generators/template.js +128 -0
  44. package/dist/generators/template.js.map +1 -0
  45. package/dist/generators/windsurf.d.ts +3 -0
  46. package/dist/generators/windsurf.d.ts.map +1 -0
  47. package/dist/generators/windsurf.js +32 -0
  48. package/dist/generators/windsurf.js.map +1 -0
  49. package/dist/git/diff.d.ts +6 -0
  50. package/dist/git/diff.d.ts.map +1 -0
  51. package/dist/git/diff.js +73 -0
  52. package/dist/git/diff.js.map +1 -0
  53. package/dist/git/hooks.d.ts +9 -0
  54. package/dist/git/hooks.d.ts.map +1 -0
  55. package/dist/git/hooks.js +70 -0
  56. package/dist/git/hooks.js.map +1 -0
  57. package/dist/index.d.ts +9 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +8 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/scanner/conventions.d.ts +3 -0
  62. package/dist/scanner/conventions.d.ts.map +1 -0
  63. package/dist/scanner/conventions.js +132 -0
  64. package/dist/scanner/conventions.js.map +1 -0
  65. package/dist/scanner/dependencies.d.ts +3 -0
  66. package/dist/scanner/dependencies.d.ts.map +1 -0
  67. package/dist/scanner/dependencies.js +219 -0
  68. package/dist/scanner/dependencies.js.map +1 -0
  69. package/dist/scanner/frameworks.d.ts +3 -0
  70. package/dist/scanner/frameworks.d.ts.map +1 -0
  71. package/dist/scanner/frameworks.js +86 -0
  72. package/dist/scanner/frameworks.js.map +1 -0
  73. package/dist/scanner/index.d.ts +3 -0
  74. package/dist/scanner/index.d.ts.map +1 -0
  75. package/dist/scanner/index.js +126 -0
  76. package/dist/scanner/index.js.map +1 -0
  77. package/dist/scanner/structure.d.ts +7 -0
  78. package/dist/scanner/structure.d.ts.map +1 -0
  79. package/dist/scanner/structure.js +153 -0
  80. package/dist/scanner/structure.js.map +1 -0
  81. package/dist/types.d.ts +72 -0
  82. package/dist/types.d.ts.map +1 -0
  83. package/dist/types.js +2 -0
  84. package/dist/types.js.map +1 -0
  85. package/dist/utils/files.d.ts +12 -0
  86. package/dist/utils/files.d.ts.map +1 -0
  87. package/dist/utils/files.js +107 -0
  88. package/dist/utils/files.js.map +1 -0
  89. package/dist/utils/logger.d.ts +9 -0
  90. package/dist/utils/logger.d.ts.map +1 -0
  91. package/dist/utils/logger.js +10 -0
  92. package/dist/utils/logger.js.map +1 -0
  93. package/package.json +48 -0
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,313 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import chalk from "chalk";
4
+ import ora from "ora";
5
+ import { resolve } from "node:path";
6
+ import { createInterface } from "node:readline";
7
+ import { scanProject } from "./scanner/index.js";
8
+ import { loadCache, saveCache } from "./context/store.js";
9
+ import { computeFileHashes, getChangedFiles } from "./context/hasher.js";
10
+ import { generateAll, GENERATOR_TARGETS } from "./generators/index.js";
11
+ import { isGitRepo, getCurrentCommitHash, getChangedFilesSinceCommit, getUntrackedFiles, } from "./git/diff.js";
12
+ import { installHook, uninstallHook } from "./git/hooks.js";
13
+ import { detectIDE, getTargetLabel } from "./detect-ide.js";
14
+ import { logger } from "./utils/logger.js";
15
+ const program = new Command();
16
+ program
17
+ .name("project-context-ai")
18
+ .description("Automatically maps your project and generates AI context files for Claude, Cursor, Copilot, Codex, Gemini, and Windsurf")
19
+ .version("1.0.0");
20
+ // ─── Resolve target: flag > cache > auto-detect > prompt ───
21
+ async function resolveTarget(rootPath, flagTarget, silent = false) {
22
+ // 1. Explicit flag (--target claude or --all)
23
+ if (flagTarget === "all")
24
+ return [...GENERATOR_TARGETS];
25
+ if (flagTarget)
26
+ return [flagTarget];
27
+ // 2. Cached preference from previous init
28
+ const cache = await loadCache(rootPath);
29
+ if (cache?.target)
30
+ return [cache.target];
31
+ // 3. Auto-detect IDE from environment
32
+ const detected = await detectIDE(rootPath);
33
+ if (detected) {
34
+ if (!silent) {
35
+ logger.info(`Auto-detected: ${chalk.bold(getTargetLabel(detected.target))} (${detected.source})`);
36
+ }
37
+ return [detected.target];
38
+ }
39
+ // 4. Interactive prompt
40
+ if (silent)
41
+ return [GENERATOR_TARGETS[0]]; // default to claude in silent mode
42
+ return [await promptTarget()];
43
+ }
44
+ async function promptTarget() {
45
+ console.log("");
46
+ console.log(chalk.bold(" Which AI/IDE are you using?"));
47
+ console.log("");
48
+ const options = [
49
+ { key: "1", target: "claude", label: "Claude Code → CLAUDE.md" },
50
+ { key: "2", target: "cursor", label: "Cursor → .cursorrules" },
51
+ { key: "3", target: "copilot", label: "GitHub Copilot → .github/copilot-instructions.md" },
52
+ { key: "4", target: "codex", label: "OpenAI Codex → AGENTS.md" },
53
+ { key: "5", target: "gemini", label: "Google Gemini → .gemini/STYLE_GUIDE.md" },
54
+ { key: "6", target: "windsurf", label: "Windsurf → .windsurfrules" },
55
+ ];
56
+ for (const opt of options) {
57
+ console.log(` ${chalk.cyan(opt.key)}) ${opt.label}`);
58
+ }
59
+ console.log("");
60
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
61
+ const answer = await new Promise((resolve) => {
62
+ rl.question(chalk.bold(" Choose (1-6): "), (ans) => {
63
+ rl.close();
64
+ resolve(ans.trim());
65
+ });
66
+ });
67
+ const selected = options.find((o) => o.key === answer || o.target === answer.toLowerCase());
68
+ if (!selected) {
69
+ logger.warn("Invalid selection. Defaulting to Claude.");
70
+ return "claude";
71
+ }
72
+ return selected.target;
73
+ }
74
+ // ─── INIT ──────────────────────────────────────────────────
75
+ program
76
+ .command("init")
77
+ .description("Scan the project and generate the AI context file")
78
+ .option("-p, --path <path>", "Project root path", ".")
79
+ .option("-t, --target <target>", "Target AI/IDE (claude, cursor, copilot, codex, gemini, windsurf, all)")
80
+ .option("--all", "Generate for all AI/IDEs")
81
+ .option("--no-hook", "Skip git hook installation")
82
+ .action(async (opts) => {
83
+ const rootPath = resolve(opts.path);
84
+ const flagTarget = opts.all ? "all" : opts.target;
85
+ logger.heading("project-context-ai — Init");
86
+ logger.dim(`Scanning: ${rootPath}`);
87
+ console.log("");
88
+ // Resolve target before scanning (may prompt user)
89
+ const targets = await resolveTarget(rootPath, flagTarget);
90
+ const spinner = ora("Scanning project...").start();
91
+ try {
92
+ const { context, fileHashes } = await scanProject(rootPath);
93
+ spinner.succeed(`Scanned ${Object.keys(fileHashes).length} files, detected ${context.frameworks.length} frameworks`);
94
+ // Save cache with target preference
95
+ const commitHash = isGitRepo(rootPath)
96
+ ? getCurrentCommitHash(rootPath)
97
+ : null;
98
+ const savedTarget = targets.length === 1 ? targets[0] : null;
99
+ await saveCache(rootPath, context, fileHashes, commitHash, savedTarget);
100
+ logger.success("Context cache saved to .context-ai/");
101
+ // Generate only for selected target(s)
102
+ const genSpinner = ora("Generating AI context file...").start();
103
+ const outputs = await generateAll(rootPath, context, targets);
104
+ genSpinner.succeed(outputs.length === 1
105
+ ? `Generated ${getTargetLabel(outputs[0].target)}`
106
+ : `Generated ${outputs.length} context files`);
107
+ for (const output of outputs) {
108
+ logger.dim(` → ${output.filePath}`);
109
+ }
110
+ // Install git hook
111
+ if (opts.hook !== false && isGitRepo(rootPath)) {
112
+ const { installed, message } = await installHook(rootPath);
113
+ if (installed) {
114
+ logger.success(`Git hook: ${message}`);
115
+ }
116
+ else {
117
+ logger.warn(`Git hook: ${message}`);
118
+ }
119
+ }
120
+ console.log("");
121
+ logger.success(chalk.bold("Done!"));
122
+ logger.dim("Run `pca update` or commit to refresh context.");
123
+ }
124
+ catch (err) {
125
+ spinner.fail("Scan failed");
126
+ logger.error(err.message);
127
+ process.exit(1);
128
+ }
129
+ });
130
+ // ─── UPDATE ────────────────────────────────────────────────
131
+ program
132
+ .command("update")
133
+ .description("Incrementally update context based on changes")
134
+ .option("-p, --path <path>", "Project root path", ".")
135
+ .option("--silent", "Suppress output (for git hooks)")
136
+ .option("--full", "Force a full rescan instead of incremental")
137
+ .action(async (opts) => {
138
+ const rootPath = resolve(opts.path);
139
+ const silent = opts.silent;
140
+ if (!silent) {
141
+ logger.heading("project-context-ai — Update");
142
+ }
143
+ try {
144
+ const cache = await loadCache(rootPath);
145
+ // Resolve target from cache or auto-detect
146
+ const targets = cache?.target ? [cache.target] : await resolveTarget(rootPath, undefined, silent);
147
+ const savedTarget = targets.length === 1 ? targets[0] : null;
148
+ if (!cache || opts.full) {
149
+ if (!silent) {
150
+ const spinner = ora("Full rescan...").start();
151
+ const { context, fileHashes } = await scanProject(rootPath);
152
+ const commitHash = isGitRepo(rootPath) ? getCurrentCommitHash(rootPath) : null;
153
+ await saveCache(rootPath, context, fileHashes, commitHash, savedTarget);
154
+ const outputs = await generateAll(rootPath, context, targets);
155
+ spinner.succeed(`Full rescan complete. Updated ${outputs.map((o) => o.filePath).join(", ")}`);
156
+ }
157
+ else {
158
+ const { context, fileHashes } = await scanProject(rootPath);
159
+ const commitHash = isGitRepo(rootPath) ? getCurrentCommitHash(rootPath) : null;
160
+ await saveCache(rootPath, context, fileHashes, commitHash, savedTarget);
161
+ await generateAll(rootPath, context, targets);
162
+ }
163
+ return;
164
+ }
165
+ // Incremental update
166
+ let changedFiles = [];
167
+ if (isGitRepo(rootPath) && cache.commitHash) {
168
+ changedFiles = getChangedFilesSinceCommit(rootPath, cache.commitHash);
169
+ const untracked = getUntrackedFiles(rootPath);
170
+ changedFiles = [...new Set([...changedFiles, ...untracked])];
171
+ }
172
+ else {
173
+ const { walkDirectory } = await import("./utils/files.js");
174
+ const { files } = await walkDirectory(rootPath);
175
+ const newHashes = await computeFileHashes(rootPath, files);
176
+ const diff = getChangedFiles(cache.fileHashes, newHashes);
177
+ changedFiles = [...diff.added, ...diff.modified];
178
+ }
179
+ if (changedFiles.length === 0) {
180
+ if (!silent)
181
+ logger.success("No changes detected. Context is up to date.");
182
+ return;
183
+ }
184
+ if (!silent) {
185
+ logger.info(`${changedFiles.length} files changed. Updating...`);
186
+ }
187
+ const { context, fileHashes } = await scanProject(rootPath);
188
+ const commitHash = isGitRepo(rootPath) ? getCurrentCommitHash(rootPath) : null;
189
+ const mergedHashes = { ...cache.fileHashes, ...fileHashes };
190
+ await saveCache(rootPath, context, mergedHashes, commitHash, savedTarget);
191
+ const outputs = await generateAll(rootPath, context, targets);
192
+ if (!silent) {
193
+ logger.success(`Updated ${outputs.map((o) => o.filePath).join(", ")} (${changedFiles.length} files changed)`);
194
+ }
195
+ }
196
+ catch (err) {
197
+ if (!silent) {
198
+ logger.error(`Update failed: ${err.message}`);
199
+ }
200
+ process.exit(1);
201
+ }
202
+ });
203
+ // ─── GENERATE ──────────────────────────────────────────────
204
+ program
205
+ .command("generate")
206
+ .description("Regenerate AI context file from cached context")
207
+ .option("-p, --path <path>", "Project root path", ".")
208
+ .option("-t, --target <target>", "Target AI/IDE (claude, cursor, copilot, codex, gemini, windsurf, all)")
209
+ .option("--all", "Generate for all AI/IDEs")
210
+ .action(async (opts) => {
211
+ const rootPath = resolve(opts.path);
212
+ const cache = await loadCache(rootPath);
213
+ if (!cache) {
214
+ logger.error("No context cache found. Run `pca init` first.");
215
+ process.exit(1);
216
+ }
217
+ const flagTarget = opts.all ? "all" : opts.target;
218
+ const targets = flagTarget
219
+ ? (flagTarget === "all" ? [...GENERATOR_TARGETS] : [flagTarget])
220
+ : cache.target
221
+ ? [cache.target]
222
+ : await resolveTarget(rootPath);
223
+ const spinner = ora("Generating...").start();
224
+ const outputs = await generateAll(rootPath, cache.projectContext, targets);
225
+ spinner.succeed(outputs.length === 1
226
+ ? `Generated ${outputs[0].filePath}`
227
+ : `Generated ${outputs.length} context files`);
228
+ for (const output of outputs) {
229
+ logger.dim(` → ${output.filePath}`);
230
+ }
231
+ });
232
+ // ─── HOOK ──────────────────────────────────────────────────
233
+ const hookCmd = program
234
+ .command("hook")
235
+ .description("Manage git hooks for auto-update");
236
+ hookCmd
237
+ .command("install")
238
+ .description("Install post-commit hook for auto-update")
239
+ .option("-p, --path <path>", "Project root path", ".")
240
+ .action(async (opts) => {
241
+ const rootPath = resolve(opts.path);
242
+ const { installed, message } = await installHook(rootPath);
243
+ if (installed)
244
+ logger.success(message);
245
+ else
246
+ logger.warn(message);
247
+ });
248
+ hookCmd
249
+ .command("uninstall")
250
+ .description("Remove the auto-update hook")
251
+ .option("-p, --path <path>", "Project root path", ".")
252
+ .action(async (opts) => {
253
+ const rootPath = resolve(opts.path);
254
+ const { removed, message } = await uninstallHook(rootPath);
255
+ if (removed)
256
+ logger.success(message);
257
+ else
258
+ logger.warn(message);
259
+ });
260
+ // ─── STATUS ────────────────────────────────────────────────
261
+ program
262
+ .command("status")
263
+ .description("Show current context status")
264
+ .option("-p, --path <path>", "Project root path", ".")
265
+ .action(async (opts) => {
266
+ const rootPath = resolve(opts.path);
267
+ const cache = await loadCache(rootPath);
268
+ if (!cache) {
269
+ logger.warn("No context cache found. Run `pca init` first.");
270
+ return;
271
+ }
272
+ const ctx = cache.projectContext;
273
+ logger.heading("project-context-ai — Status");
274
+ console.log("");
275
+ console.log(` ${chalk.bold("Project:")} ${ctx.meta.name} (${ctx.meta.type})`);
276
+ console.log(` ${chalk.bold("Languages:")} ${ctx.meta.languages.join(", ")}`);
277
+ console.log(` ${chalk.bold("Frameworks:")} ${ctx.frameworks.map((f) => f.name).join(", ") || "none"}`);
278
+ console.log(` ${chalk.bold("Target:")} ${cache.target ? getTargetLabel(cache.target) : "all"}`);
279
+ console.log(` ${chalk.bold("Files tracked:")} ${Object.keys(cache.fileHashes).length}`);
280
+ console.log(` ${chalk.bold("Last updated:")} ${cache.lastUpdated}`);
281
+ console.log(` ${chalk.bold("Commit:")} ${cache.commitHash?.slice(0, 8) || "n/a"}`);
282
+ console.log(` ${chalk.bold("Architecture:")} ${ctx.conventions.architecture}`);
283
+ console.log("");
284
+ });
285
+ // ─── SWITCH ────────────────────────────────────────────────
286
+ program
287
+ .command("switch")
288
+ .description("Switch to a different AI/IDE target")
289
+ .argument("[target]", "Target (claude, cursor, copilot, codex, gemini, windsurf)")
290
+ .option("-p, --path <path>", "Project root path", ".")
291
+ .action(async (target, opts) => {
292
+ const rootPath = resolve(opts.path);
293
+ const cache = await loadCache(rootPath);
294
+ if (!cache) {
295
+ logger.error("No context cache found. Run `pca init` first.");
296
+ process.exit(1);
297
+ }
298
+ const newTarget = target
299
+ ? target
300
+ : await promptTarget();
301
+ if (!GENERATOR_TARGETS.includes(newTarget)) {
302
+ logger.error(`Invalid target: ${newTarget}. Options: ${GENERATOR_TARGETS.join(", ")}`);
303
+ process.exit(1);
304
+ }
305
+ // Save new preference
306
+ await saveCache(rootPath, cache.projectContext, cache.fileHashes, cache.commitHash, newTarget);
307
+ // Regenerate for new target
308
+ const outputs = await generateAll(rootPath, cache.projectContext, [newTarget]);
309
+ logger.success(`Switched to ${getTargetLabel(newTarget)}`);
310
+ logger.dim(` → ${outputs[0].filePath}`);
311
+ });
312
+ program.parse();
313
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export declare function computeFileHashes(rootPath: string, files: string[]): Promise<Record<string, string>>;
2
+ export declare function getChangedFiles(oldHashes: Record<string, string>, newHashes: Record<string, string>): {
3
+ added: string[];
4
+ modified: string[];
5
+ removed: string[];
6
+ };
7
+ //# sourceMappingURL=hasher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hasher.d.ts","sourceRoot":"","sources":["../../src/context/hasher.ts"],"names":[],"mappings":"AAIA,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAwBjC;AAED,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACjC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAoB5D"}
@@ -0,0 +1,44 @@
1
+ import { createHash } from "node:crypto";
2
+ import { readFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ export async function computeFileHashes(rootPath, files) {
5
+ const hashes = {};
6
+ const batchSize = 50;
7
+ for (let i = 0; i < files.length; i += batchSize) {
8
+ const batch = files.slice(i, i + batchSize);
9
+ const results = await Promise.all(batch.map(async (file) => {
10
+ try {
11
+ const content = await readFile(join(rootPath, file));
12
+ const hash = createHash("sha256").update(content).digest("hex").slice(0, 16);
13
+ return { file, hash };
14
+ }
15
+ catch {
16
+ return { file, hash: "unreadable" };
17
+ }
18
+ }));
19
+ for (const { file, hash } of results) {
20
+ hashes[file] = hash;
21
+ }
22
+ }
23
+ return hashes;
24
+ }
25
+ export function getChangedFiles(oldHashes, newHashes) {
26
+ const added = [];
27
+ const modified = [];
28
+ const removed = [];
29
+ for (const [file, hash] of Object.entries(newHashes)) {
30
+ if (!(file in oldHashes)) {
31
+ added.push(file);
32
+ }
33
+ else if (oldHashes[file] !== hash) {
34
+ modified.push(file);
35
+ }
36
+ }
37
+ for (const file of Object.keys(oldHashes)) {
38
+ if (!(file in newHashes)) {
39
+ removed.push(file);
40
+ }
41
+ }
42
+ return { added, modified, removed };
43
+ }
44
+ //# sourceMappingURL=hasher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hasher.js","sourceRoot":"","sources":["../../src/context/hasher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,QAAgB,EAChB,KAAe;IAEf,MAAM,MAAM,GAA2B,EAAE,CAAC;IAE1C,MAAM,SAAS,GAAG,EAAE,CAAC;IACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC;QACjD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC;QAC5C,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YACvB,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;gBACrD,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC7E,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YACxB,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;YACtC,CAAC;QACH,CAAC,CAAC,CACH,CAAC;QAEF,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC;YACrC,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QACtB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,SAAiC,EACjC,SAAiC;IAEjC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QACrD,IAAI,CAAC,CAAC,IAAI,IAAI,SAAS,CAAC,EAAE,CAAC;YACzB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;aAAM,IAAI,SAAS,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YACpC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1C,IAAI,CAAC,CAAC,IAAI,IAAI,SAAS,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AACtC,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { ContextCache, GeneratorTarget, ProjectContext } from "../types.js";
2
+ export declare function getContextDir(rootPath: string): string;
3
+ export declare function ensureContextDir(rootPath: string): Promise<string>;
4
+ export declare function loadCache(rootPath: string): Promise<ContextCache | null>;
5
+ export declare function saveCache(rootPath: string, context: ProjectContext, fileHashes: Record<string, string>, commitHash: string | null, target?: GeneratorTarget | null): Promise<void>;
6
+ export declare function mergeContext(existing: ProjectContext, partial: ProjectContext): ProjectContext;
7
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/context/store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAOjF,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAIxE;AAED,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAY9E;AAED,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,cAAc,EACvB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,MAAM,GAAE,eAAe,GAAG,IAAW,GACpC,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,cAAc,GACtB,cAAc,CAWhB"}
@@ -0,0 +1,62 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { fileExists } from "../utils/files.js";
4
+ const CONTEXT_DIR = ".context-ai";
5
+ const CACHE_FILE = "context-cache.json";
6
+ const CURRENT_VERSION = "1.0.0";
7
+ export function getContextDir(rootPath) {
8
+ return join(rootPath, CONTEXT_DIR);
9
+ }
10
+ export async function ensureContextDir(rootPath) {
11
+ const dir = getContextDir(rootPath);
12
+ await mkdir(dir, { recursive: true });
13
+ return dir;
14
+ }
15
+ export async function loadCache(rootPath) {
16
+ const cachePath = join(getContextDir(rootPath), CACHE_FILE);
17
+ if (!(await fileExists(cachePath)))
18
+ return null;
19
+ try {
20
+ const raw = await readFile(cachePath, "utf-8");
21
+ const cache = JSON.parse(raw);
22
+ if (cache.version !== CURRENT_VERSION)
23
+ return null;
24
+ return cache;
25
+ }
26
+ catch {
27
+ return null;
28
+ }
29
+ }
30
+ export async function saveCache(rootPath, context, fileHashes, commitHash, target = null) {
31
+ const dir = await ensureContextDir(rootPath);
32
+ const cache = {
33
+ version: CURRENT_VERSION,
34
+ lastUpdated: new Date().toISOString(),
35
+ commitHash,
36
+ target,
37
+ projectContext: context,
38
+ fileHashes,
39
+ };
40
+ await writeFile(join(dir, CACHE_FILE), JSON.stringify(cache, null, 2), "utf-8");
41
+ }
42
+ export function mergeContext(existing, partial) {
43
+ return {
44
+ meta: { ...existing.meta, ...partial.meta },
45
+ structure: mergeByPath(existing.structure, partial.structure),
46
+ dependencies: partial.dependencies,
47
+ frameworks: partial.frameworks,
48
+ scripts: { ...existing.scripts, ...partial.scripts },
49
+ conventions: { ...existing.conventions, ...partial.conventions },
50
+ entryPoints: [...new Set([...existing.entryPoints, ...partial.entryPoints])],
51
+ keyFiles: mergeByPath(existing.keyFiles, partial.keyFiles),
52
+ };
53
+ }
54
+ function mergeByPath(existing, incoming) {
55
+ const map = new Map();
56
+ for (const item of existing)
57
+ map.set(item.path, item);
58
+ for (const item of incoming)
59
+ map.set(item.path, item);
60
+ return Array.from(map.values());
61
+ }
62
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/context/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { GeneratorTarget } from "./types.js";
2
+ interface IDEDetection {
3
+ target: GeneratorTarget;
4
+ source: string;
5
+ }
6
+ export declare function detectIDE(rootPath: string): Promise<IDEDetection | null>;
7
+ export declare function getTargetLabel(target: GeneratorTarget): string;
8
+ export {};
9
+ //# sourceMappingURL=detect-ide.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect-ide.d.ts","sourceRoot":"","sources":["../src/detect-ide.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAIlD,UAAU,YAAY;IACpB,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAU9E;AAwED,wBAAgB,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAU9D"}
@@ -0,0 +1,83 @@
1
+ import { fileExists } from "./utils/files.js";
2
+ import { join } from "node:path";
3
+ export async function detectIDE(rootPath) {
4
+ // 1. Check environment variables
5
+ const envDetection = detectFromEnv();
6
+ if (envDetection)
7
+ return envDetection;
8
+ // 2. Check existing config files in project
9
+ const fileDetection = await detectFromFiles(rootPath);
10
+ if (fileDetection)
11
+ return fileDetection;
12
+ return null;
13
+ }
14
+ function detectFromEnv() {
15
+ const env = process.env;
16
+ // Claude Code CLI
17
+ if (env.CLAUDE_CODE || env.CLAUDE_PROJECT_DIR) {
18
+ return { target: "claude", source: "Claude Code (env)" };
19
+ }
20
+ // Cursor IDE
21
+ if (env.CURSOR_TRACE_ID || env.CURSOR_SESSION_ID || env.TERM_PROGRAM === "cursor") {
22
+ return { target: "cursor", source: "Cursor (env)" };
23
+ }
24
+ // Windsurf IDE
25
+ if (env.WINDSURF_SESSION || env.TERM_PROGRAM === "windsurf") {
26
+ return { target: "windsurf", source: "Windsurf (env)" };
27
+ }
28
+ // VS Code + Copilot (generic VS Code detection)
29
+ if (env.VSCODE_PID ||
30
+ env.VSCODE_CWD ||
31
+ env.TERM_PROGRAM === "vscode" ||
32
+ env.VSCODE_GIT_IPC_HANDLE) {
33
+ return { target: "copilot", source: "VS Code / Copilot (env)" };
34
+ }
35
+ // OpenAI Codex CLI
36
+ if (env.OPENAI_API_KEY && env.CODEX_SESSION) {
37
+ return { target: "codex", source: "Codex (env)" };
38
+ }
39
+ // Google Gemini
40
+ if (env.GEMINI_API_KEY && env.GEMINI_SESSION) {
41
+ return { target: "gemini", source: "Gemini (env)" };
42
+ }
43
+ return null;
44
+ }
45
+ async function detectFromFiles(rootPath) {
46
+ // Check for existing AI config files that the user already has
47
+ const checks = [
48
+ { file: "CLAUDE.md", target: "claude", source: "CLAUDE.md found" },
49
+ { file: ".cursorrules", target: "cursor", source: ".cursorrules found" },
50
+ { file: ".github/copilot-instructions.md", target: "copilot", source: "copilot-instructions found" },
51
+ { file: "AGENTS.md", target: "codex", source: "AGENTS.md found" },
52
+ { file: ".gemini/STYLE_GUIDE.md", target: "gemini", source: "Gemini config found" },
53
+ { file: ".windsurfrules", target: "windsurf", source: ".windsurfrules found" },
54
+ ];
55
+ for (const check of checks) {
56
+ if (await fileExists(join(rootPath, check.file))) {
57
+ // Only count files NOT generated by us
58
+ try {
59
+ const { readFile } = await import("node:fs/promises");
60
+ const content = await readFile(join(rootPath, check.file), "utf-8");
61
+ if (!content.includes("Generated by project-context-ai")) {
62
+ return { target: check.target, source: check.source };
63
+ }
64
+ }
65
+ catch {
66
+ // ignore
67
+ }
68
+ }
69
+ }
70
+ return null;
71
+ }
72
+ export function getTargetLabel(target) {
73
+ const labels = {
74
+ claude: "Claude Code (CLAUDE.md)",
75
+ cursor: "Cursor (.cursorrules)",
76
+ copilot: "GitHub Copilot (.github/copilot-instructions.md)",
77
+ codex: "OpenAI Codex (AGENTS.md)",
78
+ gemini: "Google Gemini (.gemini/STYLE_GUIDE.md)",
79
+ windsurf: "Windsurf (.windsurfrules)",
80
+ };
81
+ return labels[target];
82
+ }
83
+ //# sourceMappingURL=detect-ide.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect-ide.js","sourceRoot":"","sources":["../src/detect-ide.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ProjectContext, GeneratorOutput } from "../types.js";
2
+ export declare function generateClaude(ctx: ProjectContext): GeneratorOutput;
3
+ //# sourceMappingURL=claude.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/generators/claude.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAWnE,wBAAgB,cAAc,CAAC,GAAG,EAAE,cAAc,GAAG,eAAe,CAmCnE"}
@@ -0,0 +1,32 @@
1
+ import { buildProjectOverview, buildStructureSection, buildKeyFilesSection, buildEntryPointsSection, buildScriptsSection, buildDependenciesSection, buildArchitectureSection, } from "./template.js";
2
+ export function generateClaude(ctx) {
3
+ const sections = [];
4
+ sections.push(buildProjectOverview(ctx));
5
+ sections.push(buildArchitectureSection(ctx));
6
+ sections.push(buildStructureSection(ctx));
7
+ sections.push(buildKeyFilesSection(ctx));
8
+ sections.push(buildEntryPointsSection(ctx));
9
+ sections.push(buildDependenciesSection(ctx));
10
+ sections.push(buildScriptsSection(ctx));
11
+ // Claude-specific instructions
12
+ sections.push("## Guidelines");
13
+ sections.push("");
14
+ sections.push("- Read relevant files before suggesting changes");
15
+ sections.push("- Follow existing code patterns and conventions");
16
+ sections.push(`- Use ${ctx.dependencies.packageManager} for package management`);
17
+ if (ctx.conventions.testing !== "No testing framework detected") {
18
+ sections.push(`- Write tests using ${ctx.conventions.testing}`);
19
+ }
20
+ if (ctx.conventions.styling !== "CSS") {
21
+ sections.push(`- Use ${ctx.conventions.styling} for styling`);
22
+ }
23
+ sections.push("- Prefer editing existing files over creating new ones");
24
+ sections.push("");
25
+ sections.push("<!-- Generated by project-context-ai -->");
26
+ return {
27
+ target: "claude",
28
+ filePath: "CLAUDE.md",
29
+ content: sections.join("\n"),
30
+ };
31
+ }
32
+ //# sourceMappingURL=claude.js.map