@aid-framework/cli 0.0.0-stage → 0.1.39
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/LICENSE +201 -0
- package/README.md +45 -2
- package/dist/.tsbuildinfo +1 -0
- package/dist/args.d.ts +37 -0
- package/dist/args.d.ts.map +1 -0
- package/dist/args.js +74 -0
- package/dist/args.js.map +1 -0
- package/dist/cli.d.ts +17 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +26 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/eval.d.ts +44 -0
- package/dist/commands/eval.d.ts.map +1 -0
- package/dist/commands/eval.js +257 -0
- package/dist/commands/eval.js.map +1 -0
- package/dist/commands/gen.d.ts +42 -0
- package/dist/commands/gen.d.ts.map +1 -0
- package/dist/commands/gen.js +138 -0
- package/dist/commands/gen.js.map +1 -0
- package/dist/commands/ingest.d.ts +44 -0
- package/dist/commands/ingest.d.ts.map +1 -0
- package/dist/commands/ingest.js +238 -0
- package/dist/commands/ingest.js.map +1 -0
- package/dist/commands/init.d.ts +38 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +203 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/validate.d.ts +22 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +53 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/context.d.ts +37 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +36 -0
- package/dist/context.js.map +1 -0
- package/dist/diagnostics.d.ts +42 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +47 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/exit.d.ts +16 -0
- package/dist/exit.d.ts.map +1 -0
- package/dist/exit.js +15 -0
- package/dist/exit.js.map +1 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/main.d.ts +25 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +155 -0
- package/dist/main.js.map +1 -0
- package/dist/output.d.ts +48 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +50 -0
- package/dist/output.js.map +1 -0
- package/dist/paths.d.ts +21 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +31 -0
- package/dist/paths.js.map +1 -0
- package/dist/pipeline.d.ts +74 -0
- package/dist/pipeline.d.ts.map +1 -0
- package/dist/pipeline.js +113 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/python.d.ts +30 -0
- package/dist/python.d.ts.map +1 -0
- package/dist/python.js +57 -0
- package/dist/python.js.map +1 -0
- package/dist/targets.d.ts +75 -0
- package/dist/targets.d.ts.map +1 -0
- package/dist/targets.js +136 -0
- package/dist/targets.js.map +1 -0
- package/dist/usage.d.ts +20 -0
- package/dist/usage.d.ts.map +1 -0
- package/dist/usage.js +49 -0
- package/dist/usage.js.map +1 -0
- package/package.json +46 -3
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `aid gen` — compile the spec and reconcile the tree with it.
|
|
3
|
+
*
|
|
4
|
+
* Every decision about *what* changes belongs to `@aid-framework/generator-sdk`: `planRegeneration`
|
|
5
|
+
* decides the actions, `regenerate` applies them, and the drift rule that refuses to
|
|
6
|
+
* overwrite an edited generated file is the SDK's. The CLI decides four things and
|
|
7
|
+
* nothing else: which target, which spec, whether to write, and what the run's exit code
|
|
8
|
+
* means. In particular it does not re-derive ownership, re-hash a file, or re-implement
|
|
9
|
+
* drift -- two implementations of that rule would eventually disagree, and the one that
|
|
10
|
+
* disagreed would be the one holding a developer's edits.
|
|
11
|
+
*
|
|
12
|
+
* One deliberate divergence from `generate-example.mjs`, noted because it is a choice: the
|
|
13
|
+
* manifest is written even when the run reports drift. `regenerate` records the *previous*
|
|
14
|
+
* hash for a file it refused to overwrite, so a run that refuses an edit and a run that
|
|
15
|
+
* discards one cannot disagree about what is on the tree; skipping the manifest write
|
|
16
|
+
* instead leaves files that this run did create unrecorded, and the next run then reports
|
|
17
|
+
* those as drift even though the generator was the one that wrote them.
|
|
18
|
+
*/
|
|
19
|
+
import { createNodeSink, formatRegenerationSummary, hasDrift, planRegeneration, regenerate, rejectionPath, serializeAidManifest, } from '@aid-framework/generator-sdk';
|
|
20
|
+
import { hasErrors, sortDiagnostics } from '@aid-framework/spec';
|
|
21
|
+
import { EXIT_FAILURE, EXIT_OK, EXIT_USAGE } from '../exit.js';
|
|
22
|
+
import { outcome } from '../output.js';
|
|
23
|
+
import { compile, provenanceFor, readManifest, readSpec } from '../pipeline.js';
|
|
24
|
+
import { resolveTarget, unknownTargetDiagnostic } from '../targets.js';
|
|
25
|
+
function lines(label, paths) {
|
|
26
|
+
if (paths.length === 0)
|
|
27
|
+
return [];
|
|
28
|
+
return [label, ...paths.map((path) => ` ${path}`)];
|
|
29
|
+
}
|
|
30
|
+
function render(context, options) {
|
|
31
|
+
const command = 'gen';
|
|
32
|
+
const target = resolveTarget(options.target);
|
|
33
|
+
if (target === undefined) {
|
|
34
|
+
return outcome({
|
|
35
|
+
command,
|
|
36
|
+
exitCode: EXIT_USAGE,
|
|
37
|
+
diagnostics: [unknownTargetDiagnostic(options.target ?? '')],
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
const specPath = options.spec ?? target.specPath;
|
|
41
|
+
const fields = { target: target.name, spec: specPath };
|
|
42
|
+
const read = readSpec(context, specPath);
|
|
43
|
+
if (!read.ok) {
|
|
44
|
+
return outcome({ command, exitCode: EXIT_FAILURE, fields, diagnostics: read.diagnostics });
|
|
45
|
+
}
|
|
46
|
+
const compiled = compile(read.text, specPath, target);
|
|
47
|
+
if (!compiled.ok) {
|
|
48
|
+
return outcome({ command, exitCode: EXIT_FAILURE, fields, diagnostics: compiled.diagnostics });
|
|
49
|
+
}
|
|
50
|
+
const sink = createNodeSink(context.cwd);
|
|
51
|
+
const manifest = readManifest(sink, target);
|
|
52
|
+
if (!manifest.ok) {
|
|
53
|
+
return outcome({ command, exitCode: EXIT_FAILURE, fields, diagnostics: manifest.diagnostics });
|
|
54
|
+
}
|
|
55
|
+
const reconciliation = { sink, manifest: manifest.manifest, force: options.force };
|
|
56
|
+
if (options.dryRun) {
|
|
57
|
+
// A dry run takes the branch in which no write call exists at all, rather than the
|
|
58
|
+
// branch that writes and is then trusted not to. `planRegeneration` is the SDK's
|
|
59
|
+
// planner without its writer, so "writes nothing" is a property of the code path
|
|
60
|
+
// and not a promise in a comment.
|
|
61
|
+
return summarize({
|
|
62
|
+
target,
|
|
63
|
+
specPath,
|
|
64
|
+
report: planRegeneration(compiled.plan, reconciliation),
|
|
65
|
+
warnings: compiled.diagnostics,
|
|
66
|
+
dryRun: true,
|
|
67
|
+
force: options.force,
|
|
68
|
+
manifestWritten: false,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
const applied = regenerate(compiled.plan, {
|
|
72
|
+
...reconciliation,
|
|
73
|
+
provenance: provenanceFor(target, compiled.ir),
|
|
74
|
+
});
|
|
75
|
+
sink.write(target.manifestPath, serializeAidManifest(applied.manifest));
|
|
76
|
+
return summarize({
|
|
77
|
+
target,
|
|
78
|
+
specPath,
|
|
79
|
+
report: applied.report,
|
|
80
|
+
warnings: compiled.diagnostics,
|
|
81
|
+
dryRun: false,
|
|
82
|
+
force: options.force,
|
|
83
|
+
manifestWritten: true,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/** The public entry point, and the one `aid init --gen` folds into its own report. */
|
|
87
|
+
export function generate(context, options) {
|
|
88
|
+
return render(context, options);
|
|
89
|
+
}
|
|
90
|
+
function summarize(success) {
|
|
91
|
+
const { report, target, specPath, warnings, dryRun, force, manifestWritten } = success;
|
|
92
|
+
const diagnostics = sortDiagnostics([...warnings, ...report.diagnostics]);
|
|
93
|
+
// Two ways to fail, and neither is redundant. `hasErrors` is the SDK's verdict on the
|
|
94
|
+
// run; `hasDrift` is checked alongside it rather than instead of it because drift is
|
|
95
|
+
// reported as an error today, and a gate that would stop failing if that changed is not
|
|
96
|
+
// a gate -- and drift is the one failure that silently destroys a developer's edits.
|
|
97
|
+
// `--force` is the caller answering it, so a run that discarded the edits did what it
|
|
98
|
+
// was told and exits 0; only an unforced run leaves drift outstanding.
|
|
99
|
+
const failed = hasErrors(diagnostics) || (!force && hasDrift(report));
|
|
100
|
+
const text = [
|
|
101
|
+
`${target.name}: ${dryRun ? 'dry run, ' : ''}${formatRegenerationSummary(report)}`,
|
|
102
|
+
];
|
|
103
|
+
text.push(...lines('created:', report.created));
|
|
104
|
+
text.push(...lines('updated:', report.updated));
|
|
105
|
+
if (report.drifted.length > 0) {
|
|
106
|
+
text.push(dryRun ? 'would refuse to overwrite:' : 'refused to overwrite, the new content is beside it:');
|
|
107
|
+
for (const drift of report.drifted) {
|
|
108
|
+
text.push(` ${drift.path} -> ${rejectionPath(drift.path)}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
text.push(...lines('no longer generated:', report.stale));
|
|
112
|
+
return outcome({
|
|
113
|
+
command: 'gen',
|
|
114
|
+
exitCode: failed ? EXIT_FAILURE : EXIT_OK,
|
|
115
|
+
diagnostics,
|
|
116
|
+
text: text.join('\n'),
|
|
117
|
+
fields: {
|
|
118
|
+
target: target.name,
|
|
119
|
+
spec: specPath,
|
|
120
|
+
dryRun,
|
|
121
|
+
manifest: { path: target.manifestPath, written: manifestWritten },
|
|
122
|
+
changes: {
|
|
123
|
+
created: report.created,
|
|
124
|
+
updated: report.updated,
|
|
125
|
+
unchanged: report.unchanged,
|
|
126
|
+
kept: report.kept,
|
|
127
|
+
// Paths, like every sibling here: the report answers "which files", and the
|
|
128
|
+
// rejected content is on disk at the deterministic `rejectionPath` the human
|
|
129
|
+
// summary prints. Mixing record objects into one entry and strings into the rest
|
|
130
|
+
// makes the one shape a consumer has to special-case the one about conflicts.
|
|
131
|
+
conflicts: report.drifted.map((file) => file.path),
|
|
132
|
+
stale: report.stale,
|
|
133
|
+
pruned: report.pruned,
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=gen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gen.js","sourceRoot":"","sources":["../../src/commands/gen.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `aid ingest` -- run the generated ingest entry point for a retriever's corpus.
|
|
3
|
+
*
|
|
4
|
+
* **What this shells out to, and why.** Indexing is a batch job, not a request, so the
|
|
5
|
+
* generator emits one runnable module per declared retriever at
|
|
6
|
+
* `app/generated/retrieval/ingest/<id>.py`, with a `main()` that chunks, embeds and writes
|
|
7
|
+
* the corpus. That module is the interface: it already knows the chunking and the store the
|
|
8
|
+
* spec declared, and re-deriving either here would be a second implementation of the
|
|
9
|
+
* runtime's rules. So the command runs `python -m app.generated.retrieval.ingest.<id>` from
|
|
10
|
+
* the project root, which is also what a person would type by hand.
|
|
11
|
+
*
|
|
12
|
+
* **The flag shape is a usage error, not a project verdict.** `--retriever` and `--all` are
|
|
13
|
+
* the two ways to say what to ingest; passing both, or neither, is a mistake in the
|
|
14
|
+
* invocation and exits 2 before the spec is even read. An id the spec does not declare is
|
|
15
|
+
* the same kind of mistake, and its message names the ids that do exist -- a typo should
|
|
16
|
+
* not require opening the spec.
|
|
17
|
+
*
|
|
18
|
+
* **A missing module is a failure, not a usage error.** `--retriever handbook` in a project
|
|
19
|
+
* that has never been generated is a well-formed command that cannot do its job; it exits 1
|
|
20
|
+
* and points at `aid gen`. Exit 2 would tell a script that it passed the wrong arguments,
|
|
21
|
+
* which is false and hides the one action that fixes it.
|
|
22
|
+
*
|
|
23
|
+
* **`--dry-run` is forwarded, not implemented here.** The generated module already grows
|
|
24
|
+
* its own `--dry-run`, which applies the chunker and reports the counts a real run would
|
|
25
|
+
* write without opening a store or calling an embedder. Answering the same question in
|
|
26
|
+
* the CLI would mean re-chunking the corpus, and a second dry run that drifted from the
|
|
27
|
+
* one the module performs is worse than no dry run at all.
|
|
28
|
+
*
|
|
29
|
+
* **Idempotence is the runtime's, not a rescan this command performs.** A chunk id is a
|
|
30
|
+
* content hash, and the store upserts on it, so a second run over unchanged documents
|
|
31
|
+
* replaces rather than appends. The CLI adds no diffing of its own: it would have to
|
|
32
|
+
* reimplement the chunker to know what changed.
|
|
33
|
+
*/
|
|
34
|
+
import type { CliContext } from '../context.js';
|
|
35
|
+
import type { CommandOutcome } from '../output.js';
|
|
36
|
+
export interface IngestOptions {
|
|
37
|
+
readonly spec: string | undefined;
|
|
38
|
+
readonly target: string | undefined;
|
|
39
|
+
readonly retriever: string | undefined;
|
|
40
|
+
readonly all: boolean;
|
|
41
|
+
readonly dryRun: boolean;
|
|
42
|
+
}
|
|
43
|
+
export declare function ingest(context: CliContext, options: IngestOptions): CommandOutcome;
|
|
44
|
+
//# sourceMappingURL=ingest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ingest.d.ts","sourceRoot":"","sources":["../../src/commands/ingest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAIhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAOnD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AA+CD,wBAAgB,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,GAAG,cAAc,CAiLlF"}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `aid ingest` -- run the generated ingest entry point for a retriever's corpus.
|
|
3
|
+
*
|
|
4
|
+
* **What this shells out to, and why.** Indexing is a batch job, not a request, so the
|
|
5
|
+
* generator emits one runnable module per declared retriever at
|
|
6
|
+
* `app/generated/retrieval/ingest/<id>.py`, with a `main()` that chunks, embeds and writes
|
|
7
|
+
* the corpus. That module is the interface: it already knows the chunking and the store the
|
|
8
|
+
* spec declared, and re-deriving either here would be a second implementation of the
|
|
9
|
+
* runtime's rules. So the command runs `python -m app.generated.retrieval.ingest.<id>` from
|
|
10
|
+
* the project root, which is also what a person would type by hand.
|
|
11
|
+
*
|
|
12
|
+
* **The flag shape is a usage error, not a project verdict.** `--retriever` and `--all` are
|
|
13
|
+
* the two ways to say what to ingest; passing both, or neither, is a mistake in the
|
|
14
|
+
* invocation and exits 2 before the spec is even read. An id the spec does not declare is
|
|
15
|
+
* the same kind of mistake, and its message names the ids that do exist -- a typo should
|
|
16
|
+
* not require opening the spec.
|
|
17
|
+
*
|
|
18
|
+
* **A missing module is a failure, not a usage error.** `--retriever handbook` in a project
|
|
19
|
+
* that has never been generated is a well-formed command that cannot do its job; it exits 1
|
|
20
|
+
* and points at `aid gen`. Exit 2 would tell a script that it passed the wrong arguments,
|
|
21
|
+
* which is false and hides the one action that fixes it.
|
|
22
|
+
*
|
|
23
|
+
* **`--dry-run` is forwarded, not implemented here.** The generated module already grows
|
|
24
|
+
* its own `--dry-run`, which applies the chunker and reports the counts a real run would
|
|
25
|
+
* write without opening a store or calling an embedder. Answering the same question in
|
|
26
|
+
* the CLI would mean re-chunking the corpus, and a second dry run that drifted from the
|
|
27
|
+
* one the module performs is worse than no dry run at all.
|
|
28
|
+
*
|
|
29
|
+
* **Idempotence is the runtime's, not a rescan this command performs.** A chunk id is a
|
|
30
|
+
* content hash, and the store upserts on it, so a second run over unchanged documents
|
|
31
|
+
* replaces rather than appends. The CLI adds no diffing of its own: it would have to
|
|
32
|
+
* reimplement the chunker to know what changed.
|
|
33
|
+
*/
|
|
34
|
+
import { existsSync } from 'node:fs';
|
|
35
|
+
import { sortDiagnostics } from '@aid-framework/spec';
|
|
36
|
+
import { CLI_DIAGNOSTIC_CODES, cliError, cliWarning } from '../diagnostics.js';
|
|
37
|
+
import { EXIT_FAILURE, EXIT_OK, EXIT_USAGE } from '../exit.js';
|
|
38
|
+
import { outcome } from '../output.js';
|
|
39
|
+
import { absolutePath } from '../paths.js';
|
|
40
|
+
import { lowerSpec, readSpec } from '../pipeline.js';
|
|
41
|
+
import { discoverInterpreter, INTERPRETERS, interpreterCommand, invoke } from '../python.js';
|
|
42
|
+
import { resolveTarget, unknownTargetDiagnostic } from '../targets.js';
|
|
43
|
+
/** `Declared retrievers: a, b.`, or the truth when there are none. */
|
|
44
|
+
function declaredHint(ids) {
|
|
45
|
+
return ids.length > 0
|
|
46
|
+
? `Declared retrievers: ${ids.join(', ')}.`
|
|
47
|
+
: 'The spec declares no retrievers.';
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The human rendering. One retriever prints the module's own report; several get a heading
|
|
51
|
+
* each, because two unlabelled "wrote N chunks" lines cannot be told apart.
|
|
52
|
+
*/
|
|
53
|
+
function render(results, stdout) {
|
|
54
|
+
const blocks = results.map((result, index) => {
|
|
55
|
+
const body = stdout[index]?.trimEnd() ?? '';
|
|
56
|
+
if (results.length === 1)
|
|
57
|
+
return body;
|
|
58
|
+
return [`==> ${result.retriever}`, body].filter((line) => line !== '').join('\n');
|
|
59
|
+
});
|
|
60
|
+
return blocks.filter((block) => block !== '').join('\n');
|
|
61
|
+
}
|
|
62
|
+
/** The `--retriever`/`--all` shape, which is decided without reading the project. */
|
|
63
|
+
function checkFlagShape(options) {
|
|
64
|
+
if (options.retriever !== undefined && options.all) {
|
|
65
|
+
return cliError({
|
|
66
|
+
code: CLI_DIAGNOSTIC_CODES.retrieverConflict,
|
|
67
|
+
message: '`--retriever` and `--all` say two different things; pass one of them.',
|
|
68
|
+
hint: 'Use `--retriever <id>` for one retriever, or `--all` for every retriever the spec declares.',
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
if (options.retriever === undefined && !options.all) {
|
|
72
|
+
return cliError({
|
|
73
|
+
code: CLI_DIAGNOSTIC_CODES.retrieverRequired,
|
|
74
|
+
message: '`aid ingest` needs `--retriever <id>` or `--all`.',
|
|
75
|
+
hint: 'Use `--all` to ingest every retriever the spec declares.',
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
export function ingest(context, options) {
|
|
81
|
+
const command = 'ingest';
|
|
82
|
+
const target = resolveTarget(options.target);
|
|
83
|
+
if (target === undefined) {
|
|
84
|
+
return outcome({
|
|
85
|
+
command,
|
|
86
|
+
exitCode: EXIT_USAGE,
|
|
87
|
+
diagnostics: [unknownTargetDiagnostic(options.target ?? '')],
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
// The flag shape is judged before the project is touched: an invocation that asks two
|
|
91
|
+
// contradictory things is wrong whether or not the spec happens to be readable, and
|
|
92
|
+
// reporting a spec problem instead would bury the actual mistake.
|
|
93
|
+
const malformed = checkFlagShape(options);
|
|
94
|
+
if (malformed !== undefined) {
|
|
95
|
+
return outcome({ command, exitCode: EXIT_USAGE, diagnostics: [malformed] });
|
|
96
|
+
}
|
|
97
|
+
const specPath = options.spec ?? target.specPath;
|
|
98
|
+
const fields = { target: target.name, spec: specPath };
|
|
99
|
+
const read = readSpec(context, specPath);
|
|
100
|
+
if (!read.ok) {
|
|
101
|
+
return outcome({ command, exitCode: EXIT_FAILURE, fields, diagnostics: read.diagnostics });
|
|
102
|
+
}
|
|
103
|
+
const lowered = lowerSpec(read.text, specPath);
|
|
104
|
+
if (!lowered.ok) {
|
|
105
|
+
return outcome({ command, exitCode: EXIT_FAILURE, fields, diagnostics: lowered.diagnostics });
|
|
106
|
+
}
|
|
107
|
+
const declared = lowered.ir.retrievers.map((entry) => entry.id);
|
|
108
|
+
if (options.retriever !== undefined && !declared.includes(options.retriever)) {
|
|
109
|
+
return outcome({
|
|
110
|
+
command,
|
|
111
|
+
exitCode: EXIT_USAGE,
|
|
112
|
+
fields: { ...fields, retrievers: declared },
|
|
113
|
+
diagnostics: [
|
|
114
|
+
cliError({
|
|
115
|
+
code: CLI_DIAGNOSTIC_CODES.retrieverNotFound,
|
|
116
|
+
message: `No retriever named "${options.retriever}" in ${specPath}.`,
|
|
117
|
+
path: [specPath],
|
|
118
|
+
hint: declaredHint(declared),
|
|
119
|
+
}),
|
|
120
|
+
],
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
// `--all` over a project that declares none is a well-formed request with nothing to do.
|
|
124
|
+
// It is not an error: a generated app with no retrieval is a legitimate app, and making
|
|
125
|
+
// its CI fail would force a `--retriever` that does not exist.
|
|
126
|
+
const selected = options.all || options.retriever === undefined ? declared : [options.retriever];
|
|
127
|
+
const scoped = { ...fields, retrievers: selected };
|
|
128
|
+
if (selected.length === 0) {
|
|
129
|
+
return outcome({
|
|
130
|
+
command,
|
|
131
|
+
exitCode: EXIT_OK,
|
|
132
|
+
fields: { ...scoped, results: [] },
|
|
133
|
+
diagnostics: sortDiagnostics(lowered.diagnostics),
|
|
134
|
+
text: 'No retrievers are declared; nothing to ingest.',
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
// A declared retriever whose module is absent is a project that has not been generated,
|
|
138
|
+
// not a misuse of the command. Checked before discovery so the message is about the
|
|
139
|
+
// missing artefact rather than about the interpreter that would have run it.
|
|
140
|
+
const missing = selected.filter((id) => !existsSync(absolutePath(context.cwd, target.retrievalIngestModuleFile(id))));
|
|
141
|
+
if (missing.length > 0) {
|
|
142
|
+
return outcome({
|
|
143
|
+
command,
|
|
144
|
+
exitCode: EXIT_FAILURE,
|
|
145
|
+
fields: scoped,
|
|
146
|
+
diagnostics: [
|
|
147
|
+
cliError({
|
|
148
|
+
code: CLI_DIAGNOSTIC_CODES.ingestModulesMissing,
|
|
149
|
+
message: `No generated ingest module for ${missing.map((id) => `"${id}"`).join(', ')}.`,
|
|
150
|
+
path: missing.map((id) => target.retrievalIngestModuleFile(id)),
|
|
151
|
+
hint: 'Run `aid gen`: the ingest entry points are the modules the generator emits.',
|
|
152
|
+
}),
|
|
153
|
+
],
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
if (target.runner !== 'python') {
|
|
157
|
+
return outcome({
|
|
158
|
+
command,
|
|
159
|
+
// Exit 2, not 1: this command has no runner for this target, so nothing was
|
|
160
|
+
// ingested and the corpus was not judged.
|
|
161
|
+
exitCode: EXIT_USAGE,
|
|
162
|
+
fields: scoped,
|
|
163
|
+
diagnostics: [
|
|
164
|
+
cliError({
|
|
165
|
+
code: CLI_DIAGNOSTIC_CODES.runnerUnsupported,
|
|
166
|
+
message: `\`aid ingest\` runs generated Python modules, and ${target.name} emits TypeScript.`,
|
|
167
|
+
hint: 'The emitted ingest module exports `ingest()`; run it with Node.',
|
|
168
|
+
}),
|
|
169
|
+
],
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
const interpreter = discoverInterpreter(context);
|
|
173
|
+
if (interpreter === undefined) {
|
|
174
|
+
return outcome({
|
|
175
|
+
command,
|
|
176
|
+
// Exit 2, not 1: nothing about the project was judged. Ingest has no verdict when the
|
|
177
|
+
// thing that would run it cannot start, and `1` would read as "the corpus was wrong".
|
|
178
|
+
exitCode: EXIT_USAGE,
|
|
179
|
+
fields: scoped,
|
|
180
|
+
diagnostics: [
|
|
181
|
+
cliError({
|
|
182
|
+
code: CLI_DIAGNOSTIC_CODES.pythonMissing,
|
|
183
|
+
message: `No interpreter could import aid_runtime (tried ${INTERPRETERS.join(', ')}).`,
|
|
184
|
+
hint: 'Install the runtime into the interpreter you run with, or run the generated ingest modules yourself.',
|
|
185
|
+
}),
|
|
186
|
+
],
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
const base = interpreterCommand(interpreter);
|
|
190
|
+
const results = [];
|
|
191
|
+
const stdout = [];
|
|
192
|
+
const spoken = [];
|
|
193
|
+
const diagnostics = [...lowered.diagnostics];
|
|
194
|
+
for (const id of selected) {
|
|
195
|
+
const module = target.retrievalIngestModule(id);
|
|
196
|
+
// Appended after the module name so it lands as an argument to the module, which owns
|
|
197
|
+
// what a dry run means -- see the header note.
|
|
198
|
+
const run = invoke(context, [...base, '-m', module, ...(options.dryRun ? ['--dry-run'] : [])]);
|
|
199
|
+
if (run === undefined) {
|
|
200
|
+
return outcome({
|
|
201
|
+
command,
|
|
202
|
+
exitCode: EXIT_USAGE,
|
|
203
|
+
fields: { ...scoped, interpreter },
|
|
204
|
+
diagnostics: [
|
|
205
|
+
cliError({
|
|
206
|
+
code: CLI_DIAGNOSTIC_CODES.runnerFailed,
|
|
207
|
+
message: `Could not start ${interpreter} to run "${module}".`,
|
|
208
|
+
}),
|
|
209
|
+
],
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
results.push({ retriever: id, module, status: run.status ?? EXIT_FAILURE });
|
|
213
|
+
stdout.push(run.stdout);
|
|
214
|
+
// The module reports what it could not ingest on stderr. It is surfaced rather than
|
|
215
|
+
// swallowed, and on the CLI's stderr even under `--json`, because that is where the
|
|
216
|
+
// process that wrote it wrote it.
|
|
217
|
+
if (run.stderr.trim() !== '') {
|
|
218
|
+
spoken.push(run.stderr.trimEnd());
|
|
219
|
+
diagnostics.push(cliWarning({
|
|
220
|
+
code: CLI_DIAGNOSTIC_CODES.runnerWarned,
|
|
221
|
+
message: `"${id}" wrote to stderr.`,
|
|
222
|
+
}));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
// A non-zero exit from a generated module is that module's verdict, so it propagates.
|
|
226
|
+
// Every selected retriever still runs: one corpus that could not be built should not
|
|
227
|
+
// hide the state of the others.
|
|
228
|
+
const failed = results.some((result) => result.status !== 0);
|
|
229
|
+
return outcome({
|
|
230
|
+
command,
|
|
231
|
+
exitCode: failed ? EXIT_FAILURE : EXIT_OK,
|
|
232
|
+
fields: { ...scoped, interpreter, results },
|
|
233
|
+
diagnostics: sortDiagnostics(diagnostics),
|
|
234
|
+
text: render(results, stdout),
|
|
235
|
+
stderr: spoken.join('\n'),
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=ingest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ingest.js","sourceRoot":"","sources":["../../src/commands/ingest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `aid init` — scaffold a project: a starter spec and a README.
|
|
3
|
+
*
|
|
4
|
+
* It does not generate. `aid gen` generates, and `--gen` is the convenience for the one
|
|
5
|
+
* thing a person types next; keeping the two apart is what makes "scaffold" and "compile"
|
|
6
|
+
* separately testable and separately re-runnable.
|
|
7
|
+
*
|
|
8
|
+
* Two deliberate refusals, because scaffolding is the command most likely to be pointed at
|
|
9
|
+
* a directory that already has something in it:
|
|
10
|
+
*
|
|
11
|
+
* - An existing spec is not overwritten without `--force`. That file is the project's
|
|
12
|
+
* source of truth; replacing it silently is the worst thing this command could do.
|
|
13
|
+
* - An existing README is left exactly as it is, and reported as skipped -- under `--force`
|
|
14
|
+
* too. A README is the file a directory is most likely to already have, its contents are
|
|
15
|
+
* the author's, and `--force` here is usually aimed at the spec.
|
|
16
|
+
*
|
|
17
|
+
* `--from <spec>` imports a spec rather than copying one: the imported text has to lower to
|
|
18
|
+
* an IR and pass the gates before anything is written, so `aid init --from` cannot produce a
|
|
19
|
+
* project that `aid validate` immediately rejects.
|
|
20
|
+
*/
|
|
21
|
+
import type { CliContext } from '../context.js';
|
|
22
|
+
import type { CommandOutcome } from '../output.js';
|
|
23
|
+
export interface InitOptions {
|
|
24
|
+
readonly dir: string | undefined;
|
|
25
|
+
readonly from: string | undefined;
|
|
26
|
+
readonly target: string | undefined;
|
|
27
|
+
readonly force: boolean;
|
|
28
|
+
readonly gen: boolean;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A `project.name` from a directory name. The spec's pattern is `^[a-z][a-z0-9-]{0,63}$`,
|
|
32
|
+
* and a directory called `My App` or `2024-prototype` is not a reason to fail `aid init`
|
|
33
|
+
* with a schema error about a field the caller never wrote.
|
|
34
|
+
*/
|
|
35
|
+
export declare function projectNameFor(directory: string): string;
|
|
36
|
+
export declare function starterSpec(target: string, projectName: string): string;
|
|
37
|
+
export declare function init(context: CliContext, options: InitOptions): CommandOutcome;
|
|
38
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAQnD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;CACvB;AA0BD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAKxD;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAYvE;AA+CD,wBAAgB,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,GAAG,cAAc,CA8F9E"}
|