genesis-compiler 1.2.6 → 1.2.8
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 +38 -17
- package/docs/prompt-integration.md +1 -1
- package/docs/stack-components.md +19 -4
- package/package.json +2 -4
- package/plugins/genesis/.codex-plugin/plugin.json +1 -1
- package/src/cli.js +20 -8
- package/src/index/agent-skills.js +11 -3
- package/src/index/check.js +9 -5
- package/src/index/code-index.js +7 -2
- package/src/index/context.js +2 -2
- package/src/index/deployment.js +2 -2
- package/src/index/environment-files.js +6 -2
- package/src/index/init.js +2 -2
- package/src/index/launch.js +2 -1
- package/src/index/prompt.js +24 -16
- package/src/index/stack-catalog.js +111 -26
- package/src/index/stack.js +60 -8
- package/src/index/verification.js +2 -1
- package/src/index/workspace-setup.js +4 -2
- package/src/index.js +42 -18
- package/stacks/pieces/cpp.md +0 -34
- package/stacks/pieces/csharp.md +0 -22
- package/stacks/pieces/go.md +0 -22
- package/stacks/pieces/java.md +0 -22
- package/stacks/pieces/jskit-mysql.md +0 -56
- package/stacks/pieces/jskit-postgresql.md +0 -56
- package/stacks/pieces/jskit.md +0 -114
- package/stacks/pieces/kotlin.md +0 -22
- package/stacks/pieces/mysql.md +0 -29
- package/stacks/pieces/nodejs.md +0 -36
- package/stacks/pieces/php.md +0 -23
- package/stacks/pieces/postgresql.md +0 -30
- package/stacks/pieces/python.md +0 -23
- package/stacks/pieces/ruby.md +0 -22
- package/stacks/pieces/rust.md +0 -22
- package/stacks/pieces/shell.md +0 -23
- package/stacks/pieces/vue.md +0 -28
package/README.md
CHANGED
|
@@ -51,6 +51,18 @@ completely or correctly explains the implementation.
|
|
|
51
51
|
|
|
52
52
|
Genesis requires Node.js 22 or newer and Git.
|
|
53
53
|
|
|
54
|
+
Install the framework-neutral compiler and the optional first-party technology
|
|
55
|
+
catalog as separate packages:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npm install --global genesis-compiler genesis-stack
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`genesis-compiler` has no dependency on `genesis-stack` or on any framework.
|
|
62
|
+
The catalog is static Markdown and contains the complete curated set of
|
|
63
|
+
language, database, UI, and framework pieces. A host may supply another catalog
|
|
64
|
+
through the same contract.
|
|
65
|
+
|
|
54
66
|
For an existing codebase, `adopt` is the direct entry point:
|
|
55
67
|
|
|
56
68
|
```bash
|
|
@@ -102,7 +114,8 @@ that, use Codex normally. No technology is assumed until you explicitly select
|
|
|
102
114
|
Stack components:
|
|
103
115
|
|
|
104
116
|
```bash
|
|
105
|
-
genesis stack add
|
|
117
|
+
genesis stack add --stack-package genesis-stack nodejs
|
|
118
|
+
# or: genesis stack add --stack-package genesis-stack jskit jskit-mysql
|
|
106
119
|
```
|
|
107
120
|
|
|
108
121
|
Genesis does not install substitute generic `nodejs`, `vue`, `php`, or similar
|
|
@@ -110,8 +123,9 @@ skills. Official, user, or host skills retain their normal names. A Stack piece
|
|
|
110
123
|
may instead name one authoritative technology skill; Genesis copies that
|
|
111
124
|
complete directory into `.agents/skills/`, including its `references/`,
|
|
112
125
|
`scripts/`, `assets/`, and agent metadata. The agent loads those resources only
|
|
113
|
-
when the skill requires them. For example, the
|
|
114
|
-
package's own `jskit` skill. A piece's optional
|
|
126
|
+
when the skill requires them. For example, the `genesis-stack` catalog's JSKIT
|
|
127
|
+
piece installs the JSKIT package's own `jskit` skill. A piece's optional
|
|
128
|
+
`## Guidance` is concise
|
|
115
129
|
supplemental project-work guidance; it does not create or replace a generic
|
|
116
130
|
technology skill.
|
|
117
131
|
|
|
@@ -130,8 +144,8 @@ execute the same normalized recipe themselves. A concrete Stack piece may declar
|
|
|
130
144
|
ordered `## Workspace setup` recipe with labels, argument arrays expressed as
|
|
131
145
|
backticked tokens, abstract runtimes, and optional project-relative working
|
|
132
146
|
directories and readiness paths. A recipe whose declared project marker does
|
|
133
|
-
not exist remains unconfigured until a later inspection. The
|
|
134
|
-
piece waits for `package.json` and then declares `npm install`; generic
|
|
147
|
+
not exist remains unconfigured until a later inspection. The catalog's
|
|
148
|
+
`jskit` piece waits for `package.json` and then declares `npm install`; generic
|
|
135
149
|
`nodejs` and `php` deliberately declare no installer. One project section in
|
|
136
150
|
`genesis/stack.md` replaces all component defaults, including with
|
|
137
151
|
`- Nothing.`. Without that override, exactly one component recipe is used;
|
|
@@ -143,7 +157,7 @@ resources such as database variables do not gate dependency installation.
|
|
|
143
157
|
Hosts that manage project environments can call `inspectEnvironment()`.
|
|
144
158
|
Concrete Stack integrations may declare public, non-secret Environment
|
|
145
159
|
defaults such as the database driver selected by that integration. Explicit
|
|
146
|
-
host or user values take precedence. The
|
|
160
|
+
host or user values take precedence. The catalog's JSKIT MySQL and PostgreSQL
|
|
147
161
|
pieces respectively declare `DB_CLIENT=mysql2` and `DB_CLIENT=pg`, so users
|
|
148
162
|
provide connection values rather than restating a deterministic technology
|
|
149
163
|
choice.
|
|
@@ -164,7 +178,8 @@ optional readable `## Launch` section in `genesis/stack.md` declares labeled
|
|
|
164
178
|
targets, exact backticked argument tokens, relative working directories,
|
|
165
179
|
abstract runtime requirements, `{host}`/`{port}` substitutions, and an optional
|
|
166
180
|
application-owned Preview identity block. Concrete components may provide a
|
|
167
|
-
default: `jskit` declares its app-owned `npm run develop`
|
|
181
|
+
default: the catalog's `jskit` piece declares its app-owned `npm run develop`
|
|
182
|
+
command; generic
|
|
168
183
|
`nodejs` and `php` do not guess. Genesis starts nothing itself. It returns preview identity
|
|
169
184
|
command metadata and environment variable names, never their values. The host
|
|
170
185
|
continues to own pinned runtimes, ports, processes, readiness probing and
|
|
@@ -177,7 +192,7 @@ Hosts that publish applications can call the separate public
|
|
|
177
192
|
`inspectDeployment()` API. An optional readable `## Deployment` section
|
|
178
193
|
declares an ordered production recipe: project-relative workdir, abstract
|
|
179
194
|
runtimes, exact Prepare/Build/Migrate/Serve argv, and one HTTP readiness
|
|
180
|
-
predicate. A concrete component may provide the recipe; the
|
|
195
|
+
predicate. A concrete component may provide the recipe; the catalog's `jskit`
|
|
181
196
|
piece declares production dependency installation, build, database preparation,
|
|
182
197
|
`npm start`, and `/api/health`. Generic language pieces do not guess. A project
|
|
183
198
|
section replaces component defaults wholesale, and `- Nothing.` explicitly
|
|
@@ -355,17 +370,23 @@ object.
|
|
|
355
370
|
|
|
356
371
|
## Stack
|
|
357
372
|
|
|
358
|
-
List and select the
|
|
373
|
+
List and select pieces from the installed optional catalog:
|
|
359
374
|
|
|
360
375
|
```bash
|
|
361
|
-
genesis stack list
|
|
362
|
-
genesis stack add
|
|
376
|
+
genesis stack list --stack-package genesis-stack
|
|
377
|
+
genesis stack add --stack-package genesis-stack jskit jskit-mysql
|
|
363
378
|
```
|
|
364
379
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
380
|
+
The explicit package flag bootstraps an unconfigured project. Once a Stack
|
|
381
|
+
selection records `genesis-stack` in `genesis/stack.md`, ordinary commands use
|
|
382
|
+
that recorded package directly; `genesis stack list` needs no host flag.
|
|
383
|
+
|
|
384
|
+
`genesis/stack.md` records the owning Stack package, component ids, and optional
|
|
385
|
+
project verification commands. After the first selection, ordinary commands
|
|
386
|
+
resolve the recorded package without another flag. Selecting no components is
|
|
387
|
+
valid. `genesis-stack` contains the eleven common language families listed
|
|
388
|
+
above, plus Vue, MySQL, PostgreSQL, JSKIT, and JSKIT database integrations.
|
|
389
|
+
Components may contribute:
|
|
369
390
|
|
|
370
391
|
- a concise description and supplemental Guidance used across relevant tasks;
|
|
371
392
|
- existing-project Adoption requirements used only while importing a codebase;
|
|
@@ -381,8 +402,8 @@ cleanup tasks; `Adoption` adds import-only requirements; `Deslop` adds
|
|
|
381
402
|
cleanup-only rules. None shadows an official generic technology skill or
|
|
382
403
|
assumes that an upstream skill contains every rule Genesis needs.
|
|
383
404
|
|
|
384
|
-
Genesis core contains no database, framework, language, or
|
|
385
|
-
|
|
405
|
+
Genesis core contains no Stack pieces and no database, framework, language, or
|
|
406
|
+
platform dependency. See [Stack components](docs/stack-components.md).
|
|
386
407
|
|
|
387
408
|
## Verification
|
|
388
409
|
|
|
@@ -35,7 +35,7 @@ Genesis keeps each instruction at one useful level:
|
|
|
35
35
|
project's `.agents/skills/` directory.
|
|
36
36
|
- `prompts/<task>.txt` is a task launcher. It selects the relevant
|
|
37
37
|
workflow skill and states only that turn's edit boundary.
|
|
38
|
-
- `stacks/pieces/<component>.md` supplies concise Description, supplemental
|
|
38
|
+
- a declared Stack package's `stacks/pieces/<component>.md` supplies concise Description, supplemental
|
|
39
39
|
Guidance, Adoption requirements, Resources, Deslop overlays, structural Indexers, verification
|
|
40
40
|
Commands, and an optional authoritative Agent Skill source.
|
|
41
41
|
- `genesis/blueprint.md`, `genesis/program/`, and `genesis/stack.md` are the
|
package/docs/stack-components.md
CHANGED
|
@@ -1,8 +1,23 @@
|
|
|
1
1
|
# Stack components
|
|
2
2
|
|
|
3
3
|
Genesis core knows no framework, language, database, package manager, or
|
|
4
|
-
environment-variable name
|
|
5
|
-
|
|
4
|
+
environment-variable name, and it ships no technology pieces. A Stack package
|
|
5
|
+
is an ordinary npm package with one static manifest pointer:
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"name": "example-stack",
|
|
10
|
+
"genesis": { "stackPieces": "stacks/pieces" }
|
|
11
|
+
}
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Each piece is one Markdown file in that declared directory. Genesis reads the
|
|
15
|
+
manifest and Markdown only; it never imports or executes package code. Catalog
|
|
16
|
+
names are explicit, collisions fail, and the selected package is recorded in
|
|
17
|
+
the project's `## Stack packages` section. The first-party optional
|
|
18
|
+
`genesis-stack` package contains the complete curated catalog; Genesis core does
|
|
19
|
+
not depend on it. A framework contributes to that catalog rather than requiring
|
|
20
|
+
a compiler release or a separate catalog package.
|
|
6
21
|
|
|
7
22
|
````markdown
|
|
8
23
|
# Stack piece: example
|
|
@@ -169,7 +184,7 @@ environment name and value. Selected
|
|
|
169
184
|
component defaults compose by name; identical declarations collapse and
|
|
170
185
|
different values fail rather than silently choosing one. Defaults participate
|
|
171
186
|
in Stack identity, resource preflight, prompt context, Launch inspection, and
|
|
172
|
-
verification execution. The JSKIT database integrations use this contract for
|
|
187
|
+
verification execution. The `genesis-stack` JSKIT database integrations use this contract for
|
|
173
188
|
their deterministic `DB_CLIENT` driver ids; generic database pieces do not.
|
|
174
189
|
Secrets and deployment-specific connection values remain host inputs and must
|
|
175
190
|
never be declared as defaults.
|
|
@@ -288,7 +303,7 @@ district to a region and a campus while generating
|
|
|
288
303
|
must not reclassify or filter paths. Under a matched prefix, the first directory
|
|
289
304
|
is a campus, while files directly below the prefix belong to the prefix campus.
|
|
290
305
|
Under the fallback, each top-level directory is a campus and project-root files
|
|
291
|
-
belong to the project-root campus. The
|
|
306
|
+
belong to the project-root campus. The `genesis-stack` JSKIT piece excludes exact
|
|
292
307
|
`test`, `tests`, and `__tests__` path segments plus `*.test.*` and `*.spec.*`
|
|
293
308
|
files, then declares `Packages`, `Source`, and `Everything else`.
|
|
294
309
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "genesis-compiler",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.8",
|
|
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": {
|
|
@@ -39,8 +39,7 @@
|
|
|
39
39
|
"prompts/work.txt",
|
|
40
40
|
"plugins/genesis",
|
|
41
41
|
"skills",
|
|
42
|
-
"src"
|
|
43
|
-
"stacks/pieces"
|
|
42
|
+
"src"
|
|
44
43
|
],
|
|
45
44
|
"scripts": {
|
|
46
45
|
"test": "node --test test/*.test.js"
|
|
@@ -58,7 +57,6 @@
|
|
|
58
57
|
"@ast-grep/lang-ruby": "^0.0.7",
|
|
59
58
|
"@ast-grep/lang-rust": "^0.0.7",
|
|
60
59
|
"@ast-grep/napi": "^0.45.1",
|
|
61
|
-
"@jskit-ai/agent-docs": "0.1.134",
|
|
62
60
|
"yaml": "^2.9.0"
|
|
63
61
|
}
|
|
64
62
|
}
|
package/src/cli.js
CHANGED
|
@@ -44,6 +44,7 @@ const USAGE = `Usage:
|
|
|
44
44
|
|
|
45
45
|
Options:
|
|
46
46
|
--project-root <path> Set the project root (default: current directory)
|
|
47
|
+
--stack-package <name> Add an installed external Stack package (repeatable)
|
|
47
48
|
--task <task> Select the prompt task (default: work)
|
|
48
49
|
--json Emit one machine-readable result
|
|
49
50
|
-h, --help Show this help
|
|
@@ -70,6 +71,7 @@ function parseCommand(argv) {
|
|
|
70
71
|
options: {
|
|
71
72
|
json: { type: 'boolean', default: false },
|
|
72
73
|
'project-root': { type: 'string' },
|
|
74
|
+
'stack-package': { type: 'string', multiple: true, default: [] },
|
|
73
75
|
task: { type: 'string' },
|
|
74
76
|
},
|
|
75
77
|
});
|
|
@@ -79,6 +81,7 @@ function parseCommand(argv) {
|
|
|
79
81
|
const options = {
|
|
80
82
|
json: parsed.values.json,
|
|
81
83
|
projectRoot: parsed.values['project-root'],
|
|
84
|
+
stackPackages: parsed.values['stack-package'],
|
|
82
85
|
task: parsed.values.task,
|
|
83
86
|
};
|
|
84
87
|
const operands = parsed.positionals;
|
|
@@ -268,24 +271,28 @@ async function hookInput() {
|
|
|
268
271
|
|
|
269
272
|
async function execute({ command, operands, options }, { signal } = {}) {
|
|
270
273
|
const projectRoot = options.projectRoot || process.cwd();
|
|
271
|
-
|
|
274
|
+
const stackPackages = options.stackPackages || [];
|
|
275
|
+
if (command === 'init') return initialize({ projectRoot, stackPackages });
|
|
272
276
|
if (command === 'adopt') {
|
|
273
|
-
return adoptProject({ projectRoot, request: operands.join(' ') });
|
|
277
|
+
return adoptProject({ projectRoot, request: operands.join(' '), stackPackages });
|
|
274
278
|
}
|
|
275
279
|
if (command === 'codex') return installCodex();
|
|
276
280
|
if (command === 'stack') {
|
|
277
|
-
if (operands[0] === 'list')
|
|
278
|
-
|
|
281
|
+
if (operands[0] === 'list') {
|
|
282
|
+
return { status: 'ok', pieces: await listStackPieces({ projectRoot, stackPackages }) };
|
|
283
|
+
}
|
|
284
|
+
return addStack({ pieces: operands.slice(1), projectRoot, stackPackages });
|
|
279
285
|
}
|
|
280
286
|
if (command === 'prompt') {
|
|
281
287
|
return generatePrompt({
|
|
282
288
|
projectRoot,
|
|
283
289
|
task: options.task || 'work',
|
|
284
290
|
request: operands.join(' '),
|
|
291
|
+
stackPackages,
|
|
285
292
|
});
|
|
286
293
|
}
|
|
287
|
-
if (command === 'context') return getContext({ paths: operands, projectRoot });
|
|
288
|
-
if (command === 'index') return indexCodebase({ projectRoot, queries: operands });
|
|
294
|
+
if (command === 'context') return getContext({ paths: operands, projectRoot, stackPackages });
|
|
295
|
+
if (command === 'index') return indexCodebase({ projectRoot, queries: operands, stackPackages });
|
|
289
296
|
if (command === 'inspect') {
|
|
290
297
|
const inspections = {
|
|
291
298
|
workspace: inspectWorkspaceSetup,
|
|
@@ -293,12 +300,16 @@ async function execute({ command, operands, options }, { signal } = {}) {
|
|
|
293
300
|
launch: inspectLaunch,
|
|
294
301
|
deployment: inspectDeployment,
|
|
295
302
|
};
|
|
296
|
-
return {
|
|
303
|
+
return {
|
|
304
|
+
inspection: operands[0],
|
|
305
|
+
...await inspections[operands[0]]({ projectRoot, stackPackages }),
|
|
306
|
+
};
|
|
297
307
|
}
|
|
298
308
|
if (command === 'prepare') {
|
|
299
309
|
return prepareWorkspace({
|
|
300
310
|
projectRoot,
|
|
301
311
|
signal,
|
|
312
|
+
stackPackages,
|
|
302
313
|
onEvent: (event) => {
|
|
303
314
|
if (!options.json) line(process.stderr, event.message);
|
|
304
315
|
},
|
|
@@ -324,12 +335,13 @@ async function execute({ command, operands, options }, { signal } = {}) {
|
|
|
324
335
|
return verify({
|
|
325
336
|
projectRoot,
|
|
326
337
|
signal,
|
|
338
|
+
stackPackages,
|
|
327
339
|
onEvent: (event) => {
|
|
328
340
|
if (!options.json) line(process.stderr, event.message);
|
|
329
341
|
},
|
|
330
342
|
});
|
|
331
343
|
}
|
|
332
|
-
if (command === 'check') return check({ projectRoot });
|
|
344
|
+
if (command === 'check') return check({ projectRoot, stackPackages });
|
|
333
345
|
fail('CLI_UNKNOWN_COMMAND', `Unknown command: ${command}`);
|
|
334
346
|
}
|
|
335
347
|
|
|
@@ -156,8 +156,14 @@ async function describeSkill(directory, source) {
|
|
|
156
156
|
};
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
-
async function packageDirectory(packageName) {
|
|
160
|
-
|
|
159
|
+
async function packageDirectory(packageName, resolveFrom = null) {
|
|
160
|
+
const roots = [
|
|
161
|
+
...(resolveFrom
|
|
162
|
+
? createRequire(path.join(resolveFrom, 'package.json')).resolve.paths(packageName) || []
|
|
163
|
+
: []),
|
|
164
|
+
...(require.resolve.paths(packageName) || []),
|
|
165
|
+
];
|
|
166
|
+
for (const modulesRoot of [...new Set(roots)]) {
|
|
161
167
|
const manifest = path.join(modulesRoot, packageName, 'package.json');
|
|
162
168
|
try {
|
|
163
169
|
const value = JSON.parse(await readFile(manifest, 'utf8'));
|
|
@@ -180,7 +186,9 @@ async function packageDirectory(packageName) {
|
|
|
180
186
|
}
|
|
181
187
|
|
|
182
188
|
async function resolveLocator(locator) {
|
|
183
|
-
const root = locator.package
|
|
189
|
+
const root = locator.package
|
|
190
|
+
? await packageDirectory(locator.package, locator.resolveFrom)
|
|
191
|
+
: packageRoot;
|
|
184
192
|
const directory = path.join(root, locator.path);
|
|
185
193
|
const source = locator.source || (
|
|
186
194
|
locator.package
|
package/src/index/check.js
CHANGED
|
@@ -32,7 +32,11 @@ function invalidResult(area, error) {
|
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
export async function checkProject({
|
|
35
|
+
export async function checkProject({
|
|
36
|
+
environment = process.env,
|
|
37
|
+
projectRoot,
|
|
38
|
+
stackPackages = [],
|
|
39
|
+
} = {}) {
|
|
36
40
|
const root = (await gitContext(projectRoot)).repositoryRoot;
|
|
37
41
|
try {
|
|
38
42
|
await readBlueprint(root, { required: true, requireDescription: true });
|
|
@@ -42,7 +46,7 @@ export async function checkProject({ environment = process.env, projectRoot } =
|
|
|
42
46
|
|
|
43
47
|
let stack;
|
|
44
48
|
try {
|
|
45
|
-
stack = await readStack(root);
|
|
49
|
+
stack = await readStack(root, { stackPackages });
|
|
46
50
|
} catch (error) {
|
|
47
51
|
return invalidResult('stack', error);
|
|
48
52
|
}
|
|
@@ -71,9 +75,9 @@ export async function checkProject({ environment = process.env, projectRoot } =
|
|
|
71
75
|
const verification = await inspectVerification({ projectRoot: root, stack });
|
|
72
76
|
const [workspaceSetup, projectEnvironment, launch, deployment] = await Promise.all([
|
|
73
77
|
inspectWorkspaceSetupForStack({ projectRoot: root, stack }),
|
|
74
|
-
inspectProjectEnvironment({ environment, projectRoot: root }),
|
|
75
|
-
inspectProjectLaunch({ environment, projectRoot: root }),
|
|
76
|
-
inspectProjectDeployment({ projectRoot: root }),
|
|
78
|
+
inspectProjectEnvironment({ environment, projectRoot: root, stackPackages }),
|
|
79
|
+
inspectProjectLaunch({ environment, projectRoot: root, stackPackages }),
|
|
80
|
+
inspectProjectDeployment({ projectRoot: root, stackPackages }),
|
|
77
81
|
]);
|
|
78
82
|
const diagnostics = [
|
|
79
83
|
...(program.diagnostic ? [program.diagnostic] : []),
|
package/src/index/code-index.js
CHANGED
|
@@ -238,9 +238,14 @@ function formatCount(value, singular) {
|
|
|
238
238
|
return `${value} ${singular}${value === 1 ? '' : 's'}`;
|
|
239
239
|
}
|
|
240
240
|
|
|
241
|
-
export async function buildProjectIndex({
|
|
241
|
+
export async function buildProjectIndex({
|
|
242
|
+
projectRoot,
|
|
243
|
+
queries = [],
|
|
244
|
+
stackPackages = [],
|
|
245
|
+
write = true,
|
|
246
|
+
} = {}) {
|
|
242
247
|
const root = (await gitContext(projectRoot)).repositoryRoot;
|
|
243
|
-
const stack = await readStack(root);
|
|
248
|
+
const stack = await readStack(root, { stackPackages });
|
|
244
249
|
const states = await gitVisibleFileStates(root, { includePath: isProjectContentPath });
|
|
245
250
|
const files = [...states]
|
|
246
251
|
.filter(([filePath, state]) => (
|
package/src/index/context.js
CHANGED
|
@@ -49,7 +49,7 @@ function pathMatchesTarget(filePath, target) {
|
|
|
49
49
|
return !target || filePath === target || filePath.startsWith(`${target}/`);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
export async function contextForProjectPaths({ paths, projectRoot } = {}) {
|
|
52
|
+
export async function contextForProjectPaths({ paths, projectRoot, stackPackages = [] } = {}) {
|
|
53
53
|
if (!Array.isArray(paths) || paths.length === 0) {
|
|
54
54
|
throw new GenesisError('CONTEXT_PATH_REQUIRED', 'Genesis context requires at least one project path.');
|
|
55
55
|
}
|
|
@@ -62,7 +62,7 @@ export async function contextForProjectPaths({ paths, projectRoot } = {}) {
|
|
|
62
62
|
modules: [],
|
|
63
63
|
diagnostic: asDiagnostic(error),
|
|
64
64
|
})),
|
|
65
|
-
readStack(root),
|
|
65
|
+
readStack(root, { stackPackages }),
|
|
66
66
|
]);
|
|
67
67
|
const modules = program.modules.filter((module) => targets.some((target) => citesTarget(module, target)));
|
|
68
68
|
const moduleSources = await Promise.all(modules.map(async (module) => ({
|
package/src/index/deployment.js
CHANGED
|
@@ -4,9 +4,9 @@ import { sha256, stableJson, uniqueSorted } from './utils.js';
|
|
|
4
4
|
import { GENESIS_CONTRACTS } from './contracts.js';
|
|
5
5
|
|
|
6
6
|
/** Read the Stack's production recipe without provisioning or publishing anything. */
|
|
7
|
-
export async function inspectProjectDeployment({ projectRoot } = {}) {
|
|
7
|
+
export async function inspectProjectDeployment({ projectRoot, stackPackages = [] } = {}) {
|
|
8
8
|
const root = (await gitContext(projectRoot)).repositoryRoot;
|
|
9
|
-
const stack = await readStack(root);
|
|
9
|
+
const stack = await readStack(root, { stackPackages });
|
|
10
10
|
const diagnostics = [...stack.deployment.diagnostics];
|
|
11
11
|
let status = 'unconfigured';
|
|
12
12
|
if (diagnostics.length > 0) status = 'blocked';
|
|
@@ -5,9 +5,13 @@ import { missingStackResources } from './stack-preflight.js';
|
|
|
5
5
|
import { GENESIS_CONTRACTS } from './contracts.js';
|
|
6
6
|
|
|
7
7
|
/** Inspect Stack environment requirements without returning supplied host values. */
|
|
8
|
-
export async function inspectProjectEnvironment({
|
|
8
|
+
export async function inspectProjectEnvironment({
|
|
9
|
+
environment = process.env,
|
|
10
|
+
projectRoot,
|
|
11
|
+
stackPackages = [],
|
|
12
|
+
} = {}) {
|
|
9
13
|
const root = (await gitContext(projectRoot)).repositoryRoot;
|
|
10
|
-
const stack = await readStack(root);
|
|
14
|
+
const stack = await readStack(root, { stackPackages });
|
|
11
15
|
const diagnostics = missingStackResources({
|
|
12
16
|
environment: withStackEnvironmentDefaults(environment, stack.environmentDefaults),
|
|
13
17
|
resources: stack.resources,
|
package/src/index/init.js
CHANGED
|
@@ -20,14 +20,14 @@ async function createIfMissing(projectRoot, relativePath, source) {
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
export async function initializeProject({ projectRoot } = {}) {
|
|
23
|
+
export async function initializeProject({ projectRoot, stackPackages = [] } = {}) {
|
|
24
24
|
const root = (await gitContext(projectRoot)).repositoryRoot;
|
|
25
25
|
const created = (await Promise.all([
|
|
26
26
|
createIfMissing(root, BLUEPRINT_PATH, BLUEPRINT_SKELETON_SOURCE),
|
|
27
27
|
createIfMissing(root, STACK_PATH, EMPTY_STACK_SOURCE),
|
|
28
28
|
])).filter(Boolean);
|
|
29
29
|
await mkdir(path.join(root, PROGRAM_ROOT), { recursive: true });
|
|
30
|
-
const stack = await readStack(root);
|
|
30
|
+
const stack = await readStack(root, { stackPackages });
|
|
31
31
|
const skills = await syncProjectSkills({ projectRoot: root, stack });
|
|
32
32
|
const hooks = await installCodexHooks({ projectRoot: root });
|
|
33
33
|
const changedFiles = [...created, ...hooks.changedFiles, ...skills.changedFiles].sort();
|
package/src/index/launch.js
CHANGED
|
@@ -9,9 +9,10 @@ import { GENESIS_CONTRACTS } from './contracts.js';
|
|
|
9
9
|
export async function inspectProjectLaunch({
|
|
10
10
|
environment = process.env,
|
|
11
11
|
projectRoot,
|
|
12
|
+
stackPackages = [],
|
|
12
13
|
} = {}) {
|
|
13
14
|
const root = (await gitContext(projectRoot)).repositoryRoot;
|
|
14
|
-
const stack = await readStack(root);
|
|
15
|
+
const stack = await readStack(root, { stackPackages });
|
|
15
16
|
const diagnostics = missingStackResources({
|
|
16
17
|
environment: withStackEnvironmentDefaults(environment, stack.environmentDefaults),
|
|
17
18
|
resources: stack.resources,
|
package/src/index/prompt.js
CHANGED
|
@@ -3,7 +3,7 @@ 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
5
|
import { readStack, stackPromptContext } from './stack.js';
|
|
6
|
-
import {
|
|
6
|
+
import { listStackCatalogPieces } from './stack-catalog.js';
|
|
7
7
|
import { GenesisError } from './errors.js';
|
|
8
8
|
import { gitContext } from './git.js';
|
|
9
9
|
import { inspectProgram } from './program.js';
|
|
@@ -120,12 +120,13 @@ function renderPrompt({
|
|
|
120
120
|
].join('\n');
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
async function generateAdoptionPrompt({ environment, instructions, program, request, root }) {
|
|
123
|
+
async function generateAdoptionPrompt({ environment, instructions, program, request, root, stackPackages }) {
|
|
124
124
|
const blueprint = await readBlueprint(root, { required: true });
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
125
|
+
const stack = await readStack(root, { stackPackages });
|
|
126
|
+
const availableStackPackages = [...new Set([...stack.stackPackages, ...stackPackages])];
|
|
127
|
+
const [index, catalog] = await Promise.all([
|
|
128
|
+
buildProjectIndex({ projectRoot: root, stackPackages, write: false }),
|
|
129
|
+
listStackCatalogPieces({ projectRoot: root, stackPackages: availableStackPackages }),
|
|
129
130
|
]);
|
|
130
131
|
const projectSkills = await inspectProjectSkills({ projectRoot: root, stack });
|
|
131
132
|
const missing = missingStackResources({
|
|
@@ -165,14 +166,14 @@ async function generateAdoptionPrompt({ environment, instructions, program, requ
|
|
|
165
166
|
};
|
|
166
167
|
}
|
|
167
168
|
|
|
168
|
-
async function generateExplanationPrompt({ instructions, program, request, root, task }) {
|
|
169
|
+
async function generateExplanationPrompt({ instructions, program, request, root, stackPackages, task }) {
|
|
169
170
|
const blueprint = await readBlueprint(root, {
|
|
170
171
|
required: true,
|
|
171
172
|
requireDescription: task === 'program',
|
|
172
173
|
});
|
|
173
174
|
const [stack, index] = await Promise.all([
|
|
174
|
-
readStack(root),
|
|
175
|
-
buildProjectIndex({ projectRoot: root, write: false }),
|
|
175
|
+
readStack(root, { stackPackages }),
|
|
176
|
+
buildProjectIndex({ projectRoot: root, stackPackages, write: false }),
|
|
176
177
|
]);
|
|
177
178
|
const projectSkills = await inspectProjectSkills({ projectRoot: root, stack });
|
|
178
179
|
const blueprintContext = task === 'describe'
|
|
@@ -204,7 +205,7 @@ async function generateExplanationPrompt({ instructions, program, request, root,
|
|
|
204
205
|
};
|
|
205
206
|
}
|
|
206
207
|
|
|
207
|
-
async function generateStartPrompt({ instructions, program, request, root }) {
|
|
208
|
+
async function generateStartPrompt({ instructions, program, request, root, stackPackages }) {
|
|
208
209
|
let blueprint;
|
|
209
210
|
try {
|
|
210
211
|
blueprint = await readBlueprint(root, { required: true });
|
|
@@ -231,10 +232,11 @@ async function generateStartPrompt({ instructions, program, request, root }) {
|
|
|
231
232
|
verificationCommands: [],
|
|
232
233
|
};
|
|
233
234
|
}
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
235
|
+
const stack = await readStack(root, { stackPackages });
|
|
236
|
+
const availableStackPackages = [...new Set([...stack.stackPackages, ...stackPackages])];
|
|
237
|
+
const [index, catalog] = await Promise.all([
|
|
238
|
+
buildProjectIndex({ projectRoot: root, stackPackages, write: false }),
|
|
239
|
+
listStackCatalogPieces({ projectRoot: root, stackPackages: availableStackPackages }),
|
|
238
240
|
]);
|
|
239
241
|
const projectSkills = await inspectProjectSkills({ projectRoot: root, stack });
|
|
240
242
|
const newProject = stack.components.length === 0 && index.fileCount === 0;
|
|
@@ -273,6 +275,7 @@ export async function generateProjectPrompt({
|
|
|
273
275
|
environment = process.env,
|
|
274
276
|
projectRoot,
|
|
275
277
|
request = '',
|
|
278
|
+
stackPackages = [],
|
|
276
279
|
task = 'work',
|
|
277
280
|
} = {}) {
|
|
278
281
|
if (!TASKS.has(task)) {
|
|
@@ -314,6 +317,7 @@ export async function generateProjectPrompt({
|
|
|
314
317
|
program,
|
|
315
318
|
request: userRequest,
|
|
316
319
|
root,
|
|
320
|
+
stackPackages,
|
|
317
321
|
});
|
|
318
322
|
}
|
|
319
323
|
if (task === 'adopt') {
|
|
@@ -323,12 +327,13 @@ export async function generateProjectPrompt({
|
|
|
323
327
|
program,
|
|
324
328
|
request: userRequest,
|
|
325
329
|
root,
|
|
330
|
+
stackPackages,
|
|
326
331
|
});
|
|
327
332
|
}
|
|
328
333
|
let stack;
|
|
329
334
|
if (task === 'work') {
|
|
330
335
|
try {
|
|
331
|
-
stack = await readStack(root);
|
|
336
|
+
stack = await readStack(root, { stackPackages });
|
|
332
337
|
} catch (error) {
|
|
333
338
|
if (error?.code !== 'STACK_REQUIRED') throw error;
|
|
334
339
|
return generateStartPrompt({
|
|
@@ -336,6 +341,7 @@ export async function generateProjectPrompt({
|
|
|
336
341
|
program,
|
|
337
342
|
request: userRequest,
|
|
338
343
|
root,
|
|
344
|
+
stackPackages,
|
|
339
345
|
});
|
|
340
346
|
}
|
|
341
347
|
if (stack.components.length === 0) {
|
|
@@ -344,6 +350,7 @@ export async function generateProjectPrompt({
|
|
|
344
350
|
program,
|
|
345
351
|
request: userRequest,
|
|
346
352
|
root,
|
|
353
|
+
stackPackages,
|
|
347
354
|
});
|
|
348
355
|
}
|
|
349
356
|
}
|
|
@@ -353,12 +360,13 @@ export async function generateProjectPrompt({
|
|
|
353
360
|
program,
|
|
354
361
|
request: userRequest,
|
|
355
362
|
root,
|
|
363
|
+
stackPackages,
|
|
356
364
|
task,
|
|
357
365
|
});
|
|
358
366
|
}
|
|
359
367
|
|
|
360
368
|
const blueprint = await readBlueprint(root, { required: true, requireDescription: true });
|
|
361
|
-
stack ||= await readStack(root);
|
|
369
|
+
stack ||= await readStack(root, { stackPackages });
|
|
362
370
|
const [index, projectSkills] = await Promise.all([
|
|
363
371
|
buildProjectIndex({ projectRoot: root, write: false }),
|
|
364
372
|
inspectProjectSkills({ projectRoot: root, stack }),
|