@happyvertical/smrt-core 0.40.65 → 0.40.66
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 +11 -0
- package/dist/knowledge.d.ts.map +1 -1
- package/dist/knowledge.js +98 -11
- package/dist/knowledge.js.map +1 -1
- package/dist/manifest/static-manifest.js +1 -1
- package/dist/manifest/static-manifest.js.map +1 -1
- package/dist/manifest/store.js +1 -1
- package/dist/manifest.json +1 -1
- package/dist/smrt-knowledge.json +587 -6
- package/package.json +10 -10
package/AGENTS.md
CHANGED
|
@@ -122,6 +122,17 @@ client at all.
|
|
|
122
122
|
Keep `manifest.json` runtime-focused. `smrt-knowledge.json` is the deterministic
|
|
123
123
|
agent contract for downstream review and architecture tools.
|
|
124
124
|
|
|
125
|
+
The schema-version-1 object projection is additive and high-signal: it retains
|
|
126
|
+
normalized tenant mode/field, explicit `cti`/`sti` strategy, conflict columns,
|
|
127
|
+
method signatures, and field defaults/constraints/readonly/transient flags.
|
|
128
|
+
Sensitive fields are removed before both `fields` and `relationships` are
|
|
129
|
+
derived, including legacy flags stored under `_meta`; matching field and
|
|
130
|
+
snake-case column names are also removed from projected conflict columns, and a
|
|
131
|
+
sensitive custom tenant field is omitted while retaining scope and mode.
|
|
132
|
+
Generated artifacts assert this boundary with `sensitiveFieldsExcluded: true`;
|
|
133
|
+
the optional marker keeps schema version 1 additive while letting readers
|
|
134
|
+
identify older artifacts that require raw-manifest corroboration.
|
|
135
|
+
|
|
125
136
|
Config precedence for knowledge is defaults → top-level `knowledge` in
|
|
126
137
|
`smrt.config.ts` → `packages[packageName].knowledge` → plugin option →
|
|
127
138
|
object-level `@smrt({ knowledge })`.
|
package/dist/knowledge.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knowledge.d.ts","sourceRoot":"","sources":["../src/knowledge.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,qBAAqB,
|
|
1
|
+
{"version":3,"file":"knowledge.d.ts","sourceRoot":"","sources":["../src/knowledge.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,qBAAqB,EAGrB,uBAAuB,EAEvB,wBAAwB,EAIzB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAEV,mBAAmB,EACpB,MAAM,oBAAoB,CAAC;AAG5B;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,qBAAqB,CAAC;CAChC;AA2CD,yFAAyF;AACzF,eAAO,MAAM,sBAAsB,eAAe,CAAC;AAEnD;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,MAAM,EAAE,CAgBV;AAED,yEAAyE;AACzE,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,wBAAwB,EAAE,CAM5B;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,2BAA2B,GACnC,uBAAuB,CAqEzB"}
|
package/dist/knowledge.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { toSnakeCase } from "./utils/naming.js";
|
|
1
2
|
import { createHash } from "node:crypto";
|
|
2
3
|
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
3
4
|
import { basename, join, relative, resolve, sep } from "node:path";
|
|
@@ -103,6 +104,7 @@ function buildDomainKnowledgeManifest(options) {
|
|
|
103
104
|
const manifestJson = stableJson(normalizeManifestForHash(options.manifest));
|
|
104
105
|
return {
|
|
105
106
|
schemaVersion: 1,
|
|
107
|
+
sensitiveFieldsExcluded: true,
|
|
106
108
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
107
109
|
packageName,
|
|
108
110
|
packageVersion,
|
|
@@ -131,13 +133,23 @@ function buildDomainKnowledgeManifest(options) {
|
|
|
131
133
|
}
|
|
132
134
|
function buildKnowledgeObject(object) {
|
|
133
135
|
const knowledge = typeof object.decoratorConfig?.knowledge === "object" ? object.decoratorConfig.knowledge : {};
|
|
134
|
-
const fields = Object.entries(object.fields).map(([name, field]) =>
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
136
|
+
const fields = Object.entries(object.fields).filter(([, field]) => !isSensitiveField(field)).map(([name, field]) => {
|
|
137
|
+
const defaultValue = fieldValue(field, "default");
|
|
138
|
+
return {
|
|
139
|
+
name,
|
|
140
|
+
type: field.type,
|
|
141
|
+
required: field.required,
|
|
142
|
+
related: field.related,
|
|
143
|
+
columnType: columnType(object, name),
|
|
144
|
+
...defaultValue.present ? { default: defaultValue.value } : {},
|
|
145
|
+
constraints: fieldConstraints(field),
|
|
146
|
+
readonly: field.readonly === true || field._meta?.readonly === true ? true : void 0,
|
|
147
|
+
transient: field.transient === true || field._meta?.transient === true ? true : void 0
|
|
148
|
+
};
|
|
149
|
+
});
|
|
150
|
+
const sensitiveIdentifiers = sensitiveFieldIdentifiers(object.fields);
|
|
151
|
+
const tenant = sanitizeTenantFacts(tenantFacts(object.decoratorConfig?.tenantScoped), sensitiveIdentifiers);
|
|
152
|
+
const conflictColumns = object.decoratorConfig?.conflictColumns?.filter((column) => !sensitiveIdentifiers.has(column));
|
|
141
153
|
const relationships = fields.filter((field) => RELATIONSHIP_FIELD_TYPES.has(field.type)).map((field) => ({
|
|
142
154
|
name: field.name,
|
|
143
155
|
type: field.type,
|
|
@@ -156,13 +168,88 @@ function buildKnowledgeObject(object) {
|
|
|
156
168
|
fields,
|
|
157
169
|
relationships,
|
|
158
170
|
methods: Object.keys(object.methods).sort(),
|
|
171
|
+
methodSignatures: methodSignatures(object),
|
|
172
|
+
tenant,
|
|
173
|
+
tableStrategy: object.decoratorConfig?.tableStrategy,
|
|
174
|
+
conflictColumns: conflictColumns && conflictColumns.length > 0 ? conflictColumns : void 0,
|
|
159
175
|
surfaces: objectSurfaces(object),
|
|
160
|
-
relationshipFeatures: relationshipFeatures(object),
|
|
176
|
+
relationshipFeatures: relationshipFeatures(object, fields),
|
|
161
177
|
tags: knowledge.tags ?? [],
|
|
162
178
|
summary: knowledge.summary,
|
|
163
179
|
risks: knowledge.risks ?? []
|
|
164
180
|
};
|
|
165
181
|
}
|
|
182
|
+
function isSensitiveField(field) {
|
|
183
|
+
return field.sensitive === true || field._meta?.sensitive === true;
|
|
184
|
+
}
|
|
185
|
+
function sensitiveFieldIdentifiers(fields) {
|
|
186
|
+
return new Set(Object.entries(fields).filter(([, field]) => isSensitiveField(field)).flatMap(([name]) => [
|
|
187
|
+
name,
|
|
188
|
+
toSnakeCase(name),
|
|
189
|
+
camelToSnake(name)
|
|
190
|
+
]));
|
|
191
|
+
}
|
|
192
|
+
function fieldValue(field, key) {
|
|
193
|
+
if (Object.hasOwn(field, key)) return {
|
|
194
|
+
present: field[key] !== void 0,
|
|
195
|
+
value: field[key]
|
|
196
|
+
};
|
|
197
|
+
const value = field._meta?.[key];
|
|
198
|
+
return {
|
|
199
|
+
present: value !== void 0,
|
|
200
|
+
value
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
function fieldConstraints(field) {
|
|
204
|
+
const constraints = {};
|
|
205
|
+
for (const key of [
|
|
206
|
+
"min",
|
|
207
|
+
"max",
|
|
208
|
+
"minLength",
|
|
209
|
+
"maxLength"
|
|
210
|
+
]) {
|
|
211
|
+
const value = fieldValue(field, key);
|
|
212
|
+
if (value.present && typeof value.value === "number") constraints[key] = value.value;
|
|
213
|
+
}
|
|
214
|
+
const pattern = normalizePattern(field.pattern ?? field._meta?.pattern);
|
|
215
|
+
if (pattern !== void 0) constraints.pattern = pattern;
|
|
216
|
+
return Object.keys(constraints).length > 0 ? constraints : void 0;
|
|
217
|
+
}
|
|
218
|
+
function normalizePattern(pattern) {
|
|
219
|
+
if (typeof pattern === "string") return pattern;
|
|
220
|
+
if (pattern instanceof RegExp) return pattern.source;
|
|
221
|
+
if (pattern && typeof pattern === "object" && typeof pattern.source === "string") return pattern.source;
|
|
222
|
+
}
|
|
223
|
+
function tenantFacts(tenantScoped) {
|
|
224
|
+
if (!tenantScoped) return void 0;
|
|
225
|
+
if (tenantScoped === true) return {
|
|
226
|
+
scoped: true,
|
|
227
|
+
mode: "required",
|
|
228
|
+
field: "tenantId"
|
|
229
|
+
};
|
|
230
|
+
return {
|
|
231
|
+
scoped: true,
|
|
232
|
+
mode: tenantScoped.mode ?? "required",
|
|
233
|
+
field: tenantScoped.field ?? "tenantId"
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
function sanitizeTenantFacts(tenant, sensitiveIdentifiers) {
|
|
237
|
+
if (!tenant?.field || !sensitiveIdentifiers.has(tenant.field)) return tenant;
|
|
238
|
+
return {
|
|
239
|
+
scoped: tenant.scoped,
|
|
240
|
+
mode: tenant.mode
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
function methodSignatures(object) {
|
|
244
|
+
const signatures = Object.values(object.methods).sort((a, b) => a.name.localeCompare(b.name)).map((method) => ({
|
|
245
|
+
name: method.name,
|
|
246
|
+
async: method.async || void 0,
|
|
247
|
+
static: method.isStatic || void 0,
|
|
248
|
+
params: method.parameters.length > 0 ? method.parameters.map((parameter) => `${parameter.name}${parameter.optional ? "?" : ""}: ${parameter.type}`) : void 0,
|
|
249
|
+
returns: method.returnType || void 0
|
|
250
|
+
}));
|
|
251
|
+
return signatures.length > 0 ? signatures : void 0;
|
|
252
|
+
}
|
|
166
253
|
function objectSurfaces(object) {
|
|
167
254
|
return [
|
|
168
255
|
...configuredSurfaces("api", object),
|
|
@@ -217,9 +304,9 @@ function apiMethod(operation) {
|
|
|
217
304
|
default: return "POST";
|
|
218
305
|
}
|
|
219
306
|
}
|
|
220
|
-
function relationshipFeatures(object) {
|
|
307
|
+
function relationshipFeatures(object, fields) {
|
|
221
308
|
const features = /* @__PURE__ */ new Set();
|
|
222
|
-
for (const field of
|
|
309
|
+
for (const field of fields) {
|
|
223
310
|
if (field.type === "foreignKey") features.add("foreignKey");
|
|
224
311
|
if (field.type === "crossPackageRef") features.add("crossPackageRef");
|
|
225
312
|
if (field.type === "oneToMany") features.add("oneToMany");
|
|
@@ -227,7 +314,7 @@ function relationshipFeatures(object) {
|
|
|
227
314
|
}
|
|
228
315
|
if (object.extends === "SmrtJunction") features.add("SmrtJunction");
|
|
229
316
|
if (object.extends === "SmrtHierarchical") features.add("SmrtHierarchical");
|
|
230
|
-
if (object.extends === "SmrtPolymorphicAssociation" ||
|
|
317
|
+
if (object.extends === "SmrtPolymorphicAssociation" || fields.some((field) => field.name === "metaType") || fields.some((field) => field.name === "metaId")) features.add("SmrtPolymorphicAssociation");
|
|
231
318
|
if (Object.keys(object.schema?.columns ?? {}).some((name) => object.schema?.columns[name]?.type === "UUID")) features.add("uuidColumns");
|
|
232
319
|
return [...features].sort();
|
|
233
320
|
}
|
package/dist/knowledge.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knowledge.js","names":[],"sources":["../src/knowledge.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';\nimport { basename, join, relative, resolve, sep } from 'node:path';\nimport type {\n DomainKnowledgeConfig,\n DomainKnowledgeManifest,\n DomainKnowledgeModuleDoc,\n DomainKnowledgeObject,\n DomainKnowledgeSurface,\n} from '@happyvertical/smrt-types';\nimport type {\n SmartObjectDefinition,\n SmartObjectManifest,\n} from './scanner/types.js';\n\n/**\n * Minimal package.json shape consumed by the knowledge builder.\n * `name`/`version` are typed concretely because they flow into the manifest's\n * string-typed metadata fields; everything else is read via `unknown`-accepting\n * helpers (`record()`, `exportKeys()`), so an index signature is sufficient.\n */\nexport interface PackageJsonLike {\n name?: string;\n version?: string;\n [key: string]: unknown;\n}\n\nexport interface BuildDomainKnowledgeOptions {\n manifest: SmartObjectManifest;\n rootDir: string;\n packageJson?: PackageJsonLike;\n manifestPath?: string;\n config?: DomainKnowledgeConfig;\n}\n\nconst SDK_PACKAGE_NAMES = new Set([\n '@happyvertical/ai',\n '@happyvertical/cache',\n '@happyvertical/documents',\n '@happyvertical/email',\n '@happyvertical/encryption',\n '@happyvertical/files',\n '@happyvertical/geo',\n '@happyvertical/images',\n '@happyvertical/jobs',\n '@happyvertical/json',\n '@happyvertical/logger',\n '@happyvertical/messages',\n '@happyvertical/ocr',\n '@happyvertical/pdf',\n '@happyvertical/projects',\n '@happyvertical/repos',\n '@happyvertical/secrets',\n '@happyvertical/spider',\n '@happyvertical/sql',\n '@happyvertical/utils',\n]);\n\nconst RELATIONSHIP_FIELD_TYPES = new Set([\n 'foreignKey',\n 'crossPackageRef',\n 'oneToMany',\n 'manyToMany',\n]);\n\nconst STANDARD_OPERATIONS = ['list', 'get', 'create', 'update', 'delete'];\n\n/**\n * Markdown inline links whose target is a `.md` file — `[label](agents/x.md)`,\n * tolerating an `#anchor` and a `\"title\"`. This is how a package registers a\n * sibling module doc (#2108): the link in `AGENTS.md` IS the registration, so\n * there is no separate index to drift out of sync.\n */\nconst MARKDOWN_MD_LINK =\n /\\[[^\\]]*\\]\\(\\s*([^)\\s#]+\\.md)(?:#[^)\\s]*)?(?:\\s+\"[^\"]*\")?\\s*\\)/g;\n\n/** `sourceHashes` key prefix for a linked module doc, e.g. `moduleDoc:agents/crm.md`. */\nexport const MODULE_DOC_HASH_PREFIX = 'moduleDoc:';\n\n/**\n * Module doc paths linked from a package's `AGENTS.md`, relative to the package\n * root and in document order.\n *\n * Instruction chains are additive (see `scripts/check-agents-chain.mjs`), so an\n * oversized package doc is split into `packages/<pkg>/agents/<module>.md` siblings\n * instead of nested `AGENTS.md` files. Only links resolving to an existing file\n * INSIDE the package are accepted — a cross-package reference such as\n * `packages/affiliates/MIGRATION.md` belongs to that package's own chain and is\n * ignored here.\n */\nexport function resolveAgentModuleDocPaths(\n rootDir: string,\n agentDoc: string | undefined,\n): string[] {\n if (!agentDoc) return [];\n const root = resolve(rootDir);\n const paths: string[] = [];\n for (const match of agentDoc.matchAll(MARKDOWN_MD_LINK)) {\n const target = match[1];\n if (target.includes('://')) continue;\n const absolute = resolve(root, target);\n if (absolute !== root && !absolute.startsWith(root + sep)) continue;\n const relativePath = relative(root, absolute).split(sep).join('/');\n if (relativePath === 'AGENTS.md' || relativePath === 'CLAUDE.md') continue;\n if (paths.includes(relativePath)) continue;\n if (!existsSync(absolute) || !statSync(absolute).isFile()) continue;\n paths.push(relativePath);\n }\n return paths;\n}\n\n/** {@link resolveAgentModuleDocPaths}, with each doc's contents read. */\nexport function readAgentModuleDocs(\n rootDir: string,\n agentDoc: string | undefined,\n): DomainKnowledgeModuleDoc[] {\n return resolveAgentModuleDocPaths(rootDir, agentDoc).map((path) => ({\n path,\n module: basename(path, '.md'),\n content: readFileSync(join(rootDir, path), 'utf8'),\n }));\n}\n\nexport function buildDomainKnowledgeManifest(\n options: BuildDomainKnowledgeOptions,\n): DomainKnowledgeManifest {\n const rootDir = options.rootDir;\n const packageJson = options.packageJson ?? readPackageJson(rootDir) ?? {};\n const packageName = options.manifest.packageName ?? packageJson.name;\n const packageVersion = options.manifest.packageVersion ?? packageJson.version;\n const agentDocPath = existingPath(rootDir, 'AGENTS.md');\n const agentDocContent = agentDocPath\n ? readFileSync(agentDocPath, 'utf8')\n : undefined;\n const includeDocs = options.config?.includeDocs !== false;\n const agentDoc = includeDocs ? agentDocContent : undefined;\n // Module doc PATHS are always resolved so their hashes gate freshness even\n // when doc bodies are excluded from the artifact — same stance as `agents`.\n const moduleDocPaths = resolveAgentModuleDocPaths(rootDir, agentDocContent);\n const allDependencies = {\n ...record(packageJson.dependencies),\n ...record(packageJson.devDependencies),\n ...record(packageJson.peerDependencies),\n };\n const manifestObjects = Object.values(options.manifest.objects).filter(\n (object) => object.decoratorConfig?.knowledge !== false,\n );\n const objects = manifestObjects.map((object) => buildKnowledgeObject(object));\n const surfaces = objects.flatMap((object) => object.surfaces);\n const manifestJson = stableJson(normalizeManifestForHash(options.manifest));\n\n return {\n schemaVersion: 1,\n generatedAt: new Date().toISOString(),\n packageName,\n packageVersion,\n sourceManifestPath: options.manifestPath\n ? relative(rootDir, options.manifestPath)\n : undefined,\n agentDocPath: agentDocPath ? relative(rootDir, agentDocPath) : undefined,\n sourceHashes: sourceHashes({\n manifest: { content: manifestJson },\n packageJson: fileHashSource(existingPath(rootDir, 'package.json')),\n agents: fileHashSource(agentDocPath),\n ...Object.fromEntries(\n moduleDocPaths.map((path) => [\n `${MODULE_DOC_HASH_PREFIX}${path}`,\n fileHashSource(join(rootDir, path)),\n ]),\n ),\n }),\n exports: exportKeys(packageJson.exports),\n dependencies: allDependencies,\n smrtDependencies: Object.keys(allDependencies)\n .filter((dep) => dep.startsWith('@happyvertical/smrt-'))\n .sort(),\n sdkDependencies: Object.keys(allDependencies)\n .filter((dep) => SDK_PACKAGE_NAMES.has(dep))\n .sort(),\n tags: options.config?.tags ?? [],\n summary: options.config?.summary,\n risks: options.config?.risks ?? [],\n objects,\n surfaces,\n prompts:\n options.config?.includePrompts === false ? [] : readPrompts(rootDir),\n relationshipsV2: summarizeRelationships(objects, manifestObjects),\n agentDoc,\n moduleDocs:\n includeDocs && moduleDocPaths.length > 0\n ? readAgentModuleDocs(rootDir, agentDocContent)\n : undefined,\n };\n}\n\nfunction buildKnowledgeObject(\n object: SmartObjectDefinition,\n): DomainKnowledgeObject {\n const knowledge =\n typeof object.decoratorConfig?.knowledge === 'object'\n ? object.decoratorConfig.knowledge\n : {};\n const fields = Object.entries(object.fields).map(([name, field]) => ({\n name,\n type: field.type,\n required: field.required,\n related: field.related,\n columnType: columnType(object, name),\n }));\n const relationships = fields\n .filter((field) => RELATIONSHIP_FIELD_TYPES.has(field.type))\n .map((field) => ({\n name: field.name,\n type: field.type,\n required: field.required,\n related: field.related,\n columnType: field.columnType,\n }));\n\n return {\n name: object.className,\n qualifiedName: object.qualifiedName,\n collection: object.collection,\n tableName: object.schema?.tableName,\n packageName: object.packageName,\n extends: object.extends,\n visibility: object.visibility,\n fields,\n relationships,\n methods: Object.keys(object.methods).sort(),\n surfaces: objectSurfaces(object),\n relationshipFeatures: relationshipFeatures(object),\n tags: knowledge.tags ?? [],\n summary: knowledge.summary,\n risks: knowledge.risks ?? [],\n };\n}\n\nfunction objectSurfaces(\n object: SmartObjectDefinition,\n): DomainKnowledgeSurface[] {\n return [\n ...configuredSurfaces('api', object),\n ...configuredSurfaces('cli', object),\n ...configuredSurfaces('mcp', object),\n ...aiSurfaces(object),\n ];\n}\n\nfunction configuredSurfaces(\n kind: 'api' | 'cli' | 'mcp',\n object: SmartObjectDefinition,\n): DomainKnowledgeSurface[] {\n const config = object.decoratorConfig?.[kind];\n if (!config) return [];\n const operations = configuredOperations(config);\n return operations.map((operation) => ({\n kind,\n name:\n kind === 'api'\n ? `${object.collection}.${operation}`\n : `${object.className.toLowerCase()}_${operation}`,\n operation,\n objectName: object.qualifiedName ?? object.className,\n path: kind === 'api' ? apiPath(object, operation) : undefined,\n method: kind === 'api' ? apiMethod(operation) : undefined,\n }));\n}\n\nfunction configuredOperations(config: unknown): string[] {\n if (config === true) return [...STANDARD_OPERATIONS];\n if (!config || typeof config !== 'object' || Array.isArray(config)) {\n return [];\n }\n const recordConfig = config as { include?: string[]; exclude?: string[] };\n const base = Array.isArray(recordConfig.include)\n ? recordConfig.include\n : STANDARD_OPERATIONS;\n const excluded = new Set(recordConfig.exclude ?? []);\n return [...new Set(base.filter((operation) => !excluded.has(operation)))];\n}\n\nfunction aiSurfaces(object: SmartObjectDefinition): DomainKnowledgeSurface[] {\n return (object.tools ?? []).map((tool) => ({\n kind: 'ai',\n name: tool.function.name,\n operation: tool.function.name,\n description: tool.function.description,\n objectName: object.qualifiedName ?? object.className,\n }));\n}\n\nfunction apiPath(object: SmartObjectDefinition, operation: string): string {\n const collection = object.decoratorConfig?.api;\n const configuredPath =\n typeof collection === 'object' && typeof collection.path === 'string'\n ? collection.path\n : object.collection.replaceAll('_', '-');\n if (operation === 'list' || operation === 'create') {\n return `/${configuredPath}`;\n }\n if (STANDARD_OPERATIONS.includes(operation)) {\n return `/${configuredPath}/[id]`;\n }\n return `/${configuredPath}/${operation}`;\n}\n\nfunction apiMethod(operation: string): string {\n switch (operation) {\n case 'list':\n case 'get':\n return 'GET';\n case 'create':\n return 'POST';\n case 'update':\n return 'PATCH';\n case 'delete':\n return 'DELETE';\n default:\n return 'POST';\n }\n}\n\nfunction relationshipFeatures(object: SmartObjectDefinition): string[] {\n const features = new Set<string>();\n for (const field of Object.values(object.fields)) {\n if (field.type === 'foreignKey') features.add('foreignKey');\n if (field.type === 'crossPackageRef') features.add('crossPackageRef');\n if (field.type === 'oneToMany') features.add('oneToMany');\n if (field.type === 'manyToMany') features.add('manyToMany');\n }\n if (object.extends === 'SmrtJunction') features.add('SmrtJunction');\n if (object.extends === 'SmrtHierarchical') features.add('SmrtHierarchical');\n if (\n object.extends === 'SmrtPolymorphicAssociation' ||\n object.fields.metaType ||\n object.fields.metaId\n ) {\n features.add('SmrtPolymorphicAssociation');\n }\n if (\n Object.keys(object.schema?.columns ?? {}).some(\n (name) => object.schema?.columns[name]?.type === 'UUID',\n )\n ) {\n features.add('uuidColumns');\n }\n return [...features].sort();\n}\n\nfunction summarizeRelationships(\n objects: DomainKnowledgeObject[],\n manifestObjects: SmartObjectDefinition[],\n) {\n const fields = objects.flatMap((object) => object.fields);\n return {\n foreignKeyFields: fields.filter((field) => field.type === 'foreignKey')\n .length,\n crossPackageRefFields: fields.filter(\n (field) => field.type === 'crossPackageRef',\n ).length,\n junctionCollections: objects.filter((object) =>\n object.relationshipFeatures.includes('SmrtJunction'),\n ).length,\n hierarchicalObjects: objects.filter((object) =>\n object.relationshipFeatures.includes('SmrtHierarchical'),\n ).length,\n polymorphicAssociations: objects.filter((object) =>\n object.relationshipFeatures.includes('SmrtPolymorphicAssociation'),\n ).length,\n uuidColumns: manifestObjects.reduce(\n (count, object) =>\n count +\n Object.values(object.schema?.columns ?? {}).filter(\n (column) => column.type === 'UUID',\n ).length,\n 0,\n ),\n };\n}\n\nfunction columnType(\n object: SmartObjectDefinition,\n fieldName: string,\n): string | undefined {\n const columnName = camelToSnake(fieldName);\n return object.schema?.columns[columnName]?.type;\n}\n\nfunction readPrompts(\n rootDir: string,\n): Array<{ filePath: string; key?: string }> {\n const srcDir = join(rootDir, 'src');\n if (!existsSync(srcDir)) return [];\n const prompts: Array<{ filePath: string; key?: string }> = [];\n for (const filePath of walkFiles(srcDir)) {\n if (!filePath.endsWith('.ts')) continue;\n const content = readFileSync(filePath, 'utf8');\n if (!content.includes('definePrompt')) continue;\n const keyMatch = content.match(/definePrompt\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]/);\n prompts.push({\n filePath: relative(rootDir, filePath),\n key: keyMatch?.[1],\n });\n }\n return prompts;\n}\n\nfunction walkFiles(dir: string): string[] {\n const files: string[] = [];\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n if (\n entry.name === 'node_modules' ||\n entry.name === 'dist' ||\n entry.name === '.svelte-kit'\n ) {\n continue;\n }\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n files.push(...walkFiles(fullPath));\n } else if (entry.isFile()) {\n files.push(fullPath);\n }\n }\n return files;\n}\n\nfunction sourceHashes(sources: Record<string, HashSource | undefined>) {\n const hashes: Record<string, string> = {};\n for (const [name, source] of Object.entries(sources)) {\n if (!source) continue;\n const content =\n 'content' in source ? source.content : readFileSync(source.path, 'utf8');\n hashes[name] = createHash('sha256').update(content).digest('hex');\n }\n return hashes;\n}\n\ntype HashSource = { content: string } | { path: string };\n\nfunction fileHashSource(path: string | undefined): HashSource | undefined {\n return path ? { path } : undefined;\n}\n\nfunction existingPath(rootDir: string, path: string): string | undefined {\n const fullPath = join(rootDir, path);\n return existsSync(fullPath) ? fullPath : undefined;\n}\n\nfunction readPackageJson(rootDir: string): PackageJsonLike | null {\n const path = join(rootDir, 'package.json');\n if (!existsSync(path)) return null;\n return JSON.parse(readFileSync(path, 'utf8'));\n}\n\nfunction record(value: unknown): Record<string, string> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, string>)\n : {};\n}\n\nfunction exportKeys(exportsField: unknown): string[] {\n if (typeof exportsField === 'string') return ['.'];\n if (\n typeof exportsField !== 'object' ||\n exportsField === null ||\n Array.isArray(exportsField)\n ) {\n return [];\n }\n return Object.keys(exportsField).sort();\n}\n\nfunction camelToSnake(value: string): string {\n return value\n .replace(/([a-z0-9])([A-Z])/g, '$1_$2')\n .replace(/[-\\s]+/g, '_')\n .toLowerCase();\n}\n\nfunction normalizeManifestForHash(manifest: SmartObjectManifest): unknown {\n const normalized = JSON.parse(JSON.stringify(manifest)) as Record<\n string,\n unknown\n >;\n delete normalized.timestamp;\n return normalized;\n}\n\nfunction stableJson(value: unknown): string {\n return JSON.stringify(sortJson(value), null, 2);\n}\n\nfunction sortJson(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(sortJson);\n if (value && typeof value === 'object') {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, entry]) => [key, sortJson(entry)]),\n );\n }\n return value;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"knowledge.js","names":[],"sources":["../src/knowledge.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';\nimport { basename, join, relative, resolve, sep } from 'node:path';\nimport type {\n DomainKnowledgeConfig,\n DomainKnowledgeField,\n DomainKnowledgeFieldConstraints,\n DomainKnowledgeManifest,\n DomainKnowledgeMethodSignature,\n DomainKnowledgeModuleDoc,\n DomainKnowledgeObject,\n DomainKnowledgeSurface,\n DomainKnowledgeTenant,\n} from '@happyvertical/smrt-types';\nimport type {\n SmartObjectDefinition,\n SmartObjectManifest,\n} from './scanner/types.js';\nimport { toSnakeCase } from './utils/naming.js';\n\n/**\n * Minimal package.json shape consumed by the knowledge builder.\n * `name`/`version` are typed concretely because they flow into the manifest's\n * string-typed metadata fields; everything else is read via `unknown`-accepting\n * helpers (`record()`, `exportKeys()`), so an index signature is sufficient.\n */\nexport interface PackageJsonLike {\n name?: string;\n version?: string;\n [key: string]: unknown;\n}\n\nexport interface BuildDomainKnowledgeOptions {\n manifest: SmartObjectManifest;\n rootDir: string;\n packageJson?: PackageJsonLike;\n manifestPath?: string;\n config?: DomainKnowledgeConfig;\n}\n\nconst SDK_PACKAGE_NAMES = new Set([\n '@happyvertical/ai',\n '@happyvertical/cache',\n '@happyvertical/documents',\n '@happyvertical/email',\n '@happyvertical/encryption',\n '@happyvertical/files',\n '@happyvertical/geo',\n '@happyvertical/images',\n '@happyvertical/jobs',\n '@happyvertical/json',\n '@happyvertical/logger',\n '@happyvertical/messages',\n '@happyvertical/ocr',\n '@happyvertical/pdf',\n '@happyvertical/projects',\n '@happyvertical/repos',\n '@happyvertical/secrets',\n '@happyvertical/spider',\n '@happyvertical/sql',\n '@happyvertical/utils',\n]);\n\nconst RELATIONSHIP_FIELD_TYPES = new Set([\n 'foreignKey',\n 'crossPackageRef',\n 'oneToMany',\n 'manyToMany',\n]);\n\nconst STANDARD_OPERATIONS = ['list', 'get', 'create', 'update', 'delete'];\n\n/**\n * Markdown inline links whose target is a `.md` file — `[label](agents/x.md)`,\n * tolerating an `#anchor` and a `\"title\"`. This is how a package registers a\n * sibling module doc (#2108): the link in `AGENTS.md` IS the registration, so\n * there is no separate index to drift out of sync.\n */\nconst MARKDOWN_MD_LINK =\n /\\[[^\\]]*\\]\\(\\s*([^)\\s#]+\\.md)(?:#[^)\\s]*)?(?:\\s+\"[^\"]*\")?\\s*\\)/g;\n\n/** `sourceHashes` key prefix for a linked module doc, e.g. `moduleDoc:agents/crm.md`. */\nexport const MODULE_DOC_HASH_PREFIX = 'moduleDoc:';\n\n/**\n * Module doc paths linked from a package's `AGENTS.md`, relative to the package\n * root and in document order.\n *\n * Instruction chains are additive (see `scripts/check-agents-chain.mjs`), so an\n * oversized package doc is split into `packages/<pkg>/agents/<module>.md` siblings\n * instead of nested `AGENTS.md` files. Only links resolving to an existing file\n * INSIDE the package are accepted — a cross-package reference such as\n * `packages/affiliates/MIGRATION.md` belongs to that package's own chain and is\n * ignored here.\n */\nexport function resolveAgentModuleDocPaths(\n rootDir: string,\n agentDoc: string | undefined,\n): string[] {\n if (!agentDoc) return [];\n const root = resolve(rootDir);\n const paths: string[] = [];\n for (const match of agentDoc.matchAll(MARKDOWN_MD_LINK)) {\n const target = match[1];\n if (target.includes('://')) continue;\n const absolute = resolve(root, target);\n if (absolute !== root && !absolute.startsWith(root + sep)) continue;\n const relativePath = relative(root, absolute).split(sep).join('/');\n if (relativePath === 'AGENTS.md' || relativePath === 'CLAUDE.md') continue;\n if (paths.includes(relativePath)) continue;\n if (!existsSync(absolute) || !statSync(absolute).isFile()) continue;\n paths.push(relativePath);\n }\n return paths;\n}\n\n/** {@link resolveAgentModuleDocPaths}, with each doc's contents read. */\nexport function readAgentModuleDocs(\n rootDir: string,\n agentDoc: string | undefined,\n): DomainKnowledgeModuleDoc[] {\n return resolveAgentModuleDocPaths(rootDir, agentDoc).map((path) => ({\n path,\n module: basename(path, '.md'),\n content: readFileSync(join(rootDir, path), 'utf8'),\n }));\n}\n\nexport function buildDomainKnowledgeManifest(\n options: BuildDomainKnowledgeOptions,\n): DomainKnowledgeManifest {\n const rootDir = options.rootDir;\n const packageJson = options.packageJson ?? readPackageJson(rootDir) ?? {};\n const packageName = options.manifest.packageName ?? packageJson.name;\n const packageVersion = options.manifest.packageVersion ?? packageJson.version;\n const agentDocPath = existingPath(rootDir, 'AGENTS.md');\n const agentDocContent = agentDocPath\n ? readFileSync(agentDocPath, 'utf8')\n : undefined;\n const includeDocs = options.config?.includeDocs !== false;\n const agentDoc = includeDocs ? agentDocContent : undefined;\n // Module doc PATHS are always resolved so their hashes gate freshness even\n // when doc bodies are excluded from the artifact — same stance as `agents`.\n const moduleDocPaths = resolveAgentModuleDocPaths(rootDir, agentDocContent);\n const allDependencies = {\n ...record(packageJson.dependencies),\n ...record(packageJson.devDependencies),\n ...record(packageJson.peerDependencies),\n };\n const manifestObjects = Object.values(options.manifest.objects).filter(\n (object) => object.decoratorConfig?.knowledge !== false,\n );\n const objects = manifestObjects.map((object) => buildKnowledgeObject(object));\n const surfaces = objects.flatMap((object) => object.surfaces);\n const manifestJson = stableJson(normalizeManifestForHash(options.manifest));\n\n return {\n schemaVersion: 1,\n sensitiveFieldsExcluded: true,\n generatedAt: new Date().toISOString(),\n packageName,\n packageVersion,\n sourceManifestPath: options.manifestPath\n ? relative(rootDir, options.manifestPath)\n : undefined,\n agentDocPath: agentDocPath ? relative(rootDir, agentDocPath) : undefined,\n sourceHashes: sourceHashes({\n manifest: { content: manifestJson },\n packageJson: fileHashSource(existingPath(rootDir, 'package.json')),\n agents: fileHashSource(agentDocPath),\n ...Object.fromEntries(\n moduleDocPaths.map((path) => [\n `${MODULE_DOC_HASH_PREFIX}${path}`,\n fileHashSource(join(rootDir, path)),\n ]),\n ),\n }),\n exports: exportKeys(packageJson.exports),\n dependencies: allDependencies,\n smrtDependencies: Object.keys(allDependencies)\n .filter((dep) => dep.startsWith('@happyvertical/smrt-'))\n .sort(),\n sdkDependencies: Object.keys(allDependencies)\n .filter((dep) => SDK_PACKAGE_NAMES.has(dep))\n .sort(),\n tags: options.config?.tags ?? [],\n summary: options.config?.summary,\n risks: options.config?.risks ?? [],\n objects,\n surfaces,\n prompts:\n options.config?.includePrompts === false ? [] : readPrompts(rootDir),\n relationshipsV2: summarizeRelationships(objects, manifestObjects),\n agentDoc,\n moduleDocs:\n includeDocs && moduleDocPaths.length > 0\n ? readAgentModuleDocs(rootDir, agentDocContent)\n : undefined,\n };\n}\n\nfunction buildKnowledgeObject(\n object: SmartObjectDefinition,\n): DomainKnowledgeObject {\n const knowledge =\n typeof object.decoratorConfig?.knowledge === 'object'\n ? object.decoratorConfig.knowledge\n : {};\n const fields = Object.entries(object.fields)\n .filter(([, field]) => !isSensitiveField(field))\n .map(([name, field]): DomainKnowledgeField => {\n const defaultValue = fieldValue(field, 'default');\n return {\n name,\n type: field.type,\n required: field.required,\n related: field.related,\n columnType: columnType(object, name),\n ...(defaultValue.present ? { default: defaultValue.value } : {}),\n constraints: fieldConstraints(field),\n readonly:\n field.readonly === true || field._meta?.readonly === true\n ? true\n : undefined,\n transient:\n field.transient === true || field._meta?.transient === true\n ? true\n : undefined,\n };\n });\n const sensitiveIdentifiers = sensitiveFieldIdentifiers(object.fields);\n const tenant = sanitizeTenantFacts(\n tenantFacts(object.decoratorConfig?.tenantScoped),\n sensitiveIdentifiers,\n );\n const conflictColumns = object.decoratorConfig?.conflictColumns?.filter(\n (column) => !sensitiveIdentifiers.has(column),\n );\n const relationships = fields\n .filter((field) => RELATIONSHIP_FIELD_TYPES.has(field.type))\n .map((field) => ({\n name: field.name,\n type: field.type,\n required: field.required,\n related: field.related,\n columnType: field.columnType,\n }));\n\n return {\n name: object.className,\n qualifiedName: object.qualifiedName,\n collection: object.collection,\n tableName: object.schema?.tableName,\n packageName: object.packageName,\n extends: object.extends,\n visibility: object.visibility,\n fields,\n relationships,\n methods: Object.keys(object.methods).sort(),\n methodSignatures: methodSignatures(object),\n tenant,\n tableStrategy: object.decoratorConfig?.tableStrategy,\n conflictColumns:\n conflictColumns && conflictColumns.length > 0\n ? conflictColumns\n : undefined,\n surfaces: objectSurfaces(object),\n relationshipFeatures: relationshipFeatures(object, fields),\n tags: knowledge.tags ?? [],\n summary: knowledge.summary,\n risks: knowledge.risks ?? [],\n };\n}\n\nfunction isSensitiveField(field: SmartObjectDefinition['fields'][string]) {\n return field.sensitive === true || field._meta?.sensitive === true;\n}\n\nfunction sensitiveFieldIdentifiers(\n fields: SmartObjectDefinition['fields'],\n): Set<string> {\n return new Set(\n Object.entries(fields)\n .filter(([, field]) => isSensitiveField(field))\n .flatMap(([name]) => [name, toSnakeCase(name), camelToSnake(name)]),\n );\n}\n\nfunction fieldValue(\n field: SmartObjectDefinition['fields'][string],\n key: 'default' | 'min' | 'max' | 'minLength' | 'maxLength',\n): { present: boolean; value: unknown } {\n if (Object.hasOwn(field, key)) {\n return { present: field[key] !== undefined, value: field[key] };\n }\n const value = field._meta?.[key];\n return { present: value !== undefined, value };\n}\n\nfunction fieldConstraints(\n field: SmartObjectDefinition['fields'][string],\n): DomainKnowledgeFieldConstraints | undefined {\n const constraints: DomainKnowledgeFieldConstraints = {};\n for (const key of ['min', 'max', 'minLength', 'maxLength'] as const) {\n const value = fieldValue(field, key);\n if (value.present && typeof value.value === 'number') {\n constraints[key] = value.value;\n }\n }\n const pattern = normalizePattern(\n (field as { pattern?: unknown }).pattern ?? field._meta?.pattern,\n );\n if (pattern !== undefined) constraints.pattern = pattern;\n return Object.keys(constraints).length > 0 ? constraints : undefined;\n}\n\nfunction normalizePattern(pattern: unknown): string | undefined {\n if (typeof pattern === 'string') return pattern;\n if (pattern instanceof RegExp) return pattern.source;\n if (\n pattern &&\n typeof pattern === 'object' &&\n typeof (pattern as { source?: unknown }).source === 'string'\n ) {\n return (pattern as { source: string }).source;\n }\n return undefined;\n}\n\nfunction tenantFacts(\n tenantScoped: SmartObjectDefinition['decoratorConfig']['tenantScoped'],\n): DomainKnowledgeTenant | undefined {\n if (!tenantScoped) return undefined;\n if (tenantScoped === true) {\n return { scoped: true, mode: 'required', field: 'tenantId' };\n }\n return {\n scoped: true,\n mode: tenantScoped.mode ?? 'required',\n field: tenantScoped.field ?? 'tenantId',\n };\n}\n\nfunction sanitizeTenantFacts(\n tenant: DomainKnowledgeTenant | undefined,\n sensitiveIdentifiers: Set<string>,\n): DomainKnowledgeTenant | undefined {\n if (!tenant?.field || !sensitiveIdentifiers.has(tenant.field)) return tenant;\n return { scoped: tenant.scoped, mode: tenant.mode };\n}\n\nfunction methodSignatures(\n object: SmartObjectDefinition,\n): DomainKnowledgeMethodSignature[] | undefined {\n const signatures = Object.values(object.methods)\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((method) => ({\n name: method.name,\n async: method.async || undefined,\n static: method.isStatic || undefined,\n params:\n method.parameters.length > 0\n ? method.parameters.map(\n (parameter) =>\n `${parameter.name}${parameter.optional ? '?' : ''}: ${parameter.type}`,\n )\n : undefined,\n returns: method.returnType || undefined,\n }));\n return signatures.length > 0 ? signatures : undefined;\n}\n\nfunction objectSurfaces(\n object: SmartObjectDefinition,\n): DomainKnowledgeSurface[] {\n return [\n ...configuredSurfaces('api', object),\n ...configuredSurfaces('cli', object),\n ...configuredSurfaces('mcp', object),\n ...aiSurfaces(object),\n ];\n}\n\nfunction configuredSurfaces(\n kind: 'api' | 'cli' | 'mcp',\n object: SmartObjectDefinition,\n): DomainKnowledgeSurface[] {\n const config = object.decoratorConfig?.[kind];\n if (!config) return [];\n const operations = configuredOperations(config);\n return operations.map((operation) => ({\n kind,\n name:\n kind === 'api'\n ? `${object.collection}.${operation}`\n : `${object.className.toLowerCase()}_${operation}`,\n operation,\n objectName: object.qualifiedName ?? object.className,\n path: kind === 'api' ? apiPath(object, operation) : undefined,\n method: kind === 'api' ? apiMethod(operation) : undefined,\n }));\n}\n\nfunction configuredOperations(config: unknown): string[] {\n if (config === true) return [...STANDARD_OPERATIONS];\n if (!config || typeof config !== 'object' || Array.isArray(config)) {\n return [];\n }\n const recordConfig = config as { include?: string[]; exclude?: string[] };\n const base = Array.isArray(recordConfig.include)\n ? recordConfig.include\n : STANDARD_OPERATIONS;\n const excluded = new Set(recordConfig.exclude ?? []);\n return [...new Set(base.filter((operation) => !excluded.has(operation)))];\n}\n\nfunction aiSurfaces(object: SmartObjectDefinition): DomainKnowledgeSurface[] {\n return (object.tools ?? []).map((tool) => ({\n kind: 'ai',\n name: tool.function.name,\n operation: tool.function.name,\n description: tool.function.description,\n objectName: object.qualifiedName ?? object.className,\n }));\n}\n\nfunction apiPath(object: SmartObjectDefinition, operation: string): string {\n const collection = object.decoratorConfig?.api;\n const configuredPath =\n typeof collection === 'object' && typeof collection.path === 'string'\n ? collection.path\n : object.collection.replaceAll('_', '-');\n if (operation === 'list' || operation === 'create') {\n return `/${configuredPath}`;\n }\n if (STANDARD_OPERATIONS.includes(operation)) {\n return `/${configuredPath}/[id]`;\n }\n return `/${configuredPath}/${operation}`;\n}\n\nfunction apiMethod(operation: string): string {\n switch (operation) {\n case 'list':\n case 'get':\n return 'GET';\n case 'create':\n return 'POST';\n case 'update':\n return 'PATCH';\n case 'delete':\n return 'DELETE';\n default:\n return 'POST';\n }\n}\n\nfunction relationshipFeatures(\n object: SmartObjectDefinition,\n fields: DomainKnowledgeField[],\n): string[] {\n const features = new Set<string>();\n for (const field of fields) {\n if (field.type === 'foreignKey') features.add('foreignKey');\n if (field.type === 'crossPackageRef') features.add('crossPackageRef');\n if (field.type === 'oneToMany') features.add('oneToMany');\n if (field.type === 'manyToMany') features.add('manyToMany');\n }\n if (object.extends === 'SmrtJunction') features.add('SmrtJunction');\n if (object.extends === 'SmrtHierarchical') features.add('SmrtHierarchical');\n if (\n object.extends === 'SmrtPolymorphicAssociation' ||\n fields.some((field) => field.name === 'metaType') ||\n fields.some((field) => field.name === 'metaId')\n ) {\n features.add('SmrtPolymorphicAssociation');\n }\n if (\n Object.keys(object.schema?.columns ?? {}).some(\n (name) => object.schema?.columns[name]?.type === 'UUID',\n )\n ) {\n features.add('uuidColumns');\n }\n return [...features].sort();\n}\n\nfunction summarizeRelationships(\n objects: DomainKnowledgeObject[],\n manifestObjects: SmartObjectDefinition[],\n) {\n const fields = objects.flatMap((object) => object.fields);\n return {\n foreignKeyFields: fields.filter((field) => field.type === 'foreignKey')\n .length,\n crossPackageRefFields: fields.filter(\n (field) => field.type === 'crossPackageRef',\n ).length,\n junctionCollections: objects.filter((object) =>\n object.relationshipFeatures.includes('SmrtJunction'),\n ).length,\n hierarchicalObjects: objects.filter((object) =>\n object.relationshipFeatures.includes('SmrtHierarchical'),\n ).length,\n polymorphicAssociations: objects.filter((object) =>\n object.relationshipFeatures.includes('SmrtPolymorphicAssociation'),\n ).length,\n uuidColumns: manifestObjects.reduce(\n (count, object) =>\n count +\n Object.values(object.schema?.columns ?? {}).filter(\n (column) => column.type === 'UUID',\n ).length,\n 0,\n ),\n };\n}\n\nfunction columnType(\n object: SmartObjectDefinition,\n fieldName: string,\n): string | undefined {\n const columnName = camelToSnake(fieldName);\n return object.schema?.columns[columnName]?.type;\n}\n\nfunction readPrompts(\n rootDir: string,\n): Array<{ filePath: string; key?: string }> {\n const srcDir = join(rootDir, 'src');\n if (!existsSync(srcDir)) return [];\n const prompts: Array<{ filePath: string; key?: string }> = [];\n for (const filePath of walkFiles(srcDir)) {\n if (!filePath.endsWith('.ts')) continue;\n const content = readFileSync(filePath, 'utf8');\n if (!content.includes('definePrompt')) continue;\n const keyMatch = content.match(/definePrompt\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]/);\n prompts.push({\n filePath: relative(rootDir, filePath),\n key: keyMatch?.[1],\n });\n }\n return prompts;\n}\n\nfunction walkFiles(dir: string): string[] {\n const files: string[] = [];\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n if (\n entry.name === 'node_modules' ||\n entry.name === 'dist' ||\n entry.name === '.svelte-kit'\n ) {\n continue;\n }\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n files.push(...walkFiles(fullPath));\n } else if (entry.isFile()) {\n files.push(fullPath);\n }\n }\n return files;\n}\n\nfunction sourceHashes(sources: Record<string, HashSource | undefined>) {\n const hashes: Record<string, string> = {};\n for (const [name, source] of Object.entries(sources)) {\n if (!source) continue;\n const content =\n 'content' in source ? source.content : readFileSync(source.path, 'utf8');\n hashes[name] = createHash('sha256').update(content).digest('hex');\n }\n return hashes;\n}\n\ntype HashSource = { content: string } | { path: string };\n\nfunction fileHashSource(path: string | undefined): HashSource | undefined {\n return path ? { path } : undefined;\n}\n\nfunction existingPath(rootDir: string, path: string): string | undefined {\n const fullPath = join(rootDir, path);\n return existsSync(fullPath) ? fullPath : undefined;\n}\n\nfunction readPackageJson(rootDir: string): PackageJsonLike | null {\n const path = join(rootDir, 'package.json');\n if (!existsSync(path)) return null;\n return JSON.parse(readFileSync(path, 'utf8'));\n}\n\nfunction record(value: unknown): Record<string, string> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, string>)\n : {};\n}\n\nfunction exportKeys(exportsField: unknown): string[] {\n if (typeof exportsField === 'string') return ['.'];\n if (\n typeof exportsField !== 'object' ||\n exportsField === null ||\n Array.isArray(exportsField)\n ) {\n return [];\n }\n return Object.keys(exportsField).sort();\n}\n\nfunction camelToSnake(value: string): string {\n return value\n .replace(/([a-z0-9])([A-Z])/g, '$1_$2')\n .replace(/[-\\s]+/g, '_')\n .toLowerCase();\n}\n\nfunction normalizeManifestForHash(manifest: SmartObjectManifest): unknown {\n const normalized = JSON.parse(JSON.stringify(manifest)) as Record<\n string,\n unknown\n >;\n delete normalized.timestamp;\n return normalized;\n}\n\nfunction stableJson(value: unknown): string {\n return JSON.stringify(sortJson(value), null, 2);\n}\n\nfunction sortJson(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(sortJson);\n if (value && typeof value === 'object') {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, entry]) => [key, sortJson(entry)]),\n );\n }\n return value;\n}\n"],"mappings":"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"}
|