genesis-compiler 1.2.29 → 1.3.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.
- package/README.md +70 -3
- package/docs/prompt-integration.md +93 -0
- package/package.json +1 -1
- package/plugins/genesis/.codex-plugin/plugin.json +1 -1
- package/plugins/opencode/project-guidance.js +41 -5
- package/src/cli.js +124 -7
- package/src/index/check.js +10 -0
- package/src/index/codex-hooks.js +16 -1
- package/src/index/collaboration.js +371 -0
- package/src/index/contracts.js +3 -0
- package/src/index/host-context-resolver.js +73 -0
- package/src/index/init.js +4 -0
- package/src/index/migration.js +2 -0
- package/src/index/paths.js +1 -0
- package/src/index/project-format.js +3 -1
- package/src/index/prompt.js +74 -21
- package/src/index/session-context.js +115 -25
- package/src/index.js +27 -2
package/src/index/prompt.js
CHANGED
|
@@ -2,6 +2,7 @@ import { readInstalledAsset } from './assets.js';
|
|
|
2
2
|
import { inspectProjectSkills, renderAgentSkillCatalog } from './agent-skills.js';
|
|
3
3
|
import { buildProjectIndex, MACHINE_CITY_PATH, PROGRAM_CITY_PATH } from './code-index.js';
|
|
4
4
|
import { BLUEPRINT_SKELETON_SOURCE, readBlueprint } from './blueprint.js';
|
|
5
|
+
import { defaultCollaboration, readCollaboration } from './collaboration.js';
|
|
5
6
|
import {
|
|
6
7
|
engineeringPromptContext,
|
|
7
8
|
listEngineeringProfileCatalog,
|
|
@@ -18,6 +19,7 @@ import { missingStackResources } from './stack-preflight.js';
|
|
|
18
19
|
import { withStackEnvironmentDefaults } from './stack-environment-defaults.js';
|
|
19
20
|
import { stableJson } from './utils.js';
|
|
20
21
|
import { classifyProjectKind } from './project-files.js';
|
|
22
|
+
import { inspectProjectFormatAtRoot } from './project-format.js';
|
|
21
23
|
|
|
22
24
|
const TASKS = new Set(['start', 'adopt', 'work', 'deslop', 'program', 'blueprint', 'describe', 'review']);
|
|
23
25
|
const DEFAULT_REQUEST = {
|
|
@@ -128,6 +130,7 @@ function renderPrompt({
|
|
|
128
130
|
cleanup = '',
|
|
129
131
|
postChange = '',
|
|
130
132
|
adoption = '',
|
|
133
|
+
collaborationGuidance = '',
|
|
131
134
|
engineeringGuidance = '',
|
|
132
135
|
}) {
|
|
133
136
|
return [
|
|
@@ -143,6 +146,7 @@ function renderPrompt({
|
|
|
143
146
|
stableJson(context).trimEnd(),
|
|
144
147
|
'```',
|
|
145
148
|
...(engineeringGuidance ? ['', 'ENGINEERING APPROACH', '', engineeringGuidance] : []),
|
|
149
|
+
...(collaborationGuidance ? ['', 'COLLABORATION APPROACH', '', collaborationGuidance] : []),
|
|
146
150
|
...(guidance ? ['', 'SELECTED STACK GUIDANCE', '', guidance] : []),
|
|
147
151
|
...(adoption ? ['', 'SELECTED STACK ADOPTION GUIDANCE', '', adoption] : []),
|
|
148
152
|
...(skills ? ['', 'AVAILABLE AGENT SKILLS', '', skills] : []),
|
|
@@ -152,7 +156,43 @@ function renderPrompt({
|
|
|
152
156
|
].join('\n');
|
|
153
157
|
}
|
|
154
158
|
|
|
155
|
-
|
|
159
|
+
function collaborationPromptContext(collaboration) {
|
|
160
|
+
return {
|
|
161
|
+
path: collaboration.path,
|
|
162
|
+
status: collaboration.status,
|
|
163
|
+
tone: collaboration.tone,
|
|
164
|
+
responseLength: collaboration.responseLength,
|
|
165
|
+
experience: collaboration.experience,
|
|
166
|
+
explanationStyle: collaboration.explanationStyle,
|
|
167
|
+
requirements: collaboration.requirements || 'Nothing.',
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function stableSessionPromptParts({ collaboration, engineering, installed }) {
|
|
172
|
+
return installed
|
|
173
|
+
? { context: {}, collaborationGuidance: '', engineeringGuidance: '' }
|
|
174
|
+
: {
|
|
175
|
+
context: {
|
|
176
|
+
collaboration: collaborationPromptContext(collaboration),
|
|
177
|
+
engineering: engineeringPromptContext(engineering),
|
|
178
|
+
},
|
|
179
|
+
collaborationGuidance: collaboration.guidance,
|
|
180
|
+
engineeringGuidance: engineering.guidance,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
async function collaborationForPrompt(projectRoot) {
|
|
185
|
+
try {
|
|
186
|
+
return await readCollaboration(projectRoot);
|
|
187
|
+
} catch (error) {
|
|
188
|
+
if (error?.code !== 'COLLABORATION_REQUIRED') throw error;
|
|
189
|
+
const format = await inspectProjectFormatAtRoot(projectRoot);
|
|
190
|
+
if (format.status !== 'uninitialized') throw error;
|
|
191
|
+
return defaultCollaboration();
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
async function generateAdoptionPrompt({ environment, instructions, program, request, root, sessionPrompt, stackPackages }) {
|
|
156
196
|
const blueprint = await readBlueprint(root, { required: true });
|
|
157
197
|
const stack = await readStack(root, { stackPackages });
|
|
158
198
|
const availableStackPackages = [...new Set([...stack.stackPackages, ...stackPackages])];
|
|
@@ -176,7 +216,7 @@ async function generateAdoptionPrompt({ engineering, environment, instructions,
|
|
|
176
216
|
projectRoot: root,
|
|
177
217
|
projectKind: 'existing',
|
|
178
218
|
blueprint: { path: blueprint.path, source: blueprint.source },
|
|
179
|
-
|
|
219
|
+
...sessionPrompt.context,
|
|
180
220
|
stack: stackPromptContext(stack),
|
|
181
221
|
availableStackPieces: stackCatalogContext(catalog),
|
|
182
222
|
program: programContext(program),
|
|
@@ -185,7 +225,8 @@ async function generateAdoptionPrompt({ engineering, environment, instructions,
|
|
|
185
225
|
: { status: 'present' },
|
|
186
226
|
codeIndex: codeIndexContext(index),
|
|
187
227
|
},
|
|
188
|
-
|
|
228
|
+
collaborationGuidance: sessionPrompt.collaborationGuidance,
|
|
229
|
+
engineeringGuidance: sessionPrompt.engineeringGuidance,
|
|
189
230
|
guidance: stack.guidance,
|
|
190
231
|
adoption: stack.adoption,
|
|
191
232
|
skills: renderAgentSkillCatalog(projectSkills.skills),
|
|
@@ -200,7 +241,7 @@ async function generateAdoptionPrompt({ engineering, environment, instructions,
|
|
|
200
241
|
};
|
|
201
242
|
}
|
|
202
243
|
|
|
203
|
-
async function generateExplanationPrompt({
|
|
244
|
+
async function generateExplanationPrompt({ instructions, program, request, root, sessionPrompt, stackPackages, task }) {
|
|
204
245
|
const blueprint = await readBlueprint(root, {
|
|
205
246
|
required: true,
|
|
206
247
|
requireDescription: task === 'program',
|
|
@@ -223,12 +264,13 @@ async function generateExplanationPrompt({ engineering, instructions, program, r
|
|
|
223
264
|
task,
|
|
224
265
|
projectRoot: root,
|
|
225
266
|
blueprint: blueprintContext,
|
|
226
|
-
|
|
267
|
+
...sessionPrompt.context,
|
|
227
268
|
stack: stackPromptContext(stack),
|
|
228
269
|
program: programContext(program),
|
|
229
270
|
codeIndex: codeIndexContext(index),
|
|
230
271
|
},
|
|
231
|
-
|
|
272
|
+
collaborationGuidance: sessionPrompt.collaborationGuidance,
|
|
273
|
+
engineeringGuidance: sessionPrompt.engineeringGuidance,
|
|
232
274
|
guidance: stack.guidance,
|
|
233
275
|
skills: renderAgentSkillCatalog(projectSkills.skills),
|
|
234
276
|
}),
|
|
@@ -243,11 +285,11 @@ async function generateExplanationPrompt({ engineering, instructions, program, r
|
|
|
243
285
|
|
|
244
286
|
async function generateStartPrompt({
|
|
245
287
|
hiddenStackPieces,
|
|
246
|
-
engineering,
|
|
247
288
|
instructions,
|
|
248
289
|
program,
|
|
249
290
|
request,
|
|
250
291
|
root,
|
|
292
|
+
sessionPrompt,
|
|
251
293
|
stackPackages,
|
|
252
294
|
}) {
|
|
253
295
|
let blueprint;
|
|
@@ -267,9 +309,10 @@ async function generateStartPrompt({
|
|
|
267
309
|
projectRoot: root,
|
|
268
310
|
projectKind: 'existing-uninitialized',
|
|
269
311
|
genesis: { initialized: false },
|
|
270
|
-
|
|
312
|
+
...sessionPrompt.context,
|
|
271
313
|
},
|
|
272
|
-
|
|
314
|
+
collaborationGuidance: sessionPrompt.collaborationGuidance,
|
|
315
|
+
engineeringGuidance: sessionPrompt.engineeringGuidance,
|
|
273
316
|
}),
|
|
274
317
|
warnings: program.diagnostic ? [program.diagnostic] : [],
|
|
275
318
|
verificationCommands: [],
|
|
@@ -306,7 +349,7 @@ async function generateStartPrompt({
|
|
|
306
349
|
path: blueprint.path,
|
|
307
350
|
description: blueprint.description,
|
|
308
351
|
},
|
|
309
|
-
|
|
352
|
+
...sessionPrompt.context,
|
|
310
353
|
stack: startStackContext(stack),
|
|
311
354
|
...(projectKind === 'new'
|
|
312
355
|
? {
|
|
@@ -315,7 +358,8 @@ async function generateStartPrompt({
|
|
|
315
358
|
}
|
|
316
359
|
: { program: startProgramContext(program) }),
|
|
317
360
|
},
|
|
318
|
-
|
|
361
|
+
collaborationGuidance: sessionPrompt.collaborationGuidance,
|
|
362
|
+
engineeringGuidance: sessionPrompt.engineeringGuidance,
|
|
319
363
|
guidance: stack.guidance,
|
|
320
364
|
}),
|
|
321
365
|
warnings: [
|
|
@@ -331,6 +375,7 @@ export async function generateProjectPrompt({
|
|
|
331
375
|
hiddenStackPieces = [],
|
|
332
376
|
projectRoot,
|
|
333
377
|
request = '',
|
|
378
|
+
sessionContextInstalled = false,
|
|
334
379
|
stackPackages = [],
|
|
335
380
|
task = 'work',
|
|
336
381
|
} = {}) {
|
|
@@ -339,10 +384,16 @@ export async function generateProjectPrompt({
|
|
|
339
384
|
}
|
|
340
385
|
const root = (await gitContext(projectRoot)).repositoryRoot;
|
|
341
386
|
const userRequest = requestText(request, task);
|
|
342
|
-
const [instructions, engineering] = await Promise.all([
|
|
387
|
+
const [instructions, collaboration, engineering] = await Promise.all([
|
|
343
388
|
readInstalledAsset(task),
|
|
389
|
+
collaborationForPrompt(root),
|
|
344
390
|
readEngineering(root),
|
|
345
391
|
]);
|
|
392
|
+
const sessionPrompt = stableSessionPromptParts({
|
|
393
|
+
collaboration,
|
|
394
|
+
engineering,
|
|
395
|
+
installed: sessionContextInstalled === true,
|
|
396
|
+
});
|
|
346
397
|
|
|
347
398
|
if (task === 'blueprint') {
|
|
348
399
|
const blueprint = await readBlueprint(root);
|
|
@@ -357,9 +408,10 @@ export async function generateProjectPrompt({
|
|
|
357
408
|
path: 'genesis/blueprint.md',
|
|
358
409
|
source: blueprint?.source || BLUEPRINT_SKELETON_SOURCE,
|
|
359
410
|
},
|
|
360
|
-
|
|
411
|
+
...sessionPrompt.context,
|
|
361
412
|
},
|
|
362
|
-
|
|
413
|
+
collaborationGuidance: sessionPrompt.collaborationGuidance,
|
|
414
|
+
engineeringGuidance: sessionPrompt.engineeringGuidance,
|
|
363
415
|
skills: renderAgentSkillCatalog(projectSkills.skills),
|
|
364
416
|
});
|
|
365
417
|
return {
|
|
@@ -376,21 +428,21 @@ export async function generateProjectPrompt({
|
|
|
376
428
|
return generateStartPrompt({
|
|
377
429
|
instructions,
|
|
378
430
|
hiddenStackPieces,
|
|
379
|
-
engineering,
|
|
380
431
|
program,
|
|
381
432
|
request: userRequest,
|
|
382
433
|
root,
|
|
434
|
+
sessionPrompt,
|
|
383
435
|
stackPackages,
|
|
384
436
|
});
|
|
385
437
|
}
|
|
386
438
|
if (task === 'adopt') {
|
|
387
439
|
return generateAdoptionPrompt({
|
|
388
440
|
environment,
|
|
389
|
-
engineering,
|
|
390
441
|
instructions,
|
|
391
442
|
program,
|
|
392
443
|
request: userRequest,
|
|
393
444
|
root,
|
|
445
|
+
sessionPrompt,
|
|
394
446
|
stackPackages,
|
|
395
447
|
});
|
|
396
448
|
}
|
|
@@ -403,10 +455,10 @@ export async function generateProjectPrompt({
|
|
|
403
455
|
return generateStartPrompt({
|
|
404
456
|
instructions: await readInstalledAsset('start'),
|
|
405
457
|
hiddenStackPieces,
|
|
406
|
-
engineering,
|
|
407
458
|
program,
|
|
408
459
|
request: userRequest,
|
|
409
460
|
root,
|
|
461
|
+
sessionPrompt,
|
|
410
462
|
stackPackages,
|
|
411
463
|
});
|
|
412
464
|
}
|
|
@@ -414,10 +466,10 @@ export async function generateProjectPrompt({
|
|
|
414
466
|
return generateStartPrompt({
|
|
415
467
|
instructions: await readInstalledAsset('start'),
|
|
416
468
|
hiddenStackPieces,
|
|
417
|
-
engineering,
|
|
418
469
|
program,
|
|
419
470
|
request: userRequest,
|
|
420
471
|
root,
|
|
472
|
+
sessionPrompt,
|
|
421
473
|
stackPackages,
|
|
422
474
|
});
|
|
423
475
|
}
|
|
@@ -425,10 +477,10 @@ export async function generateProjectPrompt({
|
|
|
425
477
|
if (['describe', 'program'].includes(task)) {
|
|
426
478
|
return generateExplanationPrompt({
|
|
427
479
|
instructions,
|
|
428
|
-
engineering,
|
|
429
480
|
program,
|
|
430
481
|
request: userRequest,
|
|
431
482
|
root,
|
|
483
|
+
sessionPrompt,
|
|
432
484
|
stackPackages,
|
|
433
485
|
task,
|
|
434
486
|
});
|
|
@@ -454,7 +506,7 @@ export async function generateProjectPrompt({
|
|
|
454
506
|
task,
|
|
455
507
|
projectRoot: root,
|
|
456
508
|
blueprint: { path: blueprint.path, description: blueprint.description },
|
|
457
|
-
|
|
509
|
+
...sessionPrompt.context,
|
|
458
510
|
stack: stackPromptContext(stack),
|
|
459
511
|
program: programContext(program),
|
|
460
512
|
resourceInputs: missing.length > 0
|
|
@@ -472,7 +524,8 @@ export async function generateProjectPrompt({
|
|
|
472
524
|
instructions,
|
|
473
525
|
request: userRequest,
|
|
474
526
|
context,
|
|
475
|
-
|
|
527
|
+
collaborationGuidance: sessionPrompt.collaborationGuidance,
|
|
528
|
+
engineeringGuidance: sessionPrompt.engineeringGuidance,
|
|
476
529
|
guidance: stack.guidance,
|
|
477
530
|
skills: renderAgentSkillCatalog(projectSkills.skills),
|
|
478
531
|
postChange: task === 'work' ? stack.postChange : '',
|
|
@@ -1,7 +1,16 @@
|
|
|
1
|
+
import { readCollaboration } from './collaboration.js';
|
|
2
|
+
import { GENESIS_CONTRACTS } from './contracts.js';
|
|
1
3
|
import { readEngineering, readEngineeringBaseline } from './engineering.js';
|
|
4
|
+
import { GenesisError } from './errors.js';
|
|
2
5
|
import { gitContext } from './git.js';
|
|
3
6
|
import { readStack } from './stack.js';
|
|
4
7
|
import { listStackCatalogPieces } from './stack-catalog.js';
|
|
8
|
+
import { normalizeSource, sha256, stableJson } from './utils.js';
|
|
9
|
+
|
|
10
|
+
const HOST_CONTEXT_MAX_BYTES = Object.freeze({
|
|
11
|
+
session: 16 * 1024,
|
|
12
|
+
turn: 512,
|
|
13
|
+
});
|
|
5
14
|
|
|
6
15
|
async function optionalStack(projectRoot, stackPackages) {
|
|
7
16
|
try { return await readStack(projectRoot, { stackPackages }); } catch { return null; }
|
|
@@ -24,6 +33,65 @@ async function optionalEngineering(projectRoot) {
|
|
|
24
33
|
}
|
|
25
34
|
}
|
|
26
35
|
|
|
36
|
+
async function optionalCollaboration(projectRoot) {
|
|
37
|
+
try {
|
|
38
|
+
return await readCollaboration(projectRoot);
|
|
39
|
+
} catch {
|
|
40
|
+
return {
|
|
41
|
+
guidance: [
|
|
42
|
+
'The project collaboration approach is invalid. Do not infer replacement preferences; run the Genesis `check` operation.',
|
|
43
|
+
].join('\n'),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function hostContextContribution({ hostDriver, hostDriverInput, scope }) {
|
|
49
|
+
if (hostDriver === undefined || hostDriver === null) {
|
|
50
|
+
if (hostDriverInput !== undefined) {
|
|
51
|
+
throw new GenesisError(
|
|
52
|
+
'HOST_CONTEXT_INVALID',
|
|
53
|
+
'Host context input requires an explicitly registered host driver.',
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
return '';
|
|
57
|
+
}
|
|
58
|
+
if (typeof hostDriver !== 'function') {
|
|
59
|
+
throw new GenesisError('HOST_CONTEXT_INVALID', 'The registered host driver must be a function.');
|
|
60
|
+
}
|
|
61
|
+
if (
|
|
62
|
+
!hostDriverInput
|
|
63
|
+
|| typeof hostDriverInput !== 'object'
|
|
64
|
+
|| Array.isArray(hostDriverInput)
|
|
65
|
+
|| hostDriverInput.scope !== scope
|
|
66
|
+
) {
|
|
67
|
+
throw new GenesisError(
|
|
68
|
+
'HOST_CONTEXT_INVALID',
|
|
69
|
+
`The ${scope} context lane requires host input with scope \`${scope}\`.`,
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
const value = await hostDriver(hostDriverInput);
|
|
73
|
+
if (typeof value !== 'string') {
|
|
74
|
+
throw new GenesisError('HOST_CONTEXT_INVALID', 'The registered host driver must return plain text.');
|
|
75
|
+
}
|
|
76
|
+
const output = normalizeSource(value).trim();
|
|
77
|
+
if (Buffer.byteLength(output, 'utf8') > HOST_CONTEXT_MAX_BYTES[scope]) {
|
|
78
|
+
throw new GenesisError(
|
|
79
|
+
'HOST_CONTEXT_INVALID',
|
|
80
|
+
`The registered host driver's ${scope} contribution exceeds ${HOST_CONTEXT_MAX_BYTES[scope]} bytes.`,
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
return output;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function composedContext(contract, output) {
|
|
87
|
+
return {
|
|
88
|
+
contract,
|
|
89
|
+
status: 'ready',
|
|
90
|
+
output,
|
|
91
|
+
identity: sha256(stableJson({ contract, output })),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
27
95
|
async function optionalStackComponentIds(projectRoot, stack, stackPackages) {
|
|
28
96
|
try {
|
|
29
97
|
const packages = [...new Set([...(stack?.stackPackages || []), ...stackPackages])];
|
|
@@ -34,40 +102,62 @@ async function optionalStackComponentIds(projectRoot, stack, stackPackages) {
|
|
|
34
102
|
}
|
|
35
103
|
}
|
|
36
104
|
|
|
37
|
-
export async function projectSessionContext({
|
|
105
|
+
export async function projectSessionContext({
|
|
106
|
+
hostDriver,
|
|
107
|
+
hostDriverInput,
|
|
108
|
+
projectRoot,
|
|
109
|
+
stackPackages = [],
|
|
110
|
+
} = {}) {
|
|
38
111
|
const root = (await gitContext(projectRoot)).repositoryRoot;
|
|
39
|
-
const [stack, engineering] = await Promise.all([
|
|
112
|
+
const [stack, collaboration, engineering, hostContext] = await Promise.all([
|
|
40
113
|
optionalStack(root, stackPackages),
|
|
114
|
+
optionalCollaboration(root),
|
|
41
115
|
optionalEngineering(root),
|
|
116
|
+
hostContextContribution({ hostDriver, hostDriverInput, scope: 'session' }),
|
|
42
117
|
]);
|
|
43
118
|
const availableComponents = await optionalStackComponentIds(root, stack, stackPackages);
|
|
44
119
|
const selected = stack?.components.map(({ id }) => id) || [];
|
|
45
120
|
const stackStatus = stack
|
|
46
121
|
? (selected.length > 0 ? selected.join(', ') : 'none')
|
|
47
122
|
: 'unavailable; run the Genesis `check` operation';
|
|
123
|
+
const output = [
|
|
124
|
+
'This is a Genesis-enriched project.',
|
|
125
|
+
'- Read `genesis/blueprint.md`, `genesis/collaboration.md`, `genesis/engineering.md`, and `genesis/stack.md` for product intent, collaboration approach, engineering approach, and selected technology.',
|
|
126
|
+
'- For a new project whose Blueprint does not yet establish product direction, do not research technology or create source until the user has made clear what is being built, who or what will use or invoke it, and the first observable useful outcome. Ask only unresolved high-impact questions. A reply confirms only what it explicitly answers; Stack confirmation is not product intent.',
|
|
127
|
+
'- Once product direction is clear, choose one smallest implementation path through selected technology guidance, or authoritative technology documentation when the catalog has no match, and read only what that path requires. Do not survey alternatives, clone whole technology repositories, inspect unrelated package internals, or delegate research unless one concrete failure requires one exact investigation.',
|
|
128
|
+
`- Available Stack components: ${availableComponents.length > 0 ? availableComponents.map((id) => `\`${id}\``).join(', ') : 'none'}.`,
|
|
129
|
+
'- When the user names an unselected technology that exactly matches this catalog, run `genesis stack list`, ask whether to add and prepare it, and wait for confirmation. If confirmed, run `genesis stack add <piece...>` and follow its returned preparation prompt in the same task; then use `genesis context` and any installed technology skill. Never infer dependency commands from a component id. If declined or unmatched, continue through authoritative technology documentation without inventing a component.',
|
|
130
|
+
'- Project-owned operation sections in `genesis/stack.md` are the durable application contract. Make the implementation satisfy them or update a complete section to match evidenced reality; Genesis executes only Verification.',
|
|
131
|
+
'- Use the relevant project Agent Skills below `.agents/skills/`.',
|
|
132
|
+
'- After locating source, run `genesis context <path...>`; before adding a helper or public operation, run `genesis index <name-or-path...>` and reuse an existing owner.',
|
|
133
|
+
'- Program is fallible explanation; code, tests, and runtime behavior remain evidence.',
|
|
134
|
+
'- Keep Blueprint and affected Program explanations aligned with intentional observable product behavior in the same implementation turn. Private restructuring may need only source citations or no explanatory change.',
|
|
135
|
+
'- Before reporting completion, compare the requested observable behavior, required inputs and resources, declared project operations, and focused evidence with what actually exists. State anything not proven.',
|
|
136
|
+
'- Deslop only when explicitly requested. Genesis defines its behavior-preserving committed scope; selected Stack components may add technology-specific cleanup guidance.',
|
|
137
|
+
'- This guidance is loaded for a new session and refreshed after compaction. Continue the active request without restarting completed work.',
|
|
138
|
+
`Engineering profile: ${engineering.profile?.id || 'invalid; run the Genesis `check` operation'}.`,
|
|
139
|
+
`Selected Stack components: ${stackStatus}.`,
|
|
140
|
+
'',
|
|
141
|
+
'ENGINEERING APPROACH',
|
|
142
|
+
'',
|
|
143
|
+
engineering.guidance,
|
|
144
|
+
'',
|
|
145
|
+
'COLLABORATION APPROACH',
|
|
146
|
+
'',
|
|
147
|
+
collaboration.guidance,
|
|
148
|
+
...(hostContext ? ['', 'HOST CONTEXT', '', hostContext] : []),
|
|
149
|
+
].join('\n');
|
|
150
|
+
return composedContext(GENESIS_CONTRACTS.sessionContext, output);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export async function projectTurnContext({ hostDriver, hostDriverInput } = {}) {
|
|
154
|
+
const output = await hostContextContribution({
|
|
155
|
+
hostDriver,
|
|
156
|
+
hostDriverInput,
|
|
157
|
+
scope: 'turn',
|
|
158
|
+
});
|
|
48
159
|
return {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
'This is a Genesis-enriched project.',
|
|
52
|
-
'- Read `genesis/blueprint.md`, `genesis/engineering.md`, and `genesis/stack.md` for product intent, engineering approach, and selected technology.',
|
|
53
|
-
'- For a new project whose Blueprint does not yet establish product direction, do not research technology or create source until the user has made clear what is being built, who or what will use or invoke it, and the first observable useful outcome. Ask only unresolved high-impact questions. A reply confirms only what it explicitly answers; Stack confirmation is not product intent.',
|
|
54
|
-
'- Once product direction is clear, choose one smallest implementation path through selected technology guidance, or authoritative technology documentation when the catalog has no match, and read only what that path requires. Do not survey alternatives, clone whole technology repositories, inspect unrelated package internals, or delegate research unless one concrete failure requires one exact investigation.',
|
|
55
|
-
`- Available Stack components: ${availableComponents.length > 0 ? availableComponents.map((id) => `\`${id}\``).join(', ') : 'none'}.`,
|
|
56
|
-
'- When the user names an unselected technology that exactly matches this catalog, run `genesis stack list`, ask whether to add and prepare it, and wait for confirmation. If confirmed, run `genesis stack add <piece...>` and follow its returned preparation prompt in the same task; then use `genesis context` and any installed technology skill. Never infer dependency commands from a component id. If declined or unmatched, continue through authoritative technology documentation without inventing a component.',
|
|
57
|
-
'- Project-owned operation sections in `genesis/stack.md` are the durable application contract. Make the implementation satisfy them or update a complete section to match evidenced reality; Genesis executes only Verification.',
|
|
58
|
-
'- Use the relevant project Agent Skills below `.agents/skills/`.',
|
|
59
|
-
'- After locating source, run `genesis context <path...>`; before adding a helper or public operation, run `genesis index <name-or-path...>` and reuse an existing owner.',
|
|
60
|
-
'- Program is fallible explanation; code, tests, and runtime behavior remain evidence.',
|
|
61
|
-
'- Keep Blueprint and affected Program explanations aligned with intentional observable product behavior in the same implementation turn. Private restructuring may need only source citations or no explanatory change.',
|
|
62
|
-
'- Before reporting completion, compare the requested observable behavior, required inputs and resources, declared project operations, and focused evidence with what actually exists. State anything not proven.',
|
|
63
|
-
'- Deslop only when explicitly requested. Genesis defines its behavior-preserving committed scope; selected Stack components may add technology-specific cleanup guidance.',
|
|
64
|
-
'- This guidance is loaded for a new session and refreshed after compaction. Continue the active request without restarting completed work.',
|
|
65
|
-
`Engineering profile: ${engineering.profile?.id || 'invalid; run the Genesis `check` operation'}.`,
|
|
66
|
-
`Selected Stack components: ${stackStatus}.`,
|
|
67
|
-
'',
|
|
68
|
-
'ENGINEERING APPROACH',
|
|
69
|
-
'',
|
|
70
|
-
engineering.guidance,
|
|
71
|
-
].join('\n'),
|
|
160
|
+
...composedContext(GENESIS_CONTRACTS.turnContext, output),
|
|
161
|
+
trust: 'untrusted',
|
|
72
162
|
};
|
|
73
163
|
}
|
package/src/index.js
CHANGED
|
@@ -2,6 +2,10 @@ import path from 'node:path';
|
|
|
2
2
|
|
|
3
3
|
import { checkProject } from './index/check.js';
|
|
4
4
|
import { buildProjectIndex, GENESIS_DERIVED_ARTIFACTS } from './index/code-index.js';
|
|
5
|
+
import {
|
|
6
|
+
inspectProjectCollaboration,
|
|
7
|
+
setProjectCollaboration,
|
|
8
|
+
} from './index/collaboration.js';
|
|
5
9
|
import { GENESIS_CONTRACTS } from './index/contracts.js';
|
|
6
10
|
import { contextForProjectPaths } from './index/context.js';
|
|
7
11
|
import { generateProjectPrompt } from './index/prompt.js';
|
|
@@ -19,8 +23,21 @@ import { listStackCatalogPieces } from './index/stack-catalog.js';
|
|
|
19
23
|
import { addStackPieces, readStack } from './index/stack.js';
|
|
20
24
|
import { uniqueSorted } from './index/utils.js';
|
|
21
25
|
import { verifyProject } from './index/verification.js';
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
import { projectSessionContext, projectTurnContext } from './index/session-context.js';
|
|
27
|
+
import {
|
|
28
|
+
HOST_CONTEXT_RESOLVER_DATA_ENV,
|
|
29
|
+
HOST_CONTEXT_RESOLVER_ENV,
|
|
30
|
+
SESSION_CONTEXT_INSTALLED_ENV,
|
|
31
|
+
} from './index/host-context-resolver.js';
|
|
32
|
+
|
|
33
|
+
export {
|
|
34
|
+
GENESIS_CONTRACTS,
|
|
35
|
+
HOST_CONTEXT_RESOLVER_DATA_ENV,
|
|
36
|
+
HOST_CONTEXT_RESOLVER_ENV,
|
|
37
|
+
SESSION_CONTEXT_INSTALLED_ENV,
|
|
38
|
+
projectSessionContext,
|
|
39
|
+
projectTurnContext,
|
|
40
|
+
};
|
|
24
41
|
|
|
25
42
|
function withIndexResult(result, index) {
|
|
26
43
|
const changedFiles = uniqueSorted([...result.changedFiles, ...index.changedFiles]);
|
|
@@ -115,6 +132,10 @@ export function inspectEnvironment(options) {
|
|
|
115
132
|
return inspectProjectEnvironment(options);
|
|
116
133
|
}
|
|
117
134
|
|
|
135
|
+
export function inspectCollaboration(options) {
|
|
136
|
+
return inspectProjectCollaboration(options);
|
|
137
|
+
}
|
|
138
|
+
|
|
118
139
|
export function inspectStackSection(options) {
|
|
119
140
|
return inspectProjectStackSection(options);
|
|
120
141
|
}
|
|
@@ -131,6 +152,10 @@ export function setEngineeringProfile(options) {
|
|
|
131
152
|
return selectEngineeringProfile(options);
|
|
132
153
|
}
|
|
133
154
|
|
|
155
|
+
export function setCollaboration(options) {
|
|
156
|
+
return setProjectCollaboration(options);
|
|
157
|
+
}
|
|
158
|
+
|
|
134
159
|
export function generatePrompt(options) {
|
|
135
160
|
return generateProjectPrompt(options);
|
|
136
161
|
}
|