Skip to content

Commit 34ed433

Browse files
authored
Release 0.4.4 (#9)
LGTM
1 parent d41630c commit 34ed433

File tree

21 files changed

+968
-116
lines changed

21 files changed

+968
-116
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ jobs:
2222
cache: npm
2323
- run: npm ci
2424
- run: npm run check
25+
- run: npm run smoke:packed
2526

2627
generated-runtime-matrix:
2728
name: generated-runtime-matrix (${{ matrix.group.name }})

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@ The format follows Keep a Changelog and the version numbers follow Semantic Vers
66

77
## [Unreleased]
88

9+
## [0.4.4] - 2026-03-31
10+
11+
### Added
12+
13+
- Added `devforge doctor`, a machine-level readiness command that inspects Node.js, package managers, Corepack, Bun, Playwright browser installs, Git, Docker, and SSH setup before scaffold generation.
14+
- Added `devforge init --preflight-only` so users can run the same stack-aware readiness checks as the normal init flow without writing project files yet.
15+
- Added a packed-tarball smoke script and CI gate so DevForge now validates the shipped npm artifact in addition to the source checkout.
16+
17+
### Changed
18+
19+
- Centralized machine-remediation commands into a shared module so `doctor`, preflight output, and runtime guidance all recommend the same OS-specific fix commands.
20+
- Improved CLI help and repository docs to explain the new preflight workflow, `doctor`, and the difference between source smoke checks and packed-artifact smoke checks.
21+
922
## [0.4.3] - 2026-03-27
1023

1124
### Fixed

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,18 @@ npm install -g @ali-dev11/devforge
3939
devforge
4040
```
4141

42+
Machine readiness check:
43+
44+
```bash
45+
npx --yes @ali-dev11/devforge@latest doctor
46+
```
47+
48+
Plan-only preflight:
49+
50+
```bash
51+
npx --yes @ali-dev11/devforge@latest init --preflight-only
52+
```
53+
4254
## What The CLI Asks You
4355

4456
DevForge keeps core setup decisions required, and pushes the rest behind optional customization steps.
@@ -82,13 +94,15 @@ The full prompt-by-prompt guide is here:
8294

8395
```bash
8496
npm install
97+
npm run dev -- --help
8598
npm run lint
8699
npm run typecheck
87100
npm run test
88101
npm run build
89102
npm run check
90103
npm run docs:changelog
91104
npm run smoke
105+
npm run smoke:packed
92106
npm run runtime:matrix -- --scenario backend-hono --scenario cli-tool
93107
```
94108

@@ -102,6 +116,7 @@ npm run runtime:matrix -- --scenario backend-hono --scenario cli-tool
102116
- `npm run check` is the main contributor safety command because it combines linting, typechecking, tests, and build verification.
103117
- `npm run docs:changelog` refreshes the GitHub Pages changelog page from `CHANGELOG.md`.
104118
- `npm run smoke` verifies a non-interactive scaffold run end to end.
119+
- `npm run smoke:packed` packs the actual npm tarball, installs it into a temp directory, and verifies the published artifact shape instead of only the source checkout.
105120
- `npm run runtime:matrix -- --scenario ...` installs, builds, and verifies generated projects so the scaffold output is tested as a product, not just as source code.
106121

107122
## Repository Docs

docs/changelog.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,19 @@ Track what changed in DevForge CLI across releases, including scaffolding behavi
99
- [GitHub Releases](https://github.com/Ali-dev11/devforge/releases)
1010
- [Repository Changelog](https://github.com/Ali-dev11/devforge/blob/main/CHANGELOG.md)
1111

12+
## [0.4.4] - 2026-03-31
13+
14+
### Added
15+
16+
- Added `devforge doctor`, a machine-level readiness command that inspects Node.js, package managers, Corepack, Bun, Playwright browser installs, Git, Docker, and SSH setup before scaffold generation.
17+
- Added `devforge init --preflight-only` so users can run the same stack-aware readiness checks as the normal init flow without writing project files yet.
18+
- Added a packed-tarball smoke script and CI gate so DevForge now validates the shipped npm artifact in addition to the source checkout.
19+
20+
### Changed
21+
22+
- Centralized machine-remediation commands into a shared module so `doctor`, preflight output, and runtime guidance all recommend the same OS-specific fix commands.
23+
- Improved CLI help and repository docs to explain the new preflight workflow, `doctor`, and the difference between source smoke checks and packed-artifact smoke checks.
24+
1225
## [0.4.3] - 2026-03-27
1326

1427
### Fixed

docs/development.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ title: Development
1515
```bash
1616
npm install
1717
npm run check
18+
npx --yes @ali-dev11/devforge@latest doctor
1819
```
1920

2021
## Repository Commands
@@ -28,6 +29,7 @@ npm run build
2829
npm run check
2930
npm run docs:changelog
3031
npm run smoke
32+
npm run smoke:packed
3133
npm run runtime:matrix -- --scenario backend-hono --scenario cli-tool
3234
```
3335

@@ -39,14 +41,18 @@ npm run runtime:matrix -- --scenario backend-hono --scenario cli-tool
3941
- `npm run test` runs focused regression tests for prompting, normalization, generator output, changelog rendering, and runtime-matrix coverage.
4042
- `npm run build` compiles the CLI to `dist/`, which mirrors what npm users receive.
4143
- `npm run check` is the primary contributor gate because it runs lint, types, tests, and build verification together.
44+
- `npx --yes @ali-dev11/devforge@latest doctor` checks the local machine for the tool and runtime prerequisites that commonly break first-run scaffolds.
4245
- `npm run docs:changelog` keeps the GitHub Pages changelog synchronized with `CHANGELOG.md`.
4346
- `npm run smoke` verifies a fast end-to-end scaffold run without interactive prompts.
47+
- `npm run smoke:packed` verifies the built npm tarball by installing the packed artifact into a temp directory and running the shipped CLI from there.
4448
- `npm run runtime:matrix -- --scenario ...` validates generated projects as products by installing, building, and checking runtime behavior for representative stacks.
4549

4650
## Working On Generated Scaffolds
4751

4852
- Prefer `npm run smoke` for quick CLI sanity checks.
53+
- Run `npx --yes @ali-dev11/devforge@latest init --preflight-only` when you want stack-aware readiness checks without writing a new project yet.
4954
- Use `npm run runtime:matrix` when changing templates, prompts, package-manager behavior, or generated runtime surfaces.
55+
- Use `npm run smoke:packed` when changing the package entrypoints, published files, CLI dispatch, or install-time behavior.
5056
- If you touch microfrontend templates, validate the generated `dev` workflow, not just build output.
5157
- If you touch docs or release notes, rerun `npm run docs:changelog`.
5258

docs/index.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,12 @@ DevForge CLI turns project intent into a runnable JavaScript or TypeScript repos
3333
## Command Reference
3434

3535
- `npx --yes @ali-dev11/devforge@latest`: run DevForge without a global install.
36+
- `npx --yes @ali-dev11/devforge@latest doctor`: inspect local machine readiness before generating a scaffold.
37+
- `npx --yes @ali-dev11/devforge@latest init --preflight-only`: run stack-aware checks for the chosen plan without writing files yet.
3638
- `Project prompts`: use the [Prompt Reference](./prompts.md) when you want to know what a question changes before answering it.
3739
- `npm run check`: validate the DevForge repository itself before pushing changes.
3840
- `npm run smoke`: verify a non-interactive scaffold path.
41+
- `npm run smoke:packed`: validate the built npm tarball instead of only the source tree.
3942
- `npm run runtime:matrix -- --scenario ...`: validate generated installs, builds, and runtime behavior for representative stacks.
4043
- `npm run docs:changelog`: refresh the GitHub Pages changelog page from the main changelog file.
4144

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@ali-dev11/devforge",
3-
"version": "0.4.3",
3+
"version": "0.4.4",
44
"description": "Production-focused AI-native project scaffolding CLI for JavaScript and TypeScript teams.",
55
"license": "MIT",
66
"author": "Ali-dev11",
@@ -64,7 +64,8 @@
6464
"pretypecheck": "npm run prepare:metadata",
6565
"version": "npm run prepare:metadata && git add src/generated/package-metadata.ts",
6666
"prepack": "npm run check",
67-
"smoke": "npm run build && node --eval \"require('node:fs').rmSync('/tmp/devforge-smoke', { recursive: true, force: true })\" && node dist/bin/devforge.js init --yes --skip-install --output /tmp/devforge-smoke"
67+
"smoke": "npm run build && node --eval \"require('node:fs').rmSync('/tmp/devforge-smoke', { recursive: true, force: true })\" && node dist/bin/devforge.js init --yes --skip-install --output /tmp/devforge-smoke",
68+
"smoke:packed": "node scripts/smoke-packed.mjs"
6869
},
6970
"engines": {
7071
"node": ">=20.0.0"

scripts/smoke-packed.mjs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { mkdirSync, mkdtempSync, readdirSync, rmSync } from "node:fs";
2+
import { tmpdir } from "node:os";
3+
import { join, resolve } from "node:path";
4+
import { spawnSync } from "node:child_process";
5+
import process from "node:process";
6+
7+
function run(command, args, cwd, extraEnv = {}) {
8+
const result = spawnSync(command, args, {
9+
cwd,
10+
encoding: "utf8",
11+
stdio: "inherit",
12+
env: {
13+
...process.env,
14+
...extraEnv,
15+
},
16+
});
17+
18+
if (result.status !== 0) {
19+
throw new Error(`${command} ${args.join(" ")} failed with exit code ${result.status ?? "unknown"}`);
20+
}
21+
}
22+
23+
const rootDir = process.cwd();
24+
const workspace = mkdtempSync(join(tmpdir(), "devforge-packed-smoke-"));
25+
const packDir = join(workspace, "pack");
26+
const installDir = join(workspace, "install");
27+
const outputDir = join(workspace, "output");
28+
const npmCacheDir = join(workspace, "npm-cache");
29+
30+
mkdirSync(packDir, { recursive: true });
31+
mkdirSync(installDir, { recursive: true });
32+
33+
try {
34+
run(
35+
"npm",
36+
["pack", "--ignore-scripts", "--pack-destination", packDir],
37+
rootDir,
38+
{
39+
npm_config_cache: npmCacheDir,
40+
},
41+
);
42+
43+
const tarball = readdirSync(packDir)
44+
.find((entry) => entry.endsWith(".tgz"));
45+
46+
if (!tarball) {
47+
throw new Error("Could not find the packed DevForge tarball.");
48+
}
49+
50+
run(
51+
"npm",
52+
[
53+
"install",
54+
"--ignore-scripts",
55+
"--no-audit",
56+
"--no-fund",
57+
"--prefix",
58+
installDir,
59+
resolve(packDir, tarball),
60+
],
61+
rootDir,
62+
{
63+
npm_config_cache: npmCacheDir,
64+
},
65+
);
66+
67+
run(
68+
"node",
69+
[
70+
resolve(installDir, "node_modules/@ali-dev11/devforge/dist/bin/devforge.js"),
71+
"init",
72+
"--yes",
73+
"--skip-install",
74+
"--output",
75+
outputDir,
76+
],
77+
rootDir,
78+
);
79+
} finally {
80+
rmSync(workspace, { recursive: true, force: true });
81+
}

src/cli.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { CliOptions } from "./types.js";
2+
import { runDoctorCommand } from "./commands/doctor.js";
23
import { runInitCommand } from "./commands/init.js";
34
import { DEVFORGE_VERSION } from "./version.js";
45

@@ -12,11 +13,18 @@ function readFlagValue(flag: string, args: string[]): string {
1213
return value;
1314
}
1415

15-
function parseArgs(argv: string[]): CliOptions {
16+
function assertInitOnlyFlag(currentCommand: CliOptions["command"], flag: string): void {
17+
if (currentCommand !== "init") {
18+
throw new Error(`${flag} can only be used with \`devforge init\`.`);
19+
}
20+
}
21+
22+
export function parseArgs(argv: string[]): CliOptions {
1623
const options: CliOptions = {
1724
command: "init",
1825
resume: false,
1926
skipInstall: false,
27+
preflightOnly: false,
2028
yes: false,
2129
};
2230

@@ -33,6 +41,10 @@ function parseArgs(argv: string[]): CliOptions {
3341
return options;
3442
}
3543

44+
if (firstArg === "doctor") {
45+
options.command = "doctor";
46+
args.shift();
47+
} else
3648
if (firstArg === "init") {
3749
args.shift();
3850
} else if (firstArg && !firstArg.startsWith("-")) {
@@ -44,6 +56,7 @@ function parseArgs(argv: string[]): CliOptions {
4456

4557
switch (current) {
4658
case "--resume":
59+
assertInitOnlyFlag(options.command, "--resume");
4760
options.resume = true;
4861
break;
4962
case "--help":
@@ -55,16 +68,24 @@ function parseArgs(argv: string[]): CliOptions {
5568
options.command = "version";
5669
return options;
5770
case "--skip-install":
71+
assertInitOnlyFlag(options.command, "--skip-install");
5872
options.skipInstall = true;
5973
break;
74+
case "--preflight-only":
75+
assertInitOnlyFlag(options.command, "--preflight-only");
76+
options.preflightOnly = true;
77+
break;
6078
case "--yes":
6179
case "-y":
80+
assertInitOnlyFlag(options.command, "--yes");
6281
options.yes = true;
6382
break;
6483
case "--output":
84+
assertInitOnlyFlag(options.command, "--output");
6585
options.outputDir = readFlagValue("--output", args);
6686
break;
6787
case "--name":
88+
assertInitOnlyFlag(options.command, "--name");
6889
options.projectName = readFlagValue("--name", args);
6990
break;
7091
default:
@@ -86,15 +107,18 @@ Usage:
86107
devforge
87108
devforge init
88109
devforge init --resume
110+
devforge doctor
89111
90112
Commands:
91113
init Start a new scaffold session
114+
doctor Inspect local machine readiness for DevForge scaffolds
92115
help Show command help
93116
version Print the current CLI version
94117
95118
Flags:
96119
--resume Resume the last saved init session
97120
--skip-install Generate files without installing dependencies
121+
--preflight-only Stop after printing stack-aware readiness checks
98122
--yes, -y Use defaults without prompts
99123
--output <dir> Write the generated project to a custom directory
100124
--name <name> Override the generated project name
@@ -103,7 +127,9 @@ Flags:
103127
104128
Examples:
105129
npx @ali-dev11/devforge@latest
130+
npx @ali-dev11/devforge@latest doctor
106131
npx @ali-dev11/devforge@latest init --yes --skip-install --output ./my-app
132+
devforge init --preflight-only
107133
devforge init --resume
108134
`);
109135
}
@@ -125,5 +151,10 @@ export async function runCli(argv = process.argv.slice(2)): Promise<void> {
125151
return;
126152
}
127153

154+
if (options.command === "doctor") {
155+
await runDoctorCommand();
156+
return;
157+
}
158+
128159
await runInitCommand(options);
129160
}

0 commit comments

Comments
 (0)