@happyvertical/smrt-cli 0.60.10 → 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.
- package/AGENTS.md +7 -0
- package/README.md +5 -0
- package/agents/app-commands.md +2 -0
- package/dist/{AuditLogCollection-BBbvr8Qc-DU-QXhH5.js → AuditLogCollection-BBbvr8Qc-mcBSLXW9.js} +1 -1
- package/dist/{OidcIdentity-COeMidoC-BDr8b6iW.js → OidcIdentity-COeMidoC-ETkpZbIS.js} +2 -2
- package/dist/{OidcIdentityCollection-D4DIZv0K-BvsaDTZY.js → OidcIdentityCollection-D4DIZv0K-Do3bwRuw.js} +1 -1
- package/dist/{PasswordCredentialService-BSSP_kyT-DlxlWy6b.js → PasswordCredentialService-BSSP_kyT-t7bjBu4L.js} +14 -14
- package/dist/{ProfileAssetCollection-D5-tG9Mm-Be7hQJJq.js → ProfileAssetCollection-D5-tG9Mm-FbzWS3Fo.js} +3 -3
- package/dist/{ProfileCollection-CmRaiE9U-n8apgXIh.js → ProfileCollection-CmRaiE9U-BYvpJg0y.js} +17 -17
- package/dist/{ProfileLinkCollection-pvPTsysg-DCmnAd7m.js → ProfileLinkCollection-pvPTsysg-nDbgawOW.js} +2 -2
- package/dist/{ProfileMetadataCollection-CAgJyjze-BKpcvrnf.js → ProfileMetadataCollection-CAgJyjze-D-5QuGnR.js} +1 -1
- package/dist/{ProfileMetafieldCollection-19ae6Lpf-BuTJKzmz.js → ProfileMetafieldCollection-19ae6Lpf-CgEt1gPi.js} +1 -1
- package/dist/{ProfileRelationshipCollection-BFSlTQ7J-DBbNdauk.js → ProfileRelationshipCollection-BFSlTQ7J-Dv0ll9S1.js} +1 -1
- package/dist/{ProfileTypeCollection-BRLK8cHS-COCy6yqF.js → ProfileTypeCollection-BRLK8cHS-BKuh_ajh.js} +2 -2
- package/dist/app/portability-assets.d.ts +2 -0
- package/dist/app/portability-assets.d.ts.map +1 -1
- package/dist/app.js +2 -2
- package/dist/{cli-CtRx1_yP.js → cli-DXIN1FbA.js} +1 -1
- package/dist/commands/docs-claude.d.ts.map +1 -1
- package/dist/commands/docs-skills-install.d.ts +31 -0
- package/dist/commands/docs-skills-install.d.ts.map +1 -0
- package/dist/{commands-CGfM14Uj.js → commands-DD5gexRY.js} +138 -4
- package/dist/{dist-B00KCyNE.js → dist-CivxAJ6C.js} +2 -2
- package/dist/{dist-D7vejSNK.js → dist-DcYLLDwF.js} +4 -4
- package/dist/{dist-BGEMcSs-.js → dist-DjG0qPkx.js} +5 -5
- package/dist/index.js +12 -12
- package/dist/{oidcProvisioningPrimitives-KpIiLmG4-Csnh1ENp.js → oidcProvisioningPrimitives-KpIiLmG4-D5-0dAY3.js} +3 -3
- package/dist/{operator-DCwooIiI.js → operator-B0ZraSEE.js} +2 -2
- package/dist/{portability-CbMgEnD1.js → portability-sL8U5Hld.js} +21 -13
- package/dist/{resolveIdentity-j2WFuKDT-DZTwcb-u.js → resolveIdentity-j2WFuKDT-BieMIOLz.js} +14 -14
- package/dist/smrt-knowledge.okf.md +3 -2
- package/package.json +11 -10
- package/dist/dist-DEKj_L2B.js +0 -1908
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
2
|
-
import { A as assertExternalArtifactPath, L as errorCode } from "./cli-
|
|
2
|
+
import { A as assertExternalArtifactPath, L as errorCode } from "./cli-DXIN1FbA.js";
|
|
3
3
|
import { closeSync, constants, existsSync, fstatSync, linkSync, lstatSync, mkdirSync, openSync, readFileSync, readSync, readdirSync, realpathSync, renameSync, rmSync, rmdirSync, statSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
5
5
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
6
6
|
import { createHash, randomBytes } from "node:crypto";
|
|
7
|
+
import { isLocalAssetLocator, localAssetKey, makeLocalAssetLocator } from "@happyvertical/smrt-assets/locator";
|
|
7
8
|
//#region src/app/portability-assets.ts
|
|
8
9
|
/**
|
|
9
10
|
* Filesystem asset portability for logical export/import bundles.
|
|
@@ -102,45 +103,47 @@ function readBoundedDescriptor(descriptor, expectedSize, changedCode) {
|
|
|
102
103
|
if (readSync(descriptor, Buffer.allocUnsafe(1), 0, 1, null) !== 0) throw fail(changedCode);
|
|
103
104
|
return bytes;
|
|
104
105
|
}
|
|
105
|
-
function readRegularFileUnchecked(path, approvedRoot, onOpened) {
|
|
106
|
+
function readRegularFileUnchecked(path, approvedRoot, onOpened, requireSingleLink = false) {
|
|
106
107
|
const lexicalPath = resolve(path);
|
|
107
108
|
if (!isInside(approvedRoot, lexicalPath)) throw fail("asset-outside-root");
|
|
108
109
|
const before = lstatSync(lexicalPath);
|
|
109
|
-
if (before.
|
|
110
|
+
if (!before.isFile() || requireSingleLink && before.nlink !== 1) throw fail("asset-not-regular");
|
|
110
111
|
if (before.size > 67108864) throw fail("asset-too-large");
|
|
111
112
|
if (!isInside(approvedRoot, realpathSync(lexicalPath))) throw fail("asset-outside-root");
|
|
112
113
|
const noFollow = constants.O_NOFOLLOW ?? 0;
|
|
113
114
|
const descriptor = openSync(lexicalPath, constants.O_RDONLY | noFollow);
|
|
114
115
|
try {
|
|
115
116
|
const opened = fstatSync(descriptor);
|
|
116
|
-
if (!opened.isFile() || opened.size !== before.size) throw fail("asset-changed-during-read");
|
|
117
|
+
if (!opened.isFile() || opened.size !== before.size || requireSingleLink && opened.nlink !== 1) throw fail("asset-changed-during-read");
|
|
117
118
|
onOpened?.();
|
|
118
119
|
const openedPath = statSync(lexicalPath);
|
|
119
120
|
if (!isInside(approvedRoot, realpathSync(lexicalPath)) || openedPath.dev !== opened.dev || openedPath.ino !== opened.ino) throw fail("asset-changed-during-read");
|
|
120
121
|
const bytes = readBoundedDescriptor(descriptor, opened.size, "asset-changed-during-read");
|
|
121
122
|
const after = fstatSync(descriptor);
|
|
122
123
|
const afterPath = statSync(lexicalPath);
|
|
123
|
-
if (after.dev !== opened.dev || after.ino !== opened.ino || after.size !== opened.size || bytes.byteLength !== opened.size || !isInside(approvedRoot, realpathSync(lexicalPath)) || afterPath.dev !== opened.dev || afterPath.ino !== opened.ino) throw fail("asset-changed-during-read");
|
|
124
|
+
if (after.dev !== opened.dev || after.ino !== opened.ino || after.size !== opened.size || requireSingleLink && after.nlink !== 1 || bytes.byteLength !== opened.size || !isInside(approvedRoot, realpathSync(lexicalPath)) || afterPath.dev !== opened.dev || afterPath.ino !== opened.ino) throw fail("asset-changed-during-read");
|
|
124
125
|
return bytes;
|
|
125
126
|
} finally {
|
|
126
127
|
closeSync(descriptor);
|
|
127
128
|
}
|
|
128
129
|
}
|
|
129
|
-
function readRegularFile(path, approvedRoot, onOpened) {
|
|
130
|
+
function readRegularFile(path, approvedRoot, onOpened, requireSingleLink = false) {
|
|
130
131
|
try {
|
|
131
|
-
return readRegularFileUnchecked(path, approvedRoot, onOpened);
|
|
132
|
+
return readRegularFileUnchecked(path, approvedRoot, onOpened, requireSingleLink);
|
|
132
133
|
} catch (error) {
|
|
133
134
|
if (isSanitizedFailure(error)) throw error;
|
|
134
135
|
throw fail("asset-changed-during-read");
|
|
135
136
|
}
|
|
136
137
|
}
|
|
137
|
-
function pathFromSourceUri(sourceUri) {
|
|
138
|
-
if (typeof sourceUri !== "string"
|
|
138
|
+
function pathFromSourceUri(sourceUri, root) {
|
|
139
|
+
if (typeof sourceUri !== "string") throw fail("unsupported-asset-source");
|
|
139
140
|
try {
|
|
140
|
-
return
|
|
141
|
+
if (isLocalAssetLocator(sourceUri)) return join(root, localAssetKey(sourceUri));
|
|
142
|
+
if (sourceUri.startsWith("file://")) return fileURLToPath(sourceUri);
|
|
141
143
|
} catch {
|
|
142
144
|
throw fail("unsupported-asset-source");
|
|
143
145
|
}
|
|
146
|
+
throw fail("unsupported-asset-source");
|
|
144
147
|
}
|
|
145
148
|
function assetRows(tables) {
|
|
146
149
|
const table = tables.find((candidate) => candidate?.name === "assets");
|
|
@@ -175,7 +178,8 @@ function collectFilesystemAssets({ tables, sourceRoot, assetRoot, onSourceOpened
|
|
|
175
178
|
const payloadPath = payloadPathForKey(key);
|
|
176
179
|
if (payloadPaths.has(payloadPath)) throw fail("duplicate-payload-path");
|
|
177
180
|
payloadPaths.add(payloadPath);
|
|
178
|
-
const
|
|
181
|
+
const relativeLocator = typeof row.source_uri === "string" && isLocalAssetLocator(row.source_uri);
|
|
182
|
+
const bytes = readRegularFile(pathFromSourceUri(row.source_uri, root), root, onSourceOpened, relativeLocator);
|
|
179
183
|
totalBytes += bytes.byteLength;
|
|
180
184
|
if (totalBytes > 268435456) throw fail("asset-total-too-large");
|
|
181
185
|
const contentDigest = digestBytes(bytes);
|
|
@@ -183,7 +187,8 @@ function collectFilesystemAssets({ tables, sourceRoot, assetRoot, onSourceOpened
|
|
|
183
187
|
key,
|
|
184
188
|
byteLength: bytes.byteLength,
|
|
185
189
|
contentDigest,
|
|
186
|
-
payloadPath
|
|
190
|
+
payloadPath,
|
|
191
|
+
...relativeLocator ? { locator: "relative" } : {}
|
|
187
192
|
});
|
|
188
193
|
payloads.push({
|
|
189
194
|
path: payloadPath,
|
|
@@ -231,6 +236,7 @@ function verifyFilesystemAssets({ assetBundle, tables, sourceRoot, assetRoot })
|
|
|
231
236
|
}
|
|
232
237
|
const keys = /* @__PURE__ */ new Set();
|
|
233
238
|
const paths = /* @__PURE__ */ new Set();
|
|
239
|
+
const relativeLocators = /* @__PURE__ */ new Set();
|
|
234
240
|
const verified = [];
|
|
235
241
|
let totalBytes = 0;
|
|
236
242
|
for (const rawEntry of bundle.entries) {
|
|
@@ -239,6 +245,8 @@ function verifyFilesystemAssets({ assetBundle, tables, sourceRoot, assetRoot })
|
|
|
239
245
|
const payloadPath = normalizePayloadPath(entry?.payloadPath);
|
|
240
246
|
if (!key || key.length > 512 || keys.has(key)) throw fail("duplicate-asset-key");
|
|
241
247
|
if (paths.has(payloadPath)) throw fail("duplicate-payload-path");
|
|
248
|
+
if (entry?.locator === "relative") relativeLocators.add(key);
|
|
249
|
+
else if (entry?.locator !== void 0) throw fail("invalid-asset-locator");
|
|
242
250
|
keys.add(key);
|
|
243
251
|
paths.add(payloadPath);
|
|
244
252
|
const byteLength = entry?.byteLength;
|
|
@@ -270,7 +278,7 @@ function verifyFilesystemAssets({ assetBundle, tables, sourceRoot, assetRoot })
|
|
|
270
278
|
assetRoot,
|
|
271
279
|
allowMissing: true
|
|
272
280
|
});
|
|
273
|
-
for (const entry of verified) rowByKey.get(entry.key).source_uri = pathToFileURL(join(root, entry.relativePath)).href;
|
|
281
|
+
for (const entry of verified) rowByKey.get(entry.key).source_uri = relativeLocators.has(entry.key) ? makeLocalAssetLocator(entry.relativePath) : pathToFileURL(join(root, entry.relativePath)).href;
|
|
274
282
|
return {
|
|
275
283
|
root,
|
|
276
284
|
entries: verified
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
2
|
-
import { m as withSystemContext } from "./dist-
|
|
2
|
+
import { m as withSystemContext } from "./dist-CivxAJ6C.js";
|
|
3
3
|
import { a as verifyAuthEvent, n as __exportAll$1, t as NostrIdentity } from "./NostrIdentity-RJaATTCt-BbRHWyee.js";
|
|
4
4
|
import { t as ApiKey } from "./ApiKey-9YuYcpWy-BdrXOe-N.js";
|
|
5
|
-
import { t as OidcIdentity } from "./OidcIdentity-COeMidoC-
|
|
6
|
-
import { c as normalizeIdentityEmail, o as coordinateOidcProvisioning, s as isOidcProvisioningRaceConflict } from "./ProfileCollection-CmRaiE9U-
|
|
7
|
-
import { n as insertOidcProvisioningIdentity, t as createOidcProvisioningPerson } from "./oidcProvisioningPrimitives-KpIiLmG4-
|
|
5
|
+
import { t as OidcIdentity } from "./OidcIdentity-COeMidoC-ETkpZbIS.js";
|
|
6
|
+
import { c as normalizeIdentityEmail, o as coordinateOidcProvisioning, s as isOidcProvisioningRaceConflict } from "./ProfileCollection-CmRaiE9U-BYvpJg0y.js";
|
|
7
|
+
import { n as insertOidcProvisioningIdentity, t as createOidcProvisioningPerson } from "./oidcProvisioningPrimitives-KpIiLmG4-D5-0dAY3.js";
|
|
8
8
|
import { resolveDatabase } from "@happyvertical/smrt-core";
|
|
9
9
|
//#region ../profiles/dist/chunks/resolveIdentity-j2WFuKDT.js
|
|
10
10
|
var resolveIdentity_j2WFuKDT_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -72,13 +72,13 @@ async function resolveIdentity(context) {
|
|
|
72
72
|
};
|
|
73
73
|
}
|
|
74
74
|
async function findProfileByExternalId(provider, externalId, options) {
|
|
75
|
-
const { OidcIdentityCollection } = await import("./OidcIdentityCollection-D4DIZv0K-
|
|
75
|
+
const { OidcIdentityCollection } = await import("./OidcIdentityCollection-D4DIZv0K-Do3bwRuw.js").then((n) => n.r).then((n) => n.r);
|
|
76
76
|
const identities = await (await OidcIdentityCollection.create(options)).findByProvider(provider);
|
|
77
77
|
for (const identity of identities) if (identity.subject === externalId || identity.email?.includes(externalId)) {
|
|
78
78
|
const profile = await identity.getProfile();
|
|
79
79
|
if (profile) return profile;
|
|
80
80
|
}
|
|
81
|
-
const { ProfileCollection } = await import("./ProfileCollection-CmRaiE9U-
|
|
81
|
+
const { ProfileCollection } = await import("./ProfileCollection-CmRaiE9U-BYvpJg0y.js").then((n) => n.i).then((n) => n.r);
|
|
82
82
|
const profiles = await (await ProfileCollection.create(options)).list({
|
|
83
83
|
where: { email: `${externalId}@users.noreply.github.com` },
|
|
84
84
|
limit: 1
|
|
@@ -99,7 +99,7 @@ async function reuseExistingOidcIdentityForProfile(profileId, claims, provider,
|
|
|
99
99
|
createConcurrencyError: (cause) => new Error("Concurrent exact OIDC identity reuse did not converge.", cause === void 0 ? void 0 : { cause }),
|
|
100
100
|
rebindRootResult: rebindOidcProfileResult,
|
|
101
101
|
provision: (tx) => withSystemContext(async () => {
|
|
102
|
-
const { OidcIdentityCollection } = await import("./OidcIdentityCollection-D4DIZv0K-
|
|
102
|
+
const { OidcIdentityCollection } = await import("./OidcIdentityCollection-D4DIZv0K-Do3bwRuw.js").then((n) => n.r).then((n) => n.r);
|
|
103
103
|
const identity = await (await OidcIdentityCollection.create({ db: tx })).findBySubject(normalizedClaims.iss, normalizedClaims.sub);
|
|
104
104
|
if (!identity) throw new Error("OidcIdentity.findOrCreate() no longer creates authentication links; use UserCollection.getOrCreateFromOidc() or createProfileFromOidc().");
|
|
105
105
|
if (identity.profileId !== profileId) throw new Error(`OIDC identity ${normalizedClaims.iss} subject ${normalizedClaims.sub} belongs to a different Profile.`);
|
|
@@ -133,7 +133,7 @@ async function coordinateProfileOidcProvisioning(claims, provider, options) {
|
|
|
133
133
|
});
|
|
134
134
|
}
|
|
135
135
|
async function provisionOidcProfile(claims, provider, options) {
|
|
136
|
-
const { OidcIdentityCollection } = await import("./OidcIdentityCollection-D4DIZv0K-
|
|
136
|
+
const { OidcIdentityCollection } = await import("./OidcIdentityCollection-D4DIZv0K-Do3bwRuw.js").then((n) => n.r).then((n) => n.r);
|
|
137
137
|
const existingIdentity = await (await OidcIdentityCollection.create(options)).findBySubject(claims.iss, claims.sub);
|
|
138
138
|
if (existingIdentity) {
|
|
139
139
|
const profile2 = await existingIdentity.getProfile();
|
|
@@ -148,7 +148,7 @@ async function provisionOidcProfile(claims, provider, options) {
|
|
|
148
148
|
created: false
|
|
149
149
|
};
|
|
150
150
|
}
|
|
151
|
-
const { ProfileCollection } = await import("./ProfileCollection-CmRaiE9U-
|
|
151
|
+
const { ProfileCollection } = await import("./ProfileCollection-CmRaiE9U-BYvpJg0y.js").then((n) => n.i).then((n) => n.r);
|
|
152
152
|
const profileCollection = await ProfileCollection.create(options);
|
|
153
153
|
if (claims.email) {
|
|
154
154
|
if (await profileCollection.findUniqueGlobalPersonByEmail(claims.email)) {
|
|
@@ -175,8 +175,8 @@ async function provisionOidcProfile(claims, provider, options) {
|
|
|
175
175
|
};
|
|
176
176
|
}
|
|
177
177
|
async function rebindOidcProfileResult(result, rootDb) {
|
|
178
|
-
const { OidcIdentityCollection } = await import("./OidcIdentityCollection-D4DIZv0K-
|
|
179
|
-
const { ProfileCollection } = await import("./ProfileCollection-CmRaiE9U-
|
|
178
|
+
const { OidcIdentityCollection } = await import("./OidcIdentityCollection-D4DIZv0K-Do3bwRuw.js").then((n) => n.r).then((n) => n.r);
|
|
179
|
+
const { ProfileCollection } = await import("./ProfileCollection-CmRaiE9U-BYvpJg0y.js").then((n) => n.i).then((n) => n.r);
|
|
180
180
|
const profileId = requireOidcProfileId(result.profile.id);
|
|
181
181
|
const identityId = requireOidcProfileId(result.oidcIdentity.id);
|
|
182
182
|
const [profile, oidcIdentity] = await withSystemContext(async () => {
|
|
@@ -225,11 +225,11 @@ async function createProfileFromNostr(email, nostrData, options) {
|
|
|
225
225
|
created: false
|
|
226
226
|
};
|
|
227
227
|
}
|
|
228
|
-
const { Person } = await import("./oidcProvisioningPrimitives-KpIiLmG4-
|
|
229
|
-
const { ProfileTypeCollection } = await import("./ProfileTypeCollection-BRLK8cHS-
|
|
228
|
+
const { Person } = await import("./oidcProvisioningPrimitives-KpIiLmG4-D5-0dAY3.js").then((n) => n.r).then((n) => n.o);
|
|
229
|
+
const { ProfileTypeCollection } = await import("./ProfileTypeCollection-BRLK8cHS-BKuh_ajh.js").then((n) => n.n).then((n) => n.n);
|
|
230
230
|
let personType = await (await ProfileTypeCollection.create(options)).getBySlug("person");
|
|
231
231
|
if (!personType) {
|
|
232
|
-
const { ProfileType } = await import("./ProfileCollection-CmRaiE9U-
|
|
232
|
+
const { ProfileType } = await import("./ProfileCollection-CmRaiE9U-BYvpJg0y.js").then((n) => n.i).then((n) => n.h);
|
|
233
233
|
personType = new ProfileType({
|
|
234
234
|
...options,
|
|
235
235
|
slug: "person",
|
|
@@ -5,10 +5,10 @@ description: "Developer CLI for SMRT framework - introspection, testing, and pro
|
|
|
5
5
|
status: "stable"
|
|
6
6
|
generated:
|
|
7
7
|
by: "smrt/scripts/generate-knowledge-okf.ts"
|
|
8
|
-
at: "2026-11-
|
|
8
|
+
at: "2026-11-06T00:45:47Z"
|
|
9
9
|
audience: "internal"
|
|
10
10
|
evidence_level: "manifest-described"
|
|
11
|
-
source_revision: "sha256:
|
|
11
|
+
source_revision: "sha256:b70ca522a45af095ce1b1dca4c56923bcf8aa16ffa38f9932c87c1e63b0761d1"
|
|
12
12
|
sources:
|
|
13
13
|
- id: "manifest"
|
|
14
14
|
resource: "https://github.com/happyvertical/smrt/blob/main/packages/cli/package.json"
|
|
@@ -35,6 +35,7 @@ sources:
|
|
|
35
35
|
|
|
36
36
|
- [smrt-agents](/components/smrt-agents.md)
|
|
37
37
|
- [smrt-app-runtime](/components/smrt-app-runtime.md)
|
|
38
|
+
- [smrt-assets](/components/smrt-assets.md)
|
|
38
39
|
- [smrt-config](/components/smrt-config.md)
|
|
39
40
|
- [smrt-core](/components/smrt-core.md)
|
|
40
41
|
- [smrt-dev-mcp](/components/smrt-dev-mcp.md)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@happyvertical/smrt-cli",
|
|
3
|
-
"version": "0.60.
|
|
3
|
+
"version": "0.60.11",
|
|
4
4
|
"description": "Developer CLI for SMRT framework - introspection, testing, and project management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -33,15 +33,16 @@
|
|
|
33
33
|
"@happyvertical/ai": "^0.111.5",
|
|
34
34
|
"@happyvertical/files": "^0.111.5",
|
|
35
35
|
"@happyvertical/logger": "^0.111.5",
|
|
36
|
-
"@happyvertical/smrt-agents": "0.60.
|
|
37
|
-
"@happyvertical/smrt-app-runtime": "0.60.
|
|
38
|
-
"@happyvertical/smrt-
|
|
39
|
-
"@happyvertical/smrt-
|
|
40
|
-
"@happyvertical/smrt-
|
|
41
|
-
"@happyvertical/smrt-
|
|
42
|
-
"@happyvertical/smrt-
|
|
43
|
-
"@happyvertical/smrt-
|
|
44
|
-
"@happyvertical/smrt-
|
|
36
|
+
"@happyvertical/smrt-agents": "0.60.11",
|
|
37
|
+
"@happyvertical/smrt-app-runtime": "0.60.11",
|
|
38
|
+
"@happyvertical/smrt-assets": "0.60.11",
|
|
39
|
+
"@happyvertical/smrt-config": "0.60.11",
|
|
40
|
+
"@happyvertical/smrt-core": "0.60.11",
|
|
41
|
+
"@happyvertical/smrt-dev-mcp": "0.60.11",
|
|
42
|
+
"@happyvertical/smrt-ledgers": "0.60.11",
|
|
43
|
+
"@happyvertical/smrt-playground": "0.60.11",
|
|
44
|
+
"@happyvertical/smrt-types": "0.60.11",
|
|
45
|
+
"@happyvertical/smrt-users": "0.60.11",
|
|
45
46
|
"@happyvertical/sql": "^0.111.5",
|
|
46
47
|
"@happyvertical/utils": "^0.111.5",
|
|
47
48
|
"@modelcontextprotocol/server": "2.3.1",
|