@nanobpm/urban 0.52.0 → 0.53.0

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 (54) hide show
  1. package/README.md +47 -20
  2. package/dist/runtime/core/events.d.ts +135 -0
  3. package/dist/runtime/core/events.js +329 -0
  4. package/dist/runtime/core/extensions.d.ts +131 -0
  5. package/dist/runtime/core/extensions.js +137 -0
  6. package/dist/runtime/core/glob.d.ts +7 -6
  7. package/dist/runtime/core/glob.js +16 -14
  8. package/dist/runtime/core/host.d.ts +4 -1
  9. package/dist/runtime/core/modules/agent.d.ts +17 -0
  10. package/dist/runtime/core/modules/agent.js +63 -0
  11. package/dist/runtime/core/modules/deploy.d.ts +8 -5
  12. package/dist/runtime/core/modules/deploy.js +62 -16
  13. package/dist/runtime/core/modules/pages.js +397 -20
  14. package/dist/runtime/core/modules/surfaces.js +8 -0
  15. package/dist/runtime/core/phase.d.ts +168 -0
  16. package/dist/runtime/core/phase.js +367 -0
  17. package/dist/runtime/core/runtime.d.ts +17 -0
  18. package/dist/runtime/core/runtime.js +30 -0
  19. package/dist/runtime/index.d.ts +6 -0
  20. package/dist/runtime/index.js +7 -0
  21. package/dist/toolkit/derivers/system-brief.d.ts +62 -0
  22. package/dist/toolkit/derivers/system-brief.js +156 -0
  23. package/dist/toolkit/gen.d.ts +5 -5
  24. package/dist/toolkit/gen.js +20 -14
  25. package/dist/toolkit/index.d.ts +5 -0
  26. package/dist/toolkit/index.js +3 -0
  27. package/dist/toolkit/models.d.ts +4 -3
  28. package/dist/toolkit/models.js +4 -3
  29. package/package.json +1 -1
  30. package/src/runtime/core/events.test.ts +382 -0
  31. package/src/runtime/core/events.ts +370 -0
  32. package/src/runtime/core/extensions.test.ts +378 -0
  33. package/src/runtime/core/extensions.ts +276 -0
  34. package/src/runtime/core/glob.ts +15 -12
  35. package/src/runtime/core/host.ts +4 -1
  36. package/src/runtime/core/modules/agent.test.ts +104 -0
  37. package/src/runtime/core/modules/agent.ts +76 -0
  38. package/src/runtime/core/modules/deploy.test.ts +84 -16
  39. package/src/runtime/core/modules/deploy.ts +59 -16
  40. package/src/runtime/core/modules/pages.test.ts +309 -5
  41. package/src/runtime/core/modules/pages.ts +398 -20
  42. package/src/runtime/core/modules/surfaces.ts +9 -0
  43. package/src/runtime/core/phase.test.ts +350 -0
  44. package/src/runtime/core/phase.ts +526 -0
  45. package/src/runtime/core/runtime.extensions.test.ts +151 -0
  46. package/src/runtime/core/runtime.ts +49 -0
  47. package/src/runtime/devserver.test.ts +3 -0
  48. package/src/runtime/index.ts +57 -0
  49. package/src/toolkit/derivers/system-brief.test.ts +150 -0
  50. package/src/toolkit/derivers/system-brief.ts +210 -0
  51. package/src/toolkit/gen.test.ts +28 -4
  52. package/src/toolkit/gen.ts +20 -13
  53. package/src/toolkit/index.ts +14 -0
  54. package/src/toolkit/models.ts +4 -3
@@ -12,6 +12,7 @@ import { deriveMeta } from "./derivers/meta.ts";
12
12
  import { deriveMessageBindings } from "./derivers/messages.ts";
13
13
  import { resolveShapes, scanModelShapes } from "./derivers/shapes.ts";
14
14
  import { deriveApi } from "./derivers/api.ts";
15
+ import { deriveSystemBrief } from "./derivers/system-brief.ts";
15
16
  import { parseSpec, sharedRequestBodySchemas } from "../openapi/spec.ts";
16
17
  import { deriveModels, type DerivedModels, type ModelError, MODEL_PROVENANCE } from "./models.ts";
17
18
 
@@ -106,31 +107,32 @@ export async function expandPattern(root: string, io: GenIO, pattern: string): P
106
107
  }
107
108
 
108
109
  /** The deploy-by-convention directory (ADR 0062): when the manifest declares no `models`, both the
109
- * runtime deploy and this codegen scan discover deployables/models under it — shallow, one level
110
- * deep (`resources/*` and `resources/<subdir>/*`). Deploy-only by convention. */
110
+ * runtime deploy and this codegen scan discover deployables/models under it — **recursively**,
111
+ * every file at any depth (issue #231). Deploy-only by convention. */
111
112
  export const RESOURCES_DIR = "resources";
112
113
 
113
114
  /** Model file extensions the `nano:shape`/code-first scan reads by convention (BPMN + DMN). */
114
115
  const MODEL_EXTS = [".bpmn", ".dmn"];
115
116
 
116
117
  /**
117
- * Discover model files under `resources/` by convention — shallow, one level deep (`resources/*`
118
- * and `resources/<subdir>/*`), never deeper — mirroring the runtime deploy walk so the codegen scan
119
- * and the deploy see the same set. Returns root-relative paths, sorted. Descending one level needs
118
+ * Discover model files under `resources/` by convention — **recursively**, every `.bpmn`/`.dmn`
119
+ * under `resources/` at any depth (issue #231) — mirroring the runtime deploy walk so the codegen
120
+ * scan and the deploy see the same set. Returns root-relative paths, sorted. Descending needs
120
121
  * `io.listSubdirs`; without it only the files directly under `resources/` are scanned.
121
122
  */
122
123
  export async function discoverResourceModels(root: string, io: GenIO): Promise<string[]> {
123
124
  const isModel = (n: string): boolean => MODEL_EXTS.some((e) => n.endsWith(e));
124
125
  const out: string[] = [];
125
- for (const n of await io.listDir(join(root, RESOURCES_DIR))) {
126
- if (isModel(n)) out.push(`${RESOURCES_DIR}/${n}`);
127
- }
128
- const subdirs = io.listSubdirs ? await io.listSubdirs(join(root, RESOURCES_DIR)) : [];
129
- for (const sub of subdirs.slice().sort()) {
130
- for (const n of await io.listDir(join(root, `${RESOURCES_DIR}/${sub}`))) {
131
- if (isModel(n)) out.push(`${RESOURCES_DIR}/${sub}/${n}`);
126
+ const walk = async (rel: string): Promise<void> => {
127
+ for (const n of await io.listDir(join(root, rel))) {
128
+ if (isModel(n)) out.push(`${rel}/${n}`);
132
129
  }
133
- }
130
+ const subdirs = io.listSubdirs ? await io.listSubdirs(join(root, rel)) : [];
131
+ for (const sub of subdirs.slice().sort()) {
132
+ await walk(`${rel}/${sub}`);
133
+ }
134
+ };
135
+ await walk(RESOURCES_DIR);
134
136
  return out.sort();
135
137
  }
136
138
 
@@ -233,6 +235,11 @@ async function collectAll(opts: GenOptions): Promise<{ artifacts: DerivedArtifac
233
235
  artifacts.push(...deriveWorkerBindings(models, declaredTypeIds));
234
236
  artifacts.push(...deriveMeta(models));
235
237
  artifacts.push(...deriveMessageBindings(models, declaredTypeIds));
238
+ // Institutional-memory brief (ADR 0060): fold the same scanned model structure into the
239
+ // app's agent/human-readable system brief. Flows through `artifacts` like its siblings, so
240
+ // the `nano-generated/` stale sweep and the `urban gen --check` drift gate own the two new
241
+ // artifacts (system-brief.md / .json) with no extra bookkeeping.
242
+ artifacts.push(...deriveSystemBrief(models, manifest.id));
236
243
  // Surface genuine data-envelope conflicts: a taskType whose variants disagree on a field's
237
244
  // TYPE. The emitted contract is the union of the variants (sound for a shared handler), so a
238
245
  // type clash would silently widen to `A | B` — warn instead so the author unifies the envelope.
@@ -110,6 +110,18 @@ export {
110
110
  API_CONTROLLER_TS,
111
111
  } from "./derivers/api.ts";
112
112
 
113
+ export {
114
+ buildSystemBrief,
115
+ deriveSystemBrief,
116
+ emitSystemBriefMd,
117
+ foldOwnership,
118
+ scanModelDecisions,
119
+ systemBriefDeriver,
120
+ SYSTEM_BRIEF_JSON,
121
+ SYSTEM_BRIEF_MD,
122
+ } from "./derivers/system-brief.ts";
123
+ export type { DecisionRef, Ownership, SystemBrief } from "./derivers/system-brief.ts";
124
+
113
125
  // The OpenAPI machinery the deriver + runtime share (ADR 0058).
114
126
  export {
115
127
  collectOperations,
@@ -139,6 +151,7 @@ import { workerIoDeriver } from "./derivers/worker-io.ts";
139
151
  import { metaDeriver } from "./derivers/meta.ts";
140
152
  import { messagesDeriver } from "./derivers/messages.ts";
141
153
  import { apiDeriver } from "./derivers/api.ts";
154
+ import { systemBriefDeriver } from "./derivers/system-brief.ts";
142
155
  export const DERIVERS = [
143
156
  migrationsDeriver,
144
157
  domainDeriver,
@@ -146,6 +159,7 @@ export const DERIVERS = [
146
159
  metaDeriver,
147
160
  messagesDeriver,
148
161
  apiDeriver,
162
+ systemBriefDeriver,
149
163
  ] as const;
150
164
 
151
165
  // Gen orchestrator + IO
@@ -21,9 +21,10 @@ import { isRecord } from "../runtime/core/guards.ts";
21
21
  export const DEFAULT_WORKFLOW_PATTERNS = ["workflows/*.ts"];
22
22
 
23
23
  /** Default output dir for derived models when the manifest declares no `models.processes`: under
24
- * the deploy-by-convention `resources/` tree (ADR 0062), one level deep, so a derived model lands
25
- * exactly where the convention deploy + codegen scan look for it. When `models.processes` IS set,
26
- * `processesOutDir` derives the dir from that glob instead (the model-first override). */
24
+ * the deploy-by-convention `resources/` tree (ADR 0062), so a derived model lands where the
25
+ * convention deploy + codegen scan (which walk `resources/` recursively) look for it. When
26
+ * `models.processes` IS set, `processesOutDir` derives the dir from that glob instead (the
27
+ * model-first override). */
27
28
  export const PROCESSES_DIR = "resources/processes";
28
29
 
29
30
  /** Marker stamped into every derived `.bpmn` (an XML comment) so re-gen overwrites and the