@happyvertical/smrt-cli 0.60.9 → 0.60.11

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 (55) hide show
  1. package/AGENTS.md +24 -53
  2. package/README.md +5 -0
  3. package/agents/app-commands.md +2 -0
  4. package/agents/db-drop-framework-base-tables.md +49 -0
  5. package/agents/db-migrate-concurrency.md +11 -0
  6. package/dist/{AuditLogCollection-BBbvr8Qc-CoDs0BaX.js → AuditLogCollection-BBbvr8Qc-mcBSLXW9.js} +1 -1
  7. package/dist/{OidcIdentity-COeMidoC-B-cVovG3.js → OidcIdentity-COeMidoC-ETkpZbIS.js} +2 -2
  8. package/dist/{OidcIdentityCollection-D4DIZv0K-CexIL7No.js → OidcIdentityCollection-D4DIZv0K-Do3bwRuw.js} +1 -1
  9. package/dist/{PasswordCredentialService-DHJNKEeJ-DQlR62e-.js → PasswordCredentialService-BSSP_kyT-t7bjBu4L.js} +40 -22
  10. package/dist/{ProfileAssetCollection-D5-tG9Mm-Bmn4-Urc.js → ProfileAssetCollection-D5-tG9Mm-FbzWS3Fo.js} +3 -3
  11. package/dist/{ProfileCollection-CmRaiE9U-52qjwbhJ.js → ProfileCollection-CmRaiE9U-BYvpJg0y.js} +17 -17
  12. package/dist/{ProfileLinkCollection-pvPTsysg-ocN3hj_M.js → ProfileLinkCollection-pvPTsysg-nDbgawOW.js} +2 -2
  13. package/dist/{ProfileMetadataCollection-CAgJyjze-FX20yKjY.js → ProfileMetadataCollection-CAgJyjze-D-5QuGnR.js} +1 -1
  14. package/dist/{ProfileMetafieldCollection-19ae6Lpf-qg7eMcJk.js → ProfileMetafieldCollection-19ae6Lpf-CgEt1gPi.js} +1 -1
  15. package/dist/{ProfileRelationshipCollection-BFSlTQ7J-DlDILj3m.js → ProfileRelationshipCollection-BFSlTQ7J-Dv0ll9S1.js} +1 -1
  16. package/dist/{ProfileTypeCollection-BRLK8cHS-QVwjfqe8.js → ProfileTypeCollection-BRLK8cHS-BKuh_ajh.js} +2 -2
  17. package/dist/app/portability-assets.d.ts +2 -0
  18. package/dist/app/portability-assets.d.ts.map +1 -1
  19. package/dist/app.js +2 -2
  20. package/dist/{cli-CtRx1_yP.js → cli-DXIN1FbA.js} +1 -1
  21. package/dist/commands/docs-claude.d.ts +1 -0
  22. package/dist/commands/docs-claude.d.ts.map +1 -1
  23. package/dist/commands/docs-knowledge-bundle.d.ts +87 -0
  24. package/dist/commands/docs-knowledge-bundle.d.ts.map +1 -0
  25. package/dist/commands/docs-skills-install.d.ts +31 -0
  26. package/dist/commands/docs-skills-install.d.ts.map +1 -0
  27. package/dist/{commands-DNssH5Dv.js → commands-DD5gexRY.js} +400 -7
  28. package/dist/{dist-BJABhykg.js → dist-CivxAJ6C.js} +2 -2
  29. package/dist/dist-DcYLLDwF.js +1854 -0
  30. package/dist/{dist-D25iWIXX.js → dist-DjG0qPkx.js} +5 -5
  31. package/dist/index.js +12 -12
  32. package/dist/knowledge/intents/audit-trail.md +63 -0
  33. package/dist/knowledge/intents/auth-and-users.md +67 -0
  34. package/dist/knowledge/intents/background-work.md +72 -0
  35. package/dist/knowledge/intents/feature-flags-and-entitlements.md +60 -0
  36. package/dist/knowledge/intents/file-and-asset-storage.md +71 -0
  37. package/dist/knowledge/intents/human-approvals.md +56 -0
  38. package/dist/knowledge/intents/index.md +41 -0
  39. package/dist/knowledge/intents/money-and-rates.md +65 -0
  40. package/dist/knowledge/intents/outbound-messages.md +67 -0
  41. package/dist/knowledge/intents/prompts-and-ai-operations.md +72 -0
  42. package/dist/knowledge/intents/relationships-and-trees.md +56 -0
  43. package/dist/knowledge/intents/scheduled-runs.md +61 -0
  44. package/dist/knowledge/intents/search-facts-knowledge.md +68 -0
  45. package/dist/knowledge/intents/secrets-and-config.md +66 -0
  46. package/dist/knowledge/intents/tenant-scoping.md +63 -0
  47. package/dist/knowledge/intents/webhooks-and-events.md +71 -0
  48. package/dist/{oidcProvisioningPrimitives-KpIiLmG4-CnRTofeV.js → oidcProvisioningPrimitives-KpIiLmG4-D5-0dAY3.js} +3 -3
  49. package/dist/{operator-fwao3Y1j.js → operator-B0ZraSEE.js} +2 -2
  50. package/dist/{portability-CbMgEnD1.js → portability-sL8U5Hld.js} +21 -13
  51. package/dist/{resolveIdentity-j2WFuKDT-C9XtigVZ.js → resolveIdentity-j2WFuKDT-BieMIOLz.js} +14 -14
  52. package/dist/smrt-knowledge.okf.md +58 -0
  53. package/package.json +16 -15
  54. package/dist/dist-B3gpMpBj.js +0 -1908
  55. package/dist/dist-BQI8s_yA.js +0 -1854
@@ -5,7 +5,7 @@ import { t as DEFAULT_CLI_CONFIG } from "./config-CdJRSMRi.js";
5
5
  import { addMcpAppsRuntime, assertMcpAppsPluginName, configureMcpAppsConsumerRegistry, mcpAppsCommands, scaffoldMcpAppsPackage, validateMcpAppsPackage } from "./mcp-apps-packaging-CixRnxz_.js";
6
6
  import { createRequire } from "node:module";
7
7
  import * as fs from "node:fs";
8
- import { constants, createReadStream, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
8
+ import { constants, createReadStream, existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
9
9
  import * as path from "node:path";
10
10
  import { basename, dirname, extname, isAbsolute, join, normalize, relative, resolve, sep } from "node:path";
11
11
  import { fileURLToPath, pathToFileURL } from "node:url";
@@ -21,6 +21,8 @@ import { glob } from "tinyglobby";
21
21
  import { getPackageConfig, loadConfig, toAIClientOptions, tryResolveConfiguredAIProvider } from "@happyvertical/smrt-config";
22
22
  import { toSnakeCase as toSnakeCase$1 } from "@happyvertical/smrt-core/utils";
23
23
  import { checkKnowledgeGraphFreshness, discoverScopedPackageDirectories, readAgentModuleDocs, readPackageAgentDoc, resolveAgentModuleDocPaths } from "@happyvertical/smrt-core/knowledge";
24
+ import { OKF_BUNDLE_DIR_NAME, OKF_BUNDLE_FORMAT, OKF_BUNDLE_MANIFEST, OKF_SHIPPED_COMPONENT_PAGE, OKF_SHIPPED_INTENTS_DIR, buildArchitectureContext, buildKnowledgeIndex, buildReviewContext, checkKnowledgeFreshness, compactContextResult, diffKnowledgeIndex, readOkfBundleManifest, renderFreshnessResult, renderKnowledgeIndexMarkdown, stampPackageVersion } from "@happyvertical/smrt-dev-mcp/knowledge";
25
+ import { getAgentSkill, getAgentSkillsPackageVersion } from "@happyvertical/smrt-dev-mcp/agent-skills";
24
26
  import { MCPGenerator } from "@happyvertical/smrt-core/generators";
25
27
  import { generateDeclarationsFromCLI } from "@happyvertical/smrt-core/prebuild";
26
28
  import https from "node:https";
@@ -28,7 +30,6 @@ import { createServer } from "node:http";
28
30
  import { importWorkspaceModule } from "@happyvertical/smrt-core/utils/import-workspace-module";
29
31
  import { renderForeignKeyAddStatements } from "@happyvertical/smrt-core/schema";
30
32
  import { FRAMEWORK_BASE_TABLE_NAMES, SYSTEM_TABLE_TENANT_UUID_COLUMNS, backfillLegacyQualifiedNames, buildIntegerWidthTableStatements, collectIntegerWidthTargets, collectNullEqualIndexTargets, countLegacyQualifiedNameReferences, dropFrameworkBaseTables, ensurePostgresChangeFeedAppendFunction, migrateNullEqualIndexes, nullEqualIndexStatements, parsePostgresTimeoutMs, planFrameworkBaseTableDrop, preflightIntegerWidthWidening, preflightNullEqualIndexes, widenIntegerColumnsToBigInt } from "@happyvertical/smrt-core/migrations";
31
- import { buildArchitectureContext, buildKnowledgeIndex, buildReviewContext, checkKnowledgeFreshness, compactContextResult, diffKnowledgeIndex, renderFreshnessResult, renderKnowledgeIndexMarkdown } from "@happyvertical/smrt-dev-mcp/knowledge";
32
33
  import { RUNTIME_TOOLS } from "@happyvertical/smrt-dev-mcp/runtime";
33
34
  //#region src/commands/config-export.ts
34
35
  /**
@@ -4201,6 +4202,349 @@ var dispatchCommands = {
4201
4202
  }
4202
4203
  };
4203
4204
  //#endregion
4205
+ //#region src/commands/docs-knowledge-bundle.ts
4206
+ /**
4207
+ * Knowledge-bundle half of `smrt docs:agents` (#4689).
4208
+ *
4209
+ * Renders the "Find it by intent" section of `.agents/smrt-framework.md` from
4210
+ * the OKF intent index and exports the OKF pages for the installed packages
4211
+ * into `<output dir>/smrt-knowledge/`. The on-disk contract (layout,
4212
+ * `bundle.json`, version stamping) lives in `@happyvertical/smrt-dev-mcp/knowledge`
4213
+ * (`okf-bundle.ts`) so the freshness gate reads exactly what this writes.
4214
+ *
4215
+ * Where the pages come from — never the monorepo checkout in a consumer:
4216
+ * - component page: `<package>/dist/smrt-knowledge.okf.md`, shipped by every
4217
+ * published package; inside the monorepo the committed
4218
+ * `docs/knowledge/components/<name>.md` is the fallback.
4219
+ * - intent pages: `dist/knowledge/intents/` of the installed `smrt-cli` (or
4220
+ * of the running CLI when it is not a project dependency); inside the
4221
+ * monorepo the committed `docs/knowledge/intents/`.
4222
+ */
4223
+ var ROW = /^\| (.+?) \| \[[^\]]+\]\(\/intents\/([a-z0-9-]+)\.md\) \| (.+?) \| (.+?) \| .* \|$/;
4224
+ /** Strict npm package name: optional lowercase scope, no path segments. */
4225
+ var PACKAGE_NAME = /^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/;
4226
+ function isValidPackageName(name) {
4227
+ return typeof name === "string" && PACKAGE_NAME.test(name);
4228
+ }
4229
+ /**
4230
+ * `target` resolved under `root`, or a thrown error when it escapes (`..`,
4231
+ * absolute segments). Every bundle write and delete goes through this.
4232
+ */
4233
+ function containedPath(root, target) {
4234
+ const base = resolve(root);
4235
+ const full = resolve(base, target);
4236
+ if (full !== base && !full.startsWith(base + sep)) throw new Error(`Refusing to write outside ${base}: ${target}`);
4237
+ return full;
4238
+ }
4239
+ /**
4240
+ * Throws when `path` exists as a symlink. `containedPath` is lexical, so a
4241
+ * checkout that ships `.agents/smrt-knowledge` as a link would otherwise have
4242
+ * the bundle's wholesale directory replacement land wherever the link points.
4243
+ */
4244
+ function assertNotSymlink(path) {
4245
+ let link = false;
4246
+ try {
4247
+ link = lstatSync(path).isSymbolicLink();
4248
+ } catch {
4249
+ return;
4250
+ }
4251
+ if (link) throw new Error(`Refusing to write through a symlink: ${path}`);
4252
+ }
4253
+ /**
4254
+ * Whether a package may supply bundle file names: a plain npm name that equals
4255
+ * the identity its directory was discovered under (a mismatching name could
4256
+ * claim another package's page or point the target elsewhere).
4257
+ */
4258
+ function isBundleSafePackage(pkg) {
4259
+ if (isValidPackageName(pkg.name) && !(pkg.specifier && pkg.name !== pkg.specifier)) return true;
4260
+ console.warn(` ⚠️ Skipping ${JSON.stringify(pkg.name)} in the knowledge bundle: invalid package name or it does not match its directory`);
4261
+ return false;
4262
+ }
4263
+ function unscopedName(name) {
4264
+ return name.replace(/^@[^/]+\//, "");
4265
+ }
4266
+ /** Parses the intent index table; the rows are the only structure relied on. */
4267
+ function parseIntentIndex(markdown) {
4268
+ const rows = [];
4269
+ for (const line of markdown.split(/\r?\n/)) {
4270
+ const match = ROW.exec(line);
4271
+ if (!match) continue;
4272
+ const homes = [...match[3].matchAll(/\(\/components\/([^)]+)\.md\)/g)].map((home) => home[1]);
4273
+ rows.push({
4274
+ intent: match[1],
4275
+ slug: match[2],
4276
+ homes,
4277
+ entryPoint: match[4],
4278
+ raw: line
4279
+ });
4280
+ }
4281
+ return rows;
4282
+ }
4283
+ /** Intents with at least one installed home package, in index order. */
4284
+ function filterInstalledIntents(rows, installed) {
4285
+ return rows.filter((row) => row.homes.some((home) => installed.has(home)));
4286
+ }
4287
+ /** The intent index with rows for intents without an installed home removed. */
4288
+ function filterIntentIndexMarkdown(markdown, keptSlugs) {
4289
+ return markdown.split("\n").filter((line) => {
4290
+ const match = ROW.exec(line.replace(/\r$/, ""));
4291
+ return !match || keptSlugs.has(match[2]);
4292
+ }).join("\n");
4293
+ }
4294
+ /**
4295
+ * The leading "Find it by intent" section, or [] when no intent has an
4296
+ * installed home. `pagesDir` is the bundle directory relative to the file the
4297
+ * section is written into.
4298
+ */
4299
+ function renderIntentSection(rows, installed, pagesDir = OKF_BUNDLE_DIR_NAME) {
4300
+ const kept = filterInstalledIntents(rows, installed);
4301
+ if (kept.length === 0) return [];
4302
+ const lines = [
4303
+ "## Find it by intent",
4304
+ "",
4305
+ `Before hand-rolling infrastructure, check whether an installed SMRT package already provides it. Each page names the entry point and the reason not to roll your own; they live in \`${pagesDir}/\` next to this file, where a concept ID such as \`/intents/background-work.md\` resolves against that directory. Only intents with an installed home package are listed.`,
4306
+ "",
4307
+ "| Intent | Reach for | Installed package(s) | Page |",
4308
+ "| --- | --- | --- | --- |"
4309
+ ];
4310
+ for (const row of kept) {
4311
+ const homes = row.homes.filter((home) => installed.has(home)).map((home) => `${home}@${installed.get(home)}`).join(", ");
4312
+ lines.push(`| ${row.intent} | ${row.entryPoint} | ${homes} | [${row.slug}](${pagesDir}/intents/${row.slug}.md) |`);
4313
+ }
4314
+ lines.push("");
4315
+ return lines;
4316
+ }
4317
+ function findOwnPackageRoot() {
4318
+ let current = dirname(fileURLToPath(import.meta.url));
4319
+ for (;;) {
4320
+ const manifest = join(current, "package.json");
4321
+ if (existsSync(manifest)) try {
4322
+ if (JSON.parse(readFileSync(manifest, "utf8")).name === "@happyvertical/smrt-cli") return current;
4323
+ } catch {}
4324
+ const parent = dirname(current);
4325
+ if (parent === current) return null;
4326
+ current = parent;
4327
+ }
4328
+ }
4329
+ function packageVersion(dir) {
4330
+ try {
4331
+ return JSON.parse(readFileSync(join(dir, "package.json"), "utf8")).version;
4332
+ } catch {
4333
+ return;
4334
+ }
4335
+ }
4336
+ /** Finds the intent pages; null when none are reachable (the section is then omitted). */
4337
+ function resolveIntentSource(options) {
4338
+ const candidates = [];
4339
+ if (options.monorepoRoot) candidates.push({ dir: join(options.monorepoRoot, "docs", "knowledge", "intents") });
4340
+ for (const root of [options.installedCliDirectory, findOwnPackageRoot()]) {
4341
+ if (!root) continue;
4342
+ candidates.push({
4343
+ dir: join(root, "dist", OKF_SHIPPED_INTENTS_DIR),
4344
+ version: packageVersion(root)
4345
+ });
4346
+ }
4347
+ return candidates.find((candidate) => existsSync(join(candidate.dir, "index.md"))) ?? null;
4348
+ }
4349
+ function loadIntentRows(source) {
4350
+ return parseIntentIndex(readFileSync(join(source.dir, "index.md"), "utf8"));
4351
+ }
4352
+ function componentPageSource(pkg, monorepoRoot) {
4353
+ const candidates = [];
4354
+ if (pkg.directory) candidates.push(join(pkg.directory, "dist", OKF_SHIPPED_COMPONENT_PAGE));
4355
+ if (monorepoRoot) candidates.push(join(monorepoRoot, "docs", "knowledge", "components", `${unscopedName(pkg.name)}.md`));
4356
+ return candidates.find((path) => existsSync(path)) ?? null;
4357
+ }
4358
+ /**
4359
+ * Writes `<bundleDir>/{components,intents}/` and `bundle.json`. The two page
4360
+ * directories are replaced wholesale so uninstalled packages and retired
4361
+ * intents never linger; nothing else under `bundleDir` is touched. Returns null
4362
+ * (writing nothing) when no page is reachable.
4363
+ */
4364
+ function exportKnowledgeBundle(options) {
4365
+ const safePackages = options.packages.filter(isBundleSafePackage);
4366
+ const installed = new Map(safePackages.map((pkg) => [unscopedName(pkg.name), pkg.version]));
4367
+ const pages = /* @__PURE__ */ new Map();
4368
+ const manifestPackages = [];
4369
+ const withoutPages = [];
4370
+ for (const pkg of [...safePackages].sort((a, b) => a.name.localeCompare(b.name))) {
4371
+ const source = componentPageSource(pkg, options.monorepoRoot);
4372
+ if (!source) {
4373
+ withoutPages.push(pkg.name);
4374
+ continue;
4375
+ }
4376
+ const concept = `/components/${unscopedName(pkg.name)}.md`;
4377
+ pages.set(concept, stampPackageVersion(readFileSync(source, "utf8"), pkg.version));
4378
+ manifestPackages.push({
4379
+ name: pkg.name,
4380
+ version: pkg.version,
4381
+ concept
4382
+ });
4383
+ }
4384
+ const intentSlugs = [];
4385
+ if (options.intentSource) {
4386
+ const kept = filterInstalledIntents(options.intentRows, installed);
4387
+ const keptSlugs = new Set(kept.map((row) => row.slug));
4388
+ const stamp = (text) => options.intentSource?.version ? stampPackageVersion(text, options.intentSource.version) : text;
4389
+ for (const row of kept) {
4390
+ const path = join(options.intentSource.dir, `${row.slug}.md`);
4391
+ if (!existsSync(path)) continue;
4392
+ pages.set(`/intents/${row.slug}.md`, stamp(readFileSync(path, "utf8")));
4393
+ intentSlugs.push(row.slug);
4394
+ }
4395
+ if (intentSlugs.length > 0) pages.set("/intents/index.md", stamp(filterIntentIndexMarkdown(readFileSync(join(options.intentSource.dir, "index.md"), "utf8"), keptSlugs)));
4396
+ }
4397
+ if (pages.size === 0) return null;
4398
+ const hash = createHash("sha256");
4399
+ for (const concept of [...pages.keys()].sort()) hash.update(`${concept}\0${pages.get(concept)}\0`);
4400
+ const contentHash = `sha256:${hash.digest("hex")}`;
4401
+ let previous = null;
4402
+ try {
4403
+ previous = readOkfBundleManifest(options.bundleDir);
4404
+ } catch {}
4405
+ const exportedAt = previous?.contentHash === contentHash ? previous.exportedAt : (options.now ?? /* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
4406
+ const writes = [...pages].map(([concept, text]) => [containedPath(options.bundleDir, concept.replace(/^\/+/, "")), text]);
4407
+ const manifestPath = containedPath(options.bundleDir, OKF_BUNDLE_MANIFEST);
4408
+ const pageDirs = ["components", "intents"].map((dir) => containedPath(options.bundleDir, dir));
4409
+ for (const path of [
4410
+ resolve(options.bundleDir),
4411
+ ...pageDirs,
4412
+ manifestPath
4413
+ ]) assertNotSymlink(path);
4414
+ for (const dir of pageDirs) rmSync(dir, {
4415
+ recursive: true,
4416
+ force: true
4417
+ });
4418
+ for (const [target, text] of writes) {
4419
+ mkdirSync(dirname(target), { recursive: true });
4420
+ writeFileSync(target, text, "utf8");
4421
+ }
4422
+ const manifest = {
4423
+ format: OKF_BUNDLE_FORMAT,
4424
+ exportedBy: options.exportedBy,
4425
+ exportedAt,
4426
+ contentHash,
4427
+ packages: manifestPackages,
4428
+ intents: intentSlugs
4429
+ };
4430
+ writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`, "utf8");
4431
+ return {
4432
+ bundleDir: options.bundleDir,
4433
+ components: manifestPackages.length,
4434
+ intents: intentSlugs.length,
4435
+ withoutPages,
4436
+ exportedAt
4437
+ };
4438
+ }
4439
+ //#endregion
4440
+ //#region src/commands/docs-skills-install.ts
4441
+ /**
4442
+ * Skill-installation half of `smrt docs:agents` (#4708).
4443
+ *
4444
+ * Writes the bundled smrt skills from `@happyvertical/smrt-dev-mcp` into the
4445
+ * consumer's harness directories so a harness discovers them without the MCP
4446
+ * server: `.claude/skills/<name>/SKILL.md` (Claude Code) and the
4447
+ * harness-neutral `.agents/skills/<name>/SKILL.md` (Codex, Gemini, others).
4448
+ *
4449
+ * Ownership: an installed copy carries a generated marker with the
4450
+ * smrt-dev-mcp version. A rerun replaces a marked copy; an unmarked copy was
4451
+ * hand-edited (or hand-written) and is left alone with a warning. Writes obey
4452
+ * the bundle writer's rules: contained under the project root, never through
4453
+ * a symlink.
4454
+ */
4455
+ /** Harness directories that receive each skill, relative to the project root. */
4456
+ var SKILL_INSTALL_DIRS = [".claude/skills", ".agents/skills"];
4457
+ /** Prefix of the marker line; the rest carries the producer and version. */
4458
+ /** Where the shipped skill text says the knowledge bundle lives. */
4459
+ var DEFAULT_BUNDLE_DIR = ".agents/smrt-knowledge";
4460
+ var SKILL_MARKER_PREFIX = "<!-- smrt-generated:";
4461
+ /**
4462
+ * Inserts the generated marker after the frontmatter, which must stay the
4463
+ * first thing in the file for skill-aware harnesses.
4464
+ */
4465
+ function withGeneratedMarker(markdown, skill, version, generatedBy) {
4466
+ const marker = `${SKILL_MARKER_PREFIX} ${generatedBy} from @happyvertical/smrt-dev-mcp@${version}; ${skill}; edits are overwritten on rerun, remove this line to keep a local copy -->`;
4467
+ const frontmatter = /^---\r?\n[\s\S]*?\r?\n---\r?\n/.exec(markdown);
4468
+ if (!frontmatter) return `${marker}\n${markdown}`;
4469
+ const end = frontmatter[0].length;
4470
+ return `${markdown.slice(0, end)}\n${marker}\n${markdown.slice(end)}`;
4471
+ }
4472
+ function hasMarker(text) {
4473
+ return text.split(/\r?\n/).some((line) => line.startsWith(SKILL_MARKER_PREFIX));
4474
+ }
4475
+ /** Refuses when the file or any directory between `root` and it is a symlink. */
4476
+ function assertNoSymlinkOnPath(root, target) {
4477
+ const rel = relative(resolve(root), target);
4478
+ let current = resolve(root);
4479
+ for (const segment of rel.split(/[\\/]/).filter(Boolean)) {
4480
+ current = join(current, segment);
4481
+ assertNotSymlink(current);
4482
+ }
4483
+ }
4484
+ /**
4485
+ * Installs `skills` under every harness directory of `projectRoot`. Existing
4486
+ * unmarked copies are skipped (and reported through `warn`) unless they are
4487
+ * already byte-identical to what would be written.
4488
+ */
4489
+ function installAgentSkills(options) {
4490
+ const warn = options.warn ?? console.warn;
4491
+ const version = getAgentSkillsPackageVersion();
4492
+ const normalizedBundle = options.bundleDir?.split(sep).join("/").replace(/\/+$/, "");
4493
+ const bundleRef = normalizedBundle && normalizedBundle !== DEFAULT_BUNDLE_DIR ? normalizedBundle : void 0;
4494
+ const results = [];
4495
+ const plan = options.skills.flatMap((skill) => {
4496
+ const shipped = getAgentSkill({
4497
+ name: skill,
4498
+ includeReferences: false
4499
+ }).skillMarkdown;
4500
+ const source = bundleRef ? shipped.split(DEFAULT_BUNDLE_DIR).join(bundleRef) : shipped;
4501
+ const body = withGeneratedMarker(source, skill, version, options.generatedBy);
4502
+ return SKILL_INSTALL_DIRS.map((dir) => {
4503
+ const target = containedPath(options.projectRoot, join(dir, skill, "SKILL.md"));
4504
+ assertNoSymlinkOnPath(options.projectRoot, target);
4505
+ return {
4506
+ skill,
4507
+ target,
4508
+ body,
4509
+ source
4510
+ };
4511
+ });
4512
+ });
4513
+ for (const { skill, target, body, source } of plan) {
4514
+ const shown = relative(resolve(options.projectRoot), target);
4515
+ let status = "installed";
4516
+ if (existsSync(target)) {
4517
+ const existing = readFileSync(target, "utf8");
4518
+ if (existing === body || existing === source) {
4519
+ results.push({
4520
+ skill,
4521
+ path: shown,
4522
+ status: "unchanged"
4523
+ });
4524
+ continue;
4525
+ }
4526
+ if (!hasMarker(existing)) {
4527
+ warn(` ⚠️ ${shown} has no smrt-generated marker; leaving it alone (delete it to let docs:agents manage it)`);
4528
+ results.push({
4529
+ skill,
4530
+ path: shown,
4531
+ status: "skipped-hand-edited"
4532
+ });
4533
+ continue;
4534
+ }
4535
+ status = "updated";
4536
+ }
4537
+ mkdirSync(dirname(target), { recursive: true });
4538
+ writeFileSync(target, body, "utf8");
4539
+ results.push({
4540
+ skill,
4541
+ path: shown,
4542
+ status
4543
+ });
4544
+ }
4545
+ return results;
4546
+ }
4547
+ //#endregion
4204
4548
  //#region src/commands/docs-claude.ts
4205
4549
  /**
4206
4550
  * docs:agents / docs:claude commands
@@ -4226,6 +4570,11 @@ function createDocsCommand(config) {
4226
4570
  description: "Include every linked module document in the snapshot",
4227
4571
  default: false
4228
4572
  },
4573
+ "no-install-skills": {
4574
+ type: "boolean",
4575
+ description: "Do not install the smrt agent skills into .claude/skills and .agents/skills (installed by default)",
4576
+ default: false
4577
+ },
4229
4578
  "dry-run": {
4230
4579
  type: "boolean",
4231
4580
  description: "Print to stdout without writing file",
@@ -4248,7 +4597,18 @@ function createDocsCommand(config) {
4248
4597
  console.log(" Make sure packages are installed before running this command.\n");
4249
4598
  process.exit(1);
4250
4599
  }
4251
- const content = generateMarkdown(packages, rootDocs.length > 0 ? rootDocs : void 0, sdkPackages.length > 0 ? sdkPackages : void 0, config.generatedBy, { complete: options.complete });
4600
+ const bundlePackages = packages.filter(isBundleSafePackage);
4601
+ const installedVersions = new Map(bundlePackages.map((pkg) => [unscopedName(pkg.name), pkg.version]));
4602
+ const intentSource = resolveIntentSource({
4603
+ monorepoRoot,
4604
+ installedCliDirectory: installedDirectories.find((entry) => entry.name === "smrt-cli")?.realDirectory
4605
+ });
4606
+ const intentRows = intentSource ? loadIntentRows(intentSource) : [];
4607
+ const bundleDirName = "smrt-knowledge";
4608
+ const content = generateMarkdown(packages, rootDocs.length > 0 ? rootDocs : void 0, sdkPackages.length > 0 ? sdkPackages : void 0, config.generatedBy, {
4609
+ complete: options.complete,
4610
+ intentSection: renderIntentSection(intentRows, installedVersions, bundleDirName)
4611
+ });
4252
4612
  if (dryRun) {
4253
4613
  console.log(content);
4254
4614
  return;
@@ -4256,6 +4616,14 @@ function createDocsCommand(config) {
4256
4616
  const outputDir = dirname(outputPath);
4257
4617
  if (!existsSync(outputDir)) mkdirSync(outputDir, { recursive: true });
4258
4618
  writeFileSync(outputPath, content, "utf-8");
4619
+ const bundle = exportKnowledgeBundle({
4620
+ bundleDir: join(outputDir, bundleDirName),
4621
+ packages: bundlePackages,
4622
+ monorepoRoot,
4623
+ intentSource,
4624
+ intentRows,
4625
+ exportedBy: config.generatedBy
4626
+ });
4259
4627
  let graphExported = false;
4260
4628
  if (monorepoRoot) {
4261
4629
  const graphPath = join(monorepoRoot, ".smrt", "smrt-knowledge-graph.json");
@@ -4270,6 +4638,12 @@ function createDocsCommand(config) {
4270
4638
  graphExported = true;
4271
4639
  }
4272
4640
  }
4641
+ const skillResults = options["no-install-skills"] ? [] : installAgentSkills({
4642
+ projectRoot: process.cwd(),
4643
+ bundleDir: relative(process.cwd(), join(outputDir, bundleDirName)),
4644
+ skills: isSmrtRepository(monorepoRoot) ? ["smrt-catalog", "smrt-contribute"] : ["smrt-catalog"],
4645
+ generatedBy: config.generatedBy
4646
+ });
4273
4647
  const totalPackages = packages.length + sdkPackages.length;
4274
4648
  console.log(`\n✅ Generated ${outputPath}`);
4275
4649
  console.log(` ${totalPackages} packages documented`);
@@ -4282,6 +4656,12 @@ function createDocsCommand(config) {
4282
4656
  if (moduleDocCount > 0) console.log(` ${moduleDocCount} linked module docs`);
4283
4657
  if (rootDocs.length > 0) console.log(` ${rootDocs.length} framework documents included`);
4284
4658
  if (graphExported) console.log(" cross-package knowledge graph exported");
4659
+ if (bundle) {
4660
+ console.log(` knowledge bundle exported to ${bundle.bundleDir} (${bundle.components} component pages, ${bundle.intents} intent pages)`);
4661
+ if (bundle.withoutPages.length > 0) console.log(` ${bundle.withoutPages.length} installed packages ship no knowledge page`);
4662
+ }
4663
+ const written = skillResults.filter((result) => result.status === "installed" || result.status === "updated");
4664
+ if (written.length > 0) console.log(` ${written.length} agent skill files written (${[...new Set(written.map((result) => result.skill))].join(", ")})`);
4285
4665
  console.log("");
4286
4666
  } catch (error) {
4287
4667
  console.error("\n❌ Failed to generate agent documentation:");
@@ -4372,6 +4752,18 @@ function loadPackageInfo(packagePath, dirName, complete, specifier) {
4372
4752
  return null;
4373
4753
  }
4374
4754
  }
4755
+ /**
4756
+ * Whether `root` is the smrt repository itself (not just any pnpm monorepo):
4757
+ * only its root package is named `@happyvertical/smrt`.
4758
+ */
4759
+ function isSmrtRepository(root) {
4760
+ if (!root) return false;
4761
+ try {
4762
+ return JSON.parse(readFileSync(join(root, "package.json"), "utf-8")).name === "@happyvertical/smrt";
4763
+ } catch {
4764
+ return false;
4765
+ }
4766
+ }
4375
4767
  function detectMonorepoRoot() {
4376
4768
  try {
4377
4769
  let currentDir = realpathSync(process.cwd());
@@ -4452,6 +4844,7 @@ function generateMarkdown(packages, rootDocs, sdkPackages, generatedBy = "smrt d
4452
4844
  lines.push("");
4453
4845
  lines.push("This project uses the SMRT framework. Below are the conventions and patterns for the installed packages.");
4454
4846
  lines.push("");
4847
+ if (options.intentSection && options.intentSection.length > 0) lines.push(...options.intentSection);
4455
4848
  if (rootDocs && rootDocs.length > 0) {
4456
4849
  lines.push("## Framework Documentation");
4457
4850
  lines.push("");
@@ -8425,7 +8818,7 @@ var dbMaterializeTenantHierarchyCommand = {
8425
8818
  if (!config.database?.url || config.database.url === ":memory:") throw new Error("Database configuration required for db:materialize-tenant-hierarchy. Configure database.url in smrt.config.ts (or DATABASE_URL).");
8426
8819
  const dbType = config.database.type || "sqlite";
8427
8820
  const { getDatabase } = await import("@happyvertical/sql");
8428
- const { materializeTenantHierarchy, TenantHierarchyMaterializationError } = await import("./dist-BQI8s_yA.js");
8821
+ const { materializeTenantHierarchy, TenantHierarchyMaterializationError } = await import("./dist-DcYLLDwF.js");
8429
8822
  db = await getDatabase({
8430
8823
  type: dbType,
8431
8824
  url: config.database.url
@@ -8634,7 +9027,7 @@ var dbMigrateLedgerAccountsCommand = {
8634
9027
  if (dbType !== "postgres") throw new Error("db:migrate-ledger-accounts currently supports PostgreSQL only; no changes were made. See the smrt-ledgers README for SQLite.");
8635
9028
  await autoDiscoverAndLoad();
8636
9029
  const { getDatabase } = await import("@happyvertical/sql");
8637
- const { migrateLedgerAccountsTable, planLedgerAccountsTableMove } = await import("./dist-D25iWIXX.js");
9030
+ const { migrateLedgerAccountsTable, planLedgerAccountsTableMove } = await import("./dist-DjG0qPkx.js");
8638
9031
  db = await getDatabase({
8639
9032
  type: dbType,
8640
9033
  url: config.database.url
@@ -10860,7 +11253,7 @@ var usersProvisionOwnerCommand = {
10860
11253
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
10861
11254
  if (config.database?.type !== "postgres" || !config.database.url) throw new Error(FAILURE);
10862
11255
  const { getDatabase } = await import("@happyvertical/sql");
10863
- const { provisionPasswordOwner } = await import("./operator-fwao3Y1j.js");
11256
+ const { provisionPasswordOwner } = await import("./operator-B0ZraSEE.js");
10864
11257
  db = await getDatabase({
10865
11258
  type: "postgres",
10866
11259
  url: config.database.url
@@ -11223,7 +11616,7 @@ var utilityCommands = {
11223
11616
  description: "Application operations: install, setup, recover, start, stop, doctor, open, backup, export, import, migrate, worker, dev, build (`smrt app help`)",
11224
11617
  args: ["[operation]", "[args...]"],
11225
11618
  handler: async (args) => {
11226
- const { runAppCommand } = await import("./cli-CtRx1_yP.js").then((n) => n.r);
11619
+ const { runAppCommand } = await import("./cli-DXIN1FbA.js").then((n) => n.r);
11227
11620
  const code = await runAppCommand(args);
11228
11621
  if (code !== 0) process.exitCode = code;
11229
11622
  }
@@ -283,7 +283,7 @@ async function runTenantHierarchyReadScope(scope, callback) {
283
283
  createLogger({ level: "info" });
284
284
  //#endregion
285
285
  //#region ../tenancy/dist/index.js
286
- ObjectRegistry.registerPackageManifest(JSON.parse(`{"version":"1.0.0","timestamp":0,"packageName":"@happyvertical/smrt-tenancy","packageVersion":"0.60.9","objects":{"@happyvertical/smrt-tenancy:BillingRelationship":{"name":"billingrelationship","className":"BillingRelationship","qualifiedName":"@happyvertical/smrt-tenancy:BillingRelationship","collection":"billingrelationships","filePath":"/home/runner/work/smrt/smrt/packages/tenancy/src/billing-relationship.ts","packageName":"@happyvertical/smrt-tenancy","fields":{"childTenantId":{"type":"crossPackageRef","required":true,"related":"@happyvertical/smrt-users:Tenant","_meta":{"required":true}},"resellerTenantId":{"type":"crossPackageRef","required":true,"related":"@happyvertical/smrt-users:Tenant","_meta":{"required":true}},"billingOwnerMode":{"type":"text","required":false,"default":"self","enum":["self","reseller"]}},"methods":{},"decoratorConfig":{"tableName":"_smrt_billing_relationships","conflictColumns":["child_tenant_id"],"api":false,"cli":false,"mcp":false},"extends":"SmrtObject","exportName":"BillingRelationship","collectionExportName":"BillingRelationshipCollection","validationRules":[{"field":"childTenantId","rule":"required","fieldType":"crossPackageRef"},{"field":"resellerTenantId","rule":"required","fieldType":"crossPackageRef"}],"schema":{"tableName":"_smrt_billing_relationships","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_billing_relationships\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"child_tenant_id\\" UUID NOT NULL,\\n \\"reseller_tenant_id\\" UUID NOT NULL,\\n \\"billing_owner_mode\\" TEXT DEFAULT 'self'\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"child_tenant_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":true,"unique":false},"reseller_tenant_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":true,"unique":false},"billing_owner_mode":{"type":"TEXT","notNull":false,"unique":false,"default":"self"}},"indexes":[{"name":"_smrt_billing_relationships_child_tenant_id_idx","columns":["child_tenant_id"],"unique":true},{"name":"_smrt_billing_relationships_slug_context_idx","columns":["slug","context"]},{"name":"_smrt_billing_relationships_created_at_idx","columns":["created_at"]},{"name":"_smrt_billing_relationships_reseller_tenant_id_idx","columns":["reseller_tenant_id"]}],"version":"4d7f410a"},"importPath":"@happyvertical/smrt-tenancy"},"@happyvertical/smrt-tenancy:BillingRelationshipCollection":{"name":"billingrelationshipcollection","className":"BillingRelationshipCollection","qualifiedName":"@happyvertical/smrt-tenancy:BillingRelationshipCollection","collection":"billingrelationships","filePath":"/home/runner/work/smrt/smrt/packages/tenancy/src/billing-relationship.ts","packageName":"@happyvertical/smrt-tenancy","fields":{},"methods":{},"decoratorConfig":{"tableName":"_smrt_billing_relationships","api":false,"mcp":false,"cli":false},"extends":"SmrtCollection","extendsTypeArg":"BillingRelationship","exportName":"BillingRelationshipCollection","collectionExportName":"BillingRelationshipCollectionCollection","collectionOf":"@happyvertical/smrt-tenancy:BillingRelationship","inheritedExposure":["api","mcp","cli"],"schema":{"tableName":"_smrt_billing_relationships","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_billing_relationships\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"child_tenant_id\\" UUID NOT NULL,\\n \\"reseller_tenant_id\\" UUID NOT NULL,\\n \\"billing_owner_mode\\" TEXT DEFAULT 'self'\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"child_tenant_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":true,"unique":false},"reseller_tenant_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":true,"unique":false},"billing_owner_mode":{"type":"TEXT","notNull":false,"unique":false,"default":"self"}},"indexes":[{"name":"_smrt_billing_relationships_child_tenant_id_idx","columns":["child_tenant_id"],"unique":true},{"name":"_smrt_billing_relationships_slug_context_idx","columns":["slug","context"]},{"name":"_smrt_billing_relationships_created_at_idx","columns":["created_at"]},{"name":"_smrt_billing_relationships_reseller_tenant_id_idx","columns":["reseller_tenant_id"]}],"version":"4d7f410a"},"importPath":"@happyvertical/smrt-tenancy"}},"moduleType":"smrt","smrtDependencies":["@happyvertical/smrt-core"],"browser":{"status":"server-only","issues":["#3624"],"reason":"node:async_hooks"},"stampsConstructors":true}`));
286
+ ObjectRegistry.registerPackageManifest(JSON.parse(`{"version":"1.0.0","timestamp":0,"packageName":"@happyvertical/smrt-tenancy","packageVersion":"0.60.11","objects":{"@happyvertical/smrt-tenancy:BillingRelationship":{"name":"billingrelationship","className":"BillingRelationship","qualifiedName":"@happyvertical/smrt-tenancy:BillingRelationship","collection":"billingrelationships","filePath":"/home/runner/work/smrt/smrt/packages/tenancy/src/billing-relationship.ts","packageName":"@happyvertical/smrt-tenancy","fields":{"childTenantId":{"type":"crossPackageRef","required":true,"related":"@happyvertical/smrt-users:Tenant","_meta":{"required":true}},"resellerTenantId":{"type":"crossPackageRef","required":true,"related":"@happyvertical/smrt-users:Tenant","_meta":{"required":true}},"billingOwnerMode":{"type":"text","required":false,"default":"self","enum":["self","reseller"]}},"methods":{},"decoratorConfig":{"tableName":"_smrt_billing_relationships","conflictColumns":["child_tenant_id"],"api":false,"cli":false,"mcp":false},"extends":"SmrtObject","exportName":"BillingRelationship","collectionExportName":"BillingRelationshipCollection","validationRules":[{"field":"childTenantId","rule":"required","fieldType":"crossPackageRef"},{"field":"resellerTenantId","rule":"required","fieldType":"crossPackageRef"}],"schema":{"tableName":"_smrt_billing_relationships","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_billing_relationships\\" (\\n \\"_sync_origin_device_id\\" TEXT,\\n \\"_sync_revision\\" INTEGER,\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"child_tenant_id\\" UUID NOT NULL,\\n \\"reseller_tenant_id\\" UUID NOT NULL,\\n \\"billing_owner_mode\\" TEXT DEFAULT 'self'\\n);","columns":{"_sync_origin_device_id":{"type":"TEXT"},"_sync_revision":{"type":"INTEGER"},"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"child_tenant_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":true,"unique":false},"reseller_tenant_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":true,"unique":false},"billing_owner_mode":{"type":"TEXT","notNull":false,"unique":false,"default":"self"}},"indexes":[{"name":"_smrt_billing_relationships_child_tenant_id_idx","columns":["child_tenant_id"],"unique":true},{"name":"_smrt_billing_relationships_slug_context_idx","columns":["slug","context"]},{"name":"_smrt_billing_relationships_created_at_idx","columns":["created_at"]},{"name":"_smrt_billing_relationships_reseller_tenant_id_idx","columns":["reseller_tenant_id"]}],"version":"549503f6"},"importPath":"@happyvertical/smrt-tenancy"},"@happyvertical/smrt-tenancy:BillingRelationshipCollection":{"name":"billingrelationshipcollection","className":"BillingRelationshipCollection","qualifiedName":"@happyvertical/smrt-tenancy:BillingRelationshipCollection","collection":"billingrelationships","filePath":"/home/runner/work/smrt/smrt/packages/tenancy/src/billing-relationship.ts","packageName":"@happyvertical/smrt-tenancy","fields":{},"methods":{},"decoratorConfig":{"tableName":"_smrt_billing_relationships","api":false,"mcp":false,"cli":false},"extends":"SmrtCollection","extendsTypeArg":"BillingRelationship","exportName":"BillingRelationshipCollection","collectionExportName":"BillingRelationshipCollectionCollection","collectionOf":"@happyvertical/smrt-tenancy:BillingRelationship","inheritedExposure":["api","mcp","cli"],"schema":{"tableName":"_smrt_billing_relationships","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_billing_relationships\\" (\\n \\"_sync_origin_device_id\\" TEXT,\\n \\"_sync_revision\\" INTEGER,\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"child_tenant_id\\" UUID NOT NULL,\\n \\"reseller_tenant_id\\" UUID NOT NULL,\\n \\"billing_owner_mode\\" TEXT DEFAULT 'self'\\n);","columns":{"_sync_origin_device_id":{"type":"TEXT"},"_sync_revision":{"type":"INTEGER"},"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"child_tenant_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":true,"unique":false},"reseller_tenant_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":true,"unique":false},"billing_owner_mode":{"type":"TEXT","notNull":false,"unique":false,"default":"self"}},"indexes":[{"name":"_smrt_billing_relationships_child_tenant_id_idx","columns":["child_tenant_id"],"unique":true},{"name":"_smrt_billing_relationships_slug_context_idx","columns":["slug","context"]},{"name":"_smrt_billing_relationships_created_at_idx","columns":["created_at"]},{"name":"_smrt_billing_relationships_reseller_tenant_id_idx","columns":["reseller_tenant_id"]}],"version":"549503f6"},"importPath":"@happyvertical/smrt-tenancy"}},"moduleType":"smrt","smrtDependencies":["@happyvertical/smrt-core"],"browser":{"status":"server-only","issues":["#3624"],"reason":"node:async_hooks"},"stampsConstructors":true}`));
287
287
  var __defProp$2 = Object.defineProperty;
288
288
  var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
289
289
  var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$2(obj, key, {
@@ -398,7 +398,7 @@ var __exportAll = (all, no_symbols) => {
398
398
  if (!no_symbols) __defProp$1(target, Symbol.toStringTag, { value: "Module" });
399
399
  return target;
400
400
  };
401
- ObjectRegistry.registerPackageManifest(JSON.parse(`{"version":"1.0.0","timestamp":0,"packageName":"@happyvertical/smrt-prompts","packageVersion":"0.60.9","objects":{"@happyvertical/smrt-prompts:PromptOverrideCollection":{"name":"promptoverridecollection","className":"PromptOverrideCollection","qualifiedName":"@happyvertical/smrt-prompts:PromptOverrideCollection","collection":"promptoverrides","filePath":"/home/runner/work/smrt/smrt/packages/prompts/src/collections/PromptOverrideCollection.ts","packageName":"@happyvertical/smrt-prompts","fields":{},"methods":{"getAppOverride":{"name":"getAppOverride","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"options","type":"object","optional":true,"memberTypes":["string"]}],"returnType":"Promise<PromptOverride | null>","isStatic":false,"isPublic":true},"getTenantOverride":{"name":"getTenantOverride","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"tenantId","type":"string","optional":false},{"name":"options","type":"object","optional":true,"memberTypes":["string"]}],"returnType":"Promise<PromptOverride | null>","isStatic":false,"isPublic":true},"getResolutionLayers":{"name":"getResolutionLayers","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"tenantId","type":"string | null","optional":true,"unionBranches":[{"type":"string"},{"type":"null"}]},{"name":"options","type":"object","optional":true,"memberTypes":["string"]}],"returnType":"Promise<object>","isStatic":false,"isPublic":true},"getOverrideMapForKeys":{"name":"getOverrideMapForKeys","async":true,"parameters":[{"name":"keys","type":"string[]","optional":false},{"name":"scopeType","type":"PromptOverrideScopeType","optional":false},{"name":"scopeId","type":"string","optional":false}],"returnType":"Promise<Map<string, PromptOverride>>","isStatic":false,"isPublic":true},"findByScope":{"name":"findByScope","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"scopeType","type":"PromptOverrideScopeType","optional":false},{"name":"scopeId","type":"string","optional":false}],"returnType":"Promise<PromptOverride | null>","isStatic":false,"isPublic":true},"setTemplateOverride":{"name":"setTemplateOverride","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"scopeType","type":"PromptOverrideScopeType","optional":false},{"name":"scopeId","type":"string","optional":false},{"name":"template","type":"string | null","optional":false,"unionBranches":[{"type":"string"},{"type":"null"}]}],"returnType":"Promise<PromptOverride>","isStatic":false,"isPublic":true},"removeOverride":{"name":"removeOverride","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"scopeType","type":"PromptOverrideScopeType","optional":false},{"name":"scopeId","type":"string","optional":false}],"returnType":"Promise<boolean>","isStatic":false,"isPublic":true}},"decoratorConfig":{"tableName":"_smrt_prompt_overrides","api":false,"mcp":false,"cli":false},"extends":"SmrtCollection","extendsTypeArg":"PromptOverride","exportName":"PromptOverrideCollection","collectionExportName":"PromptOverrideCollectionCollection","collectionOf":"@happyvertical/smrt-prompts:PromptOverride","inheritedExposure":["api","mcp","cli"],"schema":{"tableName":"_smrt_prompt_overrides","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_prompt_overrides\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"key\\" TEXT NOT NULL DEFAULT '',\\n \\"tenant_id\\" UUID,\\n \\"template\\" TEXT,\\n \\"profile\\" TEXT,\\n \\"model\\" TEXT,\\n \\"params\\" TEXT\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"key":{"type":"TEXT","notNull":true,"unique":false,"default":""},"tenant_id":{"type":"UUID","notNull":false,"unique":false},"template":{"type":"TEXT","notNull":false,"unique":false},"profile":{"type":"TEXT","notNull":false,"unique":false},"model":{"type":"TEXT","notNull":false,"unique":false},"params":{"type":"TEXT","notNull":false,"unique":false}},"indexes":[{"name":"_smrt_prompt_overrides_key_context_idx","columns":["key","context"],"unique":true},{"name":"_smrt_prompt_overrides_slug_context_idx","columns":["slug","context"]},{"name":"_smrt_prompt_overrides_created_at_idx","columns":["created_at"]}],"version":"38f505e7"},"importPath":"@happyvertical/smrt-prompts"},"@happyvertical/smrt-prompts:PromptOverride":{"name":"promptoverride","className":"PromptOverride","qualifiedName":"@happyvertical/smrt-prompts:PromptOverride","collection":"promptoverrides","filePath":"/home/runner/work/smrt/smrt/packages/prompts/src/models/PromptOverride.ts","packageName":"@happyvertical/smrt-prompts","fields":{"key":{"type":"text","required":true,"default":"","_meta":{"required":true}},"tenantId":{"type":"text","required":false,"_meta":{"sqlType":"UUID","nullable":true}},"template":{"type":"text","required":false,"_meta":{"nullable":true}},"profile":{"type":"text","required":false,"_meta":{"nullable":true}},"model":{"type":"text","required":false,"_meta":{"nullable":true}},"params":{"type":"text","required":false,"_meta":{"nullable":true}}},"methods":{"getParams":{"name":"getParams","async":false,"parameters":[],"returnType":"PromptParams","isStatic":false,"isPublic":true},"setParams":{"name":"setParams","async":false,"parameters":[{"name":"params","type":"PromptParams | null","optional":false,"unionBranches":[{"type":"PromptParams"},{"type":"null"}]}],"returnType":"void","isStatic":false,"isPublic":true},"toPromptLayer":{"name":"toPromptLayer","async":false,"parameters":[],"returnType":"PromptLayer","isStatic":false,"isPublic":true},"save":{"name":"save","async":true,"parameters":[{"name":"options","type":"SmrtSaveOptions","optional":true}],"returnType":"Promise<this>","isStatic":false,"isPublic":true},"delete":{"name":"delete","async":true,"parameters":[],"returnType":"Promise<void>","isStatic":false,"isPublic":true}},"decoratorConfig":{"tableName":"_smrt_prompt_overrides","conflictColumns":["key","context"],"api":false,"cli":false,"mcp":false},"extends":"SmrtObject","exportName":"PromptOverride","collectionExportName":"PromptOverrideCollection","validationRules":[{"field":"key","rule":"required","fieldType":"text"}],"schema":{"tableName":"_smrt_prompt_overrides","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_prompt_overrides\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"key\\" TEXT NOT NULL DEFAULT '',\\n \\"tenant_id\\" UUID,\\n \\"template\\" TEXT,\\n \\"profile\\" TEXT,\\n \\"model\\" TEXT,\\n \\"params\\" TEXT\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"key":{"type":"TEXT","notNull":true,"unique":false,"default":""},"tenant_id":{"type":"UUID","notNull":false,"unique":false},"template":{"type":"TEXT","notNull":false,"unique":false},"profile":{"type":"TEXT","notNull":false,"unique":false},"model":{"type":"TEXT","notNull":false,"unique":false},"params":{"type":"TEXT","notNull":false,"unique":false}},"indexes":[{"name":"_smrt_prompt_overrides_key_context_idx","columns":["key","context"],"unique":true},{"name":"_smrt_prompt_overrides_slug_context_idx","columns":["slug","context"]},{"name":"_smrt_prompt_overrides_created_at_idx","columns":["created_at"]}],"version":"38f505e7"},"importPath":"@happyvertical/smrt-prompts"}},"moduleType":"smrt","smrtDependencies":["@happyvertical/smrt-core","@happyvertical/smrt-tenancy"],"browser":{"status":"server-only","issues":["#3624"],"via":["@happyvertical/smrt-tenancy"]},"stampsConstructors":true}`));
401
+ ObjectRegistry.registerPackageManifest(JSON.parse(`{"version":"1.0.0","timestamp":0,"packageName":"@happyvertical/smrt-prompts","packageVersion":"0.60.11","objects":{"@happyvertical/smrt-prompts:PromptOverrideCollection":{"name":"promptoverridecollection","className":"PromptOverrideCollection","qualifiedName":"@happyvertical/smrt-prompts:PromptOverrideCollection","collection":"promptoverrides","filePath":"/home/runner/work/smrt/smrt/packages/prompts/src/collections/PromptOverrideCollection.ts","packageName":"@happyvertical/smrt-prompts","fields":{},"methods":{"getAppOverride":{"name":"getAppOverride","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"options","type":"object","optional":true,"memberTypes":["string"]}],"returnType":"Promise<PromptOverride | null>","isStatic":false,"isPublic":true},"getTenantOverride":{"name":"getTenantOverride","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"tenantId","type":"string","optional":false},{"name":"options","type":"object","optional":true,"memberTypes":["string"]}],"returnType":"Promise<PromptOverride | null>","isStatic":false,"isPublic":true},"getResolutionLayers":{"name":"getResolutionLayers","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"tenantId","type":"string | null","optional":true,"unionBranches":[{"type":"string"},{"type":"null"}]},{"name":"options","type":"object","optional":true,"memberTypes":["string"]}],"returnType":"Promise<object>","isStatic":false,"isPublic":true},"getOverrideMapForKeys":{"name":"getOverrideMapForKeys","async":true,"parameters":[{"name":"keys","type":"string[]","optional":false},{"name":"scopeType","type":"PromptOverrideScopeType","optional":false},{"name":"scopeId","type":"string","optional":false}],"returnType":"Promise<Map<string, PromptOverride>>","isStatic":false,"isPublic":true},"findByScope":{"name":"findByScope","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"scopeType","type":"PromptOverrideScopeType","optional":false},{"name":"scopeId","type":"string","optional":false}],"returnType":"Promise<PromptOverride | null>","isStatic":false,"isPublic":true},"setTemplateOverride":{"name":"setTemplateOverride","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"scopeType","type":"PromptOverrideScopeType","optional":false},{"name":"scopeId","type":"string","optional":false},{"name":"template","type":"string | null","optional":false,"unionBranches":[{"type":"string"},{"type":"null"}]}],"returnType":"Promise<PromptOverride>","isStatic":false,"isPublic":true},"removeOverride":{"name":"removeOverride","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"scopeType","type":"PromptOverrideScopeType","optional":false},{"name":"scopeId","type":"string","optional":false}],"returnType":"Promise<boolean>","isStatic":false,"isPublic":true}},"decoratorConfig":{"tableName":"_smrt_prompt_overrides","api":false,"mcp":false,"cli":false},"extends":"SmrtCollection","extendsTypeArg":"PromptOverride","exportName":"PromptOverrideCollection","collectionExportName":"PromptOverrideCollectionCollection","collectionOf":"@happyvertical/smrt-prompts:PromptOverride","inheritedExposure":["api","mcp","cli"],"schema":{"tableName":"_smrt_prompt_overrides","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_prompt_overrides\\" (\\n \\"_sync_origin_device_id\\" TEXT,\\n \\"_sync_revision\\" INTEGER,\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"key\\" TEXT NOT NULL DEFAULT '',\\n \\"tenant_id\\" UUID,\\n \\"template\\" TEXT,\\n \\"profile\\" TEXT,\\n \\"model\\" TEXT,\\n \\"params\\" TEXT\\n);","columns":{"_sync_origin_device_id":{"type":"TEXT"},"_sync_revision":{"type":"INTEGER"},"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"key":{"type":"TEXT","notNull":true,"unique":false,"default":""},"tenant_id":{"type":"UUID","notNull":false,"unique":false},"template":{"type":"TEXT","notNull":false,"unique":false},"profile":{"type":"TEXT","notNull":false,"unique":false},"model":{"type":"TEXT","notNull":false,"unique":false},"params":{"type":"TEXT","notNull":false,"unique":false}},"indexes":[{"name":"_smrt_prompt_overrides_key_context_idx","columns":["key","context"],"unique":true},{"name":"_smrt_prompt_overrides_slug_context_idx","columns":["slug","context"]},{"name":"_smrt_prompt_overrides_created_at_idx","columns":["created_at"]}],"version":"3fcceb69"},"importPath":"@happyvertical/smrt-prompts"},"@happyvertical/smrt-prompts:PromptOverride":{"name":"promptoverride","className":"PromptOverride","qualifiedName":"@happyvertical/smrt-prompts:PromptOverride","collection":"promptoverrides","filePath":"/home/runner/work/smrt/smrt/packages/prompts/src/models/PromptOverride.ts","packageName":"@happyvertical/smrt-prompts","fields":{"key":{"type":"text","required":true,"default":"","_meta":{"required":true}},"tenantId":{"type":"text","required":false,"_meta":{"sqlType":"UUID","nullable":true}},"template":{"type":"text","required":false,"_meta":{"nullable":true}},"profile":{"type":"text","required":false,"_meta":{"nullable":true}},"model":{"type":"text","required":false,"_meta":{"nullable":true}},"params":{"type":"text","required":false,"_meta":{"nullable":true}}},"methods":{"getParams":{"name":"getParams","async":false,"parameters":[],"returnType":"PromptParams","isStatic":false,"isPublic":true},"setParams":{"name":"setParams","async":false,"parameters":[{"name":"params","type":"PromptParams | null","optional":false,"unionBranches":[{"type":"PromptParams"},{"type":"null"}]}],"returnType":"void","isStatic":false,"isPublic":true},"toPromptLayer":{"name":"toPromptLayer","async":false,"parameters":[],"returnType":"PromptLayer","isStatic":false,"isPublic":true},"save":{"name":"save","async":true,"parameters":[{"name":"options","type":"SmrtSaveOptions","optional":true}],"returnType":"Promise<this>","isStatic":false,"isPublic":true},"delete":{"name":"delete","async":true,"parameters":[],"returnType":"Promise<void>","isStatic":false,"isPublic":true}},"decoratorConfig":{"tableName":"_smrt_prompt_overrides","conflictColumns":["key","context"],"api":false,"cli":false,"mcp":false},"extends":"SmrtObject","exportName":"PromptOverride","collectionExportName":"PromptOverrideCollection","validationRules":[{"field":"key","rule":"required","fieldType":"text"}],"schema":{"tableName":"_smrt_prompt_overrides","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_prompt_overrides\\" (\\n \\"_sync_origin_device_id\\" TEXT,\\n \\"_sync_revision\\" INTEGER,\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"key\\" TEXT NOT NULL DEFAULT '',\\n \\"tenant_id\\" UUID,\\n \\"template\\" TEXT,\\n \\"profile\\" TEXT,\\n \\"model\\" TEXT,\\n \\"params\\" TEXT\\n);","columns":{"_sync_origin_device_id":{"type":"TEXT"},"_sync_revision":{"type":"INTEGER"},"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"key":{"type":"TEXT","notNull":true,"unique":false,"default":""},"tenant_id":{"type":"UUID","notNull":false,"unique":false},"template":{"type":"TEXT","notNull":false,"unique":false},"profile":{"type":"TEXT","notNull":false,"unique":false},"model":{"type":"TEXT","notNull":false,"unique":false},"params":{"type":"TEXT","notNull":false,"unique":false}},"indexes":[{"name":"_smrt_prompt_overrides_key_context_idx","columns":["key","context"],"unique":true},{"name":"_smrt_prompt_overrides_slug_context_idx","columns":["slug","context"]},{"name":"_smrt_prompt_overrides_created_at_idx","columns":["created_at"]}],"version":"3fcceb69"},"importPath":"@happyvertical/smrt-prompts"}},"moduleType":"smrt","smrtDependencies":["@happyvertical/smrt-core","@happyvertical/smrt-tenancy"],"browser":{"status":"server-only","issues":["#3624"],"via":["@happyvertical/smrt-tenancy"]},"stampsConstructors":true}`));
402
402
  var PROMPT_CACHE_TTL_MS = 3e4;
403
403
  var promptCache = /* @__PURE__ */ new Map();
404
404
  var cacheGenerations = /* @__PURE__ */ new Map();