@toolproof-core/schema 1.0.0 → 1.0.2

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 (83) hide show
  1. package/dist/generated/types/standalone/Resource_Genesis.d.ts +3 -0
  2. package/dist/generated/types/standalone/Resource_Job.d.ts +3 -0
  3. package/dist/generated/types/standalone/Resource_RawStrategy.d.ts +3 -0
  4. package/dist/generated/types/standalone/Resource_ResourceType.d.ts +3 -0
  5. package/dist/generated/types/standalone/Resource_RunnableStrategy.d.ts +3 -0
  6. package/dist/generated/types/types.d.ts +487 -548
  7. package/dist/scripts/_lib/config.d.ts +12 -6
  8. package/dist/scripts/_lib/config.js +33 -15
  9. package/dist/scripts/{extractSchemas.js → extractSchemasFromResourceTypeShells.js} +14 -27
  10. package/dist/scripts/generateDependencies.js +2 -2
  11. package/dist/scripts/generateSchemaShims.js +22 -4
  12. package/dist/scripts/{extractSubSchemaWithDefs.js → generateStandaloneSchema.js} +12 -34
  13. package/dist/scripts/{generateResourceTypeType.js → generateStandaloneType.js} +23 -14
  14. package/dist/scripts/generateTypes.js +1 -1
  15. package/dist/scripts/{rewriteAnchors.js → normalizeAnchorsToPointers.js} +2 -2
  16. package/dist/scripts/{generateResourceShells.js → wrapResourceTypesWithResourceShells.js} +12 -34
  17. package/package.json +15 -14
  18. package/src/Genesis.json +1999 -2042
  19. package/src/generated/{dependencies.json → dependencyMap.json} +207 -214
  20. package/src/generated/{resourceTypes → normalized}/Genesis.json +44 -87
  21. package/src/generated/resources/Genesis.json +415 -478
  22. package/src/generated/schemas/Genesis.json +1026 -1057
  23. package/src/generated/schemas/{Goal.json → standalone/Goal.json} +34 -34
  24. package/src/generated/schemas/{Job.json → standalone/Job.json} +85 -85
  25. package/src/generated/schemas/{RawStrategy.json → standalone/RawStrategy.json} +238 -263
  26. package/src/generated/schemas/{ResourceType.json → standalone/ResourceType.json} +60 -60
  27. package/src/generated/schemas/{RunnableStrategy.json → standalone/RunnableStrategy.json} +296 -321
  28. package/src/generated/schemas/{StrategyRun.json → standalone/StrategyRun.json} +390 -421
  29. package/src/generated/types/standalone/Resource_Genesis.d.ts +3 -0
  30. package/src/generated/types/standalone/Resource_Genesis.js +1 -0
  31. package/src/generated/types/standalone/Resource_Job.d.ts +3 -0
  32. package/src/generated/types/standalone/Resource_Job.js +1 -0
  33. package/src/generated/types/standalone/Resource_RawStrategy.d.ts +3 -0
  34. package/src/generated/types/standalone/Resource_RawStrategy.js +1 -0
  35. package/src/generated/types/standalone/Resource_ResourceType.d.ts +3 -0
  36. package/src/generated/types/standalone/Resource_ResourceType.js +1 -0
  37. package/src/generated/types/standalone/Resource_RunnableStrategy.d.ts +3 -0
  38. package/src/generated/types/standalone/Resource_RunnableStrategy.js +1 -0
  39. package/src/generated/types/types.d.ts +487 -548
  40. package/src/generated/types/types.js +1 -1
  41. package/src/scripts/_lib/config.ts +205 -181
  42. package/src/scripts/extractSchemasFromResourceTypeShells.ts +218 -0
  43. package/src/scripts/generateDependencies.ts +120 -120
  44. package/src/scripts/generateSchemaShims.ts +135 -115
  45. package/src/scripts/{extractSubSchemaWithDefs.ts → generateStandaloneSchema.ts} +175 -196
  46. package/src/scripts/{generateResourceTypeType.ts → generateStandaloneType.ts} +119 -110
  47. package/src/scripts/generateTypes.ts +614 -614
  48. package/src/scripts/{rewriteAnchors.ts → normalizeAnchorsToPointers.ts} +123 -123
  49. package/src/scripts/{generateResourceShells.ts → wrapResourceTypesWithResourceShells.ts} +84 -105
  50. package/dist/generated/types/Resource_Genesis.d.ts +0 -3
  51. package/dist/generated/types/Resource_Job.d.ts +0 -3
  52. package/dist/generated/types/Resource_RawStrategy.d.ts +0 -3
  53. package/dist/generated/types/Resource_ResourceType.d.ts +0 -3
  54. package/dist/generated/types/Resource_RunnableStrategy.d.ts +0 -3
  55. package/src/Roadmap.json +0 -102
  56. package/src/generated/types/Resource_Genesis.d.ts +0 -3
  57. package/src/generated/types/Resource_Genesis.js +0 -1
  58. package/src/generated/types/Resource_Job.d.ts +0 -3
  59. package/src/generated/types/Resource_Job.js +0 -1
  60. package/src/generated/types/Resource_RawStrategy.d.ts +0 -3
  61. package/src/generated/types/Resource_RawStrategy.js +0 -1
  62. package/src/generated/types/Resource_ResourceType.d.ts +0 -3
  63. package/src/generated/types/Resource_ResourceType.js +0 -1
  64. package/src/generated/types/Resource_RunnableStrategy.d.ts +0 -3
  65. package/src/generated/types/Resource_RunnableStrategy.js +0 -1
  66. package/src/scripts/extractSchemas.ts +0 -229
  67. /package/dist/generated/types/{Resource_Genesis.js → standalone/Resource_Genesis.js} +0 -0
  68. /package/dist/generated/types/{Resource_Job.js → standalone/Resource_Job.js} +0 -0
  69. /package/dist/generated/types/{Resource_RawStrategy.js → standalone/Resource_RawStrategy.js} +0 -0
  70. /package/dist/generated/types/{Resource_ResourceType.js → standalone/Resource_ResourceType.js} +0 -0
  71. /package/dist/generated/types/{Resource_RunnableStrategy.js → standalone/Resource_RunnableStrategy.js} +0 -0
  72. /package/dist/scripts/{extractSchemas.d.ts → extractSchemasFromResourceTypeShells.d.ts} +0 -0
  73. /package/dist/scripts/{extractSubSchemaWithDefs.d.ts → generateStandaloneSchema.d.ts} +0 -0
  74. /package/dist/scripts/{generateResourceShells.d.ts → generateStandaloneType.d.ts} +0 -0
  75. /package/dist/scripts/{generateResourceTypeType.d.ts → normalizeAnchorsToPointers.d.ts} +0 -0
  76. /package/dist/scripts/{rewriteAnchors.d.ts → wrapResourceTypesWithResourceShells.d.ts} +0 -0
  77. /package/src/generated/{resourceTypes → normalized}/Genesis.ts +0 -0
  78. /package/src/generated/schemas/{Goal.ts → standalone/Goal.ts} +0 -0
  79. /package/src/generated/schemas/{Job.ts → standalone/Job.ts} +0 -0
  80. /package/src/generated/schemas/{RawStrategy.ts → standalone/RawStrategy.ts} +0 -0
  81. /package/src/generated/schemas/{ResourceType.ts → standalone/ResourceType.ts} +0 -0
  82. /package/src/generated/schemas/{RunnableStrategy.ts → standalone/RunnableStrategy.ts} +0 -0
  83. /package/src/generated/schemas/{StrategyRun.ts → standalone/StrategyRun.ts} +0 -0
@@ -11,11 +11,11 @@ export declare class SchemaConfig {
11
11
  private readonly sourceDir;
12
12
  private readonly sourceFile;
13
13
  private readonly normalizedDir;
14
- private readonly outputDir;
14
+ private readonly schemasDir;
15
+ private readonly resourcesDir;
16
+ private readonly dependencyMapPath;
15
17
  private readonly typesSrcDir;
16
18
  private readonly typesDistDir;
17
- private readonly generatedResourcesDir;
18
- private readonly dependencyMapPath;
19
19
  private readonly baseUrl;
20
20
  private readonly version;
21
21
  constructor();
@@ -26,13 +26,19 @@ export declare class SchemaConfig {
26
26
  getNormalizedDir(): string;
27
27
  getNormalizedSourceFile(): string;
28
28
  getNormalizedSourcePath(): string;
29
- getOutputDir(): string;
30
- getOutputPath(filename: string): string;
29
+ getSchemasDir(): string;
30
+ getSchemaPath(filename: string): string;
31
+ getSchemasStandaloneDir(): string;
32
+ getSchemaStandalonePath(filename: string): string;
31
33
  getTypesSrcDir(): string;
32
34
  getTypesDistDir(): string;
33
35
  getTypesSrcPath(filename: string): string;
34
36
  getTypesDistPath(filename: string): string;
35
- getGeneratedResourcesDir(): string;
37
+ getTypesStandaloneSrcDir(): string;
38
+ getTypesStandaloneDistDir(): string;
39
+ getTypesStandaloneSrcPath(filename: string): string;
40
+ getTypesStandaloneDistPath(filename: string): string;
41
+ getResourcesDir(): string;
36
42
  getDependencyMapPath(): string;
37
43
  getBaseUrl(): string;
38
44
  getVersion(): string;
@@ -20,14 +20,14 @@ export class SchemaConfig {
20
20
  this.root = getEnv('TP_SCHEMA_ROOT', process.cwd());
21
21
  this.sourceDir = getEnv('TP_SCHEMA_SOURCE_DIR', 'src/');
22
22
  this.sourceFile = getEnv('TP_SCHEMA_SOURCE_FILE', 'Genesis.json');
23
- // Intermediate, generated artifact produced by rewriteAnchors.
23
+ // Intermediate, generated artifact produced by normalizeAnchorsToPointers.
24
24
  // This should NOT live next to the source-of-truth schemas.
25
- this.normalizedDir = getEnv('TP_SCHEMA_NORMALIZED_DIR', 'src/generated/resourceTypes');
26
- this.outputDir = getEnv('TP_SCHEMA_OUTPUT_DIR', 'src/generated/schemas');
25
+ this.normalizedDir = getEnv('TP_SCHEMA_NORMALIZED_DIR', 'src/generated/normalized');
26
+ this.schemasDir = getEnv('TP_SCHEMA_SCHEMAS_DIR', 'src/generated/schemas');
27
+ this.resourcesDir = getEnv('TP_SCHEMA_RESOURCES_DIR', 'src/generated/resources');
28
+ this.dependencyMapPath = getEnv('TP_SCHEMA_DEPENDENCY_MAP_PATH', 'src/generated/dependencyMap.json');
27
29
  this.typesSrcDir = getEnv('TP_SCHEMA_TYPES_SRC_DIR', 'src/generated/types');
28
30
  this.typesDistDir = getEnv('TP_SCHEMA_TYPES_DIST_DIR', 'dist/generated/types');
29
- this.generatedResourcesDir = getEnv('TP_SCHEMA_RESOURCES_DIR', 'src/generated/resources');
30
- this.dependencyMapPath = getEnv('TP_SCHEMA_DEPENDENCY_MAP_PATH', 'src/generated/dependencies.json');
31
31
  this.baseUrl = getEnv('TP_SCHEMA_BASE_URL', 'https://schemas.toolproof.com');
32
32
  this.version = getEnv('TP_SCHEMA_VERSION', 'v0');
33
33
  }
@@ -60,13 +60,19 @@ export class SchemaConfig {
60
60
  getNormalizedSourcePath() {
61
61
  return path.join(this.getNormalizedDir(), this.getNormalizedSourceFile());
62
62
  }
63
- getOutputDir() {
64
- return path.isAbsolute(this.outputDir)
65
- ? this.outputDir
66
- : path.join(this.root, this.outputDir);
63
+ getSchemasDir() {
64
+ return path.isAbsolute(this.schemasDir)
65
+ ? this.schemasDir
66
+ : path.join(this.root, this.schemasDir);
67
67
  }
68
- getOutputPath(filename) {
69
- return path.join(this.getOutputDir(), filename);
68
+ getSchemaPath(filename) {
69
+ return path.join(this.getSchemasDir(), filename);
70
+ }
71
+ getSchemasStandaloneDir() {
72
+ return path.join(this.getSchemasDir(), 'standalone');
73
+ }
74
+ getSchemaStandalonePath(filename) {
75
+ return path.join(this.getSchemasStandaloneDir(), filename);
70
76
  }
71
77
  getTypesSrcDir() {
72
78
  return path.isAbsolute(this.typesSrcDir)
@@ -84,10 +90,22 @@ export class SchemaConfig {
84
90
  getTypesDistPath(filename) {
85
91
  return path.join(this.getTypesDistDir(), filename);
86
92
  }
87
- getGeneratedResourcesDir() {
88
- return path.isAbsolute(this.generatedResourcesDir)
89
- ? this.generatedResourcesDir
90
- : path.join(this.root, this.generatedResourcesDir);
93
+ getTypesStandaloneSrcDir() {
94
+ return path.join(this.getTypesSrcDir(), 'standalone');
95
+ }
96
+ getTypesStandaloneDistDir() {
97
+ return path.join(this.getTypesDistDir(), 'standalone');
98
+ }
99
+ getTypesStandaloneSrcPath(filename) {
100
+ return path.join(this.getTypesStandaloneSrcDir(), filename);
101
+ }
102
+ getTypesStandaloneDistPath(filename) {
103
+ return path.join(this.getTypesStandaloneDistDir(), filename);
104
+ }
105
+ getResourcesDir() {
106
+ return path.isAbsolute(this.resourcesDir)
107
+ ? this.resourcesDir
108
+ : path.join(this.root, this.resourcesDir);
91
109
  }
92
110
  getDependencyMapPath() {
93
111
  return path.isAbsolute(this.dependencyMapPath)
@@ -29,7 +29,7 @@ function parseArgs() {
29
29
  inPath = config.getNormalizedSourcePath();
30
30
  }
31
31
  if (!outPath) {
32
- outPath = config.getOutputPath(config.getSourceFile());
32
+ outPath = config.getSchemaPath(config.getSourceFile());
33
33
  }
34
34
  if (!topLevelId) {
35
35
  topLevelId = config.getSchemaId('Genesis');
@@ -60,10 +60,11 @@ function parseArgs() {
60
60
  }
61
61
  return { inPath, outPath, topLevelId };
62
62
  }
63
- // Heuristic: determine if a node is a Type envelope
64
- function isTypeEnvelope(node) {
63
+ // ATTENTION: we don't want heuristic behavior.
64
+ // Heuristic: determine if a node is a Type shell
65
+ function isTypeShell(node) {
65
66
  return (node && typeof node === "object" && !Array.isArray(node) &&
66
- // Treat any object that has an 'nucleusSchema' AND 'identity' as a Type envelope
67
+ // Treat any object that has an 'nucleusSchema' AND 'identity' as a Type shell
67
68
  // This prevents false positives where 'nucleusSchema' is just a regular schema property
68
69
  node.nucleusSchema && typeof node.nucleusSchema === "object" &&
69
70
  node.identity && typeof node.identity === "string");
@@ -91,7 +92,7 @@ function mergeDefs(target, source, label) {
91
92
  }
92
93
  }
93
94
  }
94
- // Deeply traverse an object replacing any Type envelope with its nucleusSchema,
95
+ // Deeply traverse an object replacing any Type shell with its nucleusSchema,
95
96
  // and hoist its inner $defs to topDefs. Prevent infinite recursion with a visited set.
96
97
  function unwrapTypes(node, topDefs, labelPath = [], visited = new Set()) {
97
98
  if (node && typeof node === "object") {
@@ -99,12 +100,12 @@ function unwrapTypes(node, topDefs, labelPath = [], visited = new Set()) {
99
100
  return node; // avoid cycles
100
101
  visited.add(node);
101
102
  }
102
- if (isTypeEnvelope(node)) {
103
+ if (isTypeShell(node)) {
103
104
  const env = node;
104
105
  const inner = env.nucleusSchema;
105
106
  // Hoist inner $defs before stripping
106
107
  mergeDefs(topDefs, inner, labelPath.join("_"));
107
- // Return the inner schema itself, after also unwrapping any nested envelopes it may contain
108
+ // Return the inner schema itself, after also unwrapping any nested shells it may contain
108
109
  const unwrappedInner = unwrapTypes(inner, topDefs, labelPath.concat([String(env.identity || "env")]), visited);
109
110
  return unwrappedInner;
110
111
  }
@@ -115,7 +116,7 @@ function unwrapTypes(node, topDefs, labelPath = [], visited = new Set()) {
115
116
  const out = {};
116
117
  for (const [k, v] of Object.entries(node)) {
117
118
  if (k === "$defs" && v && typeof v === "object" && !Array.isArray(v)) {
118
- // Process nested $defs: unwrap each entry value if it's a Type envelope
119
+ // Process nested $defs: unwrap each entry value if it's a Type shell
119
120
  const defsOut = {};
120
121
  for (const [dk, dv] of Object.entries(v)) {
121
122
  const unwrapped = unwrapTypes(dv, topDefs, labelPath.concat(["$defs", dk]), visited);
@@ -140,10 +141,11 @@ function extractSchemaLogic(doc, topLevelId) {
140
141
  throw new Error("Input must be a Type JSON with an nucleusSchema at the top level");
141
142
  }
142
143
  const topSchema = doc.nucleusSchema;
144
+ // Collect $defs so that any '#/$defs/...' pointers can be resolved from the root.
143
145
  const outDefs = {};
144
146
  // Seed with top-level $defs (if any) before unwrapping
145
147
  mergeDefs(outDefs, topSchema, "top");
146
- // Unwrap the entire top schema tree so that any nested Type envelopes become raw schemas
148
+ // Unwrap the entire top schema tree so that any nested Type shells become raw schemas
147
149
  const flattened = unwrapTypes(topSchema, outDefs, ["nucleusSchema"]);
148
150
  // Assemble output: force $schema, optionally set $id, hoist collected $defs
149
151
  let base;
@@ -166,7 +168,7 @@ function extractSchemaLogic(doc, topLevelId) {
166
168
  if (!output.$id) {
167
169
  throw new Error("Flattened schema must define $id. Provide it via CLI --id or include $id in the source nucleusSchema.");
168
170
  }
169
- // Merge collected defs into output.$defs, taking care not to clobber any existing
171
+ // Hoist collected defs into output.$defs, taking care not to clobber any existing
170
172
  if (!("$defs" in output))
171
173
  output.$defs = {};
172
174
  const finalDefs = output.$defs || {};
@@ -175,8 +177,8 @@ function extractSchemaLogic(doc, topLevelId) {
175
177
  finalDefs[k] = v;
176
178
  }
177
179
  output.$defs = finalDefs;
178
- // Ensure a stable order for readability
179
- return orderKeys(output, ["$id", "$schema", "$vocabulary", "$defs", "title", "description", "type", "allOf", "anyOf", "oneOf", "not", "if", "then", "else", "properties", "required", "additionalProperties", "unevaluatedProperties"]);
180
+ // Preserve natural key ordering (do not reorder for readability)
181
+ return output;
180
182
  }
181
183
  function main() {
182
184
  const { inPath, outPath, topLevelId } = parseArgs();
@@ -192,19 +194,4 @@ function main() {
192
194
  fs.writeFileSync(outPath, JSON.stringify(ordered, null, 4), "utf8");
193
195
  console.log(`Wrote flattened schema to ${outPath}`);
194
196
  }
195
- function orderKeys(obj, preferred) {
196
- if (Array.isArray(obj))
197
- return obj.map((v) => orderKeys(v, preferred));
198
- if (!obj || typeof obj !== "object")
199
- return obj;
200
- const keys = Object.keys(obj);
201
- const sorted = [
202
- ...preferred.filter((k) => keys.includes(k)),
203
- ...keys.filter((k) => !preferred.includes(k)).sort()
204
- ];
205
- const out = {};
206
- for (const k of sorted)
207
- out[k] = orderKeys(obj[k], preferred);
208
- return out;
209
- }
210
197
  main();
@@ -81,10 +81,10 @@ function generateDependencyMapLogic(doc) {
81
81
  }
82
82
  async function main() {
83
83
  const config = getConfig();
84
- const inPath = config.getOutputPath("Genesis.json");
84
+ const inPath = config.getSchemaPath("Genesis.json");
85
85
  const outPath = config.getDependencyMapPath();
86
86
  if (!fs.existsSync(inPath)) {
87
- console.error(`Genesis schema not found at ${inPath}. Run extractSchemas first.`);
87
+ console.error(`Genesis schema not found at ${inPath}. Run extractSchemasFromResourceTypeShells first.`);
88
88
  process.exit(1);
89
89
  }
90
90
  try {
@@ -9,8 +9,9 @@ import { getConfig } from './_lib/config.js';
9
9
  * and type inference when importing schemas in TypeScript.
10
10
  *
11
11
  * Generates shims for:
12
- * - src/genesis/generated/schemas/*.json (schema files)
13
- * - src/genesis/generated/resources/*.json (resource envelope files)
12
+ * - schemas dir: config.getSchemasDir() (schema files)
13
+ * - standalone schemas dir: config.getSchemasStandaloneDir() (standalone schema files)
14
+ * - resources dir: config.getResourcesDir() (resource envelope files)
14
15
  *
15
16
  * Usage: node ./dist/scripts/generateSchemaShims.js
16
17
  */
@@ -42,8 +43,9 @@ function getShimsForFiles(jsonFiles, variableName) {
42
43
  }
43
44
  async function main() {
44
45
  const config = getConfig();
45
- const schemasDir = config.getOutputDir();
46
- const resourcesDir = config.getGeneratedResourcesDir();
46
+ const schemasDir = config.getSchemasDir();
47
+ const standaloneSchemasDir = config.getSchemasStandaloneDir();
48
+ const resourcesDir = config.getResourcesDir();
47
49
  const generatedResourceTypesDir = config.getNormalizedDir();
48
50
  let totalCount = 0;
49
51
  // Process schemas directory
@@ -62,6 +64,22 @@ async function main() {
62
64
  else {
63
65
  console.warn(`Schemas directory not found at ${schemasDir}`);
64
66
  }
67
+ // Process standalone schemas directory
68
+ if (fs.existsSync(standaloneSchemasDir)) {
69
+ const files = fs.readdirSync(standaloneSchemasDir);
70
+ const jsonFiles = files.filter(f => f.endsWith('.json') && !f.startsWith('.'));
71
+ const shims = getShimsForFiles(jsonFiles, 'schema');
72
+ for (const [tsFile, content] of Object.entries(shims)) {
73
+ const tsPath = path.join(standaloneSchemasDir, tsFile);
74
+ fs.writeFileSync(tsPath, content, 'utf-8');
75
+ console.log(`Generated ${tsFile} in ${standaloneSchemasDir}`);
76
+ totalCount++;
77
+ }
78
+ console.log(`Generated ${jsonFiles.length} TypeScript standalone schema shims in ${standaloneSchemasDir}`);
79
+ }
80
+ else {
81
+ // Standalone schemas are optional
82
+ }
65
83
  // Process resources directory
66
84
  if (fs.existsSync(resourcesDir)) {
67
85
  const files = fs.readdirSync(resourcesDir);
@@ -2,26 +2,17 @@ import fs from 'fs';
2
2
  import path from 'path';
3
3
  import { getConfig } from './_lib/config.js';
4
4
  /**
5
- * Generic extractor: given a subschema name that exists under Genesis.json $defs,
6
- * produce a standalone JSON Schema file that contains that subschema plus an inner $defs
7
- * object holding all direct & transitive local $defs dependencies (by #/$defs/... $ref).
8
- *
9
- * Genesis.json itself is left unchanged.
5
+ * Create a standalone JSON Schema for a single $defs entry under Genesis.json,
6
+ * embedding all direct & transitive local $defs dependencies.
10
7
  *
11
8
  * Usage:
12
- * node ./dist/scripts/extractSubschemaWithDefs.js --name <DefName>
13
- *
14
- * Writes: src/genesis/generated/schemas/<DefName>.json
9
+ * node ./dist/scripts/generateStandaloneSchema.js --name <DefName>
15
10
  */
16
11
  /**
17
- * Pure function to extract a subschema and its dependencies from a genesis object.
12
+ * Pure function to extract a subschema and its dependencies from a flattened genesis schema.
18
13
  * Performs no I/O operations.
19
- *
20
- * @param genesis The root Genesis schema object
21
- * @param name The name of the definition to extract
22
- * @returns The standalone subschema
23
14
  */
24
- function extractSubSchemaLogic(genesis, name) {
15
+ function extractStandaloneSubschemaLogic(genesis, name) {
25
16
  const rootDefs = genesis.$defs;
26
17
  if (!rootDefs || typeof rootDefs !== 'object') {
27
18
  throw new Error('No $defs object found in Genesis.json');
@@ -30,13 +21,10 @@ function extractSubSchemaLogic(genesis, name) {
30
21
  if (!target) {
31
22
  throw new Error(`Subschema named '${name}' not found under $defs in Genesis.json`);
32
23
  }
33
- // Collect transitive local $defs names referenced by target
34
24
  const needed = collectLocalDefClosure(target, rootDefs);
35
- // Build output schema: clone target and attach collected subset as $defs
36
25
  const targetClone = deepClone(target);
37
26
  const defsOut = {};
38
27
  for (const defName of needed) {
39
- // Avoid including the target itself inside its own $defs (mirrors previous pattern)
40
28
  if (defName === name)
41
29
  continue;
42
30
  const defSchema = rootDefs[defName];
@@ -46,7 +34,6 @@ function extractSubSchemaLogic(genesis, name) {
46
34
  }
47
35
  defsOut[defName] = deepClone(defSchema);
48
36
  }
49
- // Merge any pre-existing inner $defs of targetClone (if present) giving precedence to collected ones
50
37
  const existingInner = isObject(targetClone.$defs) ? targetClone.$defs : {};
51
38
  targetClone.$defs = { ...existingInner, ...defsOut };
52
39
  return targetClone;
@@ -58,29 +45,26 @@ async function main() {
58
45
  console.error('Missing --name <DefName> argument');
59
46
  process.exit(1);
60
47
  }
61
- const schemasDir = config.getOutputDir();
48
+ const schemasDir = config.getSchemasDir();
62
49
  const genesisPath = path.join(schemasDir, config.getSourceFile());
63
- const outPath = config.getOutputPath(`${name}.json`);
50
+ const outPath = config.getSchemaStandalonePath(`${name}.json`);
64
51
  if (!fs.existsSync(genesisPath)) {
65
- console.error(`Genesis.json not found at ${genesisPath}`);
52
+ console.error(`Genesis.json not found at ${genesisPath}. Run extractSchemasFromResourceTypeShells first.`);
66
53
  process.exit(1);
67
54
  }
68
55
  const raw = fs.readFileSync(genesisPath, 'utf-8');
69
56
  const genesis = JSON.parse(raw);
70
57
  try {
71
- // Call the pure logic function
72
- const result = extractSubSchemaLogic(genesis, name);
73
- // I/O: Write the result
58
+ const result = extractStandaloneSubschemaLogic(genesis, name);
74
59
  fs.mkdirSync(path.dirname(outPath), { recursive: true });
75
60
  fs.writeFileSync(outPath, JSON.stringify(result, null, 2) + '\n');
76
- console.log(`Extracted subschema '${name}' -> ${outPath}`);
61
+ console.log(`Created standalone subschema '${name}' -> ${outPath}`);
77
62
  }
78
63
  catch (error) {
79
64
  console.error(error.message);
80
65
  process.exit(1);
81
66
  }
82
67
  }
83
- // ---- Helpers ----
84
68
  function parseArgs(args) {
85
69
  let name;
86
70
  for (let i = 0; i < args.length; i++) {
@@ -110,26 +94,22 @@ function deepClone(v) {
110
94
  return v;
111
95
  }
112
96
  function extractPointerDefName(ref) {
113
- // Accept refs like '#/$defs/Name' only (single-level under $defs)
114
97
  if (!ref || !ref.startsWith('#/'))
115
98
  return null;
116
- const parts = ref.slice(2).split('/'); // remove '#/'
99
+ const parts = ref.slice(2).split('/');
117
100
  if (parts.length !== 2)
118
101
  return null;
119
102
  if (parts[0] !== '$defs')
120
103
  return null;
121
- // Decode JSON Pointer tokens for the def name
122
104
  const name = parts[1].replace(/~1/g, '/').replace(/~0/g, '~');
123
105
  return name;
124
106
  }
125
107
  function resolveRefToDefName(ref, rootDefs) {
126
108
  if (!ref)
127
109
  return null;
128
- // Case 1: JSON Pointer into $defs: '#/$defs/Name'
129
110
  const byPointer = extractPointerDefName(ref);
130
111
  if (byPointer)
131
112
  return byPointer;
132
- // Case 2: Anchor ref: '#Name' -> find a def whose nucleusSchema.$anchor equals 'Name'
133
113
  if (ref.startsWith('#') && !ref.startsWith('#/')) {
134
114
  const anchor = ref.slice(1);
135
115
  if (!anchor)
@@ -137,8 +117,6 @@ function resolveRefToDefName(ref, rootDefs) {
137
117
  for (const [defName, defSchema] of Object.entries(rootDefs)) {
138
118
  if (!defSchema || typeof defSchema !== 'object')
139
119
  continue;
140
- // Flattened Genesis has defs as the extraction schema itself (with $anchor at the top level).
141
- // Unflattened may have { nucleusSchema: { $anchor } } envelopes. Support both.
142
120
  const topLevelAnchor = defSchema.$anchor;
143
121
  const nested = defSchema.nucleusSchema;
144
122
  const nestedAnchor = nested && typeof nested === 'object' ? nested.$anchor : undefined;
@@ -176,7 +154,7 @@ function collectLocalDefClosure(node, rootDefs) {
176
154
  const name = queue.shift();
177
155
  const def = rootDefs[name];
178
156
  if (!def)
179
- continue; // Missing def handled earlier
157
+ continue;
180
158
  visit(def);
181
159
  }
182
160
  return needed;
@@ -1,10 +1,10 @@
1
1
  import fs from 'fs';
2
2
  import { getConfig } from './_lib/config.js';
3
3
  /**
4
- * Generate a typed Resource variant where `extractedData` is typed to a specific schema
4
+ * Generate a typed Resource variant where `nucleus` is typed to a specific schema
5
5
  * extracted under the configured output directory.
6
6
  *
7
- * Usage: node ./dist/scripts/generateResourceTypeType.js --name Job
7
+ * Usage: node ./dist/scripts/generateStandaloneType.js --name Job
8
8
  */
9
9
  /**
10
10
  * Pure function to generate the typed Resource D.TS content.
@@ -12,10 +12,10 @@ import { getConfig } from './_lib/config.js';
12
12
  * @param name The name of the schema
13
13
  * @returns The TypeScript D.TS file content
14
14
  */
15
- function generateResourceTypeTypeLogic(name) {
15
+ function generateStandaloneTypeLogic(name) {
16
16
  const header = '// Auto-generated strict composite type. Do not edit.\n';
17
- const ts = `import type { ResourceMetaBase, ${name} as ExtractedData } from './types.js';\n` +
18
- `export type Resource_${name} = ResourceMetaBase & { extractedData: ExtractedData };\n`;
17
+ const ts = `import type { ShellMaterializedBase, ${name} as NucleusSchema } from '../types.js';\n` +
18
+ `export type Resource_${name} = ShellMaterializedBase & { nucleus: NucleusSchema };\n`;
19
19
  return header + ts;
20
20
  }
21
21
  async function main() {
@@ -25,9 +25,18 @@ async function main() {
25
25
  console.error('Missing --name <SchemaBasename> argument');
26
26
  process.exit(1);
27
27
  }
28
- const inPath = config.getOutputPath(`${name}.json`);
28
+ const inPath = name === 'Genesis'
29
+ ? config.getSchemaPath('Genesis.json')
30
+ : config.getSchemaStandalonePath(`${name}.json`);
29
31
  if (!fs.existsSync(inPath)) {
30
- console.error(`Schema file not found: ${inPath}`);
32
+ if (name === 'Genesis') {
33
+ console.error(`Schema file not found: ${inPath}`);
34
+ console.error('Run extractSchemasFromResourceTypeShells first.');
35
+ }
36
+ else {
37
+ console.error(`Standalone schema file not found: ${inPath}`);
38
+ console.error(`Run generateStandaloneSchema -- --name ${name} first.`);
39
+ }
31
40
  process.exit(1);
32
41
  }
33
42
  // Basic validation against the expected shape of nucleusSchema.
@@ -47,16 +56,16 @@ async function main() {
47
56
  if (parsed.type && parsed.type !== 'object') {
48
57
  console.warn(`Warning: nucleusSchema usually has type: 'object' but this schema has type: '${parsed.type}'. Proceeding.`);
49
58
  }
50
- const tsContent = generateResourceTypeTypeLogic(name);
59
+ const tsContent = generateStandaloneTypeLogic(name);
51
60
  const jsContent = 'export {}\n';
52
61
  // Output setup
53
62
  const outName = `Resource_${name}.d.ts`;
54
63
  const outJsName = `Resource_${name}.js`;
55
64
  // Process src output
56
- const outDir = config.getTypesSrcDir();
65
+ const outDir = config.getTypesStandaloneSrcDir();
57
66
  fs.mkdirSync(outDir, { recursive: true });
58
- const outPath = config.getTypesSrcPath(outName);
59
- const outJsPath = config.getTypesSrcPath(outJsName);
67
+ const outPath = config.getTypesStandaloneSrcPath(outName);
68
+ const outJsPath = config.getTypesStandaloneSrcPath(outJsName);
60
69
  fs.writeFileSync(outPath, tsContent, 'utf8');
61
70
  console.log(`Wrote ${outPath}`);
62
71
  if (!fs.existsSync(outJsPath)) {
@@ -64,10 +73,10 @@ async function main() {
64
73
  console.log(`Wrote ${outJsPath}`);
65
74
  }
66
75
  // Process dist output
67
- const distLibDir = config.getTypesDistDir();
76
+ const distLibDir = config.getTypesStandaloneDistDir();
68
77
  fs.mkdirSync(distLibDir, { recursive: true });
69
- const distDtsPath = config.getTypesDistPath(outName);
70
- const distJsPath = config.getTypesDistPath(outJsName);
78
+ const distDtsPath = config.getTypesStandaloneDistPath(outName);
79
+ const distJsPath = config.getTypesStandaloneDistPath(outJsName);
71
80
  fs.writeFileSync(distDtsPath, tsContent, 'utf8');
72
81
  fs.writeFileSync(distJsPath, jsContent, 'utf8');
73
82
  console.log(`Wrote ${distDtsPath}`);
@@ -4,7 +4,7 @@ import { compileFromFile } from 'json-schema-to-typescript';
4
4
  import { getConfig } from './_lib/config.js';
5
5
  const config = getConfig();
6
6
  const projectRoot = config.getRoot();
7
- const inputDir = config.getOutputDir();
7
+ const inputDir = config.getSchemasDir();
8
8
  // We emit under src/genesis/generated/types and dist/genesis/generated/types
9
9
  const srcLibTypesDir = config.getTypesSrcDir();
10
10
  const srcLibOutputPath = config.getTypesSrcPath('types.d.ts');
@@ -9,7 +9,7 @@ import { getConfig } from './_lib/config.js';
9
9
  * @param input The schema object to process
10
10
  * @returns A new schema object with rewritten references
11
11
  */
12
- function rewriteAnchorsToPointers(input) {
12
+ function normalizeAnchorsToPointersToPointers(input) {
13
13
  if (!input || typeof input !== "object")
14
14
  return input;
15
15
  // Deep clone the input to ensure the function is pure (no side effects on input)
@@ -84,7 +84,7 @@ async function main() {
84
84
  process.exit(1);
85
85
  }
86
86
  // Rewrite anchors in the nucleusSchema (pure function call)
87
- genesis.nucleusSchema = rewriteAnchorsToPointers(genesis.nucleusSchema);
87
+ genesis.nucleusSchema = normalizeAnchorsToPointersToPointers(genesis.nucleusSchema);
88
88
  // Write normalized version
89
89
  fs.mkdirSync(path.dirname(normalizedPath), { recursive: true });
90
90
  fs.writeFileSync(normalizedPath, JSON.stringify(genesis, null, 4), 'utf-8');
@@ -2,69 +2,49 @@ import fs from 'fs';
2
2
  import path from 'path';
3
3
  import { getConfig } from './_lib/config.js';
4
4
  /**
5
- * Generate Resource envelopes for all ResourceTypes defined in Genesis.json
6
- *
7
- * This script wraps each ResourceType definition (from $defs) with a Resource envelope
5
+ * Wrap each ResourceType definition (from Genesis.nucleusSchema.$defs) with a Resource shell
8
6
  * that conforms to the Resource.nucleusSchema pattern defined in Genesis.json.
9
- *
10
- * For the top-level Genesis ResourceType, extractedData is set to {} to avoid
11
- * duplicating the entire $defs object.
12
- *
13
- * Resource identities follow the pattern RESOURCE-{Name} where Name is the key
14
- * from the $defs object. Genesis itself uses RESOURCE-Genesis.
15
- *
16
- * Usage: node ./dist/scripts/generateResourceEnvelopes.js
17
7
  */
18
- /**
19
- * Pure function to generate resource envelopes from a Genesis schema.
20
- *
21
- * @param genesis The Genesis schema object
22
- * @returns A record mapping resource names to their envelopes
23
- */
24
- function generateResourceEnvelopesLogic(genesis) {
8
+ function generateResourceShellLogic(genesis) {
25
9
  if (!genesis.nucleusSchema || !genesis.nucleusSchema.$defs) {
26
10
  throw new Error('Genesis.json must have nucleusSchema.$defs');
27
11
  }
28
12
  const defs = genesis.nucleusSchema.$defs;
29
13
  const defKeys = Object.keys(defs);
30
- // Generate Resource envelopes
31
14
  const resources = {};
32
15
  // Genesis timestamp: 2025-11-30T00:00:00.000Z marks the genesis of ToolProof
33
16
  const genesisTimestamp = '2025-11-30T00:00:00.000Z';
34
- // First entry is Genesis itself with empty extractedData
35
17
  resources['Genesis'] = {
36
18
  identity: 'RESOURCE-Genesis',
37
- resourceTypeRef: 'TYPE-ResourceType',
19
+ resourceTypeHandle: 'TYPE-ResourceType',
38
20
  creationContext: {
39
- resourceRoleRef: 'ROLE-Genesis',
40
- executionRef: 'EXECUTION-Genesis'
21
+ resourceRoleHandle: 'ROLE-Genesis',
22
+ jobStepHandle: 'JOB_STEP-Genesis'
41
23
  },
42
24
  kind: 'materialized',
43
25
  timestamp: genesisTimestamp,
44
- extractedData: {}
26
+ nucleus: {}
45
27
  };
46
- // Generate resources for all other $defs
47
28
  defKeys.forEach((defName) => {
48
29
  const defValue = defs[defName];
49
30
  resources[defName] = {
50
31
  identity: `RESOURCE-${defName}`,
51
- resourceTypeRef: 'TYPE-ResourceType',
32
+ resourceTypeHandle: 'TYPE-ResourceType',
52
33
  creationContext: {
53
- resourceRoleRef: 'ROLE-Genesis',
54
- executionRef: `EXECUTION-${defName}`
34
+ resourceRoleHandle: 'ROLE-Genesis',
35
+ jobStepHandle: `JOB_STEP-${defName}`
55
36
  },
56
37
  kind: 'materialized',
57
38
  timestamp: genesisTimestamp,
58
- extractedData: defValue
39
+ nucleus: defValue
59
40
  };
60
41
  });
61
42
  return resources;
62
43
  }
63
44
  async function main() {
64
45
  const config = getConfig();
65
- // Use normalized version with anchor refs rewritten to pointers
66
46
  const genesisSourcePath = config.getNormalizedSourcePath();
67
- const outputPath = path.join(config.getGeneratedResourcesDir(), 'Genesis.json');
47
+ const outputPath = path.join(config.getResourcesDir(), 'Genesis.json');
68
48
  if (!fs.existsSync(genesisSourcePath)) {
69
49
  console.error(`Genesis source file not found at ${genesisSourcePath}`);
70
50
  process.exit(1);
@@ -72,11 +52,9 @@ async function main() {
72
52
  const raw = fs.readFileSync(genesisSourcePath, 'utf-8');
73
53
  const genesis = JSON.parse(raw);
74
54
  try {
75
- const resources = generateResourceEnvelopesLogic(genesis);
76
- // Ensure output directory exists
55
+ const resources = generateResourceShellLogic(genesis);
77
56
  const outputDir = path.dirname(outputPath);
78
57
  fs.mkdirSync(outputDir, { recursive: true });
79
- // Write the generated resources file
80
58
  fs.writeFileSync(outputPath, JSON.stringify(resources, null, 4) + '\n', 'utf-8');
81
59
  console.log(`Generated ${Object.keys(resources).length} Resource envelopes -> ${outputPath}`);
82
60
  }