@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.
- package/AGENTS.md +24 -53
- package/README.md +5 -0
- package/agents/app-commands.md +2 -0
- package/agents/db-drop-framework-base-tables.md +49 -0
- package/agents/db-migrate-concurrency.md +11 -0
- package/dist/{AuditLogCollection-BBbvr8Qc-CoDs0BaX.js → AuditLogCollection-BBbvr8Qc-mcBSLXW9.js} +1 -1
- package/dist/{OidcIdentity-COeMidoC-B-cVovG3.js → OidcIdentity-COeMidoC-ETkpZbIS.js} +2 -2
- package/dist/{OidcIdentityCollection-D4DIZv0K-CexIL7No.js → OidcIdentityCollection-D4DIZv0K-Do3bwRuw.js} +1 -1
- package/dist/{PasswordCredentialService-DHJNKEeJ-DQlR62e-.js → PasswordCredentialService-BSSP_kyT-t7bjBu4L.js} +40 -22
- package/dist/{ProfileAssetCollection-D5-tG9Mm-Bmn4-Urc.js → ProfileAssetCollection-D5-tG9Mm-FbzWS3Fo.js} +3 -3
- package/dist/{ProfileCollection-CmRaiE9U-52qjwbhJ.js → ProfileCollection-CmRaiE9U-BYvpJg0y.js} +17 -17
- package/dist/{ProfileLinkCollection-pvPTsysg-ocN3hj_M.js → ProfileLinkCollection-pvPTsysg-nDbgawOW.js} +2 -2
- package/dist/{ProfileMetadataCollection-CAgJyjze-FX20yKjY.js → ProfileMetadataCollection-CAgJyjze-D-5QuGnR.js} +1 -1
- package/dist/{ProfileMetafieldCollection-19ae6Lpf-qg7eMcJk.js → ProfileMetafieldCollection-19ae6Lpf-CgEt1gPi.js} +1 -1
- package/dist/{ProfileRelationshipCollection-BFSlTQ7J-DlDILj3m.js → ProfileRelationshipCollection-BFSlTQ7J-Dv0ll9S1.js} +1 -1
- package/dist/{ProfileTypeCollection-BRLK8cHS-QVwjfqe8.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 +1 -0
- package/dist/commands/docs-claude.d.ts.map +1 -1
- package/dist/commands/docs-knowledge-bundle.d.ts +87 -0
- package/dist/commands/docs-knowledge-bundle.d.ts.map +1 -0
- package/dist/commands/docs-skills-install.d.ts +31 -0
- package/dist/commands/docs-skills-install.d.ts.map +1 -0
- package/dist/{commands-DNssH5Dv.js → commands-DD5gexRY.js} +400 -7
- package/dist/{dist-BJABhykg.js → dist-CivxAJ6C.js} +2 -2
- package/dist/dist-DcYLLDwF.js +1854 -0
- package/dist/{dist-D25iWIXX.js → dist-DjG0qPkx.js} +5 -5
- package/dist/index.js +12 -12
- package/dist/knowledge/intents/audit-trail.md +63 -0
- package/dist/knowledge/intents/auth-and-users.md +67 -0
- package/dist/knowledge/intents/background-work.md +72 -0
- package/dist/knowledge/intents/feature-flags-and-entitlements.md +60 -0
- package/dist/knowledge/intents/file-and-asset-storage.md +71 -0
- package/dist/knowledge/intents/human-approvals.md +56 -0
- package/dist/knowledge/intents/index.md +41 -0
- package/dist/knowledge/intents/money-and-rates.md +65 -0
- package/dist/knowledge/intents/outbound-messages.md +67 -0
- package/dist/knowledge/intents/prompts-and-ai-operations.md +72 -0
- package/dist/knowledge/intents/relationships-and-trees.md +56 -0
- package/dist/knowledge/intents/scheduled-runs.md +61 -0
- package/dist/knowledge/intents/search-facts-knowledge.md +68 -0
- package/dist/knowledge/intents/secrets-and-config.md +66 -0
- package/dist/knowledge/intents/tenant-scoping.md +63 -0
- package/dist/knowledge/intents/webhooks-and-events.md +71 -0
- package/dist/{oidcProvisioningPrimitives-KpIiLmG4-CnRTofeV.js → oidcProvisioningPrimitives-KpIiLmG4-D5-0dAY3.js} +3 -3
- package/dist/{operator-fwao3Y1j.js → operator-B0ZraSEE.js} +2 -2
- package/dist/{portability-CbMgEnD1.js → portability-sL8U5Hld.js} +21 -13
- package/dist/{resolveIdentity-j2WFuKDT-C9XtigVZ.js → resolveIdentity-j2WFuKDT-BieMIOLz.js} +14 -14
- package/dist/smrt-knowledge.okf.md +58 -0
- package/package.json +16 -15
- package/dist/dist-B3gpMpBj.js +0 -1908
- package/dist/dist-BQI8s_yA.js +0 -1854
package/AGENTS.md
CHANGED
|
@@ -95,14 +95,8 @@ it in the same migration also run outside the transaction, in order.
|
|
|
95
95
|
resumes at the index build — their `error_message` carries a
|
|
96
96
|
`[smrt: concurrent-index phase 1 committed]` marker, so the non-index
|
|
97
97
|
statements that already committed are not re-run.
|
|
98
|
-
- INVALID
|
|
99
|
-
|
|
100
|
-
present — are detected via `pg_index.indisvalid` and dropped before the
|
|
101
|
-
rebuild.
|
|
102
|
-
- `migrations.postgres.useConcurrently: false` vetoes the flag; index DDL then
|
|
103
|
-
runs inside the atomic transaction (still bounded by the timeouts).
|
|
104
|
-
- Without the flag, a batch containing explicit `CONCURRENTLY` DDL is rejected
|
|
105
|
-
before the transaction opens — PostgreSQL cannot run it there.
|
|
98
|
+
- INVALID-index cleanup, the `useConcurrently: false` veto, and the explicit-`CONCURRENTLY` rejection:
|
|
99
|
+
agents/db-migrate-concurrency.md.
|
|
106
100
|
|
|
107
101
|
## `doctor`'s agent-surface section (#2591)
|
|
108
102
|
|
|
@@ -283,51 +277,8 @@ exactly those five hardcoded names and nothing else — **never** derived from
|
|
|
283
277
|
drop `includeDroppedTables` (default `false`, both call sites explicit —
|
|
284
278
|
`differ.ts:450`, `db-diff.ts:210`) deliberately refuses to be.
|
|
285
279
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
expected columns and types, or is referenced by a foreign key anywhere in
|
|
289
|
-
the live database. A consumer's own unrelated table sharing one of these
|
|
290
|
-
five names is exactly what the shape check protects.
|
|
291
|
-
- The expected shape is **per table, not one universal baseline**:
|
|
292
|
-
`smrt_objects`/`smrt_classes`/`smrt_collections` are exactly `id`/`slug`/
|
|
293
|
-
`context`/`created_at`/`updated_at`, but `smrt_hierarchicals` also
|
|
294
|
-
requires `parent_id` and `smrt_polymorphic_associations` also requires
|
|
295
|
-
`meta_type`/`meta_id`/`role`/`sort_order` — `SmrtHierarchical`'s and
|
|
296
|
-
`SmrtPolymorphicAssociation`'s own real fields, confirmed against a
|
|
297
|
-
genuine pre-#2644 `db:migrate` run. A table under either of those two
|
|
298
|
-
names with *only* the plain five columns is refused as unexpected shape,
|
|
299
|
-
not treated as safe.
|
|
300
|
-
- Companion indexes are enumerated from each table's live schema (never
|
|
301
|
-
guessed). `smrt_hierarchicals`/`smrt_polymorphic_associations` do not
|
|
302
|
-
carry the `created_at` list-ordering index the other three do (also
|
|
303
|
-
empirically confirmed, not assumed).
|
|
304
|
-
- Bounded PostgreSQL execution reuses the same `SET LOCAL lock_timeout` /
|
|
305
|
-
`statement_timeout` pattern as every other DDL path (#2362). Every target
|
|
306
|
-
is locked `IN ACCESS EXCLUSIVE MODE` before re-checking it — a plain
|
|
307
|
-
`SELECT COUNT(*)` alone would not block a concurrent writer — and shape,
|
|
308
|
-
type, and emptiness are all re-verified inside that transaction
|
|
309
|
-
immediately before dropping anything, via raw `information_schema.columns`
|
|
310
|
-
/ `PRAGMA table_info` (`getTableSchema()` is not available on the
|
|
311
|
-
transaction-scoped connection). Only `DROP TABLE` is ever executed —
|
|
312
|
-
never a `DROP INDEX` by name — so `DROP TABLE`'s own cascade removes the
|
|
313
|
-
table's indexes identity-safely instead of trusting a possibly-stale
|
|
314
|
-
planned index name.
|
|
315
|
-
- `--dry-run` prints the exact plan (which tables exist, their companion
|
|
316
|
-
indexes, and the DROP statements) without executing.
|
|
317
|
-
- Skipping it is safe: a table left behind is inert and permanently orphaned,
|
|
318
|
-
never written to or read from again. Documented, narrow residual risk, all
|
|
319
|
-
schema-integrity (never data loss — the target is always verified empty
|
|
320
|
-
first): DuckDB's adapter does not report foreign keys through
|
|
321
|
-
`getTableSchema()` at all; this module's reverse-FK scan (like every other
|
|
322
|
-
PostgreSQL schema tool in this package) only looks at the `public` schema;
|
|
323
|
-
and foreign keys are checked at planning time only, not re-scanned inside
|
|
324
|
-
the execution transaction. On PostgreSQL a foreign key that appeared after
|
|
325
|
-
planning is still caught there — `DROP TABLE` refuses when a real
|
|
326
|
-
dependent exists, dependency-based, empty parent or not. **This does not
|
|
327
|
-
hold on SQLite**: its FK enforcement on `DROP TABLE` is row-based, so an
|
|
328
|
-
empty parent (this command's precondition) drops cleanly past a real
|
|
329
|
-
foreign key, verified directly. The plan-time scan is the only gate on
|
|
330
|
-
SQLite/DuckDB, narrower than PostgreSQL's.
|
|
280
|
+
Execute-or-refuse, per-table shape checks, lock/timeout behavior, `--dry-run`, and the residual risks of
|
|
281
|
+
skipping it: agents/db-drop-framework-base-tables.md.
|
|
331
282
|
|
|
332
283
|
## Architecture
|
|
333
284
|
|
|
@@ -344,6 +295,26 @@ drop `includeDroppedTables` (default `false`, both call sites explicit —
|
|
|
344
295
|
- `src/loaders/` — class-loader, local-loader, npm-loader, git-loader, template-loader
|
|
345
296
|
- `src/discovery/manifest-discovery.ts` — manifest auto-discovery
|
|
346
297
|
- `src/commands/docs-claude.ts` — downstream AGENTS.md generation + Claude alias; no object scanning
|
|
298
|
+
- `src/commands/docs-knowledge-bundle.ts` — knowledge-bundle half of `docs:agents`
|
|
299
|
+
- `src/commands/docs-skills-install.ts` — skill-installation half of `docs:agents` (#4708)
|
|
300
|
+
|
|
301
|
+
## docs:agents knowledge bundle (consumer contract)
|
|
302
|
+
|
|
303
|
+
Beside the output file, `docs:agents` writes `smrt-knowledge/` (`.agents/smrt-knowledge/`; `docs:claude` → `.claude/`):
|
|
304
|
+
`bundle.json` (`smrt-okf-bundle/1`: `exportedAt` kept while content is unchanged, `packages[{name,version,concept}]`,
|
|
305
|
+
`intents`), `components/<unscoped>.md` per installed package shipping `dist/smrt-knowledge.okf.md` with
|
|
306
|
+
`package_version` re-stamped from the installed `package.json`, and `intents/*` limited to intents with ≥1 installed
|
|
307
|
+
home. `smrt-framework.md` leads with `## Find it by intent` over those same intents. Pages come from the published
|
|
308
|
+
artifacts — `scripts/ship-knowledge-pages.mjs` (root `pnpm build`, `prepack-package.js`) copies the committed
|
|
309
|
+
`docs/knowledge` pages into `dist/`; intents ship in smrt-cli `dist/knowledge/intents/` — never from a checkout (monorepo
|
|
310
|
+
runs fall back to `docs/knowledge`). Links to uninstalled packages' pages dangle by design. The shape lives in
|
|
311
|
+
`@happyvertical/smrt-dev-mcp/knowledge` (`okf-bundle.ts`); `dev:knowledge-check` reads it (`stale-okf-bundle`).
|
|
312
|
+
|
|
313
|
+
Skill install (#4708): unless `--no-install-skills`, `docs:agents` also writes the `smrt-catalog` skill from
|
|
314
|
+
`@happyvertical/smrt-dev-mcp` to `.claude/skills/smrt-catalog/SKILL.md` and `.agents/skills/smrt-catalog/SKILL.md`
|
|
315
|
+
under the working directory (skipped on `--dry-run`). The copy carries a `<!-- smrt-generated: … smrt-dev-mcp@<version> … -->`
|
|
316
|
+
marker after the frontmatter: a rerun replaces a marked copy, a copy without the marker is left alone with a warning.
|
|
317
|
+
The shipped text names `.agents/smrt-knowledge/`; the installer substitutes the real bundle dir (`docs:claude`, custom `--output`). Only the smrt repository itself (root `package.json` name `@happyvertical/smrt`, not any pnpm monorepo) also gets `smrt-contribute`; an unmarked copy byte-identical to the shipped skill (the repo's own `.agents/skills/smrt-contribute`) counts as current. Destinations go through `containedPath` and are refused when any path segment is a symlink, before any write.
|
|
347
318
|
|
|
348
319
|
## Gotchas
|
|
349
320
|
|
package/README.md
CHANGED
|
@@ -186,6 +186,11 @@ alias supports the same flag and retains its historical output path.
|
|
|
186
186
|
Regenerate snapshots after moving the project or updating dependencies so the
|
|
187
187
|
local source paths remain current.
|
|
188
188
|
|
|
189
|
+
`docs:agents` also installs the `smrt-catalog` agent skill into
|
|
190
|
+
`.claude/skills/` and `.agents/skills/` so an agent consults the knowledge
|
|
191
|
+
catalog before hand-rolling infrastructure. Pass `--no-install-skills` to skip
|
|
192
|
+
it. A copy you edited (the generated marker removed) is never overwritten.
|
|
193
|
+
|
|
189
194
|
Review and architecture prompt bundles include package guidance and modules
|
|
190
195
|
matched by file or focus hints. Add `--complete` to either context command to
|
|
191
196
|
include every module for the selected packages. These commands still build the
|
package/agents/app-commands.md
CHANGED
|
@@ -97,6 +97,8 @@ config loading; `bin/smrt.js` imports `dist/` in-process so SIGTERM reaches
|
|
|
97
97
|
publishes via `link()` (never replaces); import requires a 0600 regular
|
|
98
98
|
bundle for the same app, an exactly matching manifest schema, and an empty
|
|
99
99
|
target; deployed import requires `SMRT_MAINTENANCE_MODE=true`.
|
|
100
|
+
Local relative asset locators resolve against the approved asset root during
|
|
101
|
+
export and stay relative after import. Legacy file URLs import as file URLs.
|
|
100
102
|
- **Process identity**: `app.pid` is trusted only when the live command
|
|
101
103
|
line's last two tokens are a path with basename `smrt-web.mjs` and exactly
|
|
102
104
|
`--smrt-instance=<record instance>` (an app started by the template's former
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# `db:drop-framework-base-tables` details (#2647)
|
|
2
|
+
|
|
3
|
+
Detail for the one-time remediation described in `AGENTS.md`.
|
|
4
|
+
|
|
5
|
+
- Execute-or-refuse, like `db:rollback`: it refuses (non-zero exit, nothing
|
|
6
|
+
dropped) if any target table has rows, has anything but that table's own
|
|
7
|
+
expected columns and types, or is referenced by a foreign key anywhere in
|
|
8
|
+
the live database. A consumer's own unrelated table sharing one of these
|
|
9
|
+
five names is exactly what the shape check protects.
|
|
10
|
+
- The expected shape is **per table, not one universal baseline**:
|
|
11
|
+
`smrt_objects`/`smrt_classes`/`smrt_collections` are exactly `id`/`slug`/
|
|
12
|
+
`context`/`created_at`/`updated_at`, but `smrt_hierarchicals` also
|
|
13
|
+
requires `parent_id` and `smrt_polymorphic_associations` also requires
|
|
14
|
+
`meta_type`/`meta_id`/`role`/`sort_order` — `SmrtHierarchical`'s and
|
|
15
|
+
`SmrtPolymorphicAssociation`'s own real fields, confirmed against a
|
|
16
|
+
genuine pre-#2644 `db:migrate` run. A table under either of those two
|
|
17
|
+
names with *only* the plain five columns is refused as unexpected shape,
|
|
18
|
+
not treated as safe.
|
|
19
|
+
- Companion indexes are enumerated from each table's live schema (never
|
|
20
|
+
guessed). `smrt_hierarchicals`/`smrt_polymorphic_associations` do not
|
|
21
|
+
carry the `created_at` list-ordering index the other three do (also
|
|
22
|
+
empirically confirmed, not assumed).
|
|
23
|
+
- Bounded PostgreSQL execution reuses the same `SET LOCAL lock_timeout` /
|
|
24
|
+
`statement_timeout` pattern as every other DDL path (#2362). Every target
|
|
25
|
+
is locked `IN ACCESS EXCLUSIVE MODE` before re-checking it — a plain
|
|
26
|
+
`SELECT COUNT(*)` alone would not block a concurrent writer — and shape,
|
|
27
|
+
type, and emptiness are all re-verified inside that transaction
|
|
28
|
+
immediately before dropping anything, via raw `information_schema.columns`
|
|
29
|
+
/ `PRAGMA table_info` (`getTableSchema()` is not available on the
|
|
30
|
+
transaction-scoped connection). Only `DROP TABLE` is ever executed —
|
|
31
|
+
never a `DROP INDEX` by name — so `DROP TABLE`'s own cascade removes the
|
|
32
|
+
table's indexes identity-safely instead of trusting a possibly-stale
|
|
33
|
+
planned index name.
|
|
34
|
+
- `--dry-run` prints the exact plan (which tables exist, their companion
|
|
35
|
+
indexes, and the DROP statements) without executing.
|
|
36
|
+
- Skipping it is safe: a table left behind is inert and permanently orphaned,
|
|
37
|
+
never written to or read from again. Documented, narrow residual risk, all
|
|
38
|
+
schema-integrity (never data loss — the target is always verified empty
|
|
39
|
+
first): DuckDB's adapter does not report foreign keys through
|
|
40
|
+
`getTableSchema()` at all; this module's reverse-FK scan (like every other
|
|
41
|
+
PostgreSQL schema tool in this package) only looks at the `public` schema;
|
|
42
|
+
and foreign keys are checked at planning time only, not re-scanned inside
|
|
43
|
+
the execution transaction. On PostgreSQL a foreign key that appeared after
|
|
44
|
+
planning is still caught there — `DROP TABLE` refuses when a real
|
|
45
|
+
dependent exists, dependency-based, empty parent or not. **This does not
|
|
46
|
+
hold on SQLite**: its FK enforcement on `DROP TABLE` is row-based, so an
|
|
47
|
+
empty parent (this command's precondition) drops cleanly past a real
|
|
48
|
+
foreign key, verified directly. The plan-time scan is the only gate on
|
|
49
|
+
SQLite/DuckDB, narrower than PostgreSQL's.
|
|
@@ -53,3 +53,14 @@ are written after the diff, when both runs have already planned.
|
|
|
53
53
|
— two concurrent CLI runs apply one batch; a held lock blocks a run before it
|
|
54
54
|
touches schema. Each run gets its own pool (`getDatabase` caches one pool per
|
|
55
55
|
identity in-process, which two real processes would not share).
|
|
56
|
+
|
|
57
|
+
## Index and flag details
|
|
58
|
+
|
|
59
|
+
- INVALID indexes — the stump a cancelled or timed-out
|
|
60
|
+
`CREATE INDEX CONCURRENTLY` leaves, which `pg_indexes` still reports as
|
|
61
|
+
present — are detected via `pg_index.indisvalid` and dropped before the
|
|
62
|
+
rebuild.
|
|
63
|
+
- `migrations.postgres.useConcurrently: false` vetoes the flag; index DDL then
|
|
64
|
+
runs inside the atomic transaction (still bounded by the timeouts).
|
|
65
|
+
- Without the flag, a batch containing explicit `CONCURRENTLY` DDL is rejected
|
|
66
|
+
before the transaction opens — PostgreSQL cannot run it there.
|
package/dist/{AuditLogCollection-BBbvr8Qc-CoDs0BaX.js → AuditLogCollection-BBbvr8Qc-mcBSLXW9.js}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
2
|
-
import { i as tenantId, r as TenantScoped } from "./dist-
|
|
2
|
+
import { i as tenantId, r as TenantScoped } from "./dist-CivxAJ6C.js";
|
|
3
3
|
import { n as __exportAll$1 } from "./NostrIdentity-RJaATTCt-BbRHWyee.js";
|
|
4
4
|
import { SmrtCollection, SmrtObject, field, foreignKey, smrt } from "@happyvertical/smrt-core";
|
|
5
5
|
//#region ../profiles/dist/chunks/AuditLogCollection-BBbvr8Qc.js
|
|
@@ -42,7 +42,7 @@ var OidcIdentity = class extends SmrtObject {
|
|
|
42
42
|
* Find identity by issuer and subject
|
|
43
43
|
*/
|
|
44
44
|
static async findBySubject(issuer, subject, options = {}) {
|
|
45
|
-
const { OidcIdentityCollection } = await import("./OidcIdentityCollection-D4DIZv0K-
|
|
45
|
+
const { OidcIdentityCollection } = await import("./OidcIdentityCollection-D4DIZv0K-Do3bwRuw.js").then((n) => n.r).then((n) => n.r);
|
|
46
46
|
return await (await OidcIdentityCollection.create(options)).findBySubject(issuer, subject);
|
|
47
47
|
}
|
|
48
48
|
/** Build the collision-free natural key for one OIDC issuer subject. */
|
|
@@ -65,7 +65,7 @@ var OidcIdentity = class extends SmrtObject {
|
|
|
65
65
|
static async findOrCreate(profile, oidcData, options = {}) {
|
|
66
66
|
const profileId = profile.id;
|
|
67
67
|
if (typeof profileId !== "string" || !profileId) throw new Error("OidcIdentity.findOrCreate() requires a saved Profile.");
|
|
68
|
-
const { reuseExistingOidcIdentityForProfile } = await import("./resolveIdentity-j2WFuKDT-
|
|
68
|
+
const { reuseExistingOidcIdentityForProfile } = await import("./resolveIdentity-j2WFuKDT-BieMIOLz.js").then((n) => n.t).then((n) => n.i);
|
|
69
69
|
const profileOptions = profile.options ?? {};
|
|
70
70
|
return (await reuseExistingOidcIdentityForProfile(profileId, {
|
|
71
71
|
email: oidcData.email,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
2
2
|
import { n as __exportAll$1 } from "./NostrIdentity-RJaATTCt-BbRHWyee.js";
|
|
3
|
-
import { t as OidcIdentity } from "./OidcIdentity-COeMidoC-
|
|
3
|
+
import { t as OidcIdentity } from "./OidcIdentity-COeMidoC-ETkpZbIS.js";
|
|
4
4
|
import { SmrtCollection } from "@happyvertical/smrt-core";
|
|
5
5
|
//#region ../profiles/dist/chunks/OidcIdentityCollection-D4DIZv0K.js
|
|
6
6
|
var OidcIdentityCollection_D4DIZv0K_exports = /* @__PURE__ */ __exportAll({
|