genesis-compiler 1.10.7 → 1.10.9
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/README.md +25 -1
- package/docs/prompt-integration.md +2 -2
- package/docs/stack-components.md +5 -2
- package/package.json +1 -1
- package/plugins/genesis/.codex-plugin/plugin.json +1 -1
- package/profiles/engineering/baseline.md +1 -1
- package/skills/genesis-project/SKILL.md +20 -7
- package/src/cli.js +6 -4
- package/src/index/collaboration.js +37 -3
- package/src/index/prompt.js +1 -0
- package/src/index/stack-city-presentation.js +26 -4
- package/src/index/stack.js +13 -3
package/README.md
CHANGED
|
@@ -294,6 +294,10 @@ than in a host-private policy or a repeated user-message prefix:
|
|
|
294
294
|
|
|
295
295
|
- `concise`
|
|
296
296
|
|
|
297
|
+
## Long checks
|
|
298
|
+
|
|
299
|
+
- `conservative`
|
|
300
|
+
|
|
297
301
|
## Project requirements
|
|
298
302
|
|
|
299
303
|
- Nothing.
|
|
@@ -303,7 +307,7 @@ Inspect or change it without parsing Markdown yourself:
|
|
|
303
307
|
|
|
304
308
|
```bash
|
|
305
309
|
genesis collaboration show
|
|
306
|
-
genesis collaboration set direct balanced expert conclusions "Be candid."
|
|
310
|
+
genesis collaboration set direct balanced expert conclusions normal "Be candid."
|
|
307
311
|
```
|
|
308
312
|
|
|
309
313
|
Genesis owns the supported choices and their concise expansions. Authored
|
|
@@ -315,6 +319,26 @@ Updates should describe actual progress, findings, decisions, or blockers,
|
|
|
315
319
|
rather than announce compliance with guidance or reassure the user about
|
|
316
320
|
unrelated behavior staying unchanged.
|
|
317
321
|
|
|
322
|
+
The Long checks choice sets how agents handle test suites, builds and other long
|
|
323
|
+
checks. `conservative` runs each one as a single unattended, time-limited
|
|
324
|
+
command that writes its output to a local file and ends with one completion
|
|
325
|
+
signal; the agent does not watch it while it runs and passes this on to agents
|
|
326
|
+
it delegates checks to. It saves the most tokens, and results arrive only when
|
|
327
|
+
each check ends. `normal` lets the agent follow a check's progress and stop a
|
|
328
|
+
clearly broken run early, reacting sooner for more tokens. Both keep the
|
|
329
|
+
Engineering baseline's time limit, local output files, exit status and concise
|
|
330
|
+
evidence reading.
|
|
331
|
+
|
|
332
|
+
The choice belongs to the person, so Genesis never makes it for them. `genesis
|
|
333
|
+
init`, migration and `setCollaboration()` calls that do not pass `longChecks`
|
|
334
|
+
leave `## Long checks` out. While it is absent, `longChecks` is `null` and the
|
|
335
|
+
session guidance asks the agent to put both options to the person once, early,
|
|
336
|
+
before the first long check, to record the answer with `genesis collaboration
|
|
337
|
+
set` (the guidance spells out the command with the current choices), and to use
|
|
338
|
+
`conservative` until then. Once the section exists, the guidance carries only
|
|
339
|
+
the chosen option. A present section with any other value is rejected with the
|
|
340
|
+
valid choices listed.
|
|
341
|
+
|
|
318
342
|
Persistent hosts should install `projectSessionContext()` once when a provider
|
|
319
343
|
conversation is created or refreshed. They may then generate task prompts with
|
|
320
344
|
`sessionContextInstalled: true`, preventing the stable Collaboration and
|
|
@@ -180,8 +180,8 @@ Genesis keeps each instruction at one useful level:
|
|
|
180
180
|
- `genesis/blueprint.md`, `genesis/program/`, and `genesis/stack.md` are the
|
|
181
181
|
project's own intent, explanation, and selected technical composition.
|
|
182
182
|
- `genesis/collaboration.md` selects Genesis-owned tone, response-length,
|
|
183
|
-
assumed-experience,
|
|
184
|
-
project requirements.
|
|
183
|
+
assumed-experience, explanation-style, and long-checks instructions plus
|
|
184
|
+
optional authored project requirements.
|
|
185
185
|
- `profiles/engineering/*.md` owns the installed versioned engineering
|
|
186
186
|
profiles. `genesis/engineering.md` selects one profile and records explicit
|
|
187
187
|
project requirements. A universal complexity gate is composed ahead of the
|
package/docs/stack-components.md
CHANGED
|
@@ -223,8 +223,11 @@ the installed Skill do not rewrite what an already-run command proved.
|
|
|
223
223
|
|
|
224
224
|
`City regions` and `Indexers` control only the derived structural maps. Indexers
|
|
225
225
|
identify language adapters. City regions can exclude test/spec paths and group
|
|
226
|
-
indexed files into deterministic regions and campuses.
|
|
227
|
-
|
|
226
|
+
indexed files into deterministic regions and campuses. A project adds its own
|
|
227
|
+
exclusions, such as example fixtures, in a `## City exclusions` section of
|
|
228
|
+
`genesis/stack.md` with the same ``- Ignore `glob` `` lines (or `- Nothing.`);
|
|
229
|
+
they add to the component exclusions. Both projections are navigation data, not
|
|
230
|
+
proof of complete runtime behavior.
|
|
228
231
|
|
|
229
232
|
## Project customization
|
|
230
233
|
|
package/package.json
CHANGED
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
- Do not overengineer or overcomplicate the solution. Do not add speculative abstractions, layers, dependencies, infrastructure, compatibility paths, distributed patterns, cryptography, enterprise patterns, or other advanced machinery unless an explicit requirement or a concrete constraint makes it necessary.
|
|
6
6
|
- If good software requires material complexity beyond these rules, stop before writing it. Explain the requirement, why the direct design is insufficient, and the smallest added complexity proposed, then ask the user to approve or clarify the tradeoff.
|
|
7
7
|
- During implementation, run the relevant checks and batch related cases when they share setup. Follow the project's verification policy for broad or final checks; do not repeat them merely because an item finishes or a session resumes. Preserve required coverage and isolation.
|
|
8
|
-
-
|
|
8
|
+
- Bound each long check by a time limit so it ends even when it hangs; write its complete output to a local file and preserve its exit status. Afterwards read concise counts, timings and actionable failure excerpts first, expanding evidence only when needed; never load full passing reports into agent context. Retain startup and cleanup failures; retry only after a change or new evidence justifies it.
|
|
9
9
|
- For browser verification, batch related actions and return only the relevant values or page region. Capture screenshots at meaningful visual checkpoints or failures, not after every action. Preserve required viewport, identity and security coverage; prefer existing automated cases for repeated checks.
|
|
@@ -151,13 +151,26 @@ technology's workspace substrate exists. Finishing an item or resuming a
|
|
|
151
151
|
session does not itself require a broad verification run. Keep full output in
|
|
152
152
|
local artifacts, preserve exit status, and read summaries and relevant failure
|
|
153
153
|
excerpts before expanding logs. Do not weaken assertions or omit required
|
|
154
|
-
coverage to save time or tokens.
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
154
|
+
coverage to save time or tokens.
|
|
155
|
+
|
|
156
|
+
A change to user-visible behavior ships with the browser specs that cover it
|
|
157
|
+
updated and run in the same change, before pushing. When an existing spec
|
|
158
|
+
fails, first classify it as outdated (the behavior changed on purpose) or as a
|
|
159
|
+
regression. Fix regressions in the product, and change a spec only for an
|
|
160
|
+
intended change, naming the change that made it outdated. Test resources a
|
|
161
|
+
managed host supplies, such as a login state, base URL, browser, or ports, are
|
|
162
|
+
the host's contract. If they do not work (for example, tests run signed out
|
|
163
|
+
despite a supplied login), report the host defect with evidence and stop; never
|
|
164
|
+
compensate in the project by rewriting cookies or adding its own login or
|
|
165
|
+
browser.
|
|
166
|
+
|
|
167
|
+
An unconfigured result means the declared workspace or checks do not exist
|
|
168
|
+
yet; it is not a failing check. Before reporting completion, compare the
|
|
169
|
+
requested observable behavior, required inputs and resources, declared project
|
|
170
|
+
operations, and focused evidence with what actually exists. Report files
|
|
171
|
+
changed, checks actually run, anything not proven, and anything still requiring
|
|
172
|
+
attention. Never claim that an unrun check passed or that passing checks prove
|
|
173
|
+
the whole product.
|
|
161
174
|
|
|
162
175
|
## Subsystem maintenance
|
|
163
176
|
|
package/src/cli.js
CHANGED
|
@@ -55,7 +55,7 @@ const USAGE = `Usage:
|
|
|
55
55
|
genesis adopt [product guidance...]
|
|
56
56
|
genesis codex install
|
|
57
57
|
genesis collaboration show
|
|
58
|
-
genesis collaboration set <tone> <response-length> <experience> <explanation-style> [project requirements...]
|
|
58
|
+
genesis collaboration set <tone> <response-length> <experience> <explanation-style> <long-checks> [project requirements...]
|
|
59
59
|
genesis engineering list
|
|
60
60
|
genesis engineering show [profile]
|
|
61
61
|
genesis engineering set <profile>
|
|
@@ -178,10 +178,10 @@ function parseCommand(argv) {
|
|
|
178
178
|
if (action === 'show' && operands.length !== 1) {
|
|
179
179
|
fail('CLI_EXTRA_ARGUMENT', 'Command collaboration show accepts no extra arguments.');
|
|
180
180
|
}
|
|
181
|
-
if (action === 'set' && operands.length <
|
|
181
|
+
if (action === 'set' && operands.length < 6) {
|
|
182
182
|
fail(
|
|
183
183
|
'CLI_COLLABORATION_VALUES_REQUIRED',
|
|
184
|
-
'Command collaboration set requires tone, response length, experience, and
|
|
184
|
+
'Command collaboration set requires tone, response length, experience, explanation style, and long checks.',
|
|
185
185
|
);
|
|
186
186
|
}
|
|
187
187
|
} else if (command === 'stack') {
|
|
@@ -279,6 +279,7 @@ function writeCollaboration(result) {
|
|
|
279
279
|
line(process.stdout, `Response length: ${result.responseLength}`);
|
|
280
280
|
line(process.stdout, `Assumed experience: ${result.experience}`);
|
|
281
281
|
line(process.stdout, `Explanation style: ${result.explanationStyle}`);
|
|
282
|
+
line(process.stdout, `Long checks: ${result.longChecks || 'unset (conservative until chosen)'}`);
|
|
282
283
|
if (result.requirements) {
|
|
283
284
|
line(process.stdout, 'Project requirements:');
|
|
284
285
|
line(process.stdout, result.requirements);
|
|
@@ -516,7 +517,8 @@ async function execute({ command, operands, options }, { signal, hostContext = n
|
|
|
516
517
|
responseLength: operands[2],
|
|
517
518
|
experience: operands[3],
|
|
518
519
|
explanationStyle: operands[4],
|
|
519
|
-
|
|
520
|
+
longChecks: operands[5],
|
|
521
|
+
...(operands.length > 6 ? { requirements: operands.slice(6).join(' ') } : {}),
|
|
520
522
|
}),
|
|
521
523
|
};
|
|
522
524
|
}
|
|
@@ -74,6 +74,18 @@ const DIMENSIONS = {
|
|
|
74
74
|
guidance: 'Explain the practical reasoning behind decisions in a teaching-oriented way.',
|
|
75
75
|
},
|
|
76
76
|
},
|
|
77
|
+
longChecks: {
|
|
78
|
+
conservative: {
|
|
79
|
+
name: 'Conservative',
|
|
80
|
+
description: 'Saves the most tokens; results arrive only when each check ends.',
|
|
81
|
+
guidance: 'Run each long check as one unattended command, bounded by a time limit, that writes its complete output to a local file and exits with its status, so it ends with a single completion signal. Do not watch it while it runs: no progress monitors, log tails, repeated status checks or interim reports. Pass this on to any agent you delegate checks to.',
|
|
82
|
+
},
|
|
83
|
+
normal: {
|
|
84
|
+
name: 'Normal',
|
|
85
|
+
description: 'Reacts sooner, uses more tokens.',
|
|
86
|
+
guidance: 'You may follow a long check\'s progress while it runs and stop a clearly broken run early. Still keep its full output in files and read only what you need.',
|
|
87
|
+
},
|
|
88
|
+
},
|
|
77
89
|
};
|
|
78
90
|
|
|
79
91
|
const SECTION_FIELDS = Object.freeze({
|
|
@@ -81,8 +93,13 @@ const SECTION_FIELDS = Object.freeze({
|
|
|
81
93
|
'Response length': 'responseLength',
|
|
82
94
|
'Assumed experience': 'experience',
|
|
83
95
|
'Explanation style': 'explanationStyle',
|
|
96
|
+
'Long checks': 'longChecks',
|
|
84
97
|
});
|
|
85
98
|
|
|
99
|
+
// A missing optional section is an unmade choice, not a default.
|
|
100
|
+
const OPTIONAL_SECTIONS = new Set(['Long checks']);
|
|
101
|
+
const LONG_CHECKS_UNTIL_CHOSEN = 'conservative';
|
|
102
|
+
|
|
86
103
|
export const DEFAULT_COLLABORATION = Object.freeze({
|
|
87
104
|
tone: 'encouraging',
|
|
88
105
|
responseLength: 'concise',
|
|
@@ -196,6 +213,15 @@ function collaborationCatalog() {
|
|
|
196
213
|
]));
|
|
197
214
|
}
|
|
198
215
|
|
|
216
|
+
function unsetLongChecksGuidance(value) {
|
|
217
|
+
const choices = DIMENSIONS.longChecks;
|
|
218
|
+
return [
|
|
219
|
+
'The project has not chosen how agents handle long checks such as test suites and builds. Ask the person once, early, before running the first long check, which option they want:',
|
|
220
|
+
...Object.entries(choices).map(([id, choice]) => `- \`${id}\`: ${choice.description}`),
|
|
221
|
+
`Record the answer with \`genesis collaboration set ${value.tone} ${value.responseLength} ${value.experience} ${value.explanationStyle} <${Object.keys(choices).join('|')}>\`. Until the person answers, use \`${LONG_CHECKS_UNTIL_CHOSEN}\`: ${choices[LONG_CHECKS_UNTIL_CHOSEN].guidance}`,
|
|
222
|
+
].join('\n');
|
|
223
|
+
}
|
|
224
|
+
|
|
199
225
|
function collaborationGuidance(value) {
|
|
200
226
|
return [
|
|
201
227
|
'Apply the configured tone, response length, assumed experience, and explanation style to every user-facing message, including progress updates and final responses.',
|
|
@@ -217,6 +243,10 @@ function collaborationGuidance(value) {
|
|
|
217
243
|
'## Explanation style',
|
|
218
244
|
'',
|
|
219
245
|
DIMENSIONS.explanationStyle[value.explanationStyle].guidance,
|
|
246
|
+
'',
|
|
247
|
+
'## Long checks',
|
|
248
|
+
'',
|
|
249
|
+
value.longChecks ? DIMENSIONS.longChecks[value.longChecks].guidance : unsetLongChecksGuidance(value),
|
|
220
250
|
...(value.requirements ? [
|
|
221
251
|
'',
|
|
222
252
|
'## Project requirements',
|
|
@@ -231,17 +261,17 @@ export function parseCollaborationSource(source) {
|
|
|
231
261
|
const parsed = sections(source);
|
|
232
262
|
const expected = new Set([...Object.keys(SECTION_FIELDS), 'Project requirements']);
|
|
233
263
|
const unknown = [...parsed.sections.keys()].filter((name) => !expected.has(name));
|
|
234
|
-
const missing = [...expected].filter((name) => !parsed.sections.has(name));
|
|
264
|
+
const missing = [...expected].filter((name) => !parsed.sections.has(name) && !OPTIONAL_SECTIONS.has(name));
|
|
235
265
|
if (unknown.length > 0 || missing.length > 0) {
|
|
236
266
|
throw new GenesisError(
|
|
237
267
|
'COLLABORATION_INVALID',
|
|
238
|
-
`${COLLABORATION_PATH} needs only Tone, Response length, Assumed experience, Explanation style, and Project requirements sections.`,
|
|
268
|
+
`${COLLABORATION_PATH} needs only Tone, Response length, Assumed experience, Explanation style, optional Long checks, and Project requirements sections.`,
|
|
239
269
|
{ path: COLLABORATION_PATH },
|
|
240
270
|
);
|
|
241
271
|
}
|
|
242
272
|
const values = Object.fromEntries(Object.entries(SECTION_FIELDS).map(([sectionName, field]) => [
|
|
243
273
|
field,
|
|
244
|
-
dimensionValue(parsed.sections, sectionName, field),
|
|
274
|
+
parsed.sections.has(sectionName) ? dimensionValue(parsed.sections, sectionName, field) : null,
|
|
245
275
|
]));
|
|
246
276
|
const requirementsSource = sectionText(parsed.sections, 'Project requirements');
|
|
247
277
|
if (!requirementsSource) {
|
|
@@ -296,6 +326,7 @@ function renderCollaboration(value) {
|
|
|
296
326
|
'',
|
|
297
327
|
`- \`${value.explanationStyle}\``,
|
|
298
328
|
'',
|
|
329
|
+
...(value.longChecks === null ? [] : ['## Long checks', '', `- \`${value.longChecks}\``, '']),
|
|
299
330
|
'## Project requirements',
|
|
300
331
|
'',
|
|
301
332
|
value.requirements || '- Nothing.',
|
|
@@ -340,6 +371,7 @@ export async function inspectProjectCollaboration({ projectRoot } = {}) {
|
|
|
340
371
|
export async function setProjectCollaboration({
|
|
341
372
|
experience,
|
|
342
373
|
explanationStyle,
|
|
374
|
+
longChecks,
|
|
343
375
|
projectRoot,
|
|
344
376
|
requirements,
|
|
345
377
|
responseLength,
|
|
@@ -352,6 +384,7 @@ export async function setProjectCollaboration({
|
|
|
352
384
|
responseLength: responseLength ?? current.responseLength,
|
|
353
385
|
experience: experience ?? current.experience,
|
|
354
386
|
explanationStyle: explanationStyle ?? current.explanationStyle,
|
|
387
|
+
longChecks: longChecks ?? current.longChecks,
|
|
355
388
|
requirements: requirements ?? current.requirements,
|
|
356
389
|
}));
|
|
357
390
|
const rendered = renderCollaboration(next);
|
|
@@ -367,6 +400,7 @@ export async function setProjectCollaboration({
|
|
|
367
400
|
responseLength: next.responseLength,
|
|
368
401
|
experience: next.experience,
|
|
369
402
|
explanationStyle: next.explanationStyle,
|
|
403
|
+
longChecks: next.longChecks,
|
|
370
404
|
requirements: next.requirements,
|
|
371
405
|
choices: collaborationCatalog(),
|
|
372
406
|
guidance: collaborationGuidance(next),
|
package/src/index/prompt.js
CHANGED
|
@@ -167,6 +167,7 @@ function collaborationPromptContext(collaboration) {
|
|
|
167
167
|
responseLength: collaboration.responseLength,
|
|
168
168
|
experience: collaboration.experience,
|
|
169
169
|
explanationStyle: collaboration.explanationStyle,
|
|
170
|
+
longChecks: collaboration.longChecks || 'unset',
|
|
170
171
|
requirements: collaboration.requirements || 'Nothing.',
|
|
171
172
|
};
|
|
172
173
|
}
|
|
@@ -7,8 +7,8 @@ const FALLBACK_LINE = /^- Fallback `([^`]+)` as `([^`]+)`[ \t]*$/u;
|
|
|
7
7
|
const REGEXP_SPECIAL = /[.+^${}()|[\]\\]/u;
|
|
8
8
|
const compiledGlobPatterns = new Map();
|
|
9
9
|
|
|
10
|
-
function invalid(piecePath, message) {
|
|
11
|
-
throw new GenesisError(
|
|
10
|
+
function invalid(piecePath, message, code = 'STACK_PIECE_INVALID') {
|
|
11
|
+
throw new GenesisError(code, message, { path: piecePath });
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
function normalizedPrefix(value, piecePath) {
|
|
@@ -25,7 +25,7 @@ function normalizedPrefix(value, piecePath) {
|
|
|
25
25
|
return prefix;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
function normalizedGlob(value, piecePath) {
|
|
28
|
+
function normalizedGlob(value, piecePath, { code, section = 'City regions' } = {}) {
|
|
29
29
|
const pattern = String(value || '').trim();
|
|
30
30
|
if (
|
|
31
31
|
!pattern
|
|
@@ -37,7 +37,8 @@ function normalizedGlob(value, piecePath) {
|
|
|
37
37
|
) {
|
|
38
38
|
invalid(
|
|
39
39
|
piecePath,
|
|
40
|
-
|
|
40
|
+
`## ${section} ignore patterns must be canonical project-relative globs using only * and ** wildcards.`,
|
|
41
|
+
code,
|
|
41
42
|
);
|
|
42
43
|
}
|
|
43
44
|
return pattern;
|
|
@@ -156,6 +157,27 @@ export function parseStackCityPresentationLines(lines, { path = 'stack piece' }
|
|
|
156
157
|
return { exclusions, regions };
|
|
157
158
|
}
|
|
158
159
|
|
|
160
|
+
/**
|
|
161
|
+
* A project's own `## City exclusions` section removes paths no selected
|
|
162
|
+
* component can know about, such as example fixtures. It uses the City regions
|
|
163
|
+
* Ignore grammar and adds to the component exclusions.
|
|
164
|
+
*/
|
|
165
|
+
export function parseProjectCityExclusionLines(lines, { path }) {
|
|
166
|
+
if (lines === undefined) return [];
|
|
167
|
+
const content = lines.filter((line) => line.trim());
|
|
168
|
+
if (content.length === 1 && content[0].trim() === '- Nothing.') return [];
|
|
169
|
+
const options = { code: 'STACK_INVALID', section: 'City exclusions' };
|
|
170
|
+
const exclusions = content.map((line) => {
|
|
171
|
+
const ignore = line.match(IGNORE_LINE);
|
|
172
|
+
if (!ignore) invalid(path, '## City exclusions entries must each be one Ignore with a glob.', options.code);
|
|
173
|
+
return normalizedGlob(ignore[1], path, options);
|
|
174
|
+
});
|
|
175
|
+
if (exclusions.length === 0 || new Set(exclusions).size !== exclusions.length) {
|
|
176
|
+
invalid(path, '## City exclusions needs distinct Ignore entries or `- Nothing.`.', options.code);
|
|
177
|
+
}
|
|
178
|
+
return exclusions;
|
|
179
|
+
}
|
|
180
|
+
|
|
159
181
|
export function composeStackCityPresentation(components = []) {
|
|
160
182
|
const owners = components.filter((component) => (
|
|
161
183
|
component.cityRegions.length > 0 || component.cityExclusions.length > 0
|
package/src/index/stack.js
CHANGED
|
@@ -7,7 +7,10 @@ import {
|
|
|
7
7
|
normalizeStackPackageName,
|
|
8
8
|
readStackCatalog,
|
|
9
9
|
} from './stack-catalog.js';
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
composeStackCityPresentation,
|
|
12
|
+
parseProjectCityExclusionLines,
|
|
13
|
+
} from './stack-city-presentation.js';
|
|
11
14
|
import { parseUiDiscovery } from './stack-ui-discovery.js';
|
|
12
15
|
import { parsePackageDiscovery } from './stack-package-discovery.js';
|
|
13
16
|
import { resolveStackPieces } from './stack-composition.js';
|
|
@@ -371,6 +374,13 @@ async function readStackWithContractMode(projectRoot, {
|
|
|
371
374
|
source: 'project',
|
|
372
375
|
diagnostics: [],
|
|
373
376
|
}));
|
|
377
|
+
const cityExclusions = [...new Set([
|
|
378
|
+
...cityPresentation.exclusions,
|
|
379
|
+
...parseProjectCityExclusionLines(
|
|
380
|
+
extensions.find(entry => entry.name === 'City exclusions')?.lines,
|
|
381
|
+
{ path: STACK_PATH },
|
|
382
|
+
),
|
|
383
|
+
])];
|
|
374
384
|
const uiDiscovery = parseUiDiscovery(extensions.find(entry => entry.name === 'UI discovery')?.lines);
|
|
375
385
|
const packageDiscovery = parsePackageDiscovery(extensions.find(entry => entry.name === 'Package discovery')?.lines);
|
|
376
386
|
return {
|
|
@@ -378,7 +388,7 @@ async function readStackWithContractMode(projectRoot, {
|
|
|
378
388
|
identityHash: sha256(stableJson({
|
|
379
389
|
stackPackages: declaredPackages,
|
|
380
390
|
components: components.map(({ id }) => id),
|
|
381
|
-
cityExclusions
|
|
391
|
+
cityExclusions,
|
|
382
392
|
cityRegions: cityPresentation.regions,
|
|
383
393
|
verificationCommands: verificationCommands.map(({ label, argv }) => ({ label, argv })),
|
|
384
394
|
environmentDefaults,
|
|
@@ -388,7 +398,7 @@ async function readStackWithContractMode(projectRoot, {
|
|
|
388
398
|
})),
|
|
389
399
|
components,
|
|
390
400
|
stackPackages: declaredPackages,
|
|
391
|
-
cityExclusions
|
|
401
|
+
cityExclusions,
|
|
392
402
|
cityRegions: cityPresentation.regions,
|
|
393
403
|
uiDiscovery,
|
|
394
404
|
packageDiscovery,
|