@happyvertical/smrt-dev-mcp 0.40.62 → 0.40.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +31 -1
- package/README.md +10 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -8
- package/dist/index.js.map +1 -1
- package/dist/knowledge/index.d.ts +36 -3
- package/dist/knowledge/index.d.ts.map +1 -1
- package/dist/{knowledge-DUUhTM5u.js → knowledge-CCX7oQzQ.js} +122 -30
- package/dist/knowledge-CCX7oQzQ.js.map +1 -0
- package/dist/knowledge.js +1 -1
- package/package.json +4 -4
- package/dist/knowledge-DUUhTM5u.js.map +0 -1
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { DomainKnowledgeManifest, DomainKnowledgeModuleDoc } from '@happyvertical/smrt-types';
|
|
2
2
|
export type KnowledgePackageKind = 'smrt' | 'sdk' | 'workspace';
|
|
3
3
|
export type KnowledgeIssueSeverity = 'error' | 'warning';
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* `installed` is the consumer-app scope (#2275): installed
|
|
6
|
+
* `@happyvertical/smrt-*` packages and packages in the known HappyVertical SDK
|
|
7
|
+
* allowlist, rather than packages the project authors. The other scopes all
|
|
8
|
+
* describe the workspace's own sources.
|
|
9
|
+
*/
|
|
10
|
+
export type KnowledgeScope = 'project' | 'local' | 'package' | 'sdk' | 'installed';
|
|
5
11
|
/**
|
|
6
12
|
* Where a package's objects actually came from (#2143). Recording provenance is
|
|
7
13
|
* what makes an empty answer distinguishable from an unseen one: `none` means
|
|
@@ -64,6 +70,15 @@ export interface KnowledgePackage {
|
|
|
64
70
|
hasClaudeShim: boolean;
|
|
65
71
|
docSource: 'AGENTS.md' | 'CLAUDE.md' | null;
|
|
66
72
|
agentDoc?: string;
|
|
73
|
+
/**
|
|
74
|
+
* SHA-256 of the shipped `AGENTS.md`, when there is one.
|
|
75
|
+
*
|
|
76
|
+
* A version bump is a poor drift signal because most releases do not touch a
|
|
77
|
+
* package's documented surface. This hash is the stable identity a consumer
|
|
78
|
+
* diffs against its own recorded baseline to answer "which installed packages
|
|
79
|
+
* changed their documented surface since I last verified my copy?" (#2275).
|
|
80
|
+
*/
|
|
81
|
+
agentDocSha256?: string;
|
|
67
82
|
/**
|
|
68
83
|
* Sibling module docs linked from the package's `AGENTS.md` (#2108). Oversized
|
|
69
84
|
* package docs are split by module into `agents/<module>.md` rather than nested
|
|
@@ -84,6 +99,13 @@ export interface KnowledgePackage {
|
|
|
84
99
|
isWorkspaceRoot: boolean;
|
|
85
100
|
/** `private: true` packages publish nothing, so packaging rules do not apply. */
|
|
86
101
|
isPrivate: boolean;
|
|
102
|
+
/**
|
|
103
|
+
* True when the package was resolved out of `node_modules` rather than
|
|
104
|
+
* authored in this workspace. This repository's docs and packaging rules do
|
|
105
|
+
* not apply to it — a consumer cannot add an `AGENTS.md` to a dependency —
|
|
106
|
+
* so the freshness gate skips it entirely: indexed, never checked (#2275).
|
|
107
|
+
*/
|
|
108
|
+
isInstalledDependency: boolean;
|
|
87
109
|
objectSource: KnowledgeObjectSource;
|
|
88
110
|
/**
|
|
89
111
|
* Machine-readable reason a package produced no objects, or a note about
|
|
@@ -124,13 +146,24 @@ export interface KnowledgeDiagnostic {
|
|
|
124
146
|
remedy?: string;
|
|
125
147
|
}
|
|
126
148
|
export interface SmrtKnowledgeIndex {
|
|
127
|
-
/**
|
|
128
|
-
|
|
149
|
+
/**
|
|
150
|
+
* 2 adds `coverage` and `diagnostics` (additive, #2143); 3 adds
|
|
151
|
+
* `installedPackages` plus each package's `isInstalledDependency` and
|
|
152
|
+
* `agentDocSha256` (additive, #2275).
|
|
153
|
+
*/
|
|
154
|
+
schemaVersion: 3;
|
|
129
155
|
generatedAt: string;
|
|
130
156
|
rootDir: string;
|
|
131
157
|
packages: KnowledgePackage[];
|
|
132
158
|
smrtPackages: KnowledgePackage[];
|
|
133
159
|
sdkPackages: KnowledgePackage[];
|
|
160
|
+
/**
|
|
161
|
+
* Installed `@happyvertical/*` dependencies, SMRT and SDK alike. In a
|
|
162
|
+
* consumer app this is the whole audit surface. In this monorepo it holds the
|
|
163
|
+
* registry-installed SDK packages; the `smrt-*` names resolve to workspace
|
|
164
|
+
* copies, which win the name-keyed dedupe (#2275).
|
|
165
|
+
*/
|
|
166
|
+
installedPackages: KnowledgePackage[];
|
|
134
167
|
relationshipsV2: {
|
|
135
168
|
foreignKeyFields: number;
|
|
136
169
|
crossPackageRefFields: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/knowledge/index.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EACV,uBAAuB,EACvB,wBAAwB,EACzB,MAAM,2BAA2B,CAAC;AAEnC,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,KAAK,GAAG,WAAW,CAAC;AAChE,MAAM,MAAM,sBAAsB,GAAG,OAAO,GAAG,SAAS,CAAC;AACzD,MAAM,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/knowledge/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -117,7 +117,7 @@ async function buildKnowledgeIndex(options = {}) {
|
|
|
117
117
|
packages.push(readKnowledgePackage(rootDir, dir, includeDocs));
|
|
118
118
|
}
|
|
119
119
|
await applyScannerFallbacks(packages, packageDirs.filter((dir) => resolve(dir) !== resolve(rootDir)).map((dir) => `${relative(rootDir, dir).replaceAll("\\", "/")}/**`));
|
|
120
|
-
packages.push(...
|
|
120
|
+
packages.push(...discoverInstalledPackages(rootDir, packageDirs, includeDocs));
|
|
121
121
|
const uniquePackages = dedupePackages(packages);
|
|
122
122
|
const scopedPackages = filterKnowledgePackages(uniquePackages, options);
|
|
123
123
|
const smrtPackages = scopedPackages.filter((pkg) => pkg.kind === "smrt");
|
|
@@ -130,24 +130,26 @@ async function buildKnowledgeIndex(options = {}) {
|
|
|
130
130
|
packages: uniquePackages
|
|
131
131
|
});
|
|
132
132
|
return {
|
|
133
|
-
schemaVersion:
|
|
133
|
+
schemaVersion: 3,
|
|
134
134
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
135
135
|
rootDir,
|
|
136
136
|
packages: scopedPackages,
|
|
137
137
|
smrtPackages,
|
|
138
138
|
sdkPackages,
|
|
139
|
+
installedPackages: scopedPackages.filter((pkg) => pkg.isInstalledDependency),
|
|
139
140
|
relationshipsV2: summarizeRelationshipsV2(scopedPackages),
|
|
140
141
|
coverage,
|
|
141
142
|
diagnostics: buildIndexDiagnostics(rootDir, uniquePackages, coverage, discoveryDiagnostics)
|
|
142
143
|
};
|
|
143
144
|
}
|
|
144
145
|
function buildCoverage(options) {
|
|
146
|
+
const authored = options.packages.filter((pkg) => !pkg.isInstalledDependency);
|
|
145
147
|
return {
|
|
146
148
|
workspaceGlobs: options.globs,
|
|
147
149
|
workspaceGlobSource: options.globSource,
|
|
148
150
|
packageDirs: options.packageDirs.map((dir) => relative(options.rootDir, dir) || "."),
|
|
149
|
-
packagesWithObjects:
|
|
150
|
-
packagesWithoutObjects:
|
|
151
|
+
packagesWithObjects: authored.filter((pkg) => pkg.objects.length > 0).map((pkg) => `${pkg.name} (${pkg.objects.length}, ${pkg.objectSource})`),
|
|
152
|
+
packagesWithoutObjects: authored.filter((pkg) => pkg.objects.length === 0).map((pkg) => ({
|
|
151
153
|
name: pkg.name,
|
|
152
154
|
reason: pkg.objectSourceReason ?? pkg.objectSource,
|
|
153
155
|
checkedPaths: pkg.checkedObjectPaths,
|
|
@@ -171,7 +173,25 @@ function remedyForReason(pkg) {
|
|
|
171
173
|
*/
|
|
172
174
|
function buildIndexDiagnostics(rootDir, packages, coverage, discoveryDiagnostics = []) {
|
|
173
175
|
const diagnostics = [...discoveryDiagnostics];
|
|
174
|
-
|
|
176
|
+
const authoredPackages = packages.filter((pkg) => !pkg.isInstalledDependency);
|
|
177
|
+
const authoredObjects = authoredPackages.reduce((total, pkg) => total + pkg.objects.length, 0);
|
|
178
|
+
const installedObjects = packages.reduce((total, pkg) => total + (pkg.isInstalledDependency ? pkg.objects.length : 0), 0);
|
|
179
|
+
if (authoredObjects === 0 && installedObjects > 0) diagnostics.push({
|
|
180
|
+
severity: "warning",
|
|
181
|
+
code: "no-authored-smrt-objects",
|
|
182
|
+
message: [
|
|
183
|
+
`No SMRT objects were discovered in the project's own packages under ${rootDir},`,
|
|
184
|
+
`though ${installedObjects} were read from installed dependencies.`,
|
|
185
|
+
"Expected for an application that only consumes the framework;",
|
|
186
|
+
"a discovery failure if this workspace is supposed to declare @smrt() classes."
|
|
187
|
+
].join(" "),
|
|
188
|
+
remedy: [
|
|
189
|
+
"If this workspace authors SMRT objects, confirm rootDir is the workspace root,",
|
|
190
|
+
"confirm the workspace globs cover the directories that hold @smrt() classes,",
|
|
191
|
+
"and run `pnpm build` in the owning package to emit .smrt/manifest.json."
|
|
192
|
+
].join(" ")
|
|
193
|
+
});
|
|
194
|
+
if (authoredObjects === 0 && installedObjects === 0) diagnostics.push({
|
|
175
195
|
severity: "error",
|
|
176
196
|
code: "no-smrt-objects-discovered",
|
|
177
197
|
message: [
|
|
@@ -180,7 +200,7 @@ function buildIndexDiagnostics(rootDir, packages, coverage, discoveryDiagnostics
|
|
|
180
200
|
`Package directories checked (${coverage.packageDirs.length}): ${coverage.packageDirs.join(", ") || "(none)"}.`,
|
|
181
201
|
"Treat this as a discovery failure, not as evidence that the project has no SMRT model."
|
|
182
202
|
].join(" "),
|
|
183
|
-
checkedPaths: [...new Set(
|
|
203
|
+
checkedPaths: [...new Set(authoredPackages.flatMap((pkg) => pkg.checkedObjectPaths))],
|
|
184
204
|
remedy: [
|
|
185
205
|
"Confirm rootDir is the workspace root;",
|
|
186
206
|
"confirm pnpm-workspace.yaml `packages:` covers the directories that hold @smrt() classes (for example apps/*);",
|
|
@@ -250,10 +270,11 @@ async function checkKnowledgeFreshness(options = {}) {
|
|
|
250
270
|
async function checkKnowledgeFreshnessFromIndex(index, options = {}) {
|
|
251
271
|
const issues = [];
|
|
252
272
|
const changedFiles = options.changed ? getChangedFiles(index.rootDir) : void 0;
|
|
253
|
-
const
|
|
254
|
-
const
|
|
273
|
+
const authoredPackages = index.packages.filter((item) => !item.isInstalledDependency);
|
|
274
|
+
const hasMemberPackages = authoredPackages.some((item) => item.kind !== "sdk" && !item.isWorkspaceRoot);
|
|
275
|
+
const memberDirectories = authoredPackages.filter((item) => item.kind !== "sdk" && !item.isWorkspaceRoot && item.relativeDirectory).map((item) => item.relativeDirectory);
|
|
255
276
|
const isNestedMember = (pkg) => Boolean(pkg.relativeDirectory) && memberDirectories.some((directory) => directory !== pkg.relativeDirectory && pkg.relativeDirectory.startsWith(`${directory}/`));
|
|
256
|
-
for (const pkg of
|
|
277
|
+
for (const pkg of authoredPackages.filter((item) => item.kind !== "sdk" && !(item.isWorkspaceRoot && hasMemberPackages))) {
|
|
257
278
|
const packageJsonPath = join(pkg.directory, "package.json");
|
|
258
279
|
const nested = isNestedMember(pkg);
|
|
259
280
|
if (!pkg.hasAgentsMd && !nested) issues.push({
|
|
@@ -310,7 +331,7 @@ async function checkKnowledgeFreshnessFromIndex(index, options = {}) {
|
|
|
310
331
|
packageName: pkg.name
|
|
311
332
|
});
|
|
312
333
|
}
|
|
313
|
-
for (const pkg of
|
|
334
|
+
for (const pkg of authoredPackages) issues.push(...checkDomainKnowledgeArtifact(index.rootDir, pkg));
|
|
314
335
|
issues.push(...findStalePatternIssues(index.rootDir, changedFiles));
|
|
315
336
|
const effectiveIssues = issues.map((issue) => issue.code.startsWith("stale-") ? {
|
|
316
337
|
...issue,
|
|
@@ -517,6 +538,7 @@ function renderKnowledgeIndexMarkdown(index) {
|
|
|
517
538
|
"",
|
|
518
539
|
`- SMRT packages: ${index.smrtPackages.length}`,
|
|
519
540
|
`- SDK packages: ${index.sdkPackages.length}`,
|
|
541
|
+
`- Installed dependencies: ${index.installedPackages.length}`,
|
|
520
542
|
`- foreignKey fields: ${index.relationshipsV2.foreignKeyFields}`,
|
|
521
543
|
`- crossPackageRef fields: ${index.relationshipsV2.crossPackageRefFields}`,
|
|
522
544
|
`- junction collections: ${index.relationshipsV2.junctionCollections}`,
|
|
@@ -540,6 +562,10 @@ function renderKnowledgeIndexMarkdown(index) {
|
|
|
540
562
|
lines.push(`- MCP tools: ${pkg.mcpTools.length}`);
|
|
541
563
|
lines.push(`- domain knowledge: ${pkg.domainKnowledgePath ?? "(manifest fallback)"}`);
|
|
542
564
|
lines.push(`- docs: ${pkg.docSource ?? "(none)"}${pkg.hasClaudeShim ? " + CLAUDE.md shim" : ""}`);
|
|
565
|
+
if (pkg.isInstalledDependency) {
|
|
566
|
+
lines.push("- source: installed dependency");
|
|
567
|
+
lines.push(`- AGENTS.md sha256: ${pkg.agentDocSha256 ?? "(none)"}`);
|
|
568
|
+
}
|
|
543
569
|
if (pkg.moduleDocs.length > 0) lines.push(`- module docs: ${pkg.moduleDocs.map((doc) => doc.path).join(", ")}`);
|
|
544
570
|
if (pkg.relationshipFeatures.length > 0) lines.push(`- relationships-v2: ${pkg.relationshipFeatures.join(", ")}`);
|
|
545
571
|
lines.push("");
|
|
@@ -817,34 +843,85 @@ function discoverProjectPackageDirs(rootDir) {
|
|
|
817
843
|
diagnostics: expansion.diagnostics
|
|
818
844
|
};
|
|
819
845
|
}
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
846
|
+
/**
|
|
847
|
+
* Installed `@happyvertical/*` packages, resolved once each (#2275).
|
|
848
|
+
*
|
|
849
|
+
* Reads the `@happyvertical` scope directory of the project and of every
|
|
850
|
+
* workspace package — one `readdir` per scope directory, resolving each entry's
|
|
851
|
+
* real path — instead of descending through `node_modules`. Under pnpm those
|
|
852
|
+
* entries are symlinks into a store whose entries link back out to each other,
|
|
853
|
+
* so a descent revisits the same package once per path that reaches it. The
|
|
854
|
+
* realpath is the dedupe key only: the same store entry reached from three
|
|
855
|
+
* scope directories is read once, but it is read through its `node_modules`
|
|
856
|
+
* path, because a realpath is the wrong thing to report. On a host where any
|
|
857
|
+
* ancestor of the root is a symlink (`/var` on macOS, a symlinked worktree),
|
|
858
|
+
* `relative(rootDir, realpath)` escapes the root entirely.
|
|
859
|
+
*
|
|
860
|
+
* Workspace packages linked into a sibling's `node_modules` are skipped here.
|
|
861
|
+
* They are authored source that happens to be reachable through a link, and
|
|
862
|
+
* calling them installed would exempt them from the freshness gate.
|
|
863
|
+
*
|
|
864
|
+
* Both SMRT and SDK packages are returned. A consumer app authors neither, and
|
|
865
|
+
* its `@happyvertical/smrt-*` dependencies are exactly the surface it needs to
|
|
866
|
+
* audit; excluding them is why the index could see nothing in a consumer app.
|
|
867
|
+
*/
|
|
868
|
+
function discoverInstalledPackages(rootDir, packageDirs, includeDocs) {
|
|
869
|
+
const scopeDirs = [join(rootDir, "node_modules", "@happyvertical"), ...packageDirs.map((dir) => join(dir, "node_modules", "@happyvertical"))];
|
|
870
|
+
const workspaceRealPaths = new Set([rootDir, ...packageDirs].flatMap((dir) => {
|
|
871
|
+
try {
|
|
872
|
+
return [realpathSync(dir)];
|
|
873
|
+
} catch {
|
|
874
|
+
return [];
|
|
875
|
+
}
|
|
876
|
+
}));
|
|
877
|
+
const byRealPath = /* @__PURE__ */ new Map();
|
|
878
|
+
for (const scopeDir of new Set(scopeDirs)) {
|
|
879
|
+
if (!existsSync(scopeDir)) continue;
|
|
880
|
+
let entries;
|
|
823
881
|
try {
|
|
824
|
-
|
|
882
|
+
entries = readdirSync(scopeDir, { withFileTypes: true });
|
|
825
883
|
} catch {
|
|
826
|
-
|
|
884
|
+
continue;
|
|
827
885
|
}
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
886
|
+
for (const entry of entries) {
|
|
887
|
+
if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;
|
|
888
|
+
const entryPath = join(scopeDir, entry.name);
|
|
889
|
+
let resolved;
|
|
890
|
+
try {
|
|
891
|
+
resolved = realpathSync(entryPath);
|
|
892
|
+
} catch {
|
|
893
|
+
continue;
|
|
894
|
+
}
|
|
895
|
+
if (workspaceRealPaths.has(resolved)) continue;
|
|
896
|
+
if (byRealPath.has(resolved)) continue;
|
|
897
|
+
byRealPath.set(resolved, entryPath);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
const packages = [];
|
|
901
|
+
for (const directory of byRealPath.values()) {
|
|
902
|
+
const name = objectRecord(readJson(join(directory, "package.json"))).name;
|
|
903
|
+
if (typeof name !== "string") continue;
|
|
904
|
+
if (!SDK_PACKAGE_NAMES.has(name) && !name.startsWith("@happyvertical/smrt-")) continue;
|
|
905
|
+
packages.push(readKnowledgePackage(rootDir, directory, includeDocs, { installed: true }));
|
|
906
|
+
}
|
|
907
|
+
return packages.sort((a, b) => a.name.localeCompare(b.name));
|
|
832
908
|
}
|
|
833
909
|
function filterKnowledgePackages(packages, options) {
|
|
834
910
|
const packageQuery = options.packageName ?? options.package;
|
|
835
911
|
return packages.filter((pkg) => {
|
|
836
912
|
if (packageQuery && !packageMatches(pkg, packageQuery.toLowerCase())) return false;
|
|
837
913
|
switch (options.scope) {
|
|
838
|
-
case "local": return pkg.kind !== "sdk" && !pkg.relativeDirectory.includes("node_modules");
|
|
839
|
-
case "package": return pkg.kind !== "sdk";
|
|
914
|
+
case "local": return pkg.kind !== "sdk" && !pkg.isInstalledDependency && !pkg.relativeDirectory.includes("node_modules");
|
|
915
|
+
case "package": return pkg.kind !== "sdk" && !pkg.isInstalledDependency;
|
|
840
916
|
case "sdk": return pkg.kind === "sdk";
|
|
917
|
+
case "installed": return pkg.isInstalledDependency;
|
|
841
918
|
case "project":
|
|
842
919
|
case void 0: return true;
|
|
843
920
|
default: return true;
|
|
844
921
|
}
|
|
845
922
|
});
|
|
846
923
|
}
|
|
847
|
-
function readKnowledgePackage(rootDir, directory, includeDocs) {
|
|
924
|
+
function readKnowledgePackage(rootDir, directory, includeDocs, options = {}) {
|
|
848
925
|
const packageJson = objectRecord(readJson(join(directory, "package.json")));
|
|
849
926
|
const dependencies = stringRecord(packageJson.dependencies);
|
|
850
927
|
const devDependencies = stringRecord(packageJson.devDependencies);
|
|
@@ -894,6 +971,7 @@ function readKnowledgePackage(rootDir, directory, includeDocs) {
|
|
|
894
971
|
hasClaudeShim: claudeContent.trim() === "@AGENTS.md",
|
|
895
972
|
docSource,
|
|
896
973
|
agentDoc: includeDocs ? domainKnowledge?.content.agentDoc || (hasAgentsMd ? agentsContent : fallbackClaudeDoc || void 0) : void 0,
|
|
974
|
+
agentDocSha256: hasAgentsMd ? createHash("sha256").update(agentsContent).digest("hex") : void 0,
|
|
897
975
|
moduleDocs: includeDocs ? domainKnowledge?.content.moduleDocs ?? readAgentModuleDocs(directory, agentsContent || void 0) : [],
|
|
898
976
|
hasDomainKnowledge: Boolean(domainKnowledge),
|
|
899
977
|
domainKnowledgePath: domainKnowledge?.path ? relative(rootDir, domainKnowledge.path) : void 0,
|
|
@@ -906,6 +984,7 @@ function readKnowledgePackage(rootDir, directory, includeDocs) {
|
|
|
906
984
|
relationshipFeatures: relationshipFeatures(objects),
|
|
907
985
|
isWorkspaceRoot: resolve(directory) === resolve(rootDir),
|
|
908
986
|
isPrivate: packageJson.private === true,
|
|
987
|
+
isInstalledDependency: options.installed === true,
|
|
909
988
|
objectSource: resolvedObjects.source,
|
|
910
989
|
objectSourceReason: resolvedObjects.reason,
|
|
911
990
|
checkedObjectPaths: resolvedObjects.checkedPaths
|
|
@@ -1547,7 +1626,7 @@ function selectPackages(index, options) {
|
|
|
1547
1626
|
const selected = /* @__PURE__ */ new Set();
|
|
1548
1627
|
const packageName = options.packageName?.toLowerCase();
|
|
1549
1628
|
if (packageName) {
|
|
1550
|
-
for (const pkg of domainPackages(index)) if (packageMatches(pkg, packageName)) selected.add(pkg);
|
|
1629
|
+
for (const pkg of domainPackages(index)) if (scopeAllowsPackage(pkg, options.scope) && packageMatches(pkg, packageName)) selected.add(pkg);
|
|
1551
1630
|
}
|
|
1552
1631
|
for (const pkg of selectPackagesForFiles(index, options.changedFiles ?? [])) if (scopeAllowsPackage(pkg, options.scope)) selected.add(pkg);
|
|
1553
1632
|
const text = (options.text ?? "").toLowerCase();
|
|
@@ -1565,7 +1644,7 @@ function selectPackages(index, options) {
|
|
|
1565
1644
|
"@happyvertical/smrt-dev-mcp"
|
|
1566
1645
|
]) {
|
|
1567
1646
|
const pkg = index.smrtPackages.find((item) => item.name === name);
|
|
1568
|
-
if (pkg) selected.add(pkg);
|
|
1647
|
+
if (pkg && scopeAllowsPackage(pkg, options.scope)) selected.add(pkg);
|
|
1569
1648
|
}
|
|
1570
1649
|
if (selected.size === 0) {
|
|
1571
1650
|
const contributing = domainPackages(index).filter((pkg) => pkg.objects.length > 0 && scopeAllowsPackage(pkg, options.scope) && !pkg.relativeDirectory.includes("node_modules")).sort((a, b) => b.objects.length - a.objects.length).slice(0, MAX_FALLBACK_PACKAGES);
|
|
@@ -1580,28 +1659,41 @@ function selectSdkPackages(index, selectedPackages, texts, options = {}) {
|
|
|
1580
1659
|
const text = texts.filter(Boolean).join("\n").toLowerCase();
|
|
1581
1660
|
const packageName = options.packageName?.toLowerCase();
|
|
1582
1661
|
for (const sdk of index.sdkPackages) {
|
|
1662
|
+
const selectedDependency = sdkNames.has(sdk.name);
|
|
1663
|
+
if (!scopeAllowsSdkPackage(sdk, options.scope, selectedDependency)) continue;
|
|
1583
1664
|
const shortName = sdk.name.replace("@happyvertical/", "");
|
|
1584
|
-
if (options.scope === "sdk" ||
|
|
1665
|
+
if (options.scope === "sdk" || selectedDependency || packageName && packageMatches(sdk, packageName) || text.includes(sdk.name.toLowerCase()) || includesToken(text, shortName)) selected.add(sdk);
|
|
1585
1666
|
}
|
|
1586
|
-
if (selected.size === 0) for (const name of [
|
|
1667
|
+
if (selected.size === 0 && !(packageName && selectedPackages.length === 0)) for (const name of [
|
|
1587
1668
|
"@happyvertical/ai",
|
|
1588
1669
|
"@happyvertical/sql",
|
|
1589
1670
|
"@happyvertical/files",
|
|
1590
1671
|
"@happyvertical/utils"
|
|
1591
1672
|
]) {
|
|
1592
|
-
const sdk = index.sdkPackages.find((item) => item.name === name);
|
|
1673
|
+
const sdk = index.sdkPackages.find((item) => item.name === name && scopeAllowsSdkPackage(item, options.scope, false));
|
|
1593
1674
|
if (sdk) selected.add(sdk);
|
|
1594
1675
|
}
|
|
1595
1676
|
return [...selected].sort((a, b) => a.name.localeCompare(b.name));
|
|
1596
1677
|
}
|
|
1678
|
+
function scopeAllowsSdkPackage(pkg, scope, selectedDependency) {
|
|
1679
|
+
switch (scope) {
|
|
1680
|
+
case "installed": return pkg.isInstalledDependency;
|
|
1681
|
+
case "local":
|
|
1682
|
+
case "package": return !pkg.isInstalledDependency || selectedDependency;
|
|
1683
|
+
case "sdk":
|
|
1684
|
+
case "project":
|
|
1685
|
+
case void 0: return true;
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1597
1688
|
function domainPackages(index) {
|
|
1598
1689
|
return index.packages.filter((pkg) => pkg.kind !== "sdk");
|
|
1599
1690
|
}
|
|
1600
1691
|
function scopeAllowsPackage(pkg, scope) {
|
|
1601
1692
|
switch (scope) {
|
|
1602
1693
|
case "sdk": return false;
|
|
1603
|
-
case "
|
|
1604
|
-
case "
|
|
1694
|
+
case "installed": return pkg.isInstalledDependency;
|
|
1695
|
+
case "local": return !pkg.isInstalledDependency && !pkg.relativeDirectory.includes("node_modules");
|
|
1696
|
+
case "package": return !pkg.isInstalledDependency;
|
|
1605
1697
|
case "project":
|
|
1606
1698
|
case void 0: return true;
|
|
1607
1699
|
}
|
|
@@ -1836,4 +1928,4 @@ function sortJson(value) {
|
|
|
1836
1928
|
//#endregion
|
|
1837
1929
|
export { checkKnowledgeFreshnessFromIndex as a, renderFreshnessResult as c, smrtReview as d, checkKnowledgeFreshness as i, renderKnowledgeIndexMarkdown as l, buildKnowledgeIndex as n, diffKnowledgeIndex as o, buildReviewContext as r, packageDocPaths as s, buildArchitectureContext as t, smrtArchitecture as u };
|
|
1838
1930
|
|
|
1839
|
-
//# sourceMappingURL=knowledge-
|
|
1931
|
+
//# sourceMappingURL=knowledge-CCX7oQzQ.js.map
|