cabloy 5.1.213 → 5.1.215

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 (36) hide show
  1. package/.cabloy-version +1 -1
  2. package/.github/workflows/agent-governance.yml +19 -0
  3. package/CHANGELOG.md +14 -0
  4. package/package.json +3 -1
  5. package/repo-agent-governance/managed-assets.json +18 -18
  6. package/repo-agent-governance/policies/repository.md +3 -0
  7. package/repo-agent-governance/scripts/pack-check.mjs +1 -0
  8. package/repo-agent-governance/skills/cabloy-spec-execution/SKILL.md +7 -1
  9. package/repo-agent-governance/skills/cabloy-spec-execution/references/execution-protocol.md +4 -2
  10. package/repo-agent-governance/skills/cabloy-spec-execution/references/status-and-evidence.md +28 -1
  11. package/repo-agent-governance/skills/cabloy-spec-generation/SKILL.md +10 -0
  12. package/repo-agent-governance/skills/cabloy-spec-generation/references/traceability-and-status-rules.md +2 -0
  13. package/repo-agent-governance/tests/evidence-paths.test.mjs +736 -0
  14. package/repo-agent-governance/tests/governance.test.mjs +25 -0
  15. package/repo-agent-governance/tools/evidence-paths/sanitize.mjs +549 -0
  16. package/repo-docs/ai/ai-spec-driven-development.md +12 -0
  17. package/repo-docs/ai/playbook-spec-execution.md +20 -2
  18. package/repo-docs/backend/migration-and-changes.md +5 -1
  19. package/repo-docs/backend/startup-guide.md +16 -1
  20. package/repo-docs/reference/repo-scripts.md +69 -1
  21. package/scripts/bootstrapAgentGovernance.mjs +2 -0
  22. package/scripts/upgrade.ts +2 -0
  23. package/vona/packages-vona/vona/package.json +1 -1
  24. package/vona/pnpm-lock.yaml +139 -29
  25. package/vona/src/suite-vendor/a-vona/modules/a-printtip/package.json +1 -1
  26. package/vona/src/suite-vendor/a-vona/modules/a-printtip/src/bean/startup.printTip.ts +1 -1
  27. package/vona/src/suite-vendor/a-vona/modules/a-printtip/test/printTip.test.ts +46 -0
  28. package/vona/src/suite-vendor/a-vona/modules/a-startup/package.json +1 -1
  29. package/vona/src/suite-vendor/a-vona/modules/a-startup/src/service/startup.ts +16 -21
  30. package/vona/src/suite-vendor/a-vona/modules/a-startup/src/types/startup.ts +0 -1
  31. package/vona/src/suite-vendor/a-vona/modules/a-startup/test/devSeed.test.ts +282 -30
  32. package/vona/src/suite-vendor/a-vona/modules/a-version/package.json +1 -1
  33. package/vona/src/suite-vendor/a-vona/modules/a-version/src/service/version.ts +3 -0
  34. package/vona/src/suite-vendor/a-vona/modules/a-version/test/instanceSeed.test.ts +47 -0
  35. package/vona/src/suite-vendor/a-vona/package.json +1 -1
  36. package/zova/pnpm-lock.yaml +8 -8
@@ -232,7 +232,7 @@ In the current runtime behavior:
232
232
  - in `test` and `dev`, the default instance is started eagerly
233
233
  - in production-style flows, configured static instances are started from `config.instance.instances`
234
234
 
235
- A practical timeline is:
235
+ For ordinary startup without newly created development databases, a practical timeline is:
236
236
 
237
237
  1. run non-instance startups with `after !== true` during app start
238
238
  2. run non-instance startups with `after === true` during app ready
@@ -241,6 +241,21 @@ A practical timeline is:
241
241
  5. mark `appReadyInstances[instanceName] = true`
242
242
  6. run instance startups with `after === true`
243
243
 
244
+ Explicit development preparation through `npm run db:reset` is a data-preparation flow in **Cabloy Basic and Cabloy Start**. It retains non-instance startups with `after !== true`, including database migration and database-name preparation, then completes the default instance and each newly created isolated instance:
245
+
246
+ 1. run the instance's startups with `after !== true`, including instance initialization
247
+ 2. for the newly created default instance (`''`) only, run module `seed()` hooks for test/dev convenience fixtures
248
+ 3. consume the instance's creation bookkeeping and mark it ready
249
+ 4. repeat for the next instance, without seeding isolated targets such as `isolateTest`
250
+
251
+ Reset skips all instance and non-instance startups with `after === true` before dispatch. This excludes schedule loading, runtime JSON generation, development tips, queue-worker preloading, and HTTP listening, including their startup execution logs. Normal dev startup retains these runtime tasks and generates runtime JSON when the server starts. Skipping queue-worker preloading does not disable queues: an explicit queue push can still create a worker lazily, and fire-and-forget jobs are not automatically drained by reset.
252
+
253
+ Reset-required preparation must belong to migrations, `init()`, `seed()`, or a non-after startup; do not depend on an after-startup for required data. This phase filter does not bypass independent framework monkey hooks such as `appStarted`, or application teardown.
254
+
255
+ Each instance completes preparation in one queued startup task. Ordinary queued readiness requests skip reinitialization once the instance is ready, even though its after-startups were skipped. A failed default seed leaves its creation marker unconsumed and its readiness unset. There is no all-instances atomic readiness guarantee: if a later instance fails, an earlier instance may already be ready; the failure still stops preparation. Outside reset, explicitly forced startup requests retain their force behavior through instance after-startups.
256
+
257
+ Test-mode default seeding retains its existing lifecycle after default instance startup. Ordinary dev startup reuses existing databases without seeding. See [Managed development database preparation](/backend/migration-and-changes#managed-development-database-preparation) for reset safety and seed ownership.
258
+
244
259
  This is why startup should be read together with the instance and datasource story rather than as a purely global boot topic.
245
260
 
246
261
  ## Teardown-oriented monkey examples
@@ -116,6 +116,72 @@ A legacy suite with a different WBS or progress-table layout is not chart-compat
116
116
 
117
117
  These commands do not create planning authority, implement a WBS task, execute an ATP, produce acceptance evidence, or replace traceability/status review. Confirm the active root `package.json` and script input expectations before assuming equivalent behavior in Cabloy Start or another repository.
118
118
 
119
+ ## Evidence path sanitization
120
+
121
+ The dependency-free path tool lives in `repo-agent-governance/tools/evidence-paths/sanitize.mjs`. It sanitizes caller-supplied UTF-8 stdin, or independently checks explicitly selected files/directories without rewriting them:
122
+
123
+ ```bash
124
+ npm run --silent evidence:sanitize -- --help
125
+ npm run --silent evidence:check -- -- repo-specs/example/evidence
126
+ # Declare another checkout or external root; use the same mappings when checking.
127
+ npm run --silent evidence:sanitize -- --map '/synthetic/other-checkout=MAIN_CHECKOUT'
128
+ npm run --silent evidence:check -- --map '/synthetic/other-checkout=MAIN_CHECKOUT' -- evidence.pending.txt
129
+ ```
130
+
131
+ The last two commands illustrate a **synthetic** root, not a detected local location. `sanitize` waits for stdin; it does not run a producer. Use quiet npm output so npm banners are not mixed into the retained stream. Default checkout discovery comes from the tool's installed location, not the shell working directory; `--repo-root ROOT` overrides it. Repeatable `--map ROOT=ALIAS` declares additional absolute roots with stable uppercase aliases, such as `MAIN_CHECKOUT`. Longest matching roots win at path-segment boundaries. Checkout paths become repository-root-relative; explicit external mappings become `<ALIAS>/suffix`. Choose aliases that distinguish unrelated roots and review any sensitive suffixes.
132
+
133
+ ### Capture before retaining
134
+
135
+ Combine producer stdout/stderr **before** sanitization, never `tee` or spool raw output first. Use a new output filename, check sanitizer status, and retain the actual producer result, including failures. See [Verify narrowly and retain evidence](/ai/playbook-spec-execution#verify-narrowly-and-retain-evidence) for a Bash pipeline with immediate per-stage status capture. Zsh uses `pipestatus` instead of Bash `PIPESTATUS`. `pipefail` prevents a passing sanitizer from masking an upstream failure, but it does not preserve every stage's exact code. A failed sanitizer may leave earlier sanitized lines; partial output must not be accepted as evidence. The tool does not automatically intercept terminal or agent-tool output and does not authorize capturing secret-bearing streams.
136
+
137
+ ### Windows and PowerShell
138
+
139
+ The tool uses Node's native filesystem APIs on Windows, Linux and macOS; it requires the repository's Node.js version (`>=24.4.0`). Path-text recognition is cross-platform independently of the host OS. Native filesystem behavior is checked by the `evidence-platforms` CI matrix on Ubuntu, Windows and macOS. A configured matrix is not a successful run: inspect the actual job results before claiming all three platforms are verified.
140
+
141
+ From the repository root, PowerShell can invoke the CLI directly:
142
+
143
+ ```powershell
144
+ node .\repo-agent-governance\tools\evidence-paths\sanitize.mjs --help
145
+ node .\repo-agent-governance\tools\evidence-paths\sanitize.mjs check -- '.\evidence.pending.txt'
146
+ $checkExit = $LASTEXITCODE
147
+ # 0 = clean, 1 = paths found, 2 = incomplete/error
148
+ ```
149
+
150
+ For a **synthetic input smoke test only**, not evidence capture from a real producer:
151
+
152
+ ```powershell
153
+ $previousOutputEncoding = $OutputEncoding
154
+ try {
155
+ $OutputEncoding = [System.Text.UTF8Encoding]::new($false)
156
+ 'Unicode sample: café C:\Users\Synthetic\private\log.txt' |
157
+ node .\repo-agent-governance\tools\evidence-paths\sanitize.mjs sanitize
158
+ $sanitizeExit = $LASTEXITCODE
159
+ # Expected output: Unicode sample: café <PRIVATE_PATH>
160
+ } finally {
161
+ $OutputEncoding = $previousOutputEncoding
162
+ }
163
+ ```
164
+
165
+ Bash `pipefail`/`PIPESTATUS` and Zsh `pipestatus` are not PowerShell syntax. `$LASTEXITCODE` after a native pipeline is not a record of every stage's status. For real producer capture, use the Bash example in a Bash environment, or orchestration that explicitly observes both native processes and supplies UTF-8 bytes without a raw spool; do not claim the synthetic example preserves a producer exit code. Never accept evidence based only on the last pipeline command succeeding.
166
+
167
+ Prefer PowerShell 7.4+ for native byte-stream pipelines/redirection. Windows PowerShell 5.1 and text cmdlets can transcode output or create UTF-16 files; merely setting `$OutputEncoding` does not make all redirection byte-transparent. The sanitizer rejects invalid UTF-8/binary input rather than guessing an encoding. Avoid inserting text cmdlets into a byte-preserving capture pipeline, and preserve stderr and exit statuses deliberately. Do not change platform encoding globally.
168
+
169
+ POSIX mode-bit and unusual-filename tests are explicitly platform-specific. Windows permission failures are determined by native file-open/read errors, not simulated with POSIX `chmod(0)`. Symlink tests use Windows directory junctions where possible; unavailable file-symlink privileges are reported as capability skips, not successful coverage. The scan's no-symlink, no-environment-file and stable-filesystem requirements apply on every platform.
170
+
171
+ ### Coverage and result boundaries
172
+
173
+ Sanitization and checking share the same matcher. They recognize configured roots and bounded machine-local home/temp conventions, not every slash-prefixed path. Known private paths become `<PRIVATE_PATH>`; configured mappings take precedence so useful checkout-relative locations survive. Supported forms include POSIX home/temp paths, Windows drive/UNC paths, JSON-escaped backslashes and local `file:` URLs. Quote whitespace-containing path tokens; unquoted tokens end at whitespace or prose delimiters. Ordinary non-file URLs and generic API/container paths are not treated as filesystem paths. Other machine roots must be declared explicitly; unusual escaping, unknown filesystem locations, and sensitive relative suffixes still require manual review. This is **path-only tooling**, not a secret scanner or safe-publication certificate. Review credentials, tokens, customer data, and provider identifiers separately before retention/sharing.
174
+
175
+ Input must be UTF-8 text with lines no larger than 1 MiB; checked files are limited to 8 MiB each. Streaming handles split UTF-8/path chunks, CRLF and final unterminated lines; invalid encoding, NUL/non-text controls and oversized lines fail rather than emitting raw fragments. Disable producer color/terminal controls using its supported option (for example, `NO_COLOR=1` when honored); ANSI escape sequences are not silently stripped. The checker recursively visits explicit scopes in deterministic order, including hidden entries. It does not follow symlinks (including selected-scope ancestors), open special files, or read `.env*` files/directories. Select the canonical scope path when a system temp-directory alias is itself a symlink. Keep the scope tree stable while scanning; this is not an adversarial filesystem snapshot. Encountering unsupported, excluded or unreadable inputs means incomplete coverage, not clean success. Scope checks to reviewed evidence artifacts, not an arbitrary repository root. Diagnostics identify safe relative scope labels and line numbers, never matched source text or raw absolute scan roots.
176
+
177
+ | Exit | Meaning |
178
+ | ---- | ------------------------------------------------------------------------------------------------- |
179
+ | `0` | Sanitization completed, or the complete selected check scope has no recognized paths. |
180
+ | `1` | Checker detected recognized local paths. |
181
+ | `2` | Usage, I/O, encoding, size-limit or incomplete-scan failure; this takes precedence over findings. |
182
+
183
+ A clean check proves only declared path-recognition coverage. It does not prove producer success, ATP completion, approval, or release readiness. Preserve diagnostic codes, line/column locations, failures, exit codes and source hashes. Source hashes refer to original source bytes; label historical path-redacted diffs as non-byte-exact and not apply-ready. Tests run under `npm run test:agent-governance`; `spec:check` intentionally excludes evidence and is not a privacy checker.
184
+
119
185
  ## Agent-governance maintenance
120
186
 
121
187
  Use these Cabloy Basic maintenance commands when changing shared agent rules, root skill bundles, or adapter tooling:
@@ -166,7 +232,9 @@ With `database.testDatabase: true`, `npm run dev` and `npm run dev:one` only reu
166
232
  - **All required databases exist:** startup reuses them without database creation, creation-time Redis cleanup, or module seeding. Ordinary startup is not a reset or a repeatable fixture-import path.
167
233
  - **Any required database is missing:** startup fails promptly with an instruction to run `npm run db:reset`. This check covers both shared and statically configured isolate database targets; the presence of the shared database alone is not sufficient. Startup does not create the missing target or clear Redis or seed as a fallback.
168
234
 
169
- `npm run db:reset` is the explicit, destructive preparation command. It requires `database.testDatabase: true` and a connection outside the disposable database. In a single process, it clears validated application-owned Redis state with `clearAllData()`, drops and recreates the managed disposable dev databases, then runs migrations, instance initialization, and module `seed()` hooks.
235
+ `npm run db:reset` is the explicit, destructive preparation command. It requires `database.testDatabase: true` and a connection outside the disposable database. In a single process, it clears validated application-owned Redis state with `clearAllData()`, drops and recreates the managed disposable dev databases, then runs migrations and instance initialization. In both editions, only the default instance (`''`) runs module `seed()` hooks, supplying test/dev convenience fixtures before consuming its creation bookkeeping and marking it ready. Configured isolated targets such as `isolateTest` initialize and become ready without fixture seeding. Each instance completes preparation in sequence.
236
+
237
+ Reset retains non-after startups and skips all instance and application startups with `after: true`, including schedules, runtime JSON generation, development tips, queue-worker preloading, and HTTP listening. Required data preparation must not depend on after-startups. Normal dev startup retains these runtime tasks; independent framework lifecycle hooks and application teardown still run during reset. See [Backend Startup Guide](/backend/startup-guide#app-startup-and-instance-startup-in-practice).
170
238
 
171
239
  **Stop the development server and any other processes using the same database and Redis namespace before running reset.** There is no file-based preparation lock: concurrent dev/dev and dev/reset processes against the same database and Redis namespace are unsupported. Disabling the reset command's own listener does not make reset safe alongside a live server or queue worker. Do not reset data you need to retain.
172
240
 
@@ -10,6 +10,8 @@ const GOVERNANCE_SCRIPT_NAMES = [
10
10
  'spec:charts',
11
11
  'spec:charts:check',
12
12
  'spec:check',
13
+ 'evidence:sanitize',
14
+ 'evidence:check',
13
15
  'agent:governance:render',
14
16
  'agent:governance:check',
15
17
  'agent:governance:adopt',
@@ -294,6 +294,8 @@ function reconcileGovernancePackageJson(dryRun?: boolean): void {
294
294
  'test:agent-governance',
295
295
  'contract:gate',
296
296
  'spec:check',
297
+ 'evidence:sanitize',
298
+ 'evidence:check',
297
299
  ];
298
300
  const managedScripts = [...baselineScripts, ...governanceScripts];
299
301
  let changed = false;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona",
3
- "version": "5.1.108",
3
+ "version": "5.1.109",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "Vona is an intuitive, elegant and powerful Node.js framework for rapidly developing enterprise applications of any size",
6
6
  "keywords": [
@@ -573,8 +573,8 @@ importers:
573
573
  specifier: npm:@cabloy/zod@4.3.8
574
574
  version: '@cabloy/zod@4.3.8'
575
575
  zova:
576
- specifier: ^5.1.167
577
- version: 5.1.167(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3))
576
+ specifier: ^5.1.170
577
+ version: 5.1.171(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3))
578
578
  zova-jsx:
579
579
  specifier: ^1.1.92
580
580
  version: 1.1.92(typescript@5.9.3)
@@ -591,8 +591,8 @@ importers:
591
591
  specifier: ^5.1.35
592
592
  version: 5.1.35
593
593
  zova-module-a-form:
594
- specifier: ^5.1.51
595
- version: 5.1.51(vue@3.5.43(typescript@5.9.3))
594
+ specifier: ^5.1.54
595
+ version: 5.1.54(vue@3.5.43(typescript@5.9.3))
596
596
  zova-module-a-icon:
597
597
  specifier: ^5.1.27
598
598
  version: 5.1.27
@@ -603,20 +603,20 @@ importers:
603
603
  specifier: ^5.0.3
604
604
  version: 5.0.3
605
605
  zova-module-a-model:
606
- specifier: ^5.1.37
607
- version: 5.1.37(vue@3.5.43(typescript@5.9.3))
606
+ specifier: ^5.1.38
607
+ version: 5.1.38(vue@3.5.43(typescript@5.9.3))
608
608
  zova-module-a-openapi:
609
- specifier: ^5.1.55
610
- version: 5.1.55
609
+ specifier: file:/tmp/zova-module-a-openapi-5.1.56.tgz
610
+ version: file:../../../../../tmp/zova-module-a-openapi-5.1.56.tgz
611
611
  zova-module-a-pay:
612
612
  specifier: ^5.0.9
613
613
  version: 5.0.9
614
614
  zova-module-a-router:
615
- specifier: ^5.1.41
616
- version: 5.1.41
615
+ specifier: ^5.1.42
616
+ version: 5.1.42
617
617
  zova-module-a-routertabs:
618
- specifier: ^5.1.34
619
- version: 5.1.34
618
+ specifier: ^5.1.35
619
+ version: 5.1.35
620
620
  zova-module-a-ssr:
621
621
  specifier: ^5.1.40
622
622
  version: 5.1.40
@@ -630,8 +630,8 @@ importers:
630
630
  specifier: ^5.0.5
631
631
  version: 5.0.5
632
632
  zova-module-rest-resource:
633
- specifier: ^5.1.55
634
- version: 5.1.55
633
+ specifier: ^5.1.56
634
+ version: 5.1.56
635
635
 
636
636
  .zova-rest/cabloy-basic-web:
637
637
  dependencies:
@@ -657,8 +657,8 @@ importers:
657
657
  specifier: npm:@cabloy/zod@4.3.8
658
658
  version: '@cabloy/zod@4.3.8'
659
659
  zova:
660
- specifier: ^5.1.167
661
- version: 5.1.167(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3))
660
+ specifier: ^5.1.168
661
+ version: 5.1.171(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3))
662
662
  zova-jsx:
663
663
  specifier: ^1.1.92
664
664
  version: 1.1.92(typescript@5.9.3)
@@ -675,8 +675,8 @@ importers:
675
675
  specifier: ^5.1.35
676
676
  version: 5.1.35
677
677
  zova-module-a-form:
678
- specifier: ^5.1.51
679
- version: 5.1.51(vue@3.5.43(typescript@5.9.3))
678
+ specifier: ^5.1.52
679
+ version: 5.1.54(vue@3.5.43(typescript@5.9.3))
680
680
  zova-module-a-icon:
681
681
  specifier: ^5.1.27
682
682
  version: 5.1.27
@@ -687,20 +687,20 @@ importers:
687
687
  specifier: ^5.0.3
688
688
  version: 5.0.3
689
689
  zova-module-a-model:
690
- specifier: ^5.1.37
691
- version: 5.1.37(vue@3.5.43(typescript@5.9.3))
690
+ specifier: ^5.1.38
691
+ version: 5.1.38(vue@3.5.43(typescript@5.9.3))
692
692
  zova-module-a-openapi:
693
- specifier: ^5.1.55
694
- version: 5.1.55
693
+ specifier: file:/tmp/zova-module-a-openapi-5.1.56.tgz
694
+ version: file:../../../../../tmp/zova-module-a-openapi-5.1.56.tgz
695
695
  zova-module-a-pay:
696
696
  specifier: ^5.0.9
697
697
  version: 5.0.9
698
698
  zova-module-a-router:
699
- specifier: ^5.1.41
700
- version: 5.1.41
699
+ specifier: ^5.1.42
700
+ version: 5.1.42
701
701
  zova-module-a-routertabs:
702
- specifier: ^5.1.34
703
- version: 5.1.34
702
+ specifier: ^5.1.35
703
+ version: 5.1.35
704
704
  zova-module-a-ssr:
705
705
  specifier: ^5.1.40
706
706
  version: 5.1.40
@@ -714,8 +714,8 @@ importers:
714
714
  specifier: ^5.0.5
715
715
  version: 5.0.5
716
716
  zova-module-rest-resource:
717
- specifier: ^5.1.55
718
- version: 5.1.55
717
+ specifier: ^5.1.56
718
+ version: 5.1.56
719
719
 
720
720
  .zova-rest/cabloy-commerce:
721
721
  dependencies:
@@ -1652,7 +1652,7 @@ importers:
1652
1652
  specifier: ^5.0.3
1653
1653
  version: link:modules/a-markdown
1654
1654
  vona-module-a-rbac:
1655
- specifier: ^5.0.10
1655
+ specifier: ^5.0.11
1656
1656
  version: link:modules/a-rbac
1657
1657
  vona-module-a-socket:
1658
1658
  specifier: workspace:^
@@ -8920,6 +8920,9 @@ packages:
8920
8920
  zova-module-a-form@5.1.51:
8921
8921
  resolution: {integrity: sha512-/UlaorIX2SpN/ozGsXMaklfNuS64as322jD3+0wlfj9FVyhV1nz0wEBpYSGgsiX+KFLJicwpNqAz/kMI7WfvUw==}
8922
8922
 
8923
+ zova-module-a-form@5.1.54:
8924
+ resolution: {integrity: sha512-WChgaslejoVIV3PLODWMY4LB1CdSZe3c/3Z+NV5ibzF+FqeZ4AVvpX/viPcAnptb7i4m3M29BTKbZFOF/x6zAw==}
8925
+
8923
8926
  zova-module-a-icon@5.1.27:
8924
8927
  resolution: {integrity: sha512-KAvHkK6YsN2H5iQgl2IBQHIvvFDnfzPCxDzuQyTnAiCgSczD/UFO6bLZqWVT2m/qfsmJXMzWAWHPdU02J3ANZQ==}
8925
8928
 
@@ -8938,21 +8941,37 @@ packages:
8938
8941
  zova-module-a-model@5.1.37:
8939
8942
  resolution: {integrity: sha512-Ipas8Lpsi9Jcgu3AbzajgqcBffmg1GeIBOu4UtOyR5fbRDvlxYWXx45rA52oB/zgoC+QvhUVzY36fnNfTJiywg==}
8940
8943
 
8944
+ zova-module-a-model@5.1.38:
8945
+ resolution: {integrity: sha512-F0ugy8raH2J8G7Y/YUM9J2xj/J6IXnDO+sT0nN0GVCaX+DmXkxf/cTK9XnXlfuuJnWKRUgQj9ZmkVW7q4i9mnQ==}
8946
+
8941
8947
  zova-module-a-openapi@5.1.55:
8942
8948
  resolution: {integrity: sha512-jdbUN4QEAQZvx+EmwaDfIa0Xy5MoNOVYLdLnEl+LbANc6COxkGGSyroFBRXG5S/Av0YWIBUbgahuEpFdL+RYjw==}
8943
8949
 
8950
+ zova-module-a-openapi@5.1.57:
8951
+ resolution: {integrity: sha512-U6gKdYXNlD4wn1zgNUC+P3pg6lq23GZNESLipzVe7Zb7buqCXuEBjGdPa2NPrOuLxwWlZNg7Z4Q+GerBEF2geQ==}
8952
+
8953
+ zova-module-a-openapi@file:../../../../../tmp/zova-module-a-openapi-5.1.56.tgz:
8954
+ resolution: {integrity: sha512-UbcakzhP7T+MT7A41Uxly3NMHSuEyOtTS6tnen+TKgUXCY3Ls6zaOhBsowMEtBHGoJ+YMsATJXPgh5836bmQMQ==, tarball: file:../../../../../tmp/zova-module-a-openapi-5.1.56.tgz}
8955
+ version: 5.1.56
8956
+
8944
8957
  zova-module-a-pay@5.0.9:
8945
8958
  resolution: {integrity: sha512-Chl6EKp30HBOGFCJXbla2/lS19WhzQyTZwgYmsL3nnG9Vt2TeUlb82vsYCVuDcy0cgmxVaWjPF7dzKL/r3Pfng==}
8946
8959
 
8947
8960
  zova-module-a-router@5.1.41:
8948
8961
  resolution: {integrity: sha512-oSv4S+9bAx79X8oUBARFKs4n56FNG/bbqdyxP10CXxlVue8WU7CmNKN4ckzLJ2mleVIezijZk/1aHS1Fl5rk+g==}
8949
8962
 
8963
+ zova-module-a-router@5.1.42:
8964
+ resolution: {integrity: sha512-/kpRuFC1V14zVx7KLtYZJTqhPgSpn3kyhJ/iqbKSjEUu1oTCu9nE0KzF+/RV8AigeZu+GgJSRR9ngl8efSlxXA==}
8965
+
8950
8966
  zova-module-a-routerstack@5.1.29:
8951
8967
  resolution: {integrity: sha512-5gvGVPGETeTGhX+Hpj7GPV/HSqeL0EAKalXVdwvZu1fMUX/dBT0UI51QYIKcnmlvPwPX3PgiiDE0bJnVJhBo0A==}
8952
8968
 
8953
8969
  zova-module-a-routertabs@5.1.34:
8954
8970
  resolution: {integrity: sha512-j8QS0bxpfQJidh/wUsA1N2FXhckoi5qq01nm2uKCY1CHLEFA19sccP41v6JjrN5N3sw90a3YTaMjbezO5bS9Lg==}
8955
8971
 
8972
+ zova-module-a-routertabs@5.1.35:
8973
+ resolution: {integrity: sha512-OIdrdHEoxtK76m2gMw9xJjwJBWDLkRuLlP+dSiCGACm5X90oCLikQYPBAynms8hxBC4pKpSSby7jmjhi+C98WQ==}
8974
+
8956
8975
  zova-module-a-ssr@5.1.40:
8957
8976
  resolution: {integrity: sha512-K73SxTzEXKLqoXaZ5Jh1DDUOOvvGpvv8FsEDDDEjK9c0E00Y+j8v7Z/X+IALOU1WHA6FNpdwpqXTWjcpwkE9DA==}
8958
8977
 
@@ -8980,12 +8999,21 @@ packages:
8980
8999
  zova-module-rest-resource@5.1.55:
8981
9000
  resolution: {integrity: sha512-Kk3oJIcxM5EbeTLl+ucJSeI2kT0We8YilXBaX8Z7QWCbZ0fHoQDy/Ac4YsVSWIXUrC2SQ267+nMl3sHXnE9G0Q==}
8982
9001
 
9002
+ zova-module-rest-resource@5.1.56:
9003
+ resolution: {integrity: sha512-JJ25Z6I3KixofC2wn3VKi7sQmjbwayE1wqD+Y18rOW1XeYRPh+WfPHnqAwvBcA7YQ1tw1oCzQVN3s/58zSOLEA==}
9004
+
8983
9005
  zova-suite-a-zova@5.1.166:
8984
9006
  resolution: {integrity: sha512-2mmuMDS4uEvq4x9p/StuBb8E+9Czg7G/S6E9IF2SdwBGmXB6dtcog1rNquvUyNLOujw2UNn2uUyuIY0WPRUc0g==}
8985
9007
 
9008
+ zova-suite-a-zova@5.1.170:
9009
+ resolution: {integrity: sha512-Fi2uWD8waUkRsp6thq3lU2i2eByE/8e/VUe8mUDclco+FhRoVjIvCSqetLipX/PsbXNHu+WIJY5Dz6BgGyIkFg==}
9010
+
8986
9011
  zova@5.1.167:
8987
9012
  resolution: {integrity: sha512-A0vfiT2eXuKbKW1GxlZNnsZPuPvS/mAHfoaiBsN5Pf4GYOKE/7R9fJIbl9YQzNWkV3LP3vECygqBHg9q2qr9Bw==}
8988
9013
 
9014
+ zova@5.1.171:
9015
+ resolution: {integrity: sha512-aXywbs8vYGc/qarxWg/ukqnBGkYidVqwEUWj7CuaFqCrPD9l3MEllSlW6qhN1Bem2TDCIFc6L7bBjS0m6XCFZw==}
9016
+
8989
9017
  zwitch@1.0.5:
8990
9018
  resolution: {integrity: sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==}
8991
9019
 
@@ -15134,6 +15162,14 @@ snapshots:
15134
15162
  - '@vue/composition-api'
15135
15163
  - vue
15136
15164
 
15165
+ zova-module-a-form@5.1.54(vue@3.5.43(typescript@5.9.3)):
15166
+ dependencies:
15167
+ '@tanstack/vue-form': 1.33.5(vue@3.5.43(typescript@5.9.3))
15168
+ '@tanstack/vue-store': 0.11.1(vue@3.5.43(typescript@5.9.3))
15169
+ transitivePeerDependencies:
15170
+ - '@vue/composition-api'
15171
+ - vue
15172
+
15137
15173
  zova-module-a-icon@5.1.27: {}
15138
15174
 
15139
15175
  zova-module-a-interceptor@5.1.31: {}
@@ -15158,20 +15194,48 @@ snapshots:
15158
15194
  - '@vue/composition-api'
15159
15195
  - vue
15160
15196
 
15197
+ zova-module-a-model@5.1.38(vue@3.5.43(typescript@5.9.3)):
15198
+ dependencies:
15199
+ '@tanstack/query-core': 5.103.1
15200
+ '@tanstack/query-persist-client-core': 5.103.1
15201
+ '@tanstack/vue-query': 5.103.1(vue@3.5.43(typescript@5.9.3))
15202
+ localforage: 1.10.0
15203
+ mutate-on-copy: 1.1.13
15204
+ table-identity: link:packages-utils/table-identity
15205
+ transitivePeerDependencies:
15206
+ - '@vue/composition-api'
15207
+ - vue
15208
+
15161
15209
  zova-module-a-openapi@5.1.55:
15162
15210
  dependencies:
15163
15211
  '@cabloy/json-schema-to-zod': 2.6.5
15164
15212
  openapi3-ts: 4.6.1
15165
15213
  typestyle: 2.4.0
15166
15214
 
15215
+ zova-module-a-openapi@5.1.57:
15216
+ dependencies:
15217
+ '@cabloy/json-schema-to-zod': 2.6.5
15218
+ openapi3-ts: 4.6.1
15219
+ typestyle: 2.4.0
15220
+
15221
+ zova-module-a-openapi@file:../../../../../tmp/zova-module-a-openapi-5.1.56.tgz:
15222
+ dependencies:
15223
+ '@cabloy/json-schema-to-zod': 2.6.5
15224
+ openapi3-ts: 4.6.1
15225
+ typestyle: 2.4.0
15226
+
15167
15227
  zova-module-a-pay@5.0.9: {}
15168
15228
 
15169
15229
  zova-module-a-router@5.1.41: {}
15170
15230
 
15231
+ zova-module-a-router@5.1.42: {}
15232
+
15171
15233
  zova-module-a-routerstack@5.1.29: {}
15172
15234
 
15173
15235
  zova-module-a-routertabs@5.1.34: {}
15174
15236
 
15237
+ zova-module-a-routertabs@5.1.35: {}
15238
+
15175
15239
  zova-module-a-ssr@5.1.40:
15176
15240
  dependencies:
15177
15241
  devalue: 5.9.4
@@ -15225,6 +15289,8 @@ snapshots:
15225
15289
 
15226
15290
  zova-module-rest-resource@5.1.55: {}
15227
15291
 
15292
+ zova-module-rest-resource@5.1.56: {}
15293
+
15228
15294
  zova-suite-a-zova@5.1.166(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3)):
15229
15295
  dependencies:
15230
15296
  zova-module-a-api: 5.1.22
@@ -15258,6 +15324,39 @@ snapshots:
15258
15324
  - typescript
15259
15325
  - vue
15260
15326
 
15327
+ zova-suite-a-zova@5.1.170(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3)):
15328
+ dependencies:
15329
+ zova-module-a-api: 5.1.22
15330
+ zova-module-a-app: 5.1.26
15331
+ zova-module-a-bean: 5.1.36
15332
+ zova-module-a-behavior: 5.1.26
15333
+ zova-module-a-behaviors: 5.1.22
15334
+ zova-module-a-command: 5.1.35
15335
+ zova-module-a-fetch: 5.1.25
15336
+ zova-module-a-form: 5.1.54(vue@3.5.43(typescript@5.9.3))
15337
+ zova-module-a-icon: 5.1.27
15338
+ zova-module-a-interceptor: 5.1.31
15339
+ zova-module-a-logger: 5.1.28
15340
+ zova-module-a-meta: 5.1.22
15341
+ zova-module-a-model: 5.1.38(vue@3.5.43(typescript@5.9.3))
15342
+ zova-module-a-openapi: 5.1.57
15343
+ zova-module-a-router: 5.1.42
15344
+ zova-module-a-routerstack: 5.1.29
15345
+ zova-module-a-routertabs: 5.1.35
15346
+ zova-module-a-ssr: 5.1.40
15347
+ zova-module-a-ssrhmr: 5.1.23
15348
+ zova-module-a-ssrserver: 5.1.26
15349
+ zova-module-a-style: 5.1.35
15350
+ zova-module-a-table: 5.1.44(vue@3.5.43(typescript@5.9.3))
15351
+ zova-module-a-zod: 5.1.37
15352
+ zova-module-a-zova: 5.1.108(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3))
15353
+ transitivePeerDependencies:
15354
+ - '@vue/composition-api'
15355
+ - debug
15356
+ - supports-color
15357
+ - typescript
15358
+ - vue
15359
+
15261
15360
  zova@5.1.167(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3)):
15262
15361
  dependencies:
15263
15362
  zova-core: 5.1.92(patch_hash=144450bd7a567a6067e5857c0cf4c780981b7e90bc48745c09e1696a9b6f1b97)(typescript@5.9.3)
@@ -15269,6 +15368,17 @@ snapshots:
15269
15368
  - typescript
15270
15369
  - vue
15271
15370
 
15371
+ zova@5.1.171(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3)):
15372
+ dependencies:
15373
+ zova-core: 5.1.92(patch_hash=144450bd7a567a6067e5857c0cf4c780981b7e90bc48745c09e1696a9b6f1b97)(typescript@5.9.3)
15374
+ zova-suite-a-zova: 5.1.170(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3))
15375
+ transitivePeerDependencies:
15376
+ - '@vue/composition-api'
15377
+ - debug
15378
+ - supports-color
15379
+ - typescript
15380
+ - vue
15381
+
15272
15382
  zwitch@1.0.5: {}
15273
15383
 
15274
15384
  zwitch@2.0.4: {}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-module-a-printtip",
3
- "version": "5.1.13",
3
+ "version": "5.1.14",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "",
6
6
  "keywords": [
@@ -18,7 +18,7 @@ const __tipEnd = '=================== tip: end =====================';
18
18
  })
19
19
  export class StartupPrintTip extends BeanBase implements IStartupExecute {
20
20
  async execute() {
21
- if (this.app.meta.env.LOGGER_DUMMY === 'true') return;
21
+ if (process.env.VONA_DB_RESET === 'true' || this.app.meta.env.LOGGER_DUMMY === 'true') return;
22
22
  setTimeout(async () => {
23
23
  await this._print();
24
24
  }, this.scope.config.delay);
@@ -0,0 +1,46 @@
1
+ import assert from 'node:assert/strict';
2
+ import { describe, it } from 'node:test';
3
+
4
+ import { StartupPrintTip } from '../src/bean/startup.printTip.ts';
5
+
6
+ describe('development startup tips', { concurrency: false }, () => {
7
+ for (const { name, reset, dummy, expected } of [
8
+ { name: 'skips tips during db:reset', reset: 'true', dummy: undefined, expected: 0 },
9
+ {
10
+ name: 'prints tips during ordinary dev startup',
11
+ reset: undefined,
12
+ dummy: undefined,
13
+ expected: 1,
14
+ },
15
+ {
16
+ name: 'prints tips when reset is explicitly disabled',
17
+ reset: 'false',
18
+ dummy: undefined,
19
+ expected: 1,
20
+ },
21
+ { name: 'keeps dummy logger suppression', reset: undefined, dummy: 'true', expected: 0 },
22
+ ]) {
23
+ it(name, async t => {
24
+ const previousReset = process.env.VONA_DB_RESET;
25
+ t.mock.timers.enable({ apis: ['setTimeout'] });
26
+ try {
27
+ if (reset === undefined) delete process.env.VONA_DB_RESET;
28
+ else process.env.VONA_DB_RESET = reset;
29
+ const startup = Object.create(StartupPrintTip.prototype) as StartupPrintTip;
30
+ const print = t.mock.fn(async () => {});
31
+ Object.defineProperties(startup, {
32
+ app: { value: { meta: { env: { LOGGER_DUMMY: dummy } } } },
33
+ scope: { value: { config: { delay: 0 } } },
34
+ _print: { value: print },
35
+ });
36
+ await startup.execute();
37
+ assert.equal(print.mock.callCount(), 0);
38
+ t.mock.timers.runAll();
39
+ assert.equal(print.mock.callCount(), expected);
40
+ } finally {
41
+ if (previousReset === undefined) delete process.env.VONA_DB_RESET;
42
+ else process.env.VONA_DB_RESET = previousReset;
43
+ }
44
+ });
45
+ }
46
+ });
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-module-a-startup",
3
- "version": "5.1.19",
3
+ "version": "5.1.20",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "",
6
6
  "keywords": [
@@ -63,27 +63,24 @@ export class ServiceStartup extends BeanBase {
63
63
  const createdInstances = this.$scope.version.service.database.createdInstanceNames;
64
64
  const preparingDev = this.app.meta.isDev && createdInstances.length > 0;
65
65
  if (preparingDev) {
66
- // Initialize and seed fresh instances before listeners or queue workers start.
66
+ // Prepare each fresh instance before application-level after-startups.
67
67
  const instanceNames = [
68
68
  '',
69
69
  ...createdInstances.filter(name => name !== ''),
70
70
  ] as (keyof IInstanceRecord)[];
71
71
  for (const instanceName of instanceNames) {
72
- await this._appReadyInstanceStartup(instanceName, true, true);
73
- }
74
- for (const instanceName of instanceNames) {
75
- await this.bean.executor.newCtx(() => this.runStartupInstanceAfter(instanceName), {
76
- dbInfo: { level: 1 },
77
- instanceName,
78
- });
72
+ await this._appReadyInstanceStartup(instanceName, true);
79
73
  }
80
74
  }
81
75
 
82
- // run startups: after
83
- for (const startup of this._startups) {
84
- const startupOptions = startup.beanOptions.options;
85
- if (!startupOptions?.instance && startupOptions?.after === true) {
86
- await this.runStartup(startup.name, null);
76
+ // db:reset prepares data without starting runtime services.
77
+ if (!(this.app.meta.isDev && process.env.VONA_DB_RESET === 'true')) {
78
+ // run startups: after
79
+ for (const startup of this._startups) {
80
+ const startupOptions = startup.beanOptions.options;
81
+ if (!startupOptions?.instance && startupOptions?.after === true) {
82
+ await this.runStartup(startup.name, null);
83
+ }
87
84
  }
88
85
  }
89
86
 
@@ -118,17 +115,12 @@ export class ServiceStartup extends BeanBase {
118
115
  );
119
116
  }
120
117
 
121
- private async _appReadyInstanceStartup(
122
- instanceName: keyof IInstanceRecord,
123
- wait: boolean,
124
- deferAfter?: boolean,
125
- ) {
118
+ private async _appReadyInstanceStartup(instanceName: keyof IInstanceRecord, wait: boolean) {
126
119
  const res = this.$scope.instance.service.instance.instanceStartupIsolate(instanceName, {
127
120
  force:
128
121
  this.app.meta.isDev &&
129
122
  (process.env.VONA_DB_RESET === 'true' ||
130
123
  this.$scope.version.service.database.createdInstanceNames.includes(instanceName)),
131
- deferAfter,
132
124
  });
133
125
  if (wait) {
134
126
  await res;
@@ -218,10 +210,11 @@ export class ServiceStartup extends BeanBase {
218
210
  this.app.meta.isDev &&
219
211
  this.$scope.version.service.database.createdInstanceNames.includes(instanceName)
220
212
  ) {
221
- await this.$scope.version.service.version.__instanceSeed(instanceName);
213
+ if (instanceName === '') {
214
+ await this.$scope.version.service.version.__instanceSeed(instanceName);
215
+ }
222
216
  this.$scope.version.service.database.consumeCreatedInstance(instanceName);
223
217
  }
224
- if (options?.deferAfter) return;
225
218
  await this.runStartupInstanceAfter(instanceName, options);
226
219
  }
227
220
 
@@ -231,6 +224,8 @@ export class ServiceStartup extends BeanBase {
231
224
  ) {
232
225
  // set flag
233
226
  this.app.meta.appReadyInstances[instanceName] = true;
227
+ // Keep readiness checks from reentering initialization even when runtime startups are skipped.
228
+ if (this.app.meta.isDev && process.env.VONA_DB_RESET === 'true') return;
234
229
  // run startups: after
235
230
  for (const startup of this._startups) {
236
231
  const startupOptions = startup.beanOptions.options;
@@ -22,7 +22,6 @@ export interface IDecoratorStartupOptions
22
22
 
23
23
  export interface IInstanceStartupOptions {
24
24
  force?: boolean;
25
- deferAfter?: boolean;
26
25
  configInstanceBase?: ConfigInstanceBase;
27
26
  }
28
27