@volter/twin-standard 1.0.99 → 1.0.100

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.
@@ -49,7 +49,11 @@ export declare function assessPack(packDir: string, options?: AssessmentOptions)
49
49
  browser: Record<string, unknown>;
50
50
  conformance: import("./conformance.js").ConformanceResult[] | null;
51
51
  consumer: {
52
- node: string;
52
+ node: string | null;
53
+ evaluatorRuntime: {
54
+ nodeCompatibility: string;
55
+ bun: string;
56
+ };
53
57
  at: string;
54
58
  retentionNotApplicable?: string | undefined;
55
59
  measured: boolean;
@@ -29,7 +29,11 @@ export declare function prepareConsumerApp(packDir: string, appDir: string): {
29
29
  dependencies: Record<string, string>;
30
30
  };
31
31
  export declare function runConsumerWorkflow(packDir: string, options: ConsumerOptions): Promise<{
32
- node: string;
32
+ node: string | null;
33
+ evaluatorRuntime: {
34
+ nodeCompatibility: string;
35
+ bun: string;
36
+ };
33
37
  at: string;
34
38
  retentionNotApplicable?: string | undefined;
35
39
  measured: boolean;
@@ -113,24 +113,31 @@ export async function runConsumerWorkflow(packDir, options) {
113
113
  const recipe = consumerRecipe(vendor, packDir);
114
114
  const commands = [];
115
115
  const failures = [];
116
- const run = async (label, args) => {
116
+ const compiledCli = /\.[cm]?js$/.test(cliEntry);
117
+ let nodeVersion = null;
118
+ const execute = async (label, executable, argv) => {
117
119
  const result = await new Promise((done) => {
118
- const child = spawn(options.cli, ['world', ...args], { cwd: options.appDir, env: process.env, stdio: ['ignore', 'pipe', 'pipe'] });
120
+ const child = spawn(executable, argv, { cwd: options.appDir, env: process.env, stdio: ['ignore', 'pipe', 'pipe'] });
119
121
  let stdout = '', stderr = '';
120
122
  child.stdout.on('data', (chunk) => { stdout += chunk; });
121
123
  child.stderr.on('data', (chunk) => { stderr += chunk; });
122
124
  child.on('error', (error) => done({ exitCode: 1, stdout, stderr: `${stderr}\n${error.message}` }));
123
125
  child.on('close', (exitCode) => done({ exitCode, stdout, stderr }));
124
126
  });
125
- commands.push({ label, argv: [options.cli, 'world', ...args], ...result });
127
+ commands.push({ label, argv: [executable, ...argv], ...result });
126
128
  if (result.exitCode !== 0)
127
129
  throw new Error(`${label} exited ${result.exitCode}: ${result.stderr.trim().split('\n')[0] ?? ''}`);
128
130
  return result.stdout;
129
131
  };
132
+ const run = (label, args) => compiledCli
133
+ ? execute(label, 'node', [cliEntry, 'world', ...args])
134
+ : execute(label, options.cli, ['world', ...args]);
130
135
  let upAttempted = false;
131
136
  let retainedReadback = false;
132
137
  let teardownVerified = false;
133
138
  try {
139
+ if (compiledCli)
140
+ nodeVersion = (await execute('node-version', 'node', ['--version'])).trim();
134
141
  await run('init', ['init', '--twins', vendor]);
135
142
  const config = JSON.parse(readFileSync(join(options.appDir, '.volter/world.json'), 'utf8'));
136
143
  if (!config.services?.some((service) => service.source?.package === metadata.name && service.source?.version === metadata.version))
@@ -185,6 +192,8 @@ export async function runConsumerWorkflow(packDir, options) {
185
192
  commands, failures, teardownVerified, retainedReadback,
186
193
  clock: recipe.clock ?? { mode: 'wall' },
187
194
  ...('none' in recipe.retention ? { retentionNotApplicable: recipe.retention.none } : {}),
188
- node: process.versions.node, at: new Date().toISOString(),
195
+ node: nodeVersion,
196
+ evaluatorRuntime: { nodeCompatibility: process.versions.node, bun: process.versions.bun ?? null },
197
+ at: new Date().toISOString(),
189
198
  };
190
199
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/twin-standard",
3
- "version": "1.0.99",
3
+ "version": "1.0.100",
4
4
  "description": "The Protocol 3 standard for Volter twin packs: the criteria a pack is graded by, the grader, the gate a pack repository and the twin catalog run on every change and submission, and the spec derivation the grade checks against. Pin a version: every place a pack is judged judges by that standard.",
5
5
  "keywords": [
6
6
  "twin",
@@ -75,7 +75,7 @@
75
75
  "yaml": "2.9.0"
76
76
  },
77
77
  "peerDependencies": {
78
- "@volter/world-core": "3.0.107",
78
+ "@volter/world-core": "3.0.108",
79
79
  "@volter/world-runtime": "*",
80
80
  "playwright": "^1.63.0"
81
81
  },
package/src/consumer.ts CHANGED
@@ -103,23 +103,29 @@ export async function runConsumerWorkflow(packDir: string, options: ConsumerOpti
103
103
  const recipe = consumerRecipe(vendor, packDir);
104
104
  const commands: Array<{ label: string; argv: string[]; exitCode: number | null; stdout: string; stderr: string }> = [];
105
105
  const failures: string[] = [];
106
- const run = async (label: string, args: string[]) => {
106
+ const compiledCli = /\.[cm]?js$/.test(cliEntry);
107
+ let nodeVersion: string | null = null;
108
+ const execute = async (label: string, executable: string, argv: string[]) => {
107
109
  const result = await new Promise<{ exitCode: number | null; stdout: string; stderr: string }>((done) => {
108
- const child = spawn(options.cli, ['world', ...args], { cwd: options.appDir, env: process.env, stdio: ['ignore', 'pipe', 'pipe'] });
110
+ const child = spawn(executable, argv, { cwd: options.appDir, env: process.env, stdio: ['ignore', 'pipe', 'pipe'] });
109
111
  let stdout = '', stderr = '';
110
112
  child.stdout.on('data', (chunk) => { stdout += chunk; });
111
113
  child.stderr.on('data', (chunk) => { stderr += chunk; });
112
114
  child.on('error', (error) => done({ exitCode: 1, stdout, stderr: `${stderr}\n${error.message}` }));
113
115
  child.on('close', (exitCode) => done({ exitCode, stdout, stderr }));
114
116
  });
115
- commands.push({ label, argv: [options.cli, 'world', ...args], ...result });
117
+ commands.push({ label, argv: [executable, ...argv], ...result });
116
118
  if (result.exitCode !== 0) throw new Error(`${label} exited ${result.exitCode}: ${result.stderr.trim().split('\n')[0] ?? ''}`);
117
119
  return result.stdout;
118
120
  };
121
+ const run = (label: string, args: string[]) => compiledCli
122
+ ? execute(label, 'node', [cliEntry, 'world', ...args])
123
+ : execute(label, options.cli, ['world', ...args]);
119
124
  let upAttempted = false;
120
125
  let retainedReadback = false;
121
126
  let teardownVerified = false;
122
127
  try {
128
+ if (compiledCli) nodeVersion = (await execute('node-version', 'node', ['--version'])).trim();
123
129
  await run('init', ['init', '--twins', vendor]);
124
130
  const config = JSON.parse(readFileSync(join(options.appDir, '.volter/world.json'), 'utf8'));
125
131
  if (!config.services?.some((service: { source?: { package?: string; version?: string } }) => service.source?.package === metadata.name && service.source?.version === metadata.version)) throw new Error('World init did not select the installed candidate package and exact version');
@@ -163,6 +169,8 @@ export async function runConsumerWorkflow(packDir: string, options: ConsumerOpti
163
169
  commands, failures, teardownVerified, retainedReadback,
164
170
  clock: recipe.clock ?? { mode: 'wall' },
165
171
  ...('none' in recipe.retention ? { retentionNotApplicable: recipe.retention.none } : {}),
166
- node: process.versions.node, at: new Date().toISOString(),
172
+ node: nodeVersion,
173
+ evaluatorRuntime: { nodeCompatibility: process.versions.node, bun: process.versions.bun ?? null },
174
+ at: new Date().toISOString(),
167
175
  };
168
176
  }