@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.
Files changed (61) hide show
  1. package/README.md +88 -88
  2. package/dist/action-validation.test.js +5 -2
  3. package/dist/catalog-installation.js +50 -7
  4. package/dist/catalog-installation.test.js +59 -22
  5. package/dist/catalog-listing.test.js +4 -4
  6. package/dist/index.js +48 -48
  7. package/dist/index.test.js +9 -9
  8. package/dist/repository-inspection.test.js +2 -2
  9. package/dist/route-processing.js +24 -25
  10. package/dist/route-processing.test.js +166 -233
  11. package/dist/stack-defaults.js +14 -14
  12. package/dist/stack-defaults.test.js +79 -79
  13. package/dist/tui.test.js +10 -7
  14. package/dist/workflow-catalog.d.ts +1 -1
  15. package/dist/workflow-catalog.js +1 -5
  16. package/loops/actions/add-issue-labels/action.yml +2 -2
  17. package/loops/actions/agent-output.cjs +17 -17
  18. package/loops/actions/apply-agent-bundle/apply-bundle.sh +14 -1
  19. package/loops/actions/audit-close/action.yml +24 -0
  20. package/loops/actions/classify-route/action.yml +8 -3
  21. package/loops/actions/classify-route/classify-route.sh +58 -38
  22. package/loops/actions/cleanup-artifacts/action.yml +38 -12
  23. package/loops/actions/identify-gate-subject/action.yml +3 -1
  24. package/loops/actions/remove-issue-labels/action.yml +4 -2
  25. package/loops/actions/update-changelog/action.yml +113 -0
  26. package/loops/actions/validate-merge-gate-output/action.yml +40 -40
  27. package/loops/actions/validate-refine-output/validate-refine-output.sh +34 -5
  28. package/loops/actions/validate-review-output/action.yml +35 -35
  29. package/loops/actions/validate-triage-output/action.yml +36 -36
  30. package/loops/actions/verify-refine-output/verify-refine-output.sh +20 -0
  31. package/loops/actions/verify-route-matrix/verify-route-matrix.sh +375 -36
  32. package/loops/scripts/compile-agent-workflows.mjs +290 -6
  33. package/loops/scripts/merge-changelog.mjs +76 -0
  34. package/loops/templates/agentics/actionlint.yaml +13 -0
  35. package/loops/templates/agentics/agentics-checks.yml +125 -8
  36. package/loops/templates/agentics/agentics-maintenance.yml +121 -121
  37. package/loops/templates/ci/app-ci-dotnet-next.yml +330 -171
  38. package/loops/templates/ci/app-ci-node-monorepo.yml +260 -178
  39. package/loops/templates/issues/bug_report.yml +109 -109
  40. package/loops/templates/issues/feature_request.yml +75 -75
  41. package/loops/templates/opencode/opencode.ci.json +49 -47
  42. package/loops/templates/opencode/opencode.ci.json.md +49 -41
  43. package/loops/templates/release/github-release.yml +30 -30
  44. package/loops/workflows/agent-apply-review.md +469 -443
  45. package/loops/workflows/agent-audit.md +213 -197
  46. package/loops/workflows/agent-implement.md +640 -414
  47. package/loops/workflows/agent-merge-gate.md +844 -584
  48. package/loops/workflows/agent-refine.md +633 -418
  49. package/loops/workflows/agent-release.md +258 -0
  50. package/loops/workflows/agent-triage.md +447 -439
  51. package/loops/workflows/authorize-bot-work.yml +85 -82
  52. package/loops/workflows/shared/opencode-ci.md +206 -197
  53. package/loops/workflows/shared/platform-defaults.md +19 -16
  54. package/loops/workflows/work-router.yml +1038 -632
  55. package/package.json +7 -8
  56. package/dist/repository-state.d.ts +0 -18
  57. package/dist/repository-state.js +0 -77
  58. package/dist/repository-state.test.d.ts +0 -1
  59. package/dist/repository-state.test.js +0 -96
  60. package/loops/workflows/agent-direct.md +0 -375
  61. 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, direct, triage, apply-review, merge-gate, audit, propose
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_;
@@ -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, direct, triage, apply-review, merge-gate, audit, propose");
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, direct, triage, apply-review, merge-gate, audit, propose.");
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
- // 8 routes + 9 templates = 17 entries
68
+ // 6 routes + 9 templates = 15 entries
69
69
  const uninstalledCount = (output.match(/\[ \]/g) ?? []).length;
70
- expect(uninstalledCount).toBe(17);
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", "direct", "triage", "apply-review", "merge-gate", "propose"];
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", "direct"])).resolves.toBe(0);
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", "direct"] }));
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", "direct"], repositoryPath)).resolves.toBe(0);
230
- expect(installCatalog).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({ selectedRoutes: ["direct", "refine", "implement"] }));
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/Numa.slnx": "<Solution />",
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", "Numa.slnx")],
27
+ solutionFiles: [join("apps", "api", "Contoso.slnx")],
28
28
  openSpec: true,
29
29
  },
30
30
  });
@@ -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) {