plain-forge 1.0.22-next.e8a40fd → 1.0.22
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 +17 -26
- package/bin/cli.mjs +7 -4
- package/bin/python-tools.mjs +139 -0
- package/forge/rules/integration-embedded-testing.md +1 -1
- package/forge/rules/linked-resources.md +5 -2
- package/forge/skills/add-feature/SKILL.md +2 -1
- package/forge/skills/add-feature/references/checklist.md +1 -1
- package/forge/skills/add-resource/SKILL.md +5 -3
- package/forge/skills/check-forge-version/SKILL.md +1 -1
- package/forge/skills/check-forge-version/scripts/check-forge-version.mjs +1 -1
- package/forge/skills/check-plain-env/SKILL.md +7 -8
- package/forge/skills/forge-plain/SKILL.md +3 -4
- package/forge/skills/forge-plain/references/checklist.md +2 -2
- package/forge/skills/forge-plain/references/phase-3-testing.md +1 -1
- package/forge/skills/forge-plain/references/phase-4-validate-handoff.md +13 -15
- package/forge/skills/implement-conformance-testing-script/SKILL.md +3 -3
- package/forge/skills/implement-prepare-environment-script/SKILL.md +3 -3
- package/forge/skills/implement-unit-testing-script/SKILL.md +3 -3
- package/forge/skills/init-config-file/SKILL.md +22 -134
- package/forge/skills/init-plain-project/SKILL.md +5 -5
- package/forge/skills/init-plain-project/references/checklist.md +2 -2
- package/forge/skills/load-plain-reference/SKILL.md +3 -4
- package/forge/skills/load-plain-reference/references/project-model.md +1 -1
- package/forge/skills/plain-healthcheck/SKILL.md +42 -33
- package/package.json +2 -2
- package/forge/skills/load-codeplain-reference/SKILL.md +0 -188
- package/forge/skills/run-codeplain/SKILL.md +0 -483
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
name: plain-healthcheck
|
|
3
3
|
description: >-
|
|
4
4
|
Verification gate for a ***plain project. Verifies that every `config.yaml`
|
|
5
|
-
exists
|
|
6
|
-
`
|
|
7
|
-
the
|
|
5
|
+
exists and points at scripts that actually live in `test_scripts/`, parses
|
|
6
|
+
every top module with `plain-parser check`, and checks every module for what
|
|
7
|
+
the parser can't judge (section ownership, bullets, linked resources). Run this whenever anything in the project is finalized —
|
|
8
8
|
including (but not limited to) the end of `forge-plain`, the end of
|
|
9
9
|
`add-feature`, after `debug-specs`, after any single-skill edit that
|
|
10
10
|
finalizes a concept, functional spec, requirement, template, or config —
|
|
@@ -13,13 +13,13 @@ description: >-
|
|
|
13
13
|
|
|
14
14
|
# Plain Healthcheck
|
|
15
15
|
|
|
16
|
-
Always use the skill `load-
|
|
16
|
+
Always use the skill `load-plain-reference` to retrieve the ***plain syntax rules — but only if you haven't done so yet. Step 3b checks every module against those rules, and they are needed to fix what `plain-parser` reports in Step 3a.
|
|
17
17
|
|
|
18
18
|
## When to run
|
|
19
19
|
|
|
20
20
|
Run this skill **whenever anything in the ***plain project is finalized** and the project is about to be left in a state the user (or another skill) might render from. That includes, but is not limited to:
|
|
21
21
|
|
|
22
|
-
- **End of `forge-plain`** (Phase 4) — before
|
|
22
|
+
- **End of `forge-plain`** (Phase 4) — before handing off the render target.
|
|
23
23
|
- **End of `add-feature`** (Phase 3 final review) — before declaring the feature done.
|
|
24
24
|
- **End of `debug-specs`** — after applying a fix, before telling the user to re-render.
|
|
25
25
|
- **After finalizing any single edit** that changes the renderable surface — e.g. after `add-concept`, `add-functional-spec`, `add-functional-specs`, `add-implementation-requirement`, `add-test-requirement`, `add-acceptance-test`, `add-template`, `add-resource`, `resolve-spec-conflict`, `break-down-func-spec`, `consolidate-concepts`, `refactor-module`, `create-import-module`, `create-requires-module`, or any of the `implement-*-testing-script` skills.
|
|
@@ -28,7 +28,7 @@ Run this skill **whenever anything in the ***plain project is finalized** and th
|
|
|
28
28
|
|
|
29
29
|
The healthcheck is **not** a forge-plain-only step. Treat it as the default closing move for any workflow that finalizes something in the project.
|
|
30
30
|
|
|
31
|
-
Do **not** skip this skill because "the
|
|
31
|
+
Do **not** skip this skill because "the healthcheck passed earlier" — `config.yaml`s, scripts, and specs can all drift between runs. The healthcheck is cheap; rendering against stale specs is expensive.
|
|
32
32
|
|
|
33
33
|
## Workflow
|
|
34
34
|
|
|
@@ -36,7 +36,7 @@ The skill is a **detect → fix → re-run** loop. It does not stop at the first
|
|
|
36
36
|
|
|
37
37
|
### Step 1 — Inventory the project
|
|
38
38
|
|
|
39
|
-
1. List every `.plain` file in the repo root (and any subdirectories that contain `.plain` files). Build the module graph from each file's YAML frontmatter (`requires`, `import`)
|
|
39
|
+
1. List every `.plain` file in the repo root (and any subdirectories that contain `.plain` files). Build the module graph from each file's YAML frontmatter (`requires`, `import`); Step 3a validates it.
|
|
40
40
|
2. Identify **top modules** — every module that is not `requires`-ed by any other module. A single-stack project has one top module; a multi-part project (e.g. backend + frontend) has one top module per part.
|
|
41
41
|
3. List every `config.yaml` in the repo (root and per-part directories such as `backend/`, `frontend/`).
|
|
42
42
|
4. List every script under `test_scripts/`.
|
|
@@ -52,7 +52,7 @@ For each `config.yaml` in the inventory, check **all** of the following. Collect
|
|
|
52
52
|
2. **At minimum `unittests-script` is present.** Every project gets a unit-test runner.
|
|
53
53
|
3. **For every script field that is present** (`unittests-script`, `conformance-tests-script`, `prepare-environment-script`):
|
|
54
54
|
- The path is a string ending in `.sh` (macOS/Linux) or `.ps1` (Windows). The extension must match the rest of the project — do not mix `.sh` and `.ps1` in a single config.
|
|
55
|
-
- The referenced file actually exists on disk
|
|
55
|
+
- The referenced file actually exists on disk: absolute / `~` paths as-is, relative paths against the **config file's directory** (typically landing under `test_scripts/`). There is no other fallback, so a path that only "works" from some other directory is a failure here.
|
|
56
56
|
- On Unix, the script has the executable bit set (`-x`). If not, that is a fixable failure.
|
|
57
57
|
4. **No mixed stacks per config.** Every script referenced from a single `config.yaml` must target the same language/stack. For example, `backend/config.yaml` should not reference `run_unittests_js.sh`. If a config crosses stacks, that is a failure — the project should have been split into multiple configs per the applicable module rules loaded by `load-plain-reference`.
|
|
58
58
|
5. **No dangling fields.** Any `*-script` field whose target file does not exist is a failure.
|
|
@@ -68,46 +68,54 @@ For each failure, record the offending config path, the offending field, and the
|
|
|
68
68
|
|
|
69
69
|
Anything else (missing script, mixed stacks, missing `config.yaml`) must be surfaced to the user — do not silently regenerate scripts here. Re-invoking `implement-unit-testing-script`, `implement-conformance-testing-script`, or `implement-prepare-environment-script` from inside the healthcheck is allowed **only** if the user explicitly approves it after being shown the gap.
|
|
70
70
|
|
|
71
|
-
### Step 3 —
|
|
71
|
+
### Step 3 — Validate every module
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
Step 3 has two halves: a mechanical parse by `plain-parser`, then the checks that need judgement. Collect every failure from both — do **not** stop at the first.
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
codeplain <top_module>.plain --dry-run
|
|
77
|
-
```
|
|
75
|
+
#### 3a. Parse every top module with `plain-parser`
|
|
78
76
|
|
|
79
|
-
|
|
77
|
+
[`plain-parser`](https://pypi.org/project/plain-parser/) is the ***plain parser. It parses a module together with its whole `import` / `requires` chain, so running it on every top module covers every module in the project.
|
|
80
78
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
- **`--full-plain`** — useful when an `import`/`requires` chain is suspect.
|
|
84
|
-
- **`--verbose` / `-v`** — strongly recommended on a failed dry-run; the extra log output usually pinpoints the offending `.plain` file and spec.
|
|
79
|
+
1. **Check it is installed.** Run `plain-parser --help`. If the command is not found, stop and report `FAIL` with the install command (`pipx install plain-parser` or `uv tool install plain-parser`; it needs Python 3.11 or newer). Do **not** fall back to checking these rules by reading the files — without the parser there is no syntax gate.
|
|
80
|
+
2. **Run it from the top module's own directory**, once per top module:
|
|
85
81
|
|
|
86
|
-
|
|
82
|
+
```bash
|
|
83
|
+
cd <top-module-dir> && plain-parser check <top>.plain
|
|
84
|
+
```
|
|
87
85
|
|
|
88
|
-
|
|
86
|
+
Add `--config-name <name>` when the governing config is not named `config.yaml`. `plain-parser` reads `template-dir` from the config next to the `.plain` file or in the working directory, and exits `2` when it finds one in both — running from the module's own directory avoids that in multi-part projects.
|
|
87
|
+
3. **Read the result.** Exit `0` prints `<file>: OK`. Exit `1` prints `Error: …` on stderr — record that message verbatim as a failure against the top module. Exit `2` is a usage or config error (ambiguous or malformed config) — record it against the config.
|
|
89
88
|
|
|
90
|
-
|
|
89
|
+
`plain-parser` checks, among other things: frontmatter, that every `import` / `requires` entry exists and the graph has no cycles, that `requires` modules have one fixed order, that imported modules have no functional specs, section headings (allowed, not duplicated, `***definitions***` first, `***acceptance tests***` nested under a functional spec), concepts (defined, exported and required correctly), that a module with functional specs has implementation reqs, and that every linked resource and template resolves to an existing, relative, non-`.plain` file. It does not always report every error in one run, so after fixing what it reported, run it again until it prints `OK`.
|
|
91
90
|
|
|
92
|
-
|
|
93
|
-
2. Fix only the `.plain` files (or the relevant `config.yaml` / template) using the appropriate edit skill — `add-concept`, `add-functional-spec`, `add-functional-specs`, `add-implementation-requirement`, `resolve-spec-conflict`, `break-down-func-spec`, `consolidate-concepts`, or an inline edit. **Never** modify generated code under `plain_modules/<module>/code/` or `plain_modules/<module>/tests/`.
|
|
94
|
-
3. If you are uncertain about ***plain syntax for the failing construct, re-load `load-plain-reference` before fixing.
|
|
95
|
-
4. Re-run the same `codeplain <top_module>.plain --dry-run …` command with the same flags. Repeat until it exits successfully.
|
|
91
|
+
#### 3b. Check what the parser can't judge
|
|
96
92
|
|
|
97
|
-
|
|
93
|
+
Check every `.plain` module against the rules loaded by `load-plain-reference`:
|
|
94
|
+
|
|
95
|
+
1. **Section ownership.** No fact sits in a section that doesn't own it — `:UnitTests:` facts only in `***implementation reqs***`, `:ConformanceTests:` facts only in `***test reqs***`, technology only in `***implementation reqs***`.
|
|
96
|
+
2. **Bullets.** Every line in every section is a valid `- ` list item or a correctly indented sub-bullet — no bare continuation lines.
|
|
97
|
+
3. **Linked resources.** Every linked resource is a single **text** file (not a binary), and no URL or folder path appears in the surrounding spec text unless it is a runtime value the generated software itself uses.
|
|
98
|
+
|
|
99
|
+
Functional-spec complexity is checked when a spec is authored (`add-functional-spec(s)` → `analyze-if-func-spec-too-complex`). Re-run `analyze-if-func-spec-too-complex` here only for a spec that was hand-edited since it was authored.
|
|
98
100
|
|
|
99
|
-
|
|
101
|
+
Treat 3a and 3b together as a hard gate: the healthcheck **only passes** when `plain-parser check` prints `OK` for every top module and every module passes every check in 3b.
|
|
100
102
|
|
|
101
|
-
|
|
103
|
+
#### When a check fails
|
|
102
104
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
+
Iterate until it passes:
|
|
106
|
+
|
|
107
|
+
1. Identify the offending `.plain` file, the line, and the kind of issue: missing or duplicated concept, cyclic definition, broken `import`/`requires`, misplaced fact, bare continuation line, missing resource or template, etc.
|
|
108
|
+
2. Fix only the `.plain` files (or the relevant `config.yaml` / template) using the appropriate edit skill — `add-concept`, `add-functional-spec`, `add-functional-specs`, `add-implementation-requirement`, `resolve-section-ownership`, `resolve-spec-conflict`, `break-down-func-spec`, `consolidate-concepts`, or an inline edit. **Never** modify generated code under `plain_modules/<module>/code/` or `plain_modules/<module>/tests/`.
|
|
109
|
+
3. If you are uncertain about ***plain syntax for the failing construct, re-load `load-plain-reference` before fixing.
|
|
110
|
+
4. Re-run the failed checks — for a `plain-parser` failure, re-run `plain-parser check`. Repeat until they pass.
|
|
111
|
+
|
|
112
|
+
If the failure is something the healthcheck cannot reasonably fix on its own (e.g. the user has to choose between two contradictory specs and neither side was pre-approved, or a missing concept whose semantics aren't clear), **stop and surface it to the user** with the offending snippet and a concrete question. Do not invent behavior.
|
|
105
113
|
|
|
106
114
|
### Step 4 — Report
|
|
107
115
|
|
|
108
116
|
Emit one of:
|
|
109
117
|
|
|
110
|
-
- **`PASS`** — followed by a short summary of what was checked: `N config.yaml(s) validated`, `M
|
|
118
|
+
- **`PASS`** — followed by a short summary of what was checked: `N config.yaml(s) validated`, `M module(s) checked (plain-parser OK for every top module)`, `K scripts referenced`. The caller (`forge-plain`, `add-feature`, `debug-specs`) can then continue to its hand-off step.
|
|
111
119
|
- **`FAIL`** — followed by a numbered list of every unresolved problem. Each entry must include: the file (config / `.plain` / script) it applies to, the concrete issue, and what the user needs to decide if the healthcheck couldn't resolve it.
|
|
112
120
|
|
|
113
121
|
The verdict goes on the first line so callers can pattern-match without parsing the whole report.
|
|
@@ -115,7 +123,7 @@ The verdict goes on the first line so callers can pattern-match without parsing
|
|
|
115
123
|
## What this skill does NOT do
|
|
116
124
|
|
|
117
125
|
- It does **not** author new specs from scratch — use `forge-plain` / `add-feature` for that.
|
|
118
|
-
- It does **not**
|
|
126
|
+
- It does **not** render anything.
|
|
119
127
|
- It does **not** execute the testing scripts (`run_unittests`, `run_conformance_tests`, `prepare_environment`). It only verifies that the scripts are wired up correctly via `config.yaml`. The user runs the scripts themselves.
|
|
120
128
|
- It does **not** silently regenerate config files or scripts. The most it does is `chmod +x` and (with user approval) re-invoke the relevant `implement-*-testing-script` skill.
|
|
121
129
|
|
|
@@ -128,5 +136,6 @@ The verdict goes on the first line so callers can pattern-match without parsing
|
|
|
128
136
|
- [ ] No `config.yaml` mixes stacks (e.g. Python + JS scripts in the same file)
|
|
129
137
|
- [ ] No `config.yaml` declares `prepare-environment-script` without also declaring `conformance-tests-script`
|
|
130
138
|
- [ ] Every `test_scripts/*` file is referenced by some `config.yaml` (or surfaced as a warning)
|
|
131
|
-
- [ ] `
|
|
139
|
+
- [ ] `plain-parser check` printed `OK` for every top module, run from that module's directory
|
|
140
|
+
- [ ] Every module passes every check in Step 3b (section ownership, bullets, linked resources)
|
|
132
141
|
- [ ] Verdict (`PASS` / `FAIL`) is on the first line, with a numbered list of remaining problems if it failed
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "plain-forge",
|
|
3
|
-
"version": "1.0.22
|
|
3
|
+
"version": "1.0.22",
|
|
4
4
|
"description": "Conversational spec-writing tool for ***plain specification language",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
"license": "MIT",
|
|
18
18
|
"keywords": [
|
|
19
19
|
"plain",
|
|
20
|
-
"codeplain",
|
|
21
20
|
"claude-code",
|
|
22
21
|
"skills",
|
|
23
22
|
"spec",
|
|
@@ -28,6 +27,7 @@
|
|
|
28
27
|
},
|
|
29
28
|
"files": [
|
|
30
29
|
"bin/cli.mjs",
|
|
30
|
+
"bin/python-tools.mjs",
|
|
31
31
|
"forge"
|
|
32
32
|
],
|
|
33
33
|
"scripts": {
|
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: load-codeplain-reference
|
|
3
|
-
description: >-
|
|
4
|
-
Loads the full `codeplain` CLI reference into context: the render command and
|
|
5
|
-
its positional plain-file argument, every flag (render control, config,
|
|
6
|
-
folders, test-script wiring, output copying, API, logging, headless mode),
|
|
7
|
-
path-resolution rules, the CODEPLAIN_API_KEY environment variable, the
|
|
8
|
-
config.yaml mapping, and the success/failure render banners. Use whenever
|
|
9
|
-
running, configuring, resuming, or reasoning about a `codeplain` render or its
|
|
10
|
-
config.yaml. Not for the ***plain language syntax itself (use
|
|
11
|
-
load-plain-reference) or for supervising a live render (use run-codeplain).
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
# CODEPLAIN_CLI_REFERENCE.md
|
|
15
|
-
|
|
16
|
-
`codeplain` is the CLI that renders `***plain` specification files into production-ready code. It reads a `.plain` module (and everything it `import`s / `requires`), calls the codeplain API, and writes generated code under `plain_modules/<module>/code/` and conformance tests under `plain_modules/<module>/tests/`. The `.plain` specs are the source of truth; the generated code is a read-only artifact.
|
|
17
|
-
|
|
18
|
-
This reference covers the CLI surface only. For the `***plain` language itself use `load-plain-reference`; to supervise a live render use `run-codeplain`; to assemble or validate `config.yaml` use `init-config-file` / `plain-healthcheck`.
|
|
19
|
-
|
|
20
|
-
## Usage
|
|
21
|
-
|
|
22
|
-
```text
|
|
23
|
-
codeplain [options] filename
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
```text
|
|
27
|
-
usage: codeplain [-h] [--verbose] [--base-folder BASE_FOLDER]
|
|
28
|
-
[--build-folder BUILD_FOLDER]
|
|
29
|
-
[--log-to-file | --no-log-to-file]
|
|
30
|
-
[--log-file-name LOG_FILE_NAME] [--config-name CONFIG_NAME]
|
|
31
|
-
[--render-range RENDER_RANGE | --render-from RENDER_FROM]
|
|
32
|
-
[--force-render] [--unittests-script UNITTESTS_SCRIPT]
|
|
33
|
-
[--conformance-tests-folder CONFORMANCE_TESTS_FOLDER]
|
|
34
|
-
[--conformance-tests-script CONFORMANCE_TESTS_SCRIPT]
|
|
35
|
-
[--prepare-environment-script PREPARE_ENVIRONMENT_SCRIPT]
|
|
36
|
-
[--test-script-timeout TEST_SCRIPT_TIMEOUT] [--api [API]]
|
|
37
|
-
[--api-key API_KEY] [--full-plain] [--dry-run]
|
|
38
|
-
[--replay-with REPLAY_WITH] [--template-dir TEMPLATE_DIR]
|
|
39
|
-
[--copy-build] [--build-dest BUILD_DEST]
|
|
40
|
-
[--copy-conformance-tests]
|
|
41
|
-
[--conformance-tests-dest CONFORMANCE_TESTS_DEST]
|
|
42
|
-
[--render-machine-graph]
|
|
43
|
-
[--logging-config-path LOGGING_CONFIG_PATH] [--headless]
|
|
44
|
-
filename
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## Positional argument
|
|
48
|
-
|
|
49
|
-
- **`filename`** — path to the `.plain` file to render. The directory containing this file has the **highest precedence for template loading**, so custom templates placed there override the defaults (see `--template-dir`). Render the **top module** of the dependency chain — the module not `requires`-ed by any other; its `requires`/`import` graph is pulled in automatically.
|
|
50
|
-
|
|
51
|
-
## Path resolution (read this before setting any path flag)
|
|
52
|
-
|
|
53
|
-
A path's meaning depends on **where it was written**:
|
|
54
|
-
|
|
55
|
-
- Values given **on the command line** resolve against the **current working directory**.
|
|
56
|
-
- Values read from **`config.yaml`** resolve against the **config file's directory**.
|
|
57
|
-
- **Default** values resolve against the **directory containing the `.plain` file**.
|
|
58
|
-
- **Absolute paths** (and paths starting with `~`) are used as-is.
|
|
59
|
-
|
|
60
|
-
## Options
|
|
61
|
-
|
|
62
|
-
### Render control
|
|
63
|
-
|
|
64
|
-
- **`--dry-run`** — preview code generation without making any changes. This is the static-validation gate; `plain-healthcheck` runs `codeplain <top>.plain --dry-run` for every top module before a real render. **Per-invocation only — never store in `config.yaml`.**
|
|
65
|
-
- **`--full-plain`** — full preview of the assembled `***plain` specification before code generation. Use to inspect the context of all `***plain` primitives that will be included to render the given module. **Per-invocation only — never in `config.yaml`.**
|
|
66
|
-
- **`--render-range RENDER_RANGE`** — render a range of functionalities (e.g. `1`, or `2,3`). A comma separates the start and end IDs; the range is inclusive of both. A single ID renders only that one functionality. Mutually exclusive with `--render-from`. **Per-invocation only — never in `config.yaml`.**
|
|
67
|
-
- **`--render-from RENDER_FROM`** — continue generation starting from this functionality ID (inclusive). The ID must match a functionality in the `.plain` file. This is how a run resumes after a spec fix — pass the **first functionality to re-render**. Mutually exclusive with `--render-range`. **Per-invocation only — never in `config.yaml`.**
|
|
68
|
-
- **`--force-render`** — force a re-render of all required modules, invalidating cached module renders. Use only when a backward dependency genuinely changed; it costs more credits.
|
|
69
|
-
- **`--replay-with REPLAY_WITH`** — replay a previous render. **Per-invocation only — never in `config.yaml`.**
|
|
70
|
-
|
|
71
|
-
### Configuration
|
|
72
|
-
|
|
73
|
-
- **`--config-name CONFIG_NAME`** — name of the config file to look for. It is looked up in the `.plain` file's directory and in the current working directory. Defaults to `config.yaml`. Use it for multi-part projects (one config per part) or a non-default config file name.
|
|
74
|
-
|
|
75
|
-
### Folders
|
|
76
|
-
|
|
77
|
-
- **`--base-folder BASE_FOLDER`** — base folder for the build files.
|
|
78
|
-
- **`--build-folder BUILD_FOLDER`** — folder for build files (generated code lands under here, per module: `plain_modules/<module>/code/` and `plain_modules/<module>/tests/`).
|
|
79
|
-
- **`--template-dir TEMPLATE_DIR`** — path to a custom template directory. Templates are searched in this order: 1) the directory containing the `.plain` file, 2) this custom template directory, 3) the built-in `standard_template_library` directory. In `config.yaml` the equivalent key is `template_dir` — set it whenever the project has import modules or templates.
|
|
80
|
-
|
|
81
|
-
### Test-script wiring
|
|
82
|
-
|
|
83
|
-
- **`--unittests-script UNITTESTS_SCRIPT`** — shell script that runs unit tests on the generated code. Receives the build folder path as its first argument (default: `plain_modules`). `config.yaml` key: `unittests-script`.
|
|
84
|
-
- **`--conformance-tests-folder CONFORMANCE_TESTS_FOLDER`** — folder for conformance test files.
|
|
85
|
-
- **`--conformance-tests-script CONFORMANCE_TESTS_SCRIPT`** — path to the conformance-tests shell script. It must accept two arguments: 1) a folder containing generated source code (e.g. `plain_modules/module_name`), and 2) a subfolder of the conformance-tests folder containing the test files (e.g. `conformance_tests/subfoldername`). `config.yaml` key: `conformance-tests-script`.
|
|
86
|
-
- **`--prepare-environment-script PREPARE_ENVIRONMENT_SCRIPT`** — path to a shell script that prepares the testing environment. It must accept the source-code folder path as its first argument. It runs once per render, only to warm the environment the conformance runner attaches to. `config.yaml` key: `prepare-environment-script`. If this is declared, `conformance-tests-script` must be declared too.
|
|
87
|
-
- **`--test-script-timeout TEST_SCRIPT_TIMEOUT`** — timeout for test scripts, in seconds. Defaults to 120 seconds. Raise it if the project's test scripts are slow.
|
|
88
|
-
|
|
89
|
-
### Output copying
|
|
90
|
-
|
|
91
|
-
- **`--copy-build`** — after a successful render, copy the rendered code in `--base-folder` to `--build-dest`.
|
|
92
|
-
- **`--build-dest BUILD_DEST`** — target folder for `--copy-build` (used only when `--copy-build` is set).
|
|
93
|
-
- **`--copy-conformance-tests`** — after a successful render, copy the conformance tests in `--conformance-tests-folder` to `--conformance-tests-dest`. Requires `--conformance-tests-script`.
|
|
94
|
-
- **`--conformance-tests-dest CONFORMANCE_TESTS_DEST`** — target folder for `--copy-conformance-tests` (used only when it is set).
|
|
95
|
-
|
|
96
|
-
### API
|
|
97
|
-
|
|
98
|
-
- **`--api [API]`** — alternative base URL for the API. Default: `https://api.codeplain.ai`.
|
|
99
|
-
- **`--api-key API_KEY`** — API key used to access the API. If not provided, the `CODEPLAIN_API_KEY` environment variable is used. **Secret — never store it in `config.yaml`.**
|
|
100
|
-
|
|
101
|
-
### Logging & output mode
|
|
102
|
-
|
|
103
|
-
- **`--verbose`, `-v`** — enable verbose output. Verbose logging captures each test script's stdout/stderr into the log file between the renderer's own wrapper lines, which is what makes a live render inspectable. Keep logging verbose.
|
|
104
|
-
- **`--log-to-file` / `--no-log-to-file`** — enable or disable logging to a file. Defaults to `True`; pass `--no-log-to-file` to disable.
|
|
105
|
-
- **`--log-file-name LOG_FILE_NAME`** — name of the log file. Defaults to `codeplain.log`. If a file already exists at the resolved path, it is **overwritten** by the current run's logs — the log is therefore per-run, and its default location is the `.plain` file's directory.
|
|
106
|
-
- **`--logging-config-path LOGGING_CONFIG_PATH`** — path to a logging configuration file.
|
|
107
|
-
- **`--headless`** — run without the TUI: no terminal output except a single render-started message; all logs are written to the log file. **Required for agent-supervised runs** — a terminal tool cannot drive the interactive TUI, so supervision reads `codeplain.log` instead.
|
|
108
|
-
- **`--render-machine-graph`** — render the state-machine graph. Use only on explicit request.
|
|
109
|
-
- **`-h`, `--help`** — show the help message and exit.
|
|
110
|
-
|
|
111
|
-
## Environment variables
|
|
112
|
-
|
|
113
|
-
- **`CODEPLAIN_API_KEY`** — the API key used when `--api-key` is not passed on the command line. Export it before rendering (or pass `--api-key`). It is a secret and must never be written into `config.yaml`.
|
|
114
|
-
|
|
115
|
-
## `config.yaml` relationship
|
|
116
|
-
|
|
117
|
-
`codeplain` reads persistent options from a `config.yaml` (or the file named by `--config-name`), looked up in the `.plain` file's directory and the current working directory. This avoids retyping stable options on every run.
|
|
118
|
-
|
|
119
|
-
- **One `config.yaml` per part of the system that has its own test scripts.** A single-stack project has one at the root; a multi-part project (e.g. a Python backend and a React frontend) has one per part, each referencing only its own scripts.
|
|
120
|
-
- **Established keys:** `unittests-script`, `conformance-tests-script`, `prepare-environment-script`, `template_dir`, `base-folder`, `build-folder`, plus copy/log settings. `init-config-file` is the canonical assembler and the source of truth for the full valid key set; treat it as authoritative.
|
|
121
|
-
- **Constraint:** if `prepare-environment-script` is declared, `conformance-tests-script` must be declared too — a prepare script only exists in service of conformance.
|
|
122
|
-
- **Never put in `config.yaml`:** secrets (`api-key`) and per-invocation flags (`dry-run`, `full-plain`, `render-range`, `render-from`, `replay-with`). Supply these on the command line only.
|
|
123
|
-
- Remember the path-resolution rule above: a script path written in `config.yaml` resolves against the config file's directory, not the working directory.
|
|
124
|
-
|
|
125
|
-
## Render output
|
|
126
|
-
|
|
127
|
-
Generated artifacts (gitignored, read-only — never edit):
|
|
128
|
-
|
|
129
|
-
- `plain_modules/<module>/code/` — the generated project for each `.plain` spec (implementation + unit tests).
|
|
130
|
-
- `plain_modules/<module>/tests/<functionality>/` — generated conformance tests, one subfolder per functionality.
|
|
131
|
-
- `codeplain.log` — the per-run log (overwritten each run).
|
|
132
|
-
|
|
133
|
-
When a run ends, `codeplain` writes a result banner (to the log, and to the terminal outside headless mode):
|
|
134
|
-
|
|
135
|
-
- **Success:** `✓ rendering succeeded` (or `rendering complete`), followed by a metadata block: render id, input file, generated code folder, functionalities count, used credits, render time.
|
|
136
|
-
- **Failure:** `✗ rendering failed`, followed by the same metadata block.
|
|
137
|
-
|
|
138
|
-
## Test-script exit-code contract
|
|
139
|
-
|
|
140
|
-
The three wired scripts (`unittests-script`, `conformance-tests-script`, `prepare-environment-script`) share an exit-code contract that `codeplain`, `plain-healthcheck`, and `check-plain-env` all branch on:
|
|
141
|
-
|
|
142
|
-
- **`69`** — unrecoverable error (missing toolchain, bad arguments, cannot enter the working folder, install failed).
|
|
143
|
-
- **`1`** — the "no tests discovered" guard in the conformance runner (and bad usage in the unit-test runner).
|
|
144
|
-
- **any other non-zero** — propagated verbatim from the underlying test command (a real test failure).
|
|
145
|
-
|
|
146
|
-
Author or modify these scripts only through the matching `implement-{unit-testing,conformance-testing,prepare-environment}-script` skill — never by hand.
|
|
147
|
-
|
|
148
|
-
## Common invocation patterns
|
|
149
|
-
|
|
150
|
-
```bash
|
|
151
|
-
# Static-validation gate before a real render (what plain-healthcheck runs)
|
|
152
|
-
codeplain <module>.plain --dry-run
|
|
153
|
-
|
|
154
|
-
# Full render of the top module
|
|
155
|
-
codeplain <module>.plain
|
|
156
|
-
|
|
157
|
-
# Multi-part project: render one part with its own config file
|
|
158
|
-
codeplain backend/api.plain --config-name config.yaml
|
|
159
|
-
|
|
160
|
-
# Agent-supervised render: background + headless, watch codeplain.log
|
|
161
|
-
nohup codeplain <module>.plain --headless > /dev/null 2>&1 &
|
|
162
|
-
|
|
163
|
-
# Resume after a spec fix: re-render from functionality N (inclusive)
|
|
164
|
-
codeplain <module>.plain --render-from <N>
|
|
165
|
-
|
|
166
|
-
# Re-render exactly one functionality
|
|
167
|
-
codeplain <module>.plain --render-range <N>
|
|
168
|
-
|
|
169
|
-
# Force a full re-render (backward dependency changed) — costs more credits
|
|
170
|
-
codeplain <module>.plain --force-render
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
## Common errors and signals
|
|
174
|
-
|
|
175
|
-
- **`codeplain: command not found`** — the CLI is not installed or not on `PATH`. Confirm with `command -v codeplain`.
|
|
176
|
-
- **`401` / `403` / `unauthorized`** — `CODEPLAIN_API_KEY` is unset or invalid; export it or pass `--api-key`. This is an API/auth problem, not a spec problem.
|
|
177
|
-
- **`429` / `rate limit` / `quota`** — API throttling or credit limit; not a spec problem.
|
|
178
|
-
- **`Functional spec too complex!`** — a single functional spec implies more than 200 lines of code; break it down (`break-down-func-spec`).
|
|
179
|
-
- **`missing concept` / `unknown definition` / `cyclic` / `not defined` / `cannot resolve`** — a spec-graph error (a concept used before it is defined, a cycle, or a broken `import`/`requires` chain). A `--dry-run` catches these before spending credits.
|
|
180
|
-
- **`Traceback (most recent call last):`** — the renderer itself crashed (a bug), not a spec error; capture the stack for a bug report.
|
|
181
|
-
|
|
182
|
-
## See also
|
|
183
|
-
|
|
184
|
-
- `load-plain-reference` — the `***plain` language syntax and authoring rules.
|
|
185
|
-
- `run-codeplain` — supervising a live render (monitor loop, pathologies, resume).
|
|
186
|
-
- `plain-healthcheck` — the pre-render dry-run gate across every top module.
|
|
187
|
-
- `init-config-file` — canonical `config.yaml` assembly and the full valid key set.
|
|
188
|
-
- `implement-{unit-testing,conformance-testing,prepare-environment}-script` — authoring the wired test scripts.
|