@delegance/claude-autopilot 7.2.1 → 7.4.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/CHANGELOG.md +41 -0
- package/dist/src/cli/help-text.js +1 -1
- package/dist/src/cli/index.js +19 -2
- package/dist/src/cli/scaffold/node.d.ts +20 -0
- package/dist/src/cli/scaffold/node.js +162 -0
- package/dist/src/cli/scaffold/python.d.ts +71 -0
- package/dist/src/cli/scaffold/python.js +338 -0
- package/dist/src/cli/scaffold/types.d.ts +68 -0
- package/dist/src/cli/scaffold/types.js +6 -0
- package/dist/src/cli/scaffold.d.ts +43 -29
- package/dist/src/cli/scaffold.js +245 -174
- package/dist/src/index.d.ts +13 -0
- package/dist/src/index.js +33 -1
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,47 @@
|
|
|
2
2
|
|
|
3
3
|
- v5.6 Phase 7 (docs reconciliation) — pending.
|
|
4
4
|
|
|
5
|
+
## 7.3.0 (2026-05-10)
|
|
6
|
+
|
|
7
|
+
**v7.3.0 — library export surface for v8 daemon.** Minor bump
|
|
8
|
+
(new public API surface). The v8 daemon spec needs to call into
|
|
9
|
+
the autopilot pipeline without spawning the CLI as a subprocess
|
|
10
|
+
— subprocess boundaries lose error context, double up dependency
|
|
11
|
+
resolution, and make sandbox enforcement harder. This PR exposes
|
|
12
|
+
a curated set of `run*` functions as a stable library API.
|
|
13
|
+
|
|
14
|
+
**New exports** at `@delegance/claude-autopilot`:
|
|
15
|
+
|
|
16
|
+
* Pipeline read-only / discovery: `runScan`, `runScaffold`,
|
|
17
|
+
`runValidate`, `runFix`, `runCosts`, `runReport`, `runDoctor`,
|
|
18
|
+
`runSetup`.
|
|
19
|
+
* Pipeline side-effecting: `runDeploy`, `runDeployStatus`,
|
|
20
|
+
`runDeployRollback` (daemon callers must wrap in policy gates
|
|
21
|
+
per v8 spec C3).
|
|
22
|
+
* Helpers: `detectProject`.
|
|
23
|
+
* Types: `DetectionResult`, `ScaffoldOptions`, `ScaffoldResult`,
|
|
24
|
+
`SetupOptions`, `ProfileName`.
|
|
25
|
+
|
|
26
|
+
**Stability contract** documented in `docs/library-api.md`. Anything
|
|
27
|
+
in that doc is SemVer-stable; deep imports
|
|
28
|
+
(`@delegance/claude-autopilot/dist/...`) are unsupported.
|
|
29
|
+
|
|
30
|
+
**`package.json` `exports` map** gains a `default` entry pointing
|
|
31
|
+
at `./dist/src/index.js` so consumers can
|
|
32
|
+
`import { runScaffold } from '@delegance/claude-autopilot'`
|
|
33
|
+
instead of deep-importing.
|
|
34
|
+
|
|
35
|
+
**Deliberate non-exports** (still callable via deep imports, no
|
|
36
|
+
guarantee): JSON-envelope wrappers, internal `_*` helpers, the
|
|
37
|
+
`runs` engine-introspection group (separate v8 prerequisite).
|
|
38
|
+
|
|
39
|
+
4 new tests verify (a) all declared exports resolve at runtime,
|
|
40
|
+
(b) `detectProject` returns the documented shape on the autopilot
|
|
41
|
+
repo itself, (c) `package.json` `exports` map shape is locked.
|
|
42
|
+
1559 → 1563 CLI tests; tsc clean; build clean.
|
|
43
|
+
|
|
44
|
+
Version 7.2.1 → 7.3.0 (minor bump for new library surface).
|
|
45
|
+
|
|
5
46
|
## 7.2.1 (2026-05-10)
|
|
6
47
|
|
|
7
48
|
**v7.2.1 — v8 spec codex pass-2 amendment.** Docs-only PR. Folds
|
|
@@ -28,7 +28,7 @@ export const HELP_GROUPS = [
|
|
|
28
28
|
verbs: [
|
|
29
29
|
{ verb: 'init', summary: 'Scaffold guardrail.config.yaml + auto-detect migrate stack (writes .autopilot/stack.md)' },
|
|
30
30
|
{ verb: 'setup', summary: 'Auto-detect stack, write config, install pre-push hook' },
|
|
31
|
-
{ verb: 'scaffold', summary: 'Scaffold project skeleton from a spec markdown (--from-spec <path>)' },
|
|
31
|
+
{ verb: 'scaffold', summary: 'Scaffold project skeleton from a spec markdown (--from-spec <path> [--stack node|python|fastapi])' },
|
|
32
32
|
{ verb: 'autopilot', summary: 'Multi-phase orchestrator — run scan → spec → plan → implement under one runId (v6.2.0)' },
|
|
33
33
|
{ verb: 'brainstorm', summary: 'Pipeline entry point (Claude Code skill — see /brainstorm)' },
|
|
34
34
|
{ verb: 'spec', summary: 'Spec-writing pointer (Claude Code skill — see /brainstorm)' },
|
package/dist/src/cli/index.js
CHANGED
|
@@ -197,7 +197,7 @@ These are aliases for the flat subcommands; they still work without the 'advance
|
|
|
197
197
|
// `run resume` form is handled BEFORE the default `run` -> review dispatch
|
|
198
198
|
// kicks in (see disambiguation block just below).
|
|
199
199
|
const SUBCOMMANDS = ['init', 'run', 'runs', 'scan', 'report', 'explain', 'ignore', 'ci', 'pr', 'fix', 'costs', 'watch', 'hook', 'autoregress', 'baseline', 'triage', 'lsp', 'worker', 'mcp', 'test-gen', 'pr-desc', 'doctor', 'preflight', 'setup', 'council', 'migrate-v4', 'migrate', 'migrate-doctor', 'deploy', 'brainstorm', 'spec', 'plan', 'implement', 'review', 'validate', 'autopilot', 'internal', 'help', '--help', '-h'];
|
|
200
|
-
const VALUE_FLAGS = ['base', 'config', 'files', 'format', 'output', 'debounce', 'ask', 'focus', 'fail-on', 'note', 'reason', 'expires', 'profile', 'severity', 'prompt', 'context-file', 'path', 'adapter', 'ref', 'sha', 'spec', 'context', 'mode', 'phases', 'budget'];
|
|
200
|
+
const VALUE_FLAGS = ['base', 'config', 'files', 'format', 'output', 'debounce', 'ask', 'focus', 'fail-on', 'note', 'reason', 'expires', 'profile', 'severity', 'prompt', 'context-file', 'path', 'adapter', 'ref', 'sha', 'spec', 'context', 'mode', 'phases', 'budget', 'stack'];
|
|
201
201
|
// Bare invocation — no subcommand, no flags → show welcome guide
|
|
202
202
|
if (args.length === 0) {
|
|
203
203
|
const hasKey = !!(process.env.ANTHROPIC_API_KEY || process.env.GEMINI_API_KEY ||
|
|
@@ -933,14 +933,31 @@ switch (subcommand) {
|
|
|
933
933
|
}
|
|
934
934
|
case 'scaffold': {
|
|
935
935
|
// v7.2.0 — `claude-autopilot scaffold --from-spec <path>`
|
|
936
|
+
// v7.4.0 — `--stack <node|python|fastapi>` + `--list-stacks`.
|
|
937
|
+
if (boolFlag('list-stacks')) {
|
|
938
|
+
const { printStackList } = await import("./scaffold.js");
|
|
939
|
+
printStackList();
|
|
940
|
+
process.exit(0);
|
|
941
|
+
}
|
|
936
942
|
const fromSpec = flag('from-spec');
|
|
937
943
|
const dryRun = boolFlag('dry-run');
|
|
944
|
+
const stackArg = flag('stack');
|
|
945
|
+
if (stackArg && !['node', 'python', 'fastapi'].includes(stackArg)) {
|
|
946
|
+
console.error(`\x1b[31m[claude-autopilot] --stack "${stackArg}" not recognized — supported: node, python, fastapi\x1b[0m`);
|
|
947
|
+
console.error(` See: claude-autopilot scaffold --list-stacks`);
|
|
948
|
+
process.exit(3);
|
|
949
|
+
}
|
|
938
950
|
if (!fromSpec) {
|
|
939
951
|
console.error(`\x1b[31m[claude-autopilot] scaffold requires --from-spec <path>\x1b[0m`);
|
|
940
952
|
console.error(` Example: claude-autopilot scaffold --from-spec docs/specs/foo.md`);
|
|
953
|
+
console.error(` Stacks: claude-autopilot scaffold --list-stacks`);
|
|
941
954
|
process.exit(1);
|
|
942
955
|
}
|
|
943
|
-
await runScaffold({
|
|
956
|
+
await runScaffold({
|
|
957
|
+
specPath: fromSpec,
|
|
958
|
+
dryRun,
|
|
959
|
+
...(stackArg ? { stack: stackArg } : {}),
|
|
960
|
+
});
|
|
944
961
|
process.exit(0);
|
|
945
962
|
break;
|
|
946
963
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ParsedFiles, ScaffoldResult, ScaffoldRunContext } from './types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Build a minimal starter package.json. Caller passes in any explicit
|
|
4
|
+
* hints (parsed from spec); we layer Node 22 ESM defaults on top.
|
|
5
|
+
*
|
|
6
|
+
* Note: signature unchanged from v7.2.0 — re-exported through ../scaffold.ts
|
|
7
|
+
* so consumers that imported from the public scaffold module keep working.
|
|
8
|
+
*/
|
|
9
|
+
export declare function buildStarterPackageJson(projectName: string, hints: ParsedFiles['packageHints']): Record<string, unknown>;
|
|
10
|
+
/**
|
|
11
|
+
* Node ESM scaffolder. Materializes directories + placeholder files,
|
|
12
|
+
* writes package.json (when listed in spec) and tsconfig.json (when listed),
|
|
13
|
+
* choosing JS vs TS tsconfig flavor based on which extension dominates the
|
|
14
|
+
* other listed paths.
|
|
15
|
+
*
|
|
16
|
+
* Behavior is intentionally byte-identical to v7.2.0 — the existing
|
|
17
|
+
* tests/scaffold.test.ts is the regression bar.
|
|
18
|
+
*/
|
|
19
|
+
export declare function scaffoldNode(ctx: ScaffoldRunContext): Promise<ScaffoldResult>;
|
|
20
|
+
//# sourceMappingURL=node.d.ts.map
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
// v7.4.0 — Node ESM scaffolder, extracted from src/cli/scaffold.ts (was the
|
|
2
|
+
// monolithic v7.2.0 implementation). Pure module split: the buildStarterPackageJson
|
|
3
|
+
// + scaffoldNode functions here are byte-identical-in-behavior to v7.2.0; the
|
|
4
|
+
// existing 11 scaffold tests are the regression bar.
|
|
5
|
+
//
|
|
6
|
+
// Why split: v7.4.0 adds Python + FastAPI per-stack scaffolders (see ./python.ts).
|
|
7
|
+
// Keeping each stack in its own module makes the v7.5+ plan (Go, Rust, Ruby) a
|
|
8
|
+
// drop-in pattern: add a new file, register it in the dispatcher inside
|
|
9
|
+
// ../scaffold.ts.
|
|
10
|
+
import * as fs from 'node:fs';
|
|
11
|
+
import * as fsAsync from 'node:fs/promises';
|
|
12
|
+
import * as path from 'node:path';
|
|
13
|
+
const PASS = '\x1b[32m✓\x1b[0m';
|
|
14
|
+
const SKIP = '\x1b[2m·\x1b[0m';
|
|
15
|
+
const DIM = (t) => `\x1b[2m${t}\x1b[0m`;
|
|
16
|
+
/**
|
|
17
|
+
* Build a minimal starter package.json. Caller passes in any explicit
|
|
18
|
+
* hints (parsed from spec); we layer Node 22 ESM defaults on top.
|
|
19
|
+
*
|
|
20
|
+
* Note: signature unchanged from v7.2.0 — re-exported through ../scaffold.ts
|
|
21
|
+
* so consumers that imported from the public scaffold module keep working.
|
|
22
|
+
*/
|
|
23
|
+
export function buildStarterPackageJson(projectName, hints) {
|
|
24
|
+
const pkg = {
|
|
25
|
+
name: projectName,
|
|
26
|
+
version: '0.1.0',
|
|
27
|
+
private: true,
|
|
28
|
+
type: hints.type ?? 'module',
|
|
29
|
+
engines: { node: '>=22' },
|
|
30
|
+
scripts: {
|
|
31
|
+
test: 'node --test tests/*.test.js',
|
|
32
|
+
...hints.scripts,
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
if (hints.bin)
|
|
36
|
+
pkg.bin = hints.bin;
|
|
37
|
+
if (hints.dependencies)
|
|
38
|
+
pkg.dependencies = hints.dependencies;
|
|
39
|
+
if (hints.devDependencies)
|
|
40
|
+
pkg.devDependencies = hints.devDependencies;
|
|
41
|
+
return pkg;
|
|
42
|
+
}
|
|
43
|
+
const STARTER_TSCONFIG_JS = {
|
|
44
|
+
compilerOptions: {
|
|
45
|
+
target: 'ES2022',
|
|
46
|
+
module: 'NodeNext',
|
|
47
|
+
moduleResolution: 'NodeNext',
|
|
48
|
+
allowJs: true,
|
|
49
|
+
checkJs: true,
|
|
50
|
+
noEmit: true,
|
|
51
|
+
strict: true,
|
|
52
|
+
esModuleInterop: true,
|
|
53
|
+
skipLibCheck: true,
|
|
54
|
+
types: ['node'],
|
|
55
|
+
},
|
|
56
|
+
include: ['bin/**/*', 'src/**/*', 'tests/**/*'],
|
|
57
|
+
};
|
|
58
|
+
const STARTER_TSCONFIG_TS = {
|
|
59
|
+
compilerOptions: {
|
|
60
|
+
target: 'ES2022',
|
|
61
|
+
module: 'NodeNext',
|
|
62
|
+
moduleResolution: 'NodeNext',
|
|
63
|
+
outDir: 'dist',
|
|
64
|
+
strict: true,
|
|
65
|
+
esModuleInterop: true,
|
|
66
|
+
skipLibCheck: true,
|
|
67
|
+
types: ['node'],
|
|
68
|
+
},
|
|
69
|
+
include: ['bin/**/*', 'src/**/*', 'tests/**/*'],
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Node ESM scaffolder. Materializes directories + placeholder files,
|
|
73
|
+
* writes package.json (when listed in spec) and tsconfig.json (when listed),
|
|
74
|
+
* choosing JS vs TS tsconfig flavor based on which extension dominates the
|
|
75
|
+
* other listed paths.
|
|
76
|
+
*
|
|
77
|
+
* Behavior is intentionally byte-identical to v7.2.0 — the existing
|
|
78
|
+
* tests/scaffold.test.ts is the regression bar.
|
|
79
|
+
*/
|
|
80
|
+
export async function scaffoldNode(ctx) {
|
|
81
|
+
const { cwd, parsed, dryRun } = ctx;
|
|
82
|
+
const projectName = path.basename(cwd);
|
|
83
|
+
const filesCreated = [];
|
|
84
|
+
const filesSkippedExisting = [];
|
|
85
|
+
const dirsCreated = [];
|
|
86
|
+
let packageJsonAction = 'skipped-exists';
|
|
87
|
+
let tsconfigAction = 'skipped-no-ts';
|
|
88
|
+
// 1) Create directories first.
|
|
89
|
+
const dirs = new Set();
|
|
90
|
+
for (const p of parsed.paths) {
|
|
91
|
+
const d = path.dirname(p);
|
|
92
|
+
if (d && d !== '.')
|
|
93
|
+
dirs.add(d);
|
|
94
|
+
}
|
|
95
|
+
for (const d of dirs) {
|
|
96
|
+
const abs = path.join(cwd, d);
|
|
97
|
+
if (fs.existsSync(abs))
|
|
98
|
+
continue;
|
|
99
|
+
if (!dryRun)
|
|
100
|
+
await fsAsync.mkdir(abs, { recursive: true });
|
|
101
|
+
dirsCreated.push(d);
|
|
102
|
+
console.log(` ${PASS} mkdir ${DIM(d + '/')}`);
|
|
103
|
+
}
|
|
104
|
+
// 2) Create placeholder files (skip ones we'll handle specially).
|
|
105
|
+
const SPECIAL = new Set(['package.json', 'tsconfig.json']);
|
|
106
|
+
for (const p of parsed.paths) {
|
|
107
|
+
if (SPECIAL.has(p))
|
|
108
|
+
continue;
|
|
109
|
+
const abs = path.join(cwd, p);
|
|
110
|
+
if (fs.existsSync(abs)) {
|
|
111
|
+
filesSkippedExisting.push(p);
|
|
112
|
+
console.log(` ${SKIP} exists ${DIM(p)}`);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (!dryRun) {
|
|
116
|
+
await fsAsync.mkdir(path.dirname(abs), { recursive: true });
|
|
117
|
+
// Touch — empty file. Real content is the agent's job.
|
|
118
|
+
await fsAsync.writeFile(abs, '', 'utf8');
|
|
119
|
+
}
|
|
120
|
+
filesCreated.push(p);
|
|
121
|
+
console.log(` ${PASS} touch ${DIM(p)}`);
|
|
122
|
+
}
|
|
123
|
+
// 3) package.json — only if the spec lists it.
|
|
124
|
+
if (parsed.paths.includes('package.json')) {
|
|
125
|
+
const pkgAbs = path.join(cwd, 'package.json');
|
|
126
|
+
if (fs.existsSync(pkgAbs)) {
|
|
127
|
+
packageJsonAction = 'skipped-exists';
|
|
128
|
+
console.log(` ${SKIP} exists ${DIM('package.json (preserved)')}`);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
const pkg = buildStarterPackageJson(projectName, parsed.packageHints);
|
|
132
|
+
if (!dryRun) {
|
|
133
|
+
await fsAsync.writeFile(pkgAbs, JSON.stringify(pkg, null, 2) + '\n', 'utf8');
|
|
134
|
+
}
|
|
135
|
+
packageJsonAction = 'created';
|
|
136
|
+
console.log(` ${PASS} write ${DIM('package.json (Node 22 ESM starter)')}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// 4) tsconfig.json — only if the spec lists it. JS-flavor when the
|
|
140
|
+
// other paths are predominantly .js, TS-flavor for .ts.
|
|
141
|
+
if (parsed.paths.includes('tsconfig.json')) {
|
|
142
|
+
const tsAbs = path.join(cwd, 'tsconfig.json');
|
|
143
|
+
if (fs.existsSync(tsAbs)) {
|
|
144
|
+
tsconfigAction = 'skipped-exists';
|
|
145
|
+
console.log(` ${SKIP} exists ${DIM('tsconfig.json (preserved)')}`);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
const otherPaths = parsed.paths.filter((p) => !SPECIAL.has(p));
|
|
149
|
+
const tsCount = otherPaths.filter((p) => /\.tsx?$/.test(p)).length;
|
|
150
|
+
const jsCount = otherPaths.filter((p) => /\.jsx?$/.test(p)).length;
|
|
151
|
+
const config = tsCount > jsCount ? STARTER_TSCONFIG_TS : STARTER_TSCONFIG_JS;
|
|
152
|
+
tsconfigAction = 'created';
|
|
153
|
+
if (!dryRun) {
|
|
154
|
+
await fsAsync.writeFile(tsAbs, JSON.stringify(config, null, 2) + '\n', 'utf8');
|
|
155
|
+
}
|
|
156
|
+
const flavor = config === STARTER_TSCONFIG_TS ? 'compiled TS to dist/' : 'JS w/ JSDoc + checkJs';
|
|
157
|
+
console.log(` ${PASS} write ${DIM(`tsconfig.json (${flavor})`)}`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return { filesCreated, dirsCreated, filesSkippedExisting, packageJsonAction, tsconfigAction };
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=node.js.map
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { ScaffoldResult, ScaffoldRunContext } from './types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* PEP 503 distribution-name normalization, restricted to what we need
|
|
4
|
+
* here. Lowercase, runs of `[._-]+` collapse to a single `-`, leading +
|
|
5
|
+
* trailing `[._-]` stripped. Empty result falls back to 'app' (so the
|
|
6
|
+
* worst-case `cwd` of `___` still produces a buildable pyproject).
|
|
7
|
+
*/
|
|
8
|
+
export declare function normalizeDistributionName(raw: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Convert a (PEP 503 normalized) distribution name into a valid Python
|
|
11
|
+
* identifier suitable for a top-level package directory:
|
|
12
|
+
* - replace `-` and `.` with `_`
|
|
13
|
+
* - prefix `_` if it starts with a digit (so `2cool` -> `_2cool`)
|
|
14
|
+
*
|
|
15
|
+
* Tests pin both transformations:
|
|
16
|
+
* my-pkg-2 -> my_pkg_2
|
|
17
|
+
* 2cool -> _2cool
|
|
18
|
+
*/
|
|
19
|
+
export declare function packageNameFromDistribution(distribution: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Parse a dependency string (`fastapi`, `fastapi>=0.110`,
|
|
22
|
+
* `uvicorn[standard]`, `pyramid==2.0`) into its PEP 503 normalized
|
|
23
|
+
* "name" portion — used purely as a dedup key. We don't care about the
|
|
24
|
+
* version specifier when keying; first-occurrence wins (per spec
|
|
25
|
+
* "Dedupe by PEP 503 normalized name; first occurrence wins").
|
|
26
|
+
*/
|
|
27
|
+
export declare function dependencyNameKey(dep: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* Build the dependency list for the generated pyproject.toml. Honors
|
|
30
|
+
* the narrow contract from spec ("Dependency hint extraction (codex
|
|
31
|
+
* WARNING #6)"): values flow through verbatim, no version inference,
|
|
32
|
+
* deduped by PEP 503 normalized name. For FastAPI we ALSO seed
|
|
33
|
+
* `fastapi>=0.110` and `uvicorn[standard]>=0.27` if not already present.
|
|
34
|
+
*/
|
|
35
|
+
export declare function buildPythonDependencies(hintDeps: string[] | undefined, isFastapi: boolean): string[];
|
|
36
|
+
/**
|
|
37
|
+
* Generate the pyproject.toml body. Caller supplies the resolved
|
|
38
|
+
* distribution name, package name, dependency list, and FastAPI flag
|
|
39
|
+
* (only difference: FastAPI adds a `[project.scripts]` block).
|
|
40
|
+
*/
|
|
41
|
+
export declare function buildPyproject(opts: {
|
|
42
|
+
distributionName: string;
|
|
43
|
+
packageName: string;
|
|
44
|
+
dependencies: string[];
|
|
45
|
+
isFastapi: boolean;
|
|
46
|
+
}): string;
|
|
47
|
+
/** FastAPI entrypoint — codex CRITICAL #2: must be runnable, not a stub. */
|
|
48
|
+
export declare function buildFastapiMain(packageName: string): string;
|
|
49
|
+
/** Smoke test for the FastAPI scaffold — also auto-included so pytest config isn't dead. */
|
|
50
|
+
export declare function buildFastapiTest(packageName: string): string;
|
|
51
|
+
/**
|
|
52
|
+
* The Python scaffolder. Materializes:
|
|
53
|
+
* - src/<package_name>/__init__.py (empty)
|
|
54
|
+
* - tests/ directory
|
|
55
|
+
* - pyproject.toml (PEP 621 + hatchling)
|
|
56
|
+
* - README.md (only if missing)
|
|
57
|
+
*
|
|
58
|
+
* For FastAPI specs it also writes:
|
|
59
|
+
* - src/<package_name>/main.py (runnable FastAPI app)
|
|
60
|
+
* - tests/test_main.py (smoke test)
|
|
61
|
+
*
|
|
62
|
+
* Files explicitly listed in the spec's `## Files` get touched as empty
|
|
63
|
+
* placeholders if they don't already exist (matches the v7.2.0 Node
|
|
64
|
+
* behavior). The special files above are written with content even when
|
|
65
|
+
* not listed in `## Files` — without them the generated pyproject.toml
|
|
66
|
+
* is invalid (missing package dir) or has dead config (no tests).
|
|
67
|
+
*/
|
|
68
|
+
export declare function scaffoldPython(ctx: ScaffoldRunContext, opts: {
|
|
69
|
+
isFastapi: boolean;
|
|
70
|
+
}): Promise<ScaffoldResult>;
|
|
71
|
+
//# sourceMappingURL=python.d.ts.map
|