@plainconceptsplatform/workflows 0.4.34 → 0.6.1
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 +88 -88
- package/dist/action-validation.test.js +5 -2
- package/dist/catalog-installation.js +50 -7
- package/dist/catalog-installation.test.js +59 -22
- package/dist/catalog-listing.test.js +4 -4
- package/dist/index.js +48 -48
- package/dist/index.test.js +9 -9
- package/dist/repository-inspection.test.js +2 -2
- package/dist/route-processing.js +24 -25
- package/dist/route-processing.test.js +166 -233
- package/dist/stack-defaults.js +14 -14
- package/dist/stack-defaults.test.js +79 -79
- package/dist/tui.test.js +10 -7
- package/dist/workflow-catalog.d.ts +1 -1
- package/dist/workflow-catalog.js +1 -5
- package/loops/actions/add-issue-labels/action.yml +2 -2
- package/loops/actions/agent-output.cjs +17 -17
- package/loops/actions/apply-agent-bundle/apply-bundle.sh +14 -1
- package/loops/actions/audit-close/action.yml +24 -0
- package/loops/actions/classify-route/action.yml +8 -3
- package/loops/actions/classify-route/classify-route.sh +58 -38
- package/loops/actions/cleanup-artifacts/action.yml +38 -12
- package/loops/actions/identify-gate-subject/action.yml +3 -1
- package/loops/actions/remove-issue-labels/action.yml +4 -2
- package/loops/actions/update-changelog/action.yml +113 -0
- package/loops/actions/validate-merge-gate-output/action.yml +40 -40
- package/loops/actions/validate-refine-output/validate-refine-output.sh +34 -5
- package/loops/actions/validate-review-output/action.yml +35 -35
- package/loops/actions/validate-triage-output/action.yml +36 -36
- package/loops/actions/verify-refine-output/verify-refine-output.sh +20 -0
- package/loops/actions/verify-route-matrix/verify-route-matrix.sh +375 -36
- package/loops/scripts/compile-agent-workflows.mjs +290 -6
- package/loops/scripts/merge-changelog.mjs +76 -0
- package/loops/templates/agentics/actionlint.yaml +13 -0
- package/loops/templates/agentics/agentics-checks.yml +125 -8
- package/loops/templates/agentics/agentics-maintenance.yml +121 -121
- package/loops/templates/ci/app-ci-dotnet-next.yml +330 -171
- package/loops/templates/ci/app-ci-node-monorepo.yml +260 -178
- package/loops/templates/issues/bug_report.yml +109 -109
- package/loops/templates/issues/feature_request.yml +75 -75
- package/loops/templates/opencode/opencode.ci.json +49 -47
- package/loops/templates/opencode/opencode.ci.json.md +49 -41
- package/loops/templates/release/github-release.yml +30 -30
- package/loops/workflows/agent-apply-review.md +469 -443
- package/loops/workflows/agent-audit.md +213 -197
- package/loops/workflows/agent-implement.md +640 -414
- package/loops/workflows/agent-merge-gate.md +844 -584
- package/loops/workflows/agent-refine.md +633 -418
- package/loops/workflows/agent-release.md +258 -0
- package/loops/workflows/agent-triage.md +447 -439
- package/loops/workflows/authorize-bot-work.yml +85 -82
- package/loops/workflows/shared/opencode-ci.md +206 -197
- package/loops/workflows/shared/platform-defaults.md +19 -16
- package/loops/workflows/work-router.yml +1038 -632
- package/package.json +7 -8
- package/dist/repository-state.d.ts +0 -18
- package/dist/repository-state.js +0 -77
- package/dist/repository-state.test.d.ts +0 -1
- package/dist/repository-state.test.js +0 -96
- package/loops/workflows/agent-direct.md +0 -375
- package/loops/workflows/agent-propose.md +0 -342
package/dist/index.js
CHANGED
|
@@ -6,54 +6,54 @@ import { routeNames, templateNames } from "./workflow-catalog.js";
|
|
|
6
6
|
import { runInteractive } from "./tui.js";
|
|
7
7
|
import { resolve } from "node:path";
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
|
-
const HELP_TEXT = `Workflows CLI — install and manage Plain Concepts Platform agentic workflows.
|
|
10
|
-
|
|
11
|
-
Run with no arguments to launch the interactive TUI, the primary way to select and install
|
|
12
|
-
workflows and templates:
|
|
13
|
-
|
|
14
|
-
npx @plainconceptsplatform/workflows
|
|
15
|
-
|
|
16
|
-
Advanced (non-interactive) commands:
|
|
17
|
-
|
|
18
|
-
Usage: workflows <command> [options]
|
|
19
|
-
|
|
20
|
-
Commands:
|
|
21
|
-
(default) Launch the interactive TUI for selecting and installing items.
|
|
22
|
-
init Inspect the repository and report its stack and visibility.
|
|
23
|
-
add [routes] [--template <name>] [--force] Install route workers, a template, or mandatory files.
|
|
24
|
-
remove <routes> [--force] Uninstall route workers and regenerate the router without them.
|
|
25
|
-
update Alias for add.
|
|
26
|
-
status Print repository inspection as JSON.
|
|
27
|
-
list List all available workflows and templates with install status.
|
|
28
|
-
search <query> Filter workflows and templates by name or description.
|
|
29
|
-
|
|
30
|
-
Route names (positional arguments to add):
|
|
31
|
-
refine, implement,
|
|
32
|
-
|
|
33
|
-
add Mandatory files only (opencode.ci.json, compile script,
|
|
34
|
-
shared imports, actions, router, classifier, route matrix).
|
|
35
|
-
add implement refine direct Installs those route workers plus mandatory files.
|
|
36
|
-
add --template agentics-checks Installs the named template only (no mandatory files).
|
|
37
|
-
add refine --template agentics-checks Installs routes + mandatory + the named template.
|
|
38
|
-
add refine implement --force Forces re-install of routes plus mandatory, overwriting.
|
|
39
|
-
remove propose Uninstalls the propose worker and drops it from the router.
|
|
40
|
-
|
|
41
|
-
add and remove keep the router consistent with what is installed: add unions the requested
|
|
42
|
-
routes with the routes already present, and remove drops the requested routes from that set.
|
|
43
|
-
Both regenerate the router, classifier, and route matrix from the resulting set. Changing the
|
|
44
|
-
route set rewrites the package-owned router, so pass --force to overwrite it.
|
|
45
|
-
|
|
46
|
-
Options:
|
|
47
|
-
--visibility public|private Override repository visibility (init only).
|
|
48
|
-
--template <name> Install a standalone template alongside or instead of routes.
|
|
49
|
-
Templates: agentics-checks, agentics-maintenance,
|
|
50
|
-
app-ci-dotnet-next, app-ci-node-monorepo,
|
|
51
|
-
bug-report, feature-request, github-release,
|
|
52
|
-
opencode.ci.json.
|
|
53
|
-
--force Overwrite managed files that differ from the package source.
|
|
54
|
-
-h, --help Show this help text.
|
|
55
|
-
|
|
56
|
-
Installed workflows are marked [x] when the corresponding .github/workflows/agent-*.md
|
|
9
|
+
const HELP_TEXT = `Workflows CLI — install and manage Plain Concepts Platform agentic workflows.
|
|
10
|
+
|
|
11
|
+
Run with no arguments to launch the interactive TUI, the primary way to select and install
|
|
12
|
+
workflows and templates:
|
|
13
|
+
|
|
14
|
+
npx @plainconceptsplatform/workflows
|
|
15
|
+
|
|
16
|
+
Advanced (non-interactive) commands:
|
|
17
|
+
|
|
18
|
+
Usage: workflows <command> [options]
|
|
19
|
+
|
|
20
|
+
Commands:
|
|
21
|
+
(default) Launch the interactive TUI for selecting and installing items.
|
|
22
|
+
init Inspect the repository and report its stack and visibility.
|
|
23
|
+
add [routes] [--template <name>] [--force] Install route workers, a template, or mandatory files.
|
|
24
|
+
remove <routes> [--force] Uninstall route workers and regenerate the router without them.
|
|
25
|
+
update Alias for add.
|
|
26
|
+
status Print repository inspection as JSON.
|
|
27
|
+
list List all available workflows and templates with install status.
|
|
28
|
+
search <query> Filter workflows and templates by name or description.
|
|
29
|
+
|
|
30
|
+
Route names (positional arguments to add):
|
|
31
|
+
refine, implement, triage, apply-review, merge-gate, audit
|
|
32
|
+
|
|
33
|
+
add Mandatory files only (opencode.ci.json, compile script,
|
|
34
|
+
shared imports, actions, router, classifier, route matrix).
|
|
35
|
+
add implement refine direct Installs those route workers plus mandatory files.
|
|
36
|
+
add --template agentics-checks Installs the named template only (no mandatory files).
|
|
37
|
+
add refine --template agentics-checks Installs routes + mandatory + the named template.
|
|
38
|
+
add refine implement --force Forces re-install of routes plus mandatory, overwriting.
|
|
39
|
+
remove propose Uninstalls the propose worker and drops it from the router.
|
|
40
|
+
|
|
41
|
+
add and remove keep the router consistent with what is installed: add unions the requested
|
|
42
|
+
routes with the routes already present, and remove drops the requested routes from that set.
|
|
43
|
+
Both regenerate the router, classifier, and route matrix from the resulting set. Changing the
|
|
44
|
+
route set rewrites the package-owned router, so pass --force to overwrite it.
|
|
45
|
+
|
|
46
|
+
Options:
|
|
47
|
+
--visibility public|private Override repository visibility (init only).
|
|
48
|
+
--template <name> Install a standalone template alongside or instead of routes.
|
|
49
|
+
Templates: agentics-checks, agentics-maintenance,
|
|
50
|
+
app-ci-dotnet-next, app-ci-node-monorepo,
|
|
51
|
+
bug-report, feature-request, github-release,
|
|
52
|
+
opencode.ci.json.
|
|
53
|
+
--force Overwrite managed files that differ from the package source.
|
|
54
|
+
-h, --help Show this help text.
|
|
55
|
+
|
|
56
|
+
Installed workflows are marked [x] when the corresponding .github/workflows/agent-*.md
|
|
57
57
|
file exists relative to the current directory.`;
|
|
58
58
|
export async function run(arguments_, repositoryPath = process.cwd()) {
|
|
59
59
|
const [command, ...options] = arguments_;
|
package/dist/index.test.js
CHANGED
|
@@ -27,7 +27,7 @@ describe("workflows CLI", () => {
|
|
|
27
27
|
const log = vi.spyOn(console, "log").mockImplementation(() => undefined);
|
|
28
28
|
await expect(run(["--help"])).resolves.toBe(0);
|
|
29
29
|
const output = log.mock.calls[0][0];
|
|
30
|
-
expect(output).toContain("refine, implement,
|
|
30
|
+
expect(output).toContain("refine, implement, triage, apply-review, merge-gate, audit");
|
|
31
31
|
expect(output).toContain("add [routes]");
|
|
32
32
|
log.mockRestore();
|
|
33
33
|
});
|
|
@@ -40,7 +40,7 @@ describe("workflows CLI", () => {
|
|
|
40
40
|
it("rejects an unknown route passed to add", async () => {
|
|
41
41
|
const error = vi.spyOn(console, "error").mockImplementation(() => undefined);
|
|
42
42
|
await expect(run(["add", "frobnicate"])).resolves.toBe(1);
|
|
43
|
-
expect(error).toHaveBeenCalledWith("Unknown route: frobnicate. Valid routes: refine, implement,
|
|
43
|
+
expect(error).toHaveBeenCalledWith("Unknown route: frobnicate. Valid routes: refine, implement, triage, apply-review, merge-gate, audit.");
|
|
44
44
|
error.mockRestore();
|
|
45
45
|
});
|
|
46
46
|
it("rejects a duplicate route", async () => {
|
|
@@ -65,9 +65,9 @@ describe("workflows CLI", () => {
|
|
|
65
65
|
// None installed: all [ ]
|
|
66
66
|
const installedCount = (output.match(/\[x\]/g) ?? []).length;
|
|
67
67
|
expect(installedCount).toBe(0);
|
|
68
|
-
//
|
|
68
|
+
// 6 routes + 9 templates = 15 entries
|
|
69
69
|
const uninstalledCount = (output.match(/\[ \]/g) ?? []).length;
|
|
70
|
-
expect(uninstalledCount).toBe(
|
|
70
|
+
expect(uninstalledCount).toBe(15);
|
|
71
71
|
log.mockRestore();
|
|
72
72
|
});
|
|
73
73
|
it("marks installed workflows with [x]", async () => {
|
|
@@ -92,7 +92,7 @@ describe("workflows CLI", () => {
|
|
|
92
92
|
expect(output).toContain("audit");
|
|
93
93
|
expect(output).not.toContain("Templates:");
|
|
94
94
|
// Only the audit route should be returned — no other route name should appear.
|
|
95
|
-
const visibleRoutes = ["refine", "implement", "
|
|
95
|
+
const visibleRoutes = ["refine", "implement", "triage", "apply-review", "merge-gate"];
|
|
96
96
|
for (const route of visibleRoutes) {
|
|
97
97
|
expect(output).not.toContain(`${route} —`);
|
|
98
98
|
}
|
|
@@ -138,9 +138,9 @@ describe("workflows CLI", () => {
|
|
|
138
138
|
it("add with explicit routes passes those routes to installCatalog", async () => {
|
|
139
139
|
const { installCatalog, installTemplate } = mockInstallers();
|
|
140
140
|
const log = vi.spyOn(console, "log").mockImplementation(() => undefined);
|
|
141
|
-
await expect(run(["add", "implement", "refine", "
|
|
141
|
+
await expect(run(["add", "implement", "refine", "audit"])).resolves.toBe(0);
|
|
142
142
|
expect(installCatalog).toHaveBeenCalledOnce();
|
|
143
|
-
expect(installCatalog).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({ selectedRoutes: ["implement", "refine", "
|
|
143
|
+
expect(installCatalog).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({ selectedRoutes: ["implement", "refine", "audit"] }));
|
|
144
144
|
expect(installTemplate).not.toHaveBeenCalled();
|
|
145
145
|
log.mockRestore();
|
|
146
146
|
});
|
|
@@ -226,8 +226,8 @@ describe("workflows CLI", () => {
|
|
|
226
226
|
".github/workflows/agent-implement.md": "# Implement",
|
|
227
227
|
});
|
|
228
228
|
const log = vi.spyOn(console, "log").mockImplementation(() => undefined);
|
|
229
|
-
await expect(run(["add", "
|
|
230
|
-
expect(installCatalog).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({ selectedRoutes: ["
|
|
229
|
+
await expect(run(["add", "audit"], repositoryPath)).resolves.toBe(0);
|
|
230
|
+
expect(installCatalog).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({ selectedRoutes: ["audit", "refine", "implement"] }));
|
|
231
231
|
log.mockRestore();
|
|
232
232
|
});
|
|
233
233
|
it("remove requires at least one route", async () => {
|
|
@@ -16,7 +16,7 @@ describe("repository inspection", () => {
|
|
|
16
16
|
".github/workflows/other.md": "# Other",
|
|
17
17
|
"package.json": "{}",
|
|
18
18
|
"pnpm-lock.yaml": "lockfileVersion: '9.0'",
|
|
19
|
-
"apps/api/
|
|
19
|
+
"apps/api/Contoso.slnx": "<Solution />",
|
|
20
20
|
"openspec/changes/.gitkeep": "",
|
|
21
21
|
});
|
|
22
22
|
await expect(inspectRepository(repositoryPath)).resolves.toMatchObject({
|
|
@@ -24,7 +24,7 @@ describe("repository inspection", () => {
|
|
|
24
24
|
stackHints: {
|
|
25
25
|
packageJson: true,
|
|
26
26
|
pnpmLockfile: true,
|
|
27
|
-
solutionFiles: [join("apps", "api", "
|
|
27
|
+
solutionFiles: [join("apps", "api", "Contoso.slnx")],
|
|
28
28
|
openSpec: true,
|
|
29
29
|
},
|
|
30
30
|
});
|
package/dist/route-processing.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { routeNames, workflowRoutes } from "./workflow-catalog.js";
|
|
2
2
|
const routeCrons = {
|
|
3
3
|
audit: "17 1 * * 1",
|
|
4
|
-
propose: "29 7 * * *",
|
|
5
4
|
};
|
|
6
5
|
export function stripRouteFromRouter(yaml, route) {
|
|
7
6
|
let result = yaml;
|
|
@@ -86,30 +85,30 @@ export function processRoutes(files, selectedRoutes) {
|
|
|
86
85
|
function createRouteMatrix(selectedRoutes) {
|
|
87
86
|
const selected = selectedRoutes.join(" ");
|
|
88
87
|
const excluded = routeNames.filter((route) => !selectedRoutes.includes(route)).join(" ");
|
|
89
|
-
return `#!/usr/bin/env bash
|
|
90
|
-
set -euo pipefail
|
|
91
|
-
|
|
92
|
-
HERE="$(cd "$(dirname "\${BASH_SOURCE[0]}")" && pwd)"
|
|
93
|
-
ROUTER_YML="\${HERE}/../../workflows/work-router.yml"
|
|
94
|
-
CLASSIFIER="\${HERE}/../classify-route/classify-route.sh"
|
|
95
|
-
|
|
96
|
-
bash -n "$CLASSIFIER"
|
|
97
|
-
|
|
98
|
-
for route in ${selected}; do
|
|
99
|
-
grep -q "route == '$route'" "$ROUTER_YML" || {
|
|
100
|
-
echo "FAIL: selected route '$route' has no router job" >&2
|
|
101
|
-
exit 1
|
|
102
|
-
}
|
|
103
|
-
done
|
|
104
|
-
|
|
105
|
-
for route in ${excluded}; do
|
|
106
|
-
if grep -q "route == '$route'" "$ROUTER_YML"; then
|
|
107
|
-
echo "FAIL: excluded route '$route' remains in router" >&2
|
|
108
|
-
exit 1
|
|
109
|
-
fi
|
|
110
|
-
done
|
|
111
|
-
|
|
112
|
-
echo "Route matrix: selected routes valid"
|
|
88
|
+
return `#!/usr/bin/env bash
|
|
89
|
+
set -euo pipefail
|
|
90
|
+
|
|
91
|
+
HERE="$(cd "$(dirname "\${BASH_SOURCE[0]}")" && pwd)"
|
|
92
|
+
ROUTER_YML="\${HERE}/../../workflows/work-router.yml"
|
|
93
|
+
CLASSIFIER="\${HERE}/../classify-route/classify-route.sh"
|
|
94
|
+
|
|
95
|
+
bash -n "$CLASSIFIER"
|
|
96
|
+
|
|
97
|
+
for route in ${selected}; do
|
|
98
|
+
grep -q "route == '$route'" "$ROUTER_YML" || {
|
|
99
|
+
echo "FAIL: selected route '$route' has no router job" >&2
|
|
100
|
+
exit 1
|
|
101
|
+
}
|
|
102
|
+
done
|
|
103
|
+
|
|
104
|
+
for route in ${excluded}; do
|
|
105
|
+
if grep -q "route == '$route'" "$ROUTER_YML"; then
|
|
106
|
+
echo "FAIL: excluded route '$route' remains in router" >&2
|
|
107
|
+
exit 1
|
|
108
|
+
fi
|
|
109
|
+
done
|
|
110
|
+
|
|
111
|
+
echo "Route matrix: selected routes valid"
|
|
113
112
|
`;
|
|
114
113
|
}
|
|
115
114
|
export function excludedWorkerFiles(selectedRoutes) {
|