Skip to content

Commit a5c92de

Browse files
committed
Add CLI preflight command
1 parent 1862742 commit a5c92de

7 files changed

Lines changed: 123 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Changelog
22

3+
## 0.1.7 - 2026-06-17
4+
5+
- Added a read-only CLI `preflight` command that checks runtime prerequisites,
6+
packaged source files, and target directory state before initialization.
7+
- Documented the preflight command in the Chinese and English READMEs.
8+
- Added smoke coverage for fresh and existing target preflight results.
9+
310
## 0.1.6 - 2026-06-17
411

512
- Added a Node wrapper `upgrade` command for safe template upgrades of existing

README.en.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,12 @@ Preview initialization through the Node wrapper:
344344
npx github:s1oopX/agent-memory-workflow init --target "$HOME\.agents" --dry-run
345345
```
346346

347+
Run a read-only preflight check before initialization:
348+
349+
```powershell
350+
npx github:s1oopX/agent-memory-workflow preflight --target "$HOME\.agents"
351+
```
352+
347353
Upgrade an existing directory through the Node wrapper. This is the safe upgrade
348354
mode: it overwrites workflow-managed files, creates backups, and preserves
349355
existing machine facts under `machine\` by default:
@@ -491,7 +497,7 @@ Short term:
491497
Medium term:
492498

493499
- provide a more complete CLI experience
494-
- add preflight checks before initialization
500+
- strengthen preflight checks before initialization
495501
- add migration helpers for future workflow-version changes
496502

497503
Long term:

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,12 @@ npx github:s1oopX/agent-memory-workflow init --target "$HOME\.agents"
326326
npx github:s1oopX/agent-memory-workflow init --target "$HOME\.agents" --dry-run
327327
```
328328

329+
通过 Node 包装器执行初始化前预检,不写入文件:
330+
331+
```powershell
332+
npx github:s1oopX/agent-memory-workflow preflight --target "$HOME\.agents"
333+
```
334+
329335
通过 Node 包装器升级已有目录。该命令等价于安全升级模式,会自动覆盖工作流托管文件、创建备份,并默认保留 `machine\` 下已有的机器事实:
330336

331337
```powershell
@@ -454,7 +460,7 @@ SDK 适合在出现稳定应用边界后再引入。数据库适合需要并发
454460
中期:
455461

456462
- 提供更完整的 CLI 体验
457-
- 增加初始化前预检
463+
- 增强初始化前预检
458464
- 增加未来工作流版本迁移辅助
459465

460466
长期:

README.zh-CN.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,12 @@ npx github:s1oopX/agent-memory-workflow init --target "$HOME\.agents"
326326
npx github:s1oopX/agent-memory-workflow init --target "$HOME\.agents" --dry-run
327327
```
328328

329+
通过 Node 包装器执行初始化前预检,不写入文件:
330+
331+
```powershell
332+
npx github:s1oopX/agent-memory-workflow preflight --target "$HOME\.agents"
333+
```
334+
329335
通过 Node 包装器升级已有目录。该命令等价于安全升级模式,会自动覆盖工作流托管文件、创建备份,并默认保留 `machine\` 下已有的机器事实:
330336

331337
```powershell
@@ -454,7 +460,7 @@ SDK 适合在出现稳定应用边界后再引入。数据库适合需要并发
454460
中期:
455461

456462
- 提供更完整的 CLI 体验
457-
- 增加初始化前预检
463+
- 增强初始化前预检
458464
- 增加未来工作流版本迁移辅助
459465

460466
长期:

bin/agent-memory-workflow.js

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ function usage() {
1414
Usage:
1515
agent-memory-workflow init [--target <path>] [--force] [--dry-run] [--backup-root <path>] [--no-backup] [--overwrite-machine-facts] [--skip-verify]
1616
agent-memory-workflow upgrade [--target <path>] [--dry-run] [--backup-root <path>] [--no-backup] [--overwrite-machine-facts] [--skip-verify]
17+
agent-memory-workflow preflight [--target <path>]
1718
agent-memory-workflow verify [--root <path>]
1819
agent-memory-workflow status [--root <path>]
1920
agent-memory-workflow show-paths [--root <path>]
@@ -22,6 +23,7 @@ Usage:
2223
Examples:
2324
agent-memory-workflow init --target "$HOME/.agents"
2425
agent-memory-workflow init --target "$HOME/.agents" --dry-run
26+
agent-memory-workflow preflight --target "$HOME/.agents"
2527
agent-memory-workflow upgrade --target "$HOME/.agents"
2628
agent-memory-workflow verify --root "$HOME/.agents"
2729
agent-memory-workflow status --root "$HOME/.agents"
@@ -165,6 +167,75 @@ function printPaths(root) {
165167
console.log(`initializer=${paths.initializer}`);
166168
}
167169

170+
function sourcePaths() {
171+
return {
172+
templates: path.join(repoRoot, "templates"),
173+
bootstrapTemplate: path.join(repoRoot, "templates", "AGENT_BOOTSTRAP.md"),
174+
initializer: path.join(repoRoot, "tools", "init-agent-memory-workflow.ps1"),
175+
verifier: path.join(repoRoot, "tools", "verify-agent-memory-workflow.ps1"),
176+
};
177+
}
178+
179+
function runPreflight(target) {
180+
const resolvedTarget = path.resolve(target);
181+
const paths = workflowPaths(resolvedTarget);
182+
const sources = sourcePaths();
183+
const failures = [];
184+
185+
console.log("Agent memory workflow preflight");
186+
console.log(`CLI version: ${packageJson.version}`);
187+
console.log(`Node: ${process.version}`);
188+
189+
const pwshVersion = spawnSync("pwsh", ["--version"], { encoding: "utf8" });
190+
if (pwshVersion.error && pwshVersion.error.code === "ENOENT") {
191+
failures.push("PowerShell 7 executable `pwsh` was not found on PATH.");
192+
console.log("PowerShell: missing");
193+
} else if (pwshVersion.error) {
194+
failures.push(pwshVersion.error.message);
195+
console.log("PowerShell: error");
196+
} else {
197+
console.log(`PowerShell: ${pwshVersion.stdout.trim() || "available"}`);
198+
}
199+
200+
console.log(`Source templates: ${formatPresent(sources.templates)}`);
201+
console.log(`Bootstrap template: ${formatPresent(sources.bootstrapTemplate)}`);
202+
console.log(`Source initializer: ${formatPresent(sources.initializer)}`);
203+
console.log(`Source verifier: ${formatPresent(sources.verifier)}`);
204+
205+
if (!exists(sources.templates)) failures.push(`Missing source templates: ${sources.templates}`);
206+
if (!exists(sources.bootstrapTemplate)) failures.push(`Missing bootstrap template: ${sources.bootstrapTemplate}`);
207+
if (!exists(sources.initializer)) failures.push(`Missing source initializer: ${sources.initializer}`);
208+
if (!exists(sources.verifier)) failures.push(`Missing source verifier: ${sources.verifier}`);
209+
210+
const manifest = readManifest(paths.manifest);
211+
console.log(`Target: ${resolvedTarget}`);
212+
console.log(`Target exists: ${exists(resolvedTarget) ? "yes" : "no"}`);
213+
console.log(`Target manifest: ${formatPresent(paths.manifest)}`);
214+
if (manifest?.parseError) {
215+
console.log(`Target manifest parse: failed (${manifest.parseError})`);
216+
} else if (manifest) {
217+
console.log(`Target workflow version: ${manifest.version ?? "unknown"}`);
218+
}
219+
220+
if (!exists(resolvedTarget)) {
221+
console.log("Target mode: fresh install");
222+
} else if (manifest) {
223+
console.log("Target mode: existing workflow");
224+
} else {
225+
console.log("Target mode: existing non-workflow directory");
226+
}
227+
228+
if (failures.length > 0) {
229+
console.log("Result: FAIL");
230+
for (const failure of failures) {
231+
console.log(`- ${failure}`);
232+
}
233+
process.exit(1);
234+
}
235+
236+
console.log("Result: PASS");
237+
}
238+
168239
function runDoctor(root) {
169240
const resolvedRoot = path.resolve(root);
170241
const paths = workflowPaths(resolvedRoot);
@@ -241,6 +312,13 @@ function main() {
241312
return;
242313
}
243314

315+
if (command === "preflight") {
316+
validateOptions(args, { valueOptions: ["--target"] });
317+
const target = readOption(args, "--target", path.join(os.homedir(), ".agents"));
318+
runPreflight(target);
319+
return;
320+
}
321+
244322
if (command === "upgrade") {
245323
runInit(args, { force: true });
246324
return;

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "agent-memory-workflow",
3-
"version": "0.1.6",
3+
"version": "0.1.7",
44
"description": "Local-first file protocol for shared agent memory.",
55
"license": "MIT",
66
"type": "commonjs",

tools/test-agent-memory-workflow.ps1

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,14 @@ try {
8484
}
8585
}
8686

87+
Invoke-Step "node wrapper preflights fresh target" {
88+
$preflightOutput = (& node $cliScript preflight --target $dryRunTarget) -join "`n"
89+
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
90+
Assert-TextContains -Text $preflightOutput -Needle "Target exists: no" -Context "fresh preflight output"
91+
Assert-TextContains -Text $preflightOutput -Needle "Target mode: fresh install" -Context "fresh preflight output"
92+
Assert-TextContains -Text $preflightOutput -Needle "Result: PASS" -Context "fresh preflight output"
93+
}
94+
8795
Invoke-Step "force preserves machine facts by default" {
8896
$machineFile = Join-Path $target "machine\MACHINE_ENVIRONMENT_MEMORY.md"
8997
$sentinel = "LOCAL_SENTINEL_MACHINE_FACT"
@@ -123,6 +131,14 @@ try {
123131
Assert-FileContains -Path $machineFile -Needle $sentinel
124132
}
125133

134+
Invoke-Step "node wrapper preflights existing target" {
135+
$preflightOutput = (& node $cliScript preflight --target $target) -join "`n"
136+
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
137+
Assert-TextContains -Text $preflightOutput -Needle "Target exists: yes" -Context "existing preflight output"
138+
Assert-TextContains -Text $preflightOutput -Needle "Target mode: existing workflow" -Context "existing preflight output"
139+
Assert-TextContains -Text $preflightOutput -Needle "Result: PASS" -Context "existing preflight output"
140+
}
141+
126142
Invoke-Step "node wrapper prints package version" {
127143
$versionOutput = ((& node $cliScript --version) -join "`n").Trim()
128144
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }

0 commit comments

Comments
 (0)