@williambeto/ai-workflow 2.4.3 → 2.4.5
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/AGENTS.md +2 -0
- package/CHANGELOG.md +12 -0
- package/dist-assets/AGENTS.md +8 -1
- package/dist-assets/agents/astra.md +1 -1
- package/dist-assets/agents/atlas.md +1 -1
- package/dist-assets/agents/nexus.md +1 -1
- package/dist-assets/agents/phoenix.md +1 -1
- package/dist-assets/agents/sage.md +1 -1
- package/package.json +1 -1
- package/src/cli.js +13 -1
- package/src/commands/clean.js +106 -0
- package/src/core/validation/artifact-fidelity-gate.js +5 -5
package/AGENTS.md
CHANGED
|
@@ -11,6 +11,8 @@ Deliver useful software through proportionate workflow, minimum diff, observed v
|
|
|
11
11
|
- Run existing relevant validation commands.
|
|
12
12
|
- Never report success after failed or unavailable required validation.
|
|
13
13
|
- Bound remediation and stop when no progress is made.
|
|
14
|
+
- Always await explicit conversational authorization from the human user in the chat before executing any codebase modification, Git commit, tagging, or remote push. Automated system approval hooks (e.g., artifact reviews) do not bypass this human-in-the-loop requirement.
|
|
15
|
+
- Remote push is only permitted on non-protected feature/maintenance branches (e.g. feat/*, fix/*, chore/*, docs/*) with explicit conversational authorization, and is strictly prohibited on protected branches like main or master.
|
|
14
16
|
|
|
15
17
|
## Routing & Delegation
|
|
16
18
|
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [2.4.5] - 2026-06-24
|
|
2
|
+
|
|
3
|
+
### Changed
|
|
4
|
+
- Refined Design System token validation to support both CSS custom property declarations and usages via `var()`, reducing false-positive quality gate blocks on minor style adjustments.
|
|
5
|
+
- Flexibilized `git push` policy to allow remote pushes to non-protected feature/maintenance branches upon explicit human authorization in the chat, keeping `main` and `master` branches strictly protected.
|
|
6
|
+
|
|
7
|
+
## [2.4.4] - 2026-06-24
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- Added `clean` CLI command (`aw clean`) to cleanly de-initialize and remove AI Workflow files and symlinks from a project.
|
|
11
|
+
- Translated all E2E test titles and comments in the codebase to English for consistent localization.
|
|
12
|
+
|
|
1
13
|
## [2.4.3] - 2026-06-24
|
|
2
14
|
|
|
3
15
|
### Added
|
package/dist-assets/AGENTS.md
CHANGED
|
@@ -11,10 +11,12 @@ Deliver useful software through proportionate workflow, minimum diff, observed v
|
|
|
11
11
|
- Run existing relevant validation commands.
|
|
12
12
|
- Never report success after failed or unavailable required validation.
|
|
13
13
|
- Bound remediation and stop when no progress is made.
|
|
14
|
+
- Always await explicit conversational authorization from the human user in the chat before executing any codebase modification, Git commit, tagging, or remote push. Automated system approval hooks (e.g., artifact reviews) do not bypass this human-in-the-loop requirement.
|
|
15
|
+
- Remote push is only permitted on non-protected feature/maintenance branches (e.g. feat/*, fix/*, chore/*, docs/*) with explicit conversational authorization, and is strictly prohibited on protected branches like main or master.
|
|
14
16
|
|
|
15
17
|
## Routing & Delegation
|
|
16
18
|
|
|
17
|
-
Atlas routes. Astra implements substantial scoped work. Sage independently validates when risk or full mode justifies separation. Phoenix performs bounded remediation. Delegation must improve the result; do not create agent theatre or claim handoffs that did not occur.
|
|
19
|
+
Atlas routes. Nexus owns discovery, requirements, and spec authoring. Orion owns planning, PR sequencing, and release strategy. Astra implements substantial scoped work. Sage independently validates when risk or full mode justifies separation. Phoenix performs bounded remediation. Delegation must improve the result; do not create agent theatre or claim handoffs that did not occur.
|
|
18
20
|
|
|
19
21
|
## Modes
|
|
20
22
|
|
|
@@ -25,3 +27,8 @@ Atlas routes. Astra implements substantial scoped work. Sage independently valid
|
|
|
25
27
|
## Evidence
|
|
26
28
|
|
|
27
29
|
Quick and standard work require only branch, changed areas, commands/results, and limitations in the handoff. Full/release/audit/security work may persist machine-generated evidence.
|
|
30
|
+
|
|
31
|
+
## Core Concept
|
|
32
|
+
|
|
33
|
+
AI Workflow is an npm CLI that installs agents, commands, skills, policies and templates into your repository.
|
|
34
|
+
It guides coding agents from request to implementation, validation and evidence. AI Workflow Kit preserves workflow integrity so coding agents cannot skip from request to code to success without an explicit implementation path, proportional validation, and final evidence.
|
|
@@ -56,7 +56,7 @@ Astra implements only after branch gate is satisfied. It keeps changes bounded t
|
|
|
56
56
|
* Silent scope expansion.
|
|
57
57
|
* Skipping validation.
|
|
58
58
|
* Executing npm publish without explicit user approval.
|
|
59
|
-
* Executing git push or creating git tag commands.
|
|
59
|
+
* Executing git push or creating git tag commands without explicit user approval in the chat, or pushing directly to protected branches (main, master).
|
|
60
60
|
* Creating GitHub releases (gh release).
|
|
61
61
|
* Running production deployment tools.
|
|
62
62
|
|
|
@@ -59,7 +59,7 @@ Atlas must:
|
|
|
59
59
|
* Implement feature code directly when Astra should execute.
|
|
60
60
|
* Validate its own implementation as final evidence.
|
|
61
61
|
* `npm publish`
|
|
62
|
-
* `git push`
|
|
62
|
+
* `git push` to protected branches (main, master), or to remote without explicit user approval in the chat.
|
|
63
63
|
* `git tag`
|
|
64
64
|
* `gh release create`
|
|
65
65
|
* `gh repo create`
|
|
@@ -47,7 +47,7 @@ Nexus must inspect project structure, identify stack, entry points, scripts, con
|
|
|
47
47
|
* Modifying files during discovery.
|
|
48
48
|
* Writing codebase changes or creating code files.
|
|
49
49
|
* Executing npm publish without explicit user approval.
|
|
50
|
-
* Executing git push or creating git tag commands.
|
|
50
|
+
* Executing git push or creating git tag commands without explicit user approval in the chat, or pushing directly to protected branches (main, master).
|
|
51
51
|
* Creating GitHub releases (gh release).
|
|
52
52
|
* Bypassing safety gates or routing rules.
|
|
53
53
|
* Inventing project details without evidence.
|
|
@@ -50,7 +50,7 @@ Phoenix acts only on concrete findings, identifies root cause, applies the small
|
|
|
50
50
|
* Fixing issues without a concrete finding.
|
|
51
51
|
* Rewriting unrelated code blocks.
|
|
52
52
|
* Executing npm publish without explicit user approval.
|
|
53
|
-
* Executing git push or creating git tag commands.
|
|
53
|
+
* Executing git push or creating git tag commands without explicit user approval in the chat, or pushing directly to protected branches (main, master).
|
|
54
54
|
* Creating GitHub releases (gh release).
|
|
55
55
|
* Bypassing safety gates, branch gates, or validation gates.
|
|
56
56
|
|
|
@@ -48,7 +48,7 @@ Sage validates implementation evidence independently, classifies risk, runs or i
|
|
|
48
48
|
* Writing new features.
|
|
49
49
|
* Accepting claims without command output or logs.
|
|
50
50
|
* Executing npm publish without explicit user approval.
|
|
51
|
-
* Executing git push or creating git tag commands.
|
|
51
|
+
* Executing git push or creating git tag commands without explicit user approval in the chat, or pushing directly to protected branches (main, master).
|
|
52
52
|
* Creating GitHub releases (gh release).
|
|
53
53
|
* Bypassing quality gates, branch gates, or validation gates.
|
|
54
54
|
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -4,6 +4,7 @@ import { runDoctor } from "./commands/doctor.js";
|
|
|
4
4
|
import { runCollectEvidence } from "./commands/collect-evidence.js";
|
|
5
5
|
import { runMasterOrchestrator } from "./commands/run.js";
|
|
6
6
|
import { runExecute } from "./commands/execute.js";
|
|
7
|
+
import { runClean } from "./commands/clean.js";
|
|
7
8
|
|
|
8
9
|
function printHelp() {
|
|
9
10
|
console.log(`ai-workflow
|
|
@@ -15,6 +16,7 @@ Usage:
|
|
|
15
16
|
ai-workflow validate [--a11y] [--visual-dist=<path>] [--port=<port>]
|
|
16
17
|
ai-workflow collect-evidence [--task=<slug>] [--mode=<quick|standard|full>] [--dry-run] [--visual-dist=<path>] [--port=<port>]
|
|
17
18
|
ai-workflow doctor
|
|
19
|
+
ai-workflow clean [--yes] [--dry-run] [--purge-agents]
|
|
18
20
|
|
|
19
21
|
Commands:
|
|
20
22
|
execute Orchestrate execution of a natural request through the state machine
|
|
@@ -22,6 +24,7 @@ Commands:
|
|
|
22
24
|
init Install AI workflow defaults (OpenCode). --profile=standard (default) or --profile=full (adds examples)
|
|
23
25
|
collect-evidence Run observed project validation; persists EVIDENCE.json only for full mode
|
|
24
26
|
doctor Verify local ai-workflow installation
|
|
27
|
+
clean De-initialize and remove AI Workflow files and symlinks from the project
|
|
25
28
|
`);
|
|
26
29
|
}
|
|
27
30
|
|
|
@@ -58,7 +61,8 @@ function parseFlags(args) {
|
|
|
58
61
|
request: requestArg ? requestArg.replace("--request=", "") : undefined,
|
|
59
62
|
visualDist: visualDistArg ? visualDistArg.replace("--visual-dist=", "") : undefined,
|
|
60
63
|
port: portArg ? portArg.replace("--port=", "") : undefined,
|
|
61
|
-
a11y: args.includes("--a11y")
|
|
64
|
+
a11y: args.includes("--a11y"),
|
|
65
|
+
purgeAgents: args.includes("--purge-agents") || args.includes("--purge")
|
|
62
66
|
};
|
|
63
67
|
}
|
|
64
68
|
|
|
@@ -139,5 +143,13 @@ export async function runCli(args) {
|
|
|
139
143
|
return;
|
|
140
144
|
}
|
|
141
145
|
|
|
146
|
+
if (command === "clean") {
|
|
147
|
+
await runClean({
|
|
148
|
+
cwd: process.cwd(),
|
|
149
|
+
...parseFlags(args.slice(1))
|
|
150
|
+
});
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
142
154
|
throw new Error(`unknown command: ${command}`);
|
|
143
155
|
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { existsSync, rmSync, lstatSync, unlinkSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import readline from "node:readline";
|
|
4
|
+
|
|
5
|
+
function askConfirmation(question) {
|
|
6
|
+
const rl = readline.createInterface({
|
|
7
|
+
input: process.stdin,
|
|
8
|
+
output: process.stdout
|
|
9
|
+
});
|
|
10
|
+
return new Promise((resolve) => {
|
|
11
|
+
rl.question(question, (answer) => {
|
|
12
|
+
rl.close();
|
|
13
|
+
resolve(answer.trim().toLowerCase());
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function isSymlink(filePath) {
|
|
19
|
+
try {
|
|
20
|
+
return lstatSync(filePath).isSymbolicLink();
|
|
21
|
+
} catch (_) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export async function runClean({ cwd, yes = false, dryRun = false, purgeAgents = false }) {
|
|
27
|
+
const targets = [
|
|
28
|
+
".ai-workflow",
|
|
29
|
+
"opencode.jsonc",
|
|
30
|
+
".workflow-state.json",
|
|
31
|
+
"opencode"
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
const hasAgents = existsSync(join(cwd, ".agents"));
|
|
35
|
+
|
|
36
|
+
// Check what actually exists
|
|
37
|
+
const existingTargets = targets
|
|
38
|
+
.map(name => join(cwd, name))
|
|
39
|
+
.filter(path => existsSync(path) || isSymlink(path));
|
|
40
|
+
|
|
41
|
+
if (existingTargets.length === 0 && (!hasAgents || !purgeAgents)) {
|
|
42
|
+
console.log("No AI Workflow configuration or files found in the current project.");
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
console.log("\n[AI WORKFLOW] De-initialization");
|
|
47
|
+
console.log("===============================");
|
|
48
|
+
|
|
49
|
+
if (dryRun) {
|
|
50
|
+
console.log("[DRY RUN] The following items would be deleted:");
|
|
51
|
+
existingTargets.forEach(path => console.log(` - ${path}`));
|
|
52
|
+
if (hasAgents && purgeAgents) {
|
|
53
|
+
console.log(` - ${join(cwd, ".agents")} (customizations folder)`);
|
|
54
|
+
} else if (hasAgents) {
|
|
55
|
+
console.log(` - NOTE: ${join(cwd, ".agents")} exists but will NOT be deleted (run with --purge-agents to delete)`);
|
|
56
|
+
}
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Interactive prompts if --yes / -y is not passed
|
|
61
|
+
if (!yes) {
|
|
62
|
+
if (!process.stdin.isTTY) {
|
|
63
|
+
console.log("Error: Non-interactive terminal detected. Run with --yes to bypass confirmation.");
|
|
64
|
+
if (process.env.NODE_ENV === "test") {
|
|
65
|
+
// Allow tests to bypass TTY block if they mock/stub process.stdin
|
|
66
|
+
} else {
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const confirmDeinit = await askConfirmation("Are you sure you want to de-initialize AI Workflow from the project? [y/N] ");
|
|
72
|
+
if (confirmDeinit !== "y" && confirmDeinit !== "yes") {
|
|
73
|
+
console.log("Aborted.");
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (hasAgents && !purgeAgents) {
|
|
78
|
+
const confirmPurge = await askConfirmation("A custom '.agents' folder was detected. Do you want to purge it (this deletes custom prompts/rules/skills)? [y/N] ");
|
|
79
|
+
if (confirmPurge === "y" || confirmPurge === "yes") {
|
|
80
|
+
purgeAgents = true;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Add .agents if requested and exists
|
|
86
|
+
if (purgeAgents && hasAgents) {
|
|
87
|
+
existingTargets.push(join(cwd, ".agents"));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
console.log("\nRemoving files...");
|
|
91
|
+
for (const target of existingTargets) {
|
|
92
|
+
try {
|
|
93
|
+
if (isSymlink(target)) {
|
|
94
|
+
unlinkSync(target);
|
|
95
|
+
console.log(`Deleted symlink: ${target}`);
|
|
96
|
+
} else {
|
|
97
|
+
rmSync(target, { recursive: true, force: true });
|
|
98
|
+
console.log(`Deleted directory/file: ${target}`);
|
|
99
|
+
}
|
|
100
|
+
} catch (error) {
|
|
101
|
+
console.error(`Failed to delete ${target}: ${error.message}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
console.log("\nAI Workflow has been successfully removed from this project.");
|
|
106
|
+
}
|
|
@@ -392,19 +392,19 @@ export class ArtifactFidelityGate {
|
|
|
392
392
|
}
|
|
393
393
|
}
|
|
394
394
|
|
|
395
|
-
// 1.
|
|
395
|
+
// 1. Minimum CSS tokens check
|
|
396
396
|
const hasRules = cssContentCombined.includes("{");
|
|
397
|
-
const hasCssVars =
|
|
397
|
+
const hasCssVars = /(--[a-zA-Z0-9_-]+\s*:|var\(--[a-zA-Z0-9_-]+\))/g.test(cssContentCombined);
|
|
398
398
|
if (hasRules && !hasCssVars) {
|
|
399
|
-
violations.push("Fidelity Violation: Design System token mismatch. No CSS custom properties (variables) detected in changed UI stylesheets.");
|
|
399
|
+
violations.push("Fidelity Violation: Design System token mismatch. No CSS custom properties (variables) detected or used in changed UI stylesheets.");
|
|
400
400
|
}
|
|
401
401
|
|
|
402
|
-
// 2.
|
|
402
|
+
// 2. Excessive style="..." inline styles check
|
|
403
403
|
if (styleAttrsCount > 5) {
|
|
404
404
|
violations.push(`Fidelity Violation: excessive inline styles detected (${styleAttrsCount} style="..." declarations). Use CSS classes or utility classes instead.`);
|
|
405
405
|
}
|
|
406
406
|
|
|
407
|
-
// 3. HTML
|
|
407
|
+
// 3. Main HTML semantic tags check
|
|
408
408
|
if (htmlContentCombined.length > 0) {
|
|
409
409
|
const hasSemanticTags = /<(header|main|footer|nav|section)\b/i.test(htmlContentCombined);
|
|
410
410
|
const hasH1 = /<h1\b/i.test(htmlContentCombined);
|