noah-cursor 1.5.8 → 1.5.10

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 (169) hide show
  1. package/README.md +253 -182
  2. package/dist/commands/add.d.ts.map +1 -1
  3. package/dist/commands/add.js +2 -1
  4. package/dist/commands/add.js.map +1 -1
  5. package/dist/commands/analyze.d.ts +3 -0
  6. package/dist/commands/analyze.d.ts.map +1 -0
  7. package/dist/commands/analyze.js +48 -0
  8. package/dist/commands/analyze.js.map +1 -0
  9. package/dist/commands/auth.d.ts +3 -0
  10. package/dist/commands/auth.d.ts.map +1 -0
  11. package/dist/commands/auth.js +67 -0
  12. package/dist/commands/auth.js.map +1 -0
  13. package/dist/commands/bootstrap.d.ts +3 -0
  14. package/dist/commands/bootstrap.d.ts.map +1 -0
  15. package/dist/commands/bootstrap.js +92 -0
  16. package/dist/commands/bootstrap.js.map +1 -0
  17. package/dist/commands/config.d.ts +3 -0
  18. package/dist/commands/config.d.ts.map +1 -0
  19. package/dist/commands/config.js +109 -0
  20. package/dist/commands/config.js.map +1 -0
  21. package/dist/commands/dashboard.d.ts +3 -0
  22. package/dist/commands/dashboard.d.ts.map +1 -0
  23. package/dist/commands/dashboard.js +21 -0
  24. package/dist/commands/dashboard.js.map +1 -0
  25. package/dist/commands/doctor.d.ts.map +1 -1
  26. package/dist/commands/doctor.js +3 -2
  27. package/dist/commands/doctor.js.map +1 -1
  28. package/dist/commands/explain.d.ts +3 -0
  29. package/dist/commands/explain.d.ts.map +1 -0
  30. package/dist/commands/explain.js +27 -0
  31. package/dist/commands/explain.js.map +1 -0
  32. package/dist/commands/favorite.d.ts +3 -0
  33. package/dist/commands/favorite.d.ts.map +1 -0
  34. package/dist/commands/favorite.js +64 -0
  35. package/dist/commands/favorite.js.map +1 -0
  36. package/dist/commands/install.d.ts +3 -0
  37. package/dist/commands/install.d.ts.map +1 -0
  38. package/dist/commands/install.js +83 -0
  39. package/dist/commands/install.js.map +1 -0
  40. package/dist/commands/new.d.ts +3 -0
  41. package/dist/commands/new.d.ts.map +1 -0
  42. package/dist/commands/new.js +27 -0
  43. package/dist/commands/new.js.map +1 -0
  44. package/dist/commands/plugin.d.ts +3 -0
  45. package/dist/commands/plugin.d.ts.map +1 -0
  46. package/dist/commands/plugin.js +39 -0
  47. package/dist/commands/plugin.js.map +1 -0
  48. package/dist/commands/preview.d.ts +3 -0
  49. package/dist/commands/preview.d.ts.map +1 -0
  50. package/dist/commands/preview.js +25 -0
  51. package/dist/commands/preview.js.map +1 -0
  52. package/dist/commands/publish.d.ts +3 -0
  53. package/dist/commands/publish.d.ts.map +1 -0
  54. package/dist/commands/publish.js +22 -0
  55. package/dist/commands/publish.js.map +1 -0
  56. package/dist/commands/recent.d.ts +3 -0
  57. package/dist/commands/recent.d.ts.map +1 -0
  58. package/dist/commands/recent.js +27 -0
  59. package/dist/commands/recent.js.map +1 -0
  60. package/dist/commands/remove.d.ts.map +1 -1
  61. package/dist/commands/remove.js +2 -1
  62. package/dist/commands/remove.js.map +1 -1
  63. package/dist/commands/search.d.ts.map +1 -1
  64. package/dist/commands/search.js +39 -2
  65. package/dist/commands/search.js.map +1 -1
  66. package/dist/commands/try.d.ts +3 -0
  67. package/dist/commands/try.d.ts.map +1 -0
  68. package/dist/commands/try.js +22 -0
  69. package/dist/commands/try.js.map +1 -0
  70. package/dist/commands/undo.d.ts +3 -0
  71. package/dist/commands/undo.d.ts.map +1 -0
  72. package/dist/commands/undo.js +24 -0
  73. package/dist/commands/undo.js.map +1 -0
  74. package/dist/commands/uninstall.d.ts +3 -0
  75. package/dist/commands/uninstall.d.ts.map +1 -0
  76. package/dist/commands/uninstall.js +52 -0
  77. package/dist/commands/uninstall.js.map +1 -0
  78. package/dist/commands/update.d.ts.map +1 -1
  79. package/dist/commands/update.js +2 -1
  80. package/dist/commands/update.js.map +1 -1
  81. package/dist/commands/wizard.d.ts +3 -0
  82. package/dist/commands/wizard.d.ts.map +1 -0
  83. package/dist/commands/wizard.js +61 -0
  84. package/dist/commands/wizard.js.map +1 -0
  85. package/dist/commands/workspace.d.ts +3 -0
  86. package/dist/commands/workspace.d.ts.map +1 -0
  87. package/dist/commands/workspace.js +84 -0
  88. package/dist/commands/workspace.js.map +1 -0
  89. package/dist/constants/ides.d.ts +2 -2
  90. package/dist/constants/ides.d.ts.map +1 -1
  91. package/dist/constants/ides.js +47 -3
  92. package/dist/constants/ides.js.map +1 -1
  93. package/dist/constants/index.d.ts +4 -0
  94. package/dist/constants/index.d.ts.map +1 -1
  95. package/dist/constants/index.js +4 -0
  96. package/dist/constants/index.js.map +1 -1
  97. package/dist/core/program.d.ts.map +1 -1
  98. package/dist/core/program.js +38 -5
  99. package/dist/core/program.js.map +1 -1
  100. package/dist/index.js +36 -1
  101. package/dist/index.js.map +1 -1
  102. package/dist/metadata/user-store.d.ts +16 -0
  103. package/dist/metadata/user-store.d.ts.map +1 -0
  104. package/dist/metadata/user-store.js +99 -0
  105. package/dist/metadata/user-store.js.map +1 -0
  106. package/dist/noah-registry/manifest.json +129 -16
  107. package/dist/services/doctor-service.d.ts.map +1 -1
  108. package/dist/services/doctor-service.js +74 -7
  109. package/dist/services/doctor-service.js.map +1 -1
  110. package/dist/services/ecosystem.d.ts +17 -0
  111. package/dist/services/ecosystem.d.ts.map +1 -0
  112. package/dist/services/ecosystem.js +136 -0
  113. package/dist/services/ecosystem.js.map +1 -0
  114. package/dist/services/extras.d.ts +29 -0
  115. package/dist/services/extras.d.ts.map +1 -0
  116. package/dist/services/extras.js +164 -0
  117. package/dist/services/extras.js.map +1 -0
  118. package/dist/services/install-service.d.ts +12 -0
  119. package/dist/services/install-service.d.ts.map +1 -1
  120. package/dist/services/install-service.js +169 -12
  121. package/dist/services/install-service.js.map +1 -1
  122. package/dist/services/intelligence.d.ts +20 -0
  123. package/dist/services/intelligence.d.ts.map +1 -0
  124. package/dist/services/intelligence.js +146 -0
  125. package/dist/services/intelligence.js.map +1 -0
  126. package/dist/services/lockfile-service.d.ts +7 -0
  127. package/dist/services/lockfile-service.d.ts.map +1 -0
  128. package/dist/services/lockfile-service.js +36 -0
  129. package/dist/services/lockfile-service.js.map +1 -0
  130. package/dist/services/project-awareness.d.ts +12 -0
  131. package/dist/services/project-awareness.d.ts.map +1 -0
  132. package/dist/services/project-awareness.js +200 -0
  133. package/dist/services/project-awareness.js.map +1 -0
  134. package/dist/services/workspace-service.d.ts +49 -0
  135. package/dist/services/workspace-service.d.ts.map +1 -0
  136. package/dist/services/workspace-service.js +92 -0
  137. package/dist/services/workspace-service.js.map +1 -0
  138. package/dist/types/index.d.ts +508 -4
  139. package/dist/types/index.d.ts.map +1 -1
  140. package/dist/types/index.js +72 -0
  141. package/dist/types/index.js.map +1 -1
  142. package/dist/ui/banner.d.ts.map +1 -1
  143. package/dist/ui/banner.js +2 -3
  144. package/dist/ui/banner.js.map +1 -1
  145. package/dist/ui/homeMenu.d.ts +6 -0
  146. package/dist/ui/homeMenu.d.ts.map +1 -0
  147. package/dist/ui/homeMenu.js +72 -0
  148. package/dist/ui/homeMenu.js.map +1 -0
  149. package/dist/ui/preview.d.ts +3 -0
  150. package/dist/ui/preview.d.ts.map +1 -0
  151. package/dist/ui/preview.js +36 -0
  152. package/dist/ui/preview.js.map +1 -0
  153. package/dist/utils/assets.d.ts +7 -0
  154. package/dist/utils/assets.d.ts.map +1 -1
  155. package/dist/utils/assets.js +18 -14
  156. package/dist/utils/assets.js.map +1 -1
  157. package/dist/utils/fuzzy.d.ts +6 -0
  158. package/dist/utils/fuzzy.d.ts.map +1 -0
  159. package/dist/utils/fuzzy.js +51 -0
  160. package/dist/utils/fuzzy.js.map +1 -0
  161. package/dist/utils/registry.d.ts +8 -1
  162. package/dist/utils/registry.d.ts.map +1 -1
  163. package/dist/utils/registry.js +13 -5
  164. package/dist/utils/registry.js.map +1 -1
  165. package/dist/utils/semver.d.ts +11 -0
  166. package/dist/utils/semver.d.ts.map +1 -0
  167. package/dist/utils/semver.js +41 -0
  168. package/dist/utils/semver.js.map +1 -0
  169. package/package.json +7 -5
@@ -0,0 +1,146 @@
1
+ import { select, confirm } from "@inquirer/prompts";
2
+ import { logInfo, logSuccess, logTitle } from "../core/logger.js";
3
+ import { DEFAULT_IDE } from "../constants/index.js";
4
+ import { humanizeId } from "../ui/format.js";
5
+ import { getPackagePreview, installByPackageNames, listRegistryAssets, updateAssets, } from "./install-service.js";
6
+ import { analyzeProject, detectProjectStack, recommendPackages } from "./project-awareness.js";
7
+ import { listInstalledAssets } from "../metadata/store.js";
8
+ export async function explainPackage(input, options = {}) {
9
+ return getPackagePreview(input, options);
10
+ }
11
+ export function formatExplanation(pkg) {
12
+ const lines = [
13
+ `${humanizeId(pkg.id)}`,
14
+ "",
15
+ `Type: ${pkg.type}`,
16
+ `Version: ${pkg.version}`,
17
+ ];
18
+ if (pkg.verified)
19
+ lines.push("Status: ✓ Verified");
20
+ if (pkg.author)
21
+ lines.push(`Author: ${pkg.author}`);
22
+ if (pkg.rating != null)
23
+ lines.push(`Rating: ${"★".repeat(Math.round(pkg.rating))}${"☆".repeat(5 - Math.round(pkg.rating))} (${pkg.rating})`);
24
+ if (pkg.downloads != null)
25
+ lines.push(`Downloads: ${pkg.downloads.toLocaleString()}`);
26
+ if (pkg.description) {
27
+ lines.push("", "Purpose", pkg.description);
28
+ }
29
+ if (pkg.tags?.length) {
30
+ lines.push("", `Tags: ${pkg.tags.join(", ")}`);
31
+ }
32
+ if (pkg.dependsOn?.length) {
33
+ lines.push("", `Depends on: ${pkg.dependsOn.join(", ")}`);
34
+ }
35
+ if (pkg.changelog) {
36
+ lines.push("", "What's new", pkg.changelog);
37
+ }
38
+ lines.push("", "Benefits", `- Applies curated ${pkg.type} guidance to your AI coding assistant`, `- Keeps project conventions consistent across the team`, `- Install with: noah-cursor install ${pkg.type}/${pkg.id}`);
39
+ return lines;
40
+ }
41
+ export async function runSetupWizard(options = {}) {
42
+ const projectType = await select({
43
+ message: "What are you building?",
44
+ choices: [
45
+ { name: "API", value: "api" },
46
+ { name: "Website / Marketing", value: "website" },
47
+ { name: "Microservice", value: "microservice" },
48
+ { name: "CLI", value: "cli" },
49
+ { name: "SaaS", value: "saas" },
50
+ { name: "Detect from project", value: "detect" },
51
+ ],
52
+ });
53
+ let framework = "detect";
54
+ if (projectType !== "detect") {
55
+ framework = await select({
56
+ message: "Primary framework?",
57
+ choices: [
58
+ { name: "Laravel", value: "laravel" },
59
+ { name: "React", value: "react" },
60
+ { name: "Next.js", value: "nextjs" },
61
+ { name: "Vue / Nuxt", value: "nuxt" },
62
+ { name: "NestJS", value: "nestjs" },
63
+ { name: "Node / generic", value: "node" },
64
+ { name: "Auto-detect", value: "detect" },
65
+ ],
66
+ });
67
+ }
68
+ const stack = await detectProjectStack();
69
+ const recommendations = await recommendPackages(process.cwd(), { limit: 10 });
70
+ const frameworkHint = framework === "detect" ? stack.frameworks[0]?.toLowerCase() : framework;
71
+ const filtered = recommendations.filter((r) => {
72
+ if (!frameworkHint)
73
+ return true;
74
+ const hay = `${r.id} ${(r.tags ?? []).join(" ")} ${r.description ?? ""}`.toLowerCase();
75
+ return hay.includes(frameworkHint) || hay.includes("git") || hay.includes("docs") || hay.includes("architecture");
76
+ });
77
+ const picks = (filtered.length > 0 ? filtered : recommendations).slice(0, 5);
78
+ logTitle("Recommended packages");
79
+ for (const p of picks) {
80
+ console.log(` • ${p.type}/${p.id} — ${p.description ?? ""}`);
81
+ }
82
+ const ok = options.yes ||
83
+ (await confirm({
84
+ message: `Install ${picks.length} recommended package(s)?`,
85
+ default: true,
86
+ }));
87
+ if (!ok) {
88
+ logInfo("Setup cancelled.");
89
+ return [];
90
+ }
91
+ return installByPackageNames(picks.map((p) => `${p.type}/${p.id}`), {
92
+ ide: options.ide ?? DEFAULT_IDE,
93
+ yes: true,
94
+ dryRun: options.dryRun,
95
+ verbose: options.verbose,
96
+ });
97
+ }
98
+ export async function runUpgradeAssistant(options = {}) {
99
+ const ide = options.ide ?? DEFAULT_IDE;
100
+ const stack = await detectProjectStack();
101
+ const installed = await listInstalledAssets(process.cwd(), ide);
102
+ const registry = await listRegistryAssets(undefined, { verbose: options.verbose });
103
+ const outdated = [];
104
+ for (const asset of installed.installed) {
105
+ const latest = registry.assets.find((a) => a.type === asset.type && a.id === asset.id);
106
+ if (latest && latest.version !== asset.version && asset.version !== "local") {
107
+ outdated.push(`${asset.type}/${asset.id} ${asset.version} → ${latest.version}`);
108
+ }
109
+ }
110
+ if (stack.frameworks.includes("Laravel")) {
111
+ logInfo("Laravel detected — related packages can be refreshed.");
112
+ }
113
+ if (outdated.length === 0 && installed.installed.length === 0) {
114
+ logInfo("Nothing to upgrade. Install packages first or run bootstrap.");
115
+ return [];
116
+ }
117
+ if (outdated.length > 0) {
118
+ logTitle("Upgrades available");
119
+ for (const line of outdated)
120
+ console.log(` ${line}`);
121
+ }
122
+ else {
123
+ logInfo("Installed packages match registry versions. Reinstalling to refresh files…");
124
+ }
125
+ const ok = options.yes ||
126
+ (await confirm({
127
+ message: "Update related packages?",
128
+ default: true,
129
+ }));
130
+ if (!ok) {
131
+ logInfo("Upgrade cancelled.");
132
+ return [];
133
+ }
134
+ const results = await updateAssets({
135
+ yes: true,
136
+ dryRun: options.dryRun,
137
+ verbose: options.verbose,
138
+ ide,
139
+ });
140
+ logSuccess("Upgrade assistant finished.");
141
+ return results;
142
+ }
143
+ export async function runAnalyze(ide = DEFAULT_IDE, verbose) {
144
+ return analyzeProject(process.cwd(), ide, { verbose });
145
+ }
146
+ //# sourceMappingURL=intelligence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intelligence.js","sourceRoot":"","sources":["../../src/services/intelligence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { type IdeId } from "../constants/index.js";
2
+ import { type InstalledAsset, type Lockfile } from "../types/index.js";
3
+ export declare function getLockfilePath(cwd?: string): string;
4
+ export declare function readLockfile(cwd?: string): Promise<Lockfile | null>;
5
+ export declare function writeLockfile(packages: InstalledAsset[], ide?: IdeId, cwd?: string): Promise<Lockfile>;
6
+ export declare function syncLockfileFromInstalled(installed: InstalledAsset[], ide?: IdeId, cwd?: string): Promise<Lockfile>;
7
+ //# sourceMappingURL=lockfile-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lockfile-service.d.ts","sourceRoot":"","sources":["../../src/services/lockfile-service.ts"],"names":[],"mappings":"AAEA,OAAO,EAA8B,KAAK,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAkB,KAAK,cAAc,EAAE,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAEvF,wBAAgB,eAAe,CAAC,GAAG,SAAgB,GAAG,MAAM,CAE3D;AAED,wBAAsB,YAAY,CAAC,GAAG,SAAgB,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAQhF;AAED,wBAAsB,aAAa,CACjC,QAAQ,EAAE,cAAc,EAAE,EAC1B,GAAG,GAAE,KAAmB,EACxB,GAAG,SAAgB,GAClB,OAAO,CAAC,QAAQ,CAAC,CAanB;AAED,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,cAAc,EAAE,EAC3B,GAAG,GAAE,KAAmB,EACxB,GAAG,SAAgB,GAClB,OAAO,CAAC,QAAQ,CAAC,CAEnB"}
@@ -0,0 +1,36 @@
1
+ import path from "node:path";
2
+ import fs from "fs-extra";
3
+ import { DEFAULT_IDE, LOCKFILE_NAME } from "../constants/index.js";
4
+ import { LockfileSchema } from "../types/index.js";
5
+ export function getLockfilePath(cwd = process.cwd()) {
6
+ return path.join(cwd, LOCKFILE_NAME);
7
+ }
8
+ export async function readLockfile(cwd = process.cwd()) {
9
+ const lockPath = getLockfilePath(cwd);
10
+ if (!(await fs.pathExists(lockPath)))
11
+ return null;
12
+ try {
13
+ return LockfileSchema.parse(await fs.readJson(lockPath));
14
+ }
15
+ catch {
16
+ return null;
17
+ }
18
+ }
19
+ export async function writeLockfile(packages, ide = DEFAULT_IDE, cwd = process.cwd()) {
20
+ const lockfile = {
21
+ version: 1,
22
+ ide,
23
+ updatedAt: new Date().toISOString(),
24
+ packages: packages
25
+ .filter((p) => p.type !== "preset" || true)
26
+ .map((p) => ({ type: p.type, id: p.id, version: p.version }))
27
+ .sort((a, b) => `${a.type}:${a.id}`.localeCompare(`${b.type}:${b.id}`)),
28
+ };
29
+ const parsed = LockfileSchema.parse(lockfile);
30
+ await fs.writeJson(getLockfilePath(cwd), parsed, { spaces: 2 });
31
+ return parsed;
32
+ }
33
+ export async function syncLockfileFromInstalled(installed, ide = DEFAULT_IDE, cwd = process.cwd()) {
34
+ return writeLockfile(installed, ide, cwd);
35
+ }
36
+ //# sourceMappingURL=lockfile-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lockfile-service.js","sourceRoot":"","sources":["../../src/services/lockfile-service.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,aAAa,EAAc,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAsC,MAAM,mBAAmB,CAAC;AAEvF,MAAM,UAAU,eAAe,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IACjD,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IACpD,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAClD,IAAI,CAAC;QACH,OAAO,cAAc,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,QAA0B,EAC1B,MAAa,WAAW,EACxB,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IAEnB,MAAM,QAAQ,GAAa;QACzB,OAAO,EAAE,CAAC;QACV,GAAG;QACH,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,QAAQ,EAAE,QAAQ;aACf,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC;aAC1C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;aAC5D,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;KAC1E,CAAC;IACF,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,EAAE,CAAC,SAAS,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;IAChE,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,SAA2B,EAC3B,MAAa,WAAW,EACxB,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IAEnB,OAAO,aAAa,CAAC,SAAS,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { HealthScores, ProjectAnalysis, ProjectStack, SearchResult } from "../types/index.js";
2
+ import { type IdeId } from "../constants/index.js";
3
+ export declare function detectProjectStack(cwd?: string): Promise<ProjectStack>;
4
+ export declare function computeHealthScores(cwd?: string, ide?: IdeId): Promise<HealthScores>;
5
+ export declare function recommendPackages(cwd?: string, options?: {
6
+ verbose?: boolean;
7
+ limit?: number;
8
+ }): Promise<SearchResult[]>;
9
+ export declare function analyzeProject(cwd?: string, ide?: IdeId, options?: {
10
+ verbose?: boolean;
11
+ }): Promise<ProjectAnalysis>;
12
+ //# sourceMappingURL=project-awareness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-awareness.d.ts","sourceRoot":"","sources":["../../src/services/project-awareness.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,YAAY,EACb,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAe,KAAK,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAchE,wBAAsB,kBAAkB,CAAC,GAAG,SAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,CAmEnF;AAMD,wBAAsB,mBAAmB,CACvC,GAAG,SAAgB,EACnB,GAAG,GAAE,KAAmB,GACvB,OAAO,CAAC,YAAY,CAAC,CAmEvB;AAcD,wBAAsB,iBAAiB,CACrC,GAAG,SAAgB,EACnB,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAClD,OAAO,CAAC,YAAY,EAAE,CAAC,CA6BzB;AAED,wBAAsB,cAAc,CAClC,GAAG,SAAgB,EACnB,GAAG,GAAE,KAAmB,EACxB,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAClC,OAAO,CAAC,eAAe,CAAC,CAmB1B"}
@@ -0,0 +1,200 @@
1
+ import path from "node:path";
2
+ import fs from "fs-extra";
3
+ import { listRegistryAssets } from "./install-service.js";
4
+ import { listInstalledAssets } from "../metadata/store.js";
5
+ import { DEFAULT_IDE } from "../constants/index.js";
6
+ async function fileExists(cwd, rel) {
7
+ return fs.pathExists(path.join(cwd, rel));
8
+ }
9
+ async function readJsonSafe(cwd, rel) {
10
+ try {
11
+ return (await fs.readJson(path.join(cwd, rel)));
12
+ }
13
+ catch {
14
+ return null;
15
+ }
16
+ }
17
+ export async function detectProjectStack(cwd = process.cwd()) {
18
+ const frameworks = [];
19
+ const languages = [];
20
+ const tools = [];
21
+ const packageManagers = [];
22
+ const pkg = await readJsonSafe(cwd, "package.json");
23
+ const composer = await readJsonSafe(cwd, "composer.json");
24
+ const deps = {
25
+ ...(typeof pkg?.dependencies === "object" && pkg.dependencies
26
+ ? pkg.dependencies
27
+ : {}),
28
+ ...(typeof pkg?.devDependencies === "object" && pkg.devDependencies
29
+ ? pkg.devDependencies
30
+ : {}),
31
+ };
32
+ if (pkg) {
33
+ languages.push("JavaScript/TypeScript");
34
+ if (await fileExists(cwd, "pnpm-lock.yaml"))
35
+ packageManagers.push("pnpm");
36
+ else if (await fileExists(cwd, "yarn.lock"))
37
+ packageManagers.push("yarn");
38
+ else if (await fileExists(cwd, "package-lock.json"))
39
+ packageManagers.push("npm");
40
+ }
41
+ if (composer) {
42
+ languages.push("PHP");
43
+ packageManagers.push("composer");
44
+ const require = (composer.require ?? {});
45
+ if (require["laravel/framework"] || (await fileExists(cwd, "artisan"))) {
46
+ frameworks.push("Laravel");
47
+ }
48
+ }
49
+ if (deps.next || deps["@next/core"] || (await fileExists(cwd, "next.config.js")) || (await fileExists(cwd, "next.config.ts"))) {
50
+ frameworks.push("Next.js");
51
+ }
52
+ if (deps.nuxt || (await fileExists(cwd, "nuxt.config.ts")) || (await fileExists(cwd, "nuxt.config.js"))) {
53
+ frameworks.push("Nuxt");
54
+ }
55
+ if (deps.vue || deps["@vue/runtime-core"])
56
+ frameworks.push("Vue");
57
+ if (deps.react || deps["react-dom"])
58
+ frameworks.push("React");
59
+ if (deps["@nestjs/core"])
60
+ frameworks.push("NestJS");
61
+ if (deps.tailwindcss)
62
+ frameworks.push("Tailwind");
63
+ if (deps.prisma || deps["@prisma/client"] || (await fileExists(cwd, "prisma/schema.prisma"))) {
64
+ frameworks.push("Prisma");
65
+ }
66
+ if (await fileExists(cwd, "Dockerfile") || (await fileExists(cwd, "docker-compose.yml"))) {
67
+ tools.push("Docker");
68
+ }
69
+ if (await fileExists(cwd, ".github/workflows"))
70
+ tools.push("GitHub Actions");
71
+ if (await fileExists(cwd, ".gitlab-ci.yml"))
72
+ tools.push("GitLab CI");
73
+ if (await fileExists(cwd, "railway.toml") || (await fileExists(cwd, "railway.json"))) {
74
+ tools.push("Railway");
75
+ }
76
+ if (await fileExists(cwd, ".git"))
77
+ tools.push("Git");
78
+ for (const ideDir of [".cursor", ".claude", ".windsurf", ".continue", ".cline"]) {
79
+ if (await fileExists(cwd, ideDir))
80
+ tools.push(`AI config (${ideDir})`);
81
+ }
82
+ return {
83
+ frameworks: [...new Set(frameworks)],
84
+ languages: [...new Set(languages)],
85
+ tools: [...new Set(tools)],
86
+ packageManagers: [...new Set(packageManagers)],
87
+ };
88
+ }
89
+ function scoreFromPresence(present, weight = 20) {
90
+ return present ? weight : 0;
91
+ }
92
+ export async function computeHealthScores(cwd = process.cwd(), ide = DEFAULT_IDE) {
93
+ const stack = await detectProjectStack(cwd);
94
+ const installed = await listInstalledAssets(cwd, ide);
95
+ const hasTests = (await fileExists(cwd, "tests")) ||
96
+ (await fileExists(cwd, "__tests__")) ||
97
+ (await fileExists(cwd, "src/tests")) ||
98
+ installed.installed.some((a) => a.id.includes("test") || a.id.includes("qa"));
99
+ const hasDocs = (await fileExists(cwd, "README.md")) ||
100
+ (await fileExists(cwd, "docs")) ||
101
+ installed.installed.some((a) => a.id.includes("readme") || a.id.includes("docs"));
102
+ const hasSecurity = installed.installed.some((a) => a.id.includes("security")) ||
103
+ (await fileExists(cwd, ".env.example"));
104
+ const hasArchitecture = stack.frameworks.length > 0 ||
105
+ installed.installed.some((a) => a.id.includes("architecture") || a.id.includes("api"));
106
+ const architecture = Math.min(10, (scoreFromPresence(stack.frameworks.length > 0, 4) +
107
+ scoreFromPresence(hasArchitecture, 3) +
108
+ scoreFromPresence(stack.tools.includes("Docker"), 1.5) +
109
+ scoreFromPresence(installed.installed.length > 0, 1.5)) /
110
+ 1);
111
+ const security = Math.min(10, (scoreFromPresence(hasSecurity, 4) +
112
+ scoreFromPresence(await fileExists(cwd, ".gitignore"), 2) +
113
+ scoreFromPresence(!(await fileExists(cwd, ".env")), 2) +
114
+ scoreFromPresence(stack.tools.some((t) => t.includes("CI")), 2)) /
115
+ 1);
116
+ const documentation = Math.min(10, (scoreFromPresence(hasDocs, 5) +
117
+ scoreFromPresence(await fileExists(cwd, "LICENSE"), 2) +
118
+ scoreFromPresence(installed.installed.some((a) => a.id.includes("readme")), 3)) /
119
+ 1);
120
+ const testing = Math.min(10, (scoreFromPresence(hasTests, 5) +
121
+ scoreFromPresence(installed.installed.some((a) => a.id.includes("test") || a.id.includes("doctor") || a.id.includes("fix")), 3) +
122
+ scoreFromPresence(await fileExists(cwd, "vitest.config.ts") || await fileExists(cwd, "jest.config.js"), 2)) /
123
+ 1);
124
+ const round = (n) => Math.round(n * 10) / 10;
125
+ const scores = {
126
+ architecture: round(architecture),
127
+ security: round(security),
128
+ documentation: round(documentation),
129
+ testing: round(testing),
130
+ overall: 0,
131
+ };
132
+ scores.overall = round((scores.architecture + scores.security + scores.documentation + scores.testing) / 4);
133
+ return scores;
134
+ }
135
+ const TAG_HINTS = {
136
+ Laravel: ["laravel", "php", "api"],
137
+ React: ["react", "spa", "dashboard"],
138
+ "Next.js": ["nextjs", "marketing", "seo"],
139
+ Nuxt: ["nuxt", "vue", "marketing"],
140
+ Vue: ["vue", "nuxt"],
141
+ NestJS: ["nestjs", "node", "typescript"],
142
+ Prisma: ["prisma"],
143
+ Docker: ["docker"],
144
+ Tailwind: ["tailwind"],
145
+ };
146
+ export async function recommendPackages(cwd = process.cwd(), options = {}) {
147
+ const stack = await detectProjectStack(cwd);
148
+ const registry = await listRegistryAssets(undefined, { verbose: options.verbose });
149
+ const wantedTags = new Set();
150
+ for (const fw of [...stack.frameworks, ...stack.tools]) {
151
+ for (const tag of TAG_HINTS[fw] ?? [fw.toLowerCase()]) {
152
+ wantedTags.add(tag);
153
+ }
154
+ }
155
+ // Always useful baselines
156
+ for (const tag of ["git", "docs", "architecture", "qa"])
157
+ wantedTags.add(tag);
158
+ const scored = registry.assets
159
+ .map((asset) => {
160
+ const tags = asset.tags ?? [];
161
+ let score = 0;
162
+ for (const tag of tags) {
163
+ if (wantedTags.has(tag.toLowerCase()))
164
+ score += 10;
165
+ }
166
+ for (const fw of stack.frameworks) {
167
+ if (asset.id.toLowerCase().includes(fw.toLowerCase().replace(/\./g, "")))
168
+ score += 20;
169
+ if (asset.description?.toLowerCase().includes(fw.toLowerCase()))
170
+ score += 5;
171
+ }
172
+ return { ...asset, score };
173
+ })
174
+ .filter((a) => (a.score ?? 0) > 0)
175
+ .sort((a, b) => (b.score ?? 0) - (a.score ?? 0));
176
+ return scored.slice(0, options.limit ?? 8);
177
+ }
178
+ export async function analyzeProject(cwd = process.cwd(), ide = DEFAULT_IDE, options = {}) {
179
+ const stack = await detectProjectStack(cwd);
180
+ const health = await computeHealthScores(cwd, ide);
181
+ const recommendations = await recommendPackages(cwd, options);
182
+ const installed = await listInstalledAssets(cwd, ide);
183
+ const installedIds = new Set(installed.installed.map((a) => `${a.type}:${a.id}`));
184
+ const missing = [];
185
+ if (health.testing < 5)
186
+ missing.push("Testing");
187
+ if (health.documentation < 5)
188
+ missing.push("Documentation");
189
+ if (health.security < 5)
190
+ missing.push("Security");
191
+ if (health.architecture < 5)
192
+ missing.push("Architecture");
193
+ return {
194
+ stack,
195
+ health,
196
+ missing,
197
+ recommendations: recommendations.filter((r) => !installedIds.has(`${r.type}:${r.id}`)),
198
+ };
199
+ }
200
+ //# sourceMappingURL=project-awareness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-awareness.js","sourceRoot":"","sources":["../../src/services/project-awareness.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import { type IdeId } from "../constants/index.js";
2
+ import { type InstallResult, type WorkspaceConfig } from "../types/index.js";
3
+ import { analyzeProject } from "./project-awareness.js";
4
+ export declare function getWorkspacePath(cwd?: string): string;
5
+ export declare function readWorkspace(cwd?: string): Promise<WorkspaceConfig | null>;
6
+ export declare function writeWorkspace(config: WorkspaceConfig, cwd?: string): Promise<WorkspaceConfig>;
7
+ export declare function initWorkspace(options?: {
8
+ ide?: IdeId;
9
+ packages?: string[];
10
+ registry?: string;
11
+ }, cwd?: string): Promise<WorkspaceConfig>;
12
+ export declare function syncWorkspace(options?: {
13
+ yes?: boolean;
14
+ dryRun?: boolean;
15
+ verbose?: boolean;
16
+ force?: boolean;
17
+ }, cwd?: string): Promise<InstallResult[]>;
18
+ export interface BootstrapPlan {
19
+ analysis: Awaited<ReturnType<typeof analyzeProject>>;
20
+ packages: string[];
21
+ ide: IdeId;
22
+ }
23
+ /** Analyse the project and return recommended packages (no install). */
24
+ export declare function planBootstrap(options?: {
25
+ verbose?: boolean;
26
+ ide?: IdeId;
27
+ all?: boolean;
28
+ }, cwd?: string): Promise<BootstrapPlan>;
29
+ /** Write workspace config and install planned packages. */
30
+ export declare function applyBootstrap(plan: BootstrapPlan, options?: {
31
+ yes?: boolean;
32
+ dryRun?: boolean;
33
+ verbose?: boolean;
34
+ }, cwd?: string): Promise<InstallResult[]>;
35
+ export declare function bootstrapProject(options?: {
36
+ yes?: boolean;
37
+ dryRun?: boolean;
38
+ verbose?: boolean;
39
+ ide?: IdeId;
40
+ all?: boolean;
41
+ /** When false, skip install (caller already confirmed or user declined). */
42
+ install?: boolean;
43
+ }, cwd?: string): Promise<{
44
+ analysis: Awaited<ReturnType<typeof analyzeProject>>;
45
+ packages: string[];
46
+ results: InstallResult[];
47
+ }>;
48
+ export declare function suggestWorkspacePackages(cwd?: string): Promise<string[]>;
49
+ //# sourceMappingURL=workspace-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-service.d.ts","sourceRoot":"","sources":["../../src/services/workspace-service.ts"],"names":[],"mappings":"AAEA,OAAO,EAA+B,KAAK,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAGhF,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,eAAe,EACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAqB,MAAM,wBAAwB,CAAC;AAI3E,wBAAgB,gBAAgB,CAAC,GAAG,SAAgB,GAAG,MAAM,CAE5D;AAED,wBAAsB,aAAa,CAAC,GAAG,SAAgB,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAQxF;AAED,wBAAsB,cAAc,CAClC,MAAM,EAAE,eAAe,EACvB,GAAG,SAAgB,GAClB,OAAO,CAAC,eAAe,CAAC,CAI1B;AAED,wBAAsB,aAAa,CACjC,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,EACrE,GAAG,SAAgB,GAClB,OAAO,CAAC,eAAe,CAAC,CAW1B;AAED,wBAAsB,aAAa,CACjC,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,EACrF,GAAG,SAAgB,GAClB,OAAO,CAAC,aAAa,EAAE,CAAC,CAiB1B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC;IACrD,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,GAAG,EAAE,KAAK,CAAC;CACZ;AAED,wEAAwE;AACxE,wBAAsB,aAAa,CACjC,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,KAAK,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAO,EAC/D,GAAG,SAAgB,GAClB,OAAO,CAAC,aAAa,CAAC,CAOxB;AAED,2DAA2D;AAC3D,wBAAsB,cAAc,CAClC,IAAI,EAAE,aAAa,EACnB,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,EACpE,GAAG,SAAgB,GAClB,OAAO,CAAC,aAAa,EAAE,CAAC,CAgB1B;AAED,wBAAsB,gBAAgB,CACpC,OAAO,GAAE;IACP,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,KAAK,CAAC;IACZ,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,4EAA4E;IAC5E,OAAO,CAAC,EAAE,OAAO,CAAC;CACd,EACN,GAAG,SAAgB,GAClB,OAAO,CAAC;IACT,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC;IACrD,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B,CAAC,CAOD;AAED,wBAAsB,wBAAwB,CAAC,GAAG,SAAgB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAGrF"}
@@ -0,0 +1,92 @@
1
+ import path from "node:path";
2
+ import fs from "fs-extra";
3
+ import { DEFAULT_IDE, WORKSPACE_FILE } from "../constants/index.js";
4
+ import { ValidationError } from "../core/errors.js";
5
+ import { logInfo, logSuccess } from "../core/logger.js";
6
+ import { WorkspaceConfigSchema, } from "../types/index.js";
7
+ import { analyzeProject, recommendPackages } from "./project-awareness.js";
8
+ import { installByPackageNames } from "./install-service.js";
9
+ import { appendAudit } from "../metadata/user-store.js";
10
+ export function getWorkspacePath(cwd = process.cwd()) {
11
+ return path.join(cwd, WORKSPACE_FILE);
12
+ }
13
+ export async function readWorkspace(cwd = process.cwd()) {
14
+ const filePath = getWorkspacePath(cwd);
15
+ if (!(await fs.pathExists(filePath)))
16
+ return null;
17
+ try {
18
+ return WorkspaceConfigSchema.parse(await fs.readJson(filePath));
19
+ }
20
+ catch (error) {
21
+ throw new ValidationError(`Invalid ${WORKSPACE_FILE}: ${String(error)}`);
22
+ }
23
+ }
24
+ export async function writeWorkspace(config, cwd = process.cwd()) {
25
+ const parsed = WorkspaceConfigSchema.parse(config);
26
+ await fs.writeJson(getWorkspacePath(cwd), parsed, { spaces: 2 });
27
+ return parsed;
28
+ }
29
+ export async function initWorkspace(options = {}, cwd = process.cwd()) {
30
+ const existing = await readWorkspace(cwd);
31
+ const config = {
32
+ packages: options.packages ?? existing?.packages ?? [],
33
+ ide: options.ide ?? existing?.ide ?? DEFAULT_IDE,
34
+ registry: options.registry ?? existing?.registry,
35
+ settings: existing?.settings ?? {},
36
+ };
37
+ const written = await writeWorkspace(config, cwd);
38
+ logSuccess(`Wrote ${WORKSPACE_FILE}`);
39
+ return written;
40
+ }
41
+ export async function syncWorkspace(options = {}, cwd = process.cwd()) {
42
+ const config = await readWorkspace(cwd);
43
+ if (!config || config.packages.length === 0) {
44
+ throw new ValidationError(`No packages in ${WORKSPACE_FILE}. Run \`noah-cursor workspace init\` or \`noah-cursor bootstrap\` first.`);
45
+ }
46
+ logInfo(`Syncing ${config.packages.length} package(s) from ${WORKSPACE_FILE}`);
47
+ await appendAudit("sync", config.packages.join(", "));
48
+ return installByPackageNames(config.packages, {
49
+ ide: config.ide,
50
+ yes: options.yes,
51
+ dryRun: options.dryRun,
52
+ verbose: options.verbose,
53
+ force: options.force ?? true,
54
+ });
55
+ }
56
+ /** Analyse the project and return recommended packages (no install). */
57
+ export async function planBootstrap(options = {}, cwd = process.cwd()) {
58
+ const ide = options.ide ?? DEFAULT_IDE;
59
+ const analysis = await analyzeProject(cwd, ide, { verbose: options.verbose });
60
+ const recommended = analysis.recommendations.map((r) => `${r.type}/${r.id}`);
61
+ const packages = !options.all && recommended.length > 5 ? recommended.slice(0, 5) : recommended;
62
+ return { analysis, packages, ide };
63
+ }
64
+ /** Write workspace config and install planned packages. */
65
+ export async function applyBootstrap(plan, options = {}, cwd = process.cwd()) {
66
+ if (plan.packages.length === 0) {
67
+ logInfo("No recommended packages to install.");
68
+ return [];
69
+ }
70
+ await initWorkspace({ ide: plan.ide, packages: plan.packages }, cwd);
71
+ await appendAudit("bootstrap", plan.packages.join(", "));
72
+ return installByPackageNames(plan.packages, {
73
+ ide: plan.ide,
74
+ yes: options.yes ?? true,
75
+ dryRun: options.dryRun,
76
+ verbose: options.verbose,
77
+ force: false,
78
+ });
79
+ }
80
+ export async function bootstrapProject(options = {}, cwd = process.cwd()) {
81
+ const plan = await planBootstrap(options, cwd);
82
+ if (options.install === false) {
83
+ return { analysis: plan.analysis, packages: plan.packages, results: [] };
84
+ }
85
+ const results = await applyBootstrap(plan, options, cwd);
86
+ return { analysis: plan.analysis, packages: plan.packages, results };
87
+ }
88
+ export async function suggestWorkspacePackages(cwd = process.cwd()) {
89
+ const recs = await recommendPackages(cwd);
90
+ return recs.map((r) => `${r.type}/${r.id}`);
91
+ }
92
+ //# sourceMappingURL=workspace-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-service.js","sourceRoot":"","sources":["../../src/services/workspace-service.ts"],"names":[],"mappings":"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"}