genesis-compiler 1.2.18 → 1.2.19
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 +18 -17
- package/docs/prompt-integration.md +13 -12
- package/package.json +1 -2
- package/plugins/genesis/.codex-plugin/plugin.json +1 -1
- package/prompts/deslop.txt +5 -0
- package/src/cli.js +6 -2
- package/src/index/assets.js +0 -1
- package/src/index/codex-hooks.js +31 -13
- package/prompts/final-summary.txt +0 -12
package/README.md
CHANGED
|
@@ -261,26 +261,27 @@ Python, Java, C#, C/C++, PHP, Go, Rust, Ruby, Kotlin, and Shell. A future techno
|
|
|
261
261
|
adds its adapter through its Stack piece rather than teaching Genesis prompts
|
|
262
262
|
to parse that language.
|
|
263
263
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
264
|
+
Before changing project files for a user-requested implementation, Codex runs
|
|
265
|
+
`genesis hook authorize`. At the end of an authorized turn that changed
|
|
266
|
+
Git-visible project files, the Stop hook asks Codex for bounded follow-up turns.
|
|
267
|
+
Unmarked turns finish normally even if another process changes the same
|
|
268
|
+
checkout. When the selected Stack contributes `Post-change` work, all
|
|
269
|
+
contributions compose deterministically into one optional code-changing turn.
|
|
270
|
+
Genesis then reconciles the Blueprint and affected Program explanations from
|
|
271
|
+
the complete changed-path set and actual Git diff, and refreshes both City
|
|
272
|
+
projections. A focused, behavior-preserving Deslop pass runs before both Cities
|
|
273
|
+
are refreshed again; its response is the concise user-facing completion. A
|
|
274
|
+
project with no selected Stack uses only the `genesis-deslop` skill. Selected
|
|
275
|
+
Stack components enrich Post-change work, reconciliation, and cleanup with
|
|
276
|
+
general Guidance, and enrich cleanup further with technology-specific Deslop
|
|
277
|
+
guidance.
|
|
276
278
|
|
|
277
279
|
The hook never starts another Codex process. Its small per-session phase is
|
|
278
280
|
limited to `implementation -> optional post-change -> reconcile -> deslop ->
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
Question-only and unchanged turns finish normally.
|
|
281
|
+
done`, so it cannot keep continuing recursively. The Stop after Deslop clears
|
|
282
|
+
the sequence rather than scheduling another model turn. Empty Post-change
|
|
283
|
+
content is skipped rather than producing an empty turn. Question, explanation,
|
|
284
|
+
review, diagnosis-only, and unchanged turns finish normally.
|
|
284
285
|
|
|
285
286
|
Projects can customize a selected technology through its matching file, such
|
|
286
287
|
as `genesis/stack/jskit.md`:
|
|
@@ -77,20 +77,21 @@ command itself and follows its returned prompt in the same conversation. Other
|
|
|
77
77
|
hosts can call `adoptProject()` and send its `prompt` directly.
|
|
78
78
|
|
|
79
79
|
Codex can instead use the project-local hooks installed by `genesis init`.
|
|
80
|
-
Those hooks inject a short operating guide
|
|
81
|
-
|
|
80
|
+
Those hooks inject a short operating guide and record the Git-visible state when
|
|
81
|
+
each user prompt begins. Before editing for an explicit user implementation
|
|
82
|
+
request, Codex marks that turn with `genesis hook authorize`. Only an authorized
|
|
83
|
+
turn whose project files changed can request bounded continuations; unmarked
|
|
84
|
+
turns finish normally even if another process changes the checkout. Selected
|
|
82
85
|
`Post-change` contributions compose into one optional code-changing turn;
|
|
83
86
|
Genesis then reconciles Blueprint and affected Program explanations from the
|
|
84
|
-
complete Git-visible change set and Deslops the implementation.
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
then refreshes them again after Deslop in case cleanup changed the
|
|
93
|
-
implementation map.
|
|
87
|
+
complete Git-visible change set and Deslops the implementation. The Deslop
|
|
88
|
+
response is the concise user-facing completion. The hooks invoke the same
|
|
89
|
+
Genesis project operations and never start another agent process. A per-session
|
|
90
|
+
phase permits only `implementation -> optional post-change -> reconcile ->
|
|
91
|
+
deslop -> done`. Empty Post-change content skips that phase. Genesis refreshes
|
|
92
|
+
both City projections after reconciliation so Deslop sees the current
|
|
93
|
+
explanation and function inventory, then refreshes them again after Deslop in
|
|
94
|
+
case cleanup changed the implementation map.
|
|
94
95
|
|
|
95
96
|
Once Codex identifies relevant source, `genesis context <path...>` returns only
|
|
96
97
|
Program modules citing those paths plus the effective engineering approach and
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "genesis-compiler",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.19",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "An agent-independent prompt, multi-language code-index, cleanup, and verification companion with optional Codex hooks.",
|
|
6
6
|
"repository": {
|
|
@@ -31,7 +31,6 @@
|
|
|
31
31
|
"prompts/adopt.txt",
|
|
32
32
|
"prompts/describe.txt",
|
|
33
33
|
"prompts/deslop.txt",
|
|
34
|
-
"prompts/final-summary.txt",
|
|
35
34
|
"prompts/program.txt",
|
|
36
35
|
"prompts/reconcile.txt",
|
|
37
36
|
"prompts/review.txt",
|
package/prompts/deslop.txt
CHANGED
|
@@ -19,3 +19,8 @@ changed path or appears related to the preceding implementation.
|
|
|
19
19
|
|
|
20
20
|
Do not broaden the product change. Run focused checks when useful and summarize
|
|
21
21
|
what became simpler, files changed, and checks actually run.
|
|
22
|
+
|
|
23
|
+
Your response from this turn is the final user-facing answer for the original
|
|
24
|
+
request. Make it concise and self-contained. Lead with the outcome, include the
|
|
25
|
+
important implemented behavior and any genuine blocker or unfinished work, and
|
|
26
|
+
do not mention automatic phases, hooks, or these instructions.
|
package/src/cli.js
CHANGED
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
verify,
|
|
20
20
|
} from './index.js';
|
|
21
21
|
import {
|
|
22
|
+
authorizeCodexTurn,
|
|
22
23
|
codexAdoptionRecommendation,
|
|
23
24
|
codexSessionContext,
|
|
24
25
|
completeCodexTurn,
|
|
@@ -131,8 +132,8 @@ function parseCommand(argv) {
|
|
|
131
132
|
'Command inspect requires environment or section <name>.',
|
|
132
133
|
);
|
|
133
134
|
}
|
|
134
|
-
} else if (command === 'hook' && (operands.length !== 1 || !['begin', 'discover', 'end', 'session', 'stop'].includes(operands[0]))) {
|
|
135
|
-
fail('CLI_HOOK_ACTION_REQUIRED', 'Command hook requires exactly one of: discover, session, begin, stop, end.');
|
|
135
|
+
} else if (command === 'hook' && (operands.length !== 1 || !['authorize', 'begin', 'discover', 'end', 'session', 'stop'].includes(operands[0]))) {
|
|
136
|
+
fail('CLI_HOOK_ACTION_REQUIRED', 'Command hook requires exactly one of: discover, session, begin, authorize, stop, end.');
|
|
136
137
|
} else if (!['adopt', 'context', 'hook', 'index', 'inspect', 'prompt'].includes(command) && operands.length > 0) {
|
|
137
138
|
fail('CLI_EXTRA_ARGUMENT', `Command ${command} accepts no arguments.`);
|
|
138
139
|
}
|
|
@@ -373,6 +374,9 @@ async function execute({ command, operands, options }, { signal } = {}) {
|
|
|
373
374
|
if (operands[0] === 'session') {
|
|
374
375
|
return { kind: 'session', ...await codexSessionContext({ projectRoot }) };
|
|
375
376
|
}
|
|
377
|
+
if (operands[0] === 'authorize') {
|
|
378
|
+
return { kind: 'authorize', ...await authorizeCodexTurn({ projectRoot }) };
|
|
379
|
+
}
|
|
376
380
|
const input = await hookInput();
|
|
377
381
|
if (operands[0] === 'begin') {
|
|
378
382
|
return { kind: 'begin', ...await recordCodexTurn({ input, projectRoot }) };
|
package/src/index/assets.js
CHANGED
|
@@ -8,7 +8,6 @@ const assets = {
|
|
|
8
8
|
describe: new URL('prompts/describe.txt', root),
|
|
9
9
|
reconcile: new URL('prompts/reconcile.txt', root),
|
|
10
10
|
deslop: new URL('prompts/deslop.txt', root),
|
|
11
|
-
finalSummary: new URL('prompts/final-summary.txt', root),
|
|
12
11
|
program: new URL('prompts/program.txt', root),
|
|
13
12
|
blueprint: new URL('prompts/blueprint.txt', root),
|
|
14
13
|
review: new URL('prompts/review.txt', root),
|
package/src/index/codex-hooks.js
CHANGED
|
@@ -157,8 +157,9 @@ export async function codexSessionContext({ projectRoot } = {}) {
|
|
|
157
157
|
'- Before creating a helper or public operation, run `genesis index <name-or-path>` and reuse an existing function when it already owns the behavior.',
|
|
158
158
|
'- `.genesis/machine-city.json` is the detailed code/function map; `.genesis/program-city.json` is the simpler subsystem/operation map.',
|
|
159
159
|
'- Program is fallible explanation; code, tests, and runtime behavior remain evidence.',
|
|
160
|
+
'- Before changing project files for a user-requested implementation, run `genesis hook authorize`. Never authorize answer, explanation, review, or diagnosis-only turns.',
|
|
160
161
|
'- Apply the engineering approach below to implementation and cleanup; the Stop hook owns optional Stack Post-change work, Blueprint/Program reconciliation, and Deslop turns.',
|
|
161
|
-
'- After
|
|
162
|
+
'- After an authorized code-changing turn, Genesis may request separate post-change, explanation, and cleanup turns.',
|
|
162
163
|
`Engineering profile: ${engineering.profile?.id || 'invalid; run \`genesis check\`'}.`,
|
|
163
164
|
`Selected Stack components: ${stackStatus}.`,
|
|
164
165
|
'',
|
|
@@ -250,6 +251,7 @@ export async function recordCodexTurn({ input, projectRoot } = {}) {
|
|
|
250
251
|
schemaVersion: HOOK_STATE_SCHEMA_VERSION,
|
|
251
252
|
turnId: hookId(input, 'turn_id'),
|
|
252
253
|
phase: 'implementation',
|
|
254
|
+
implementationAuthorized: false,
|
|
253
255
|
snapshot: await repositorySnapshot(root),
|
|
254
256
|
};
|
|
255
257
|
await writeTurnState(statePath, state);
|
|
@@ -263,6 +265,27 @@ async function readTurnState(statePath) {
|
|
|
263
265
|
}
|
|
264
266
|
}
|
|
265
267
|
|
|
268
|
+
export async function authorizeCodexTurn({
|
|
269
|
+
projectRoot = process.cwd(),
|
|
270
|
+
sessionId = process.env.CODEX_SESSION_ID,
|
|
271
|
+
} = {}) {
|
|
272
|
+
if (!sessionId) {
|
|
273
|
+
throw new GenesisError(
|
|
274
|
+
'CODEX_SESSION_ID_MISSING',
|
|
275
|
+
'genesis hook authorize requires the current Codex session.',
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
const root = (await gitContext(projectRoot)).repositoryRoot;
|
|
279
|
+
const statePath = await hookStatePath(root, { session_id: sessionId });
|
|
280
|
+
const state = await readTurnState(statePath);
|
|
281
|
+
if (!state || state.schemaVersion !== HOOK_STATE_SCHEMA_VERSION || state.phase !== 'implementation') {
|
|
282
|
+
return { status: 'not-applicable' };
|
|
283
|
+
}
|
|
284
|
+
if (state.implementationAuthorized === true) return { status: 'unchanged' };
|
|
285
|
+
await writeTurnState(statePath, { ...state, implementationAuthorized: true });
|
|
286
|
+
return { status: 'authorized' };
|
|
287
|
+
}
|
|
288
|
+
|
|
266
289
|
async function committedPaths(projectRoot, before, after) {
|
|
267
290
|
if (before === after) return [];
|
|
268
291
|
if (!after) return ['repository history changed'];
|
|
@@ -382,16 +405,17 @@ async function deslopContinuation(projectRoot, changedPaths) {
|
|
|
382
405
|
].join('\n');
|
|
383
406
|
}
|
|
384
407
|
|
|
385
|
-
async function finalSummaryContinuation() {
|
|
386
|
-
return (await readInstalledAsset('finalSummary')).trim();
|
|
387
|
-
}
|
|
388
|
-
|
|
389
408
|
export async function completeCodexTurn({ input, projectRoot } = {}) {
|
|
390
409
|
const root = (await gitContext(projectRoot || input?.cwd)).repositoryRoot;
|
|
391
410
|
const statePath = await hookStatePath(root, input);
|
|
392
411
|
const state = await readTurnState(statePath);
|
|
393
412
|
if (!state || state.schemaVersion !== HOOK_STATE_SCHEMA_VERSION) return {};
|
|
394
413
|
|
|
414
|
+
if (state.implementationAuthorized !== true) {
|
|
415
|
+
await rm(statePath, { force: true });
|
|
416
|
+
return {};
|
|
417
|
+
}
|
|
418
|
+
|
|
395
419
|
if (state.phase === 'implementation') {
|
|
396
420
|
if (input?.stop_hook_active === true || state.turnId !== hookId(input, 'turn_id')) {
|
|
397
421
|
await rm(statePath, { force: true });
|
|
@@ -465,14 +489,8 @@ export async function completeCodexTurn({ input, projectRoot } = {}) {
|
|
|
465
489
|
|
|
466
490
|
if (state.phase === 'deslop') {
|
|
467
491
|
await refreshProjectIndex(root);
|
|
468
|
-
await
|
|
469
|
-
|
|
470
|
-
phase: 'summary',
|
|
471
|
-
});
|
|
472
|
-
return {
|
|
473
|
-
decision: 'block',
|
|
474
|
-
reason: await finalSummaryContinuation(),
|
|
475
|
-
};
|
|
492
|
+
await rm(statePath, { force: true });
|
|
493
|
+
return {};
|
|
476
494
|
}
|
|
477
495
|
|
|
478
496
|
await rm(statePath, { force: true });
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
This is the final automatic user-facing summary for the original request.
|
|
2
|
-
|
|
3
|
-
Use only the existing conversation context from the implementation and its
|
|
4
|
-
follow-up turns. Do not inspect the repository or codebase, call tools, run
|
|
5
|
-
commands or tests, edit files, reconcile explanations, or perform cleanup.
|
|
6
|
-
|
|
7
|
-
Write one concise, self-contained answer to the user. Lead with the outcome.
|
|
8
|
-
Include the important behavior that changed, checks that were actually run,
|
|
9
|
-
useful human verification steps, and any genuine blocker or unfinished work.
|
|
10
|
-
Do not mention automatic phases, hooks, internal follow-up turns, or these
|
|
11
|
-
instructions. Do not claim checks, commits, pushes, or deployments that are not
|
|
12
|
-
already established in the conversation. After the answer, stop.
|