@plainconceptsplatform/workflows 0.28.25 → 1.0.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.
@@ -31,31 +31,31 @@ export function generateOpencodeCi(baseContent, inspection) {
31
31
  if (inspection.stackHints.solutionFiles.length > 0) {
32
32
  const solutionPath = inspection.stackHints.solutionFiles[0].replaceAll("\\", "/");
33
33
  if (!result.includes("name: Cache NuGet packages")) {
34
- const nugetCache = ` - name: Cache NuGet packages
35
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
36
- with:
37
- path: ~/.nuget/packages
38
- key: nuget-\${{ runner.os }}-\${{ hashFiles('**/*.slnx', '**/Directory.Packages.props') }}
39
- restore-keys: nuget-\${{ runner.os }}-
40
-
34
+ const nugetCache = ` - name: Cache NuGet packages
35
+ uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
36
+ with:
37
+ path: ~/.nuget/packages
38
+ key: nuget-\${{ runner.os }}-\${{ hashFiles('**/*.slnx', '**/Directory.Packages.props') }}
39
+ restore-keys: nuget-\${{ runner.os }}-
40
+
41
41
  `;
42
42
  result = insertBeforeMarker(result, nugetCache, " - name: Install workspace dependencies");
43
43
  }
44
44
  if (!result.includes("name: Restore .NET dependencies")) {
45
- const restore = ` - name: Restore .NET dependencies
46
- run: dotnet restore ${solutionPath}
47
-
45
+ const restore = ` - name: Restore .NET dependencies
46
+ run: dotnet restore ${solutionPath}
47
+
48
48
  `;
49
49
  result = insertBeforeMarker(result, restore, " - name: Install workspace dependencies");
50
50
  }
51
51
  }
52
52
  if (inspection.stackHints.openSpec && !result.includes("name: Install OpenSpec CLI")) {
53
- const openspecStep = ` - name: Install OpenSpec CLI
54
- run: |
55
- set -euo pipefail
56
- npm install -g "@fission-ai/openspec@1.8.0"
57
- openspec --version
58
-
53
+ const openspecStep = ` - name: Install OpenSpec CLI
54
+ run: |
55
+ set -euo pipefail
56
+ npm install -g "@fission-ai/openspec@1.8.0"
57
+ openspec --version
58
+
59
59
  `;
60
60
  result = insertBeforeMarker(result, openspecStep, " - name: Install workspace dependencies");
61
61
  }
@@ -74,32 +74,24 @@ export function generateOpencodeConfig(baseContent, inspection) {
74
74
  try {
75
75
  const config = JSON.parse(baseContent);
76
76
  const hasDotnet = inspection.stackHints.solutionFiles.length > 0;
77
- if (!hasDotnet && config.lsp !== undefined) {
78
- delete config.lsp;
79
- }
80
- else if (hasDotnet && config.lsp === undefined) {
81
- config.lsp = {
82
- csharp: { disabled: true },
83
- fsharp: { disabled: true },
84
- razor: { disabled: true },
85
- };
86
- }
87
- const agent = config.agent;
88
- if (agent !== undefined) {
89
- const agentEntry = agent["ci-workflow-agent"];
77
+ // OpenCode 2 names the agent map `agents` and the prompt `system`. V2 does
78
+ // not run language servers, so there is no lsp block to add or remove.
79
+ const agents = config.agents;
80
+ if (agents !== undefined) {
81
+ const agentEntry = agents["ci-workflow-agent"];
90
82
  if (agentEntry !== undefined) {
91
- let prompt = agentEntry.prompt ?? "";
83
+ let system = agentEntry.system ?? "";
92
84
  if (hasDotnet) {
93
- if (!prompt.includes(".NET guardrails")) {
94
- prompt += "\n\n# .NET guardrails\nFollow Clean Architecture layering: API → Application → Domain. Infrastructure implements Application ports. Application must not reference EF Core or ASP.NET. Use Central Package Management (Directory.Packages.props). Build in Release mode for CI.";
85
+ if (!system.includes(".NET guardrails")) {
86
+ system += "\n\n# .NET guardrails\nFollow Clean Architecture layering: API → Application → Domain. Infrastructure implements Application ports. Application must not reference EF Core or ASP.NET. Use Central Package Management (Directory.Packages.props). Build in Release mode for CI.";
95
87
  }
96
88
  }
97
89
  else {
98
- if (!prompt.includes("Node/React rules")) {
99
- prompt += "\n\n# Node/React rules\nFollow Feature-Sliced Design import boundaries. Use pnpm, never npm or yarn. All user-facing text must be i18n messages. TypeScript strict mode.";
90
+ if (!system.includes("Node/React rules")) {
91
+ system += "\n\n# Node/React rules\nFollow Feature-Sliced Design import boundaries. Use pnpm, never npm or yarn. All user-facing text must be i18n messages. TypeScript strict mode.";
100
92
  }
101
93
  }
102
- agentEntry.prompt = prompt;
94
+ agentEntry.system = system;
103
95
  }
104
96
  }
105
97
  return JSON.stringify(config, null, 2) + "\n";
@@ -2198,15 +2198,15 @@ echo "── Runner pools ──────────────────
2198
2198
  # RunnerLandingZone while merge-gate and release stayed on agents-arc: the override reached the
2199
2199
  # workers installed at the time and never the ones added later. Nothing reported the split.
2200
2200
  #
2201
- # agent jobs of every worker except release -> agents-arc (the Azure fleet in
2202
- # agentrunner-pro-rg-01,
2203
- # runner group `agentic`)
2204
- # gate and post-processing jobs -> RunnerLandingZone (GitHub-hosted, no fleet
2205
- # capacity consumed by
2206
- # trivial checks)
2207
- # agent-release.md and work-router.yml -> RunnerLandingZone
2208
- # ubuntu-latest -> GitHub's own runner, chosen by nobody, left
2209
- # wherever the package already has it
2201
+ # agent jobs of every worker -> agents-arc (the Azure fleet in
2202
+ # agentrunner-pro-rg-01,
2203
+ # runner group `agentic`)
2204
+ # GitHub-hosted gate jobs (where a worker keeps them) -> RunnerLandingZone
2205
+ # ubuntu-latest -> GitHub's own runner, chosen by nobody, left
2206
+ # wherever the package already has it
2207
+ #
2208
+ # Since 0.28.17 every job runs on agents-arc, release and router included; the rule below
2209
+ # still accepts RunnerLandingZone for a stray gate job but requires agents-arc to be named.
2210
2210
  AGENT_POOL="agents-arc"
2211
2211
  PLUMBING_POOL="RunnerLandingZone"
2212
2212
  POOL_OK=1
@@ -2224,43 +2224,35 @@ for worker_md in "${WORKFLOWS_DIR}"/agent-*.md; do
2224
2224
  [ -f "$worker_md" ] || continue
2225
2225
  worker_name="$(basename "$worker_md" .md)"
2226
2226
  want="$AGENT_POOL"
2227
- [ "$worker_name" = "agent-release" ] && want="$PLUMBING_POOL"
2228
2227
  got="$(pools_named "$worker_md" | tr '\n' ' ' | sed 's/ $//')"
2229
- # Gate jobs and post-processing jobs run on RunnerLandingZone (GitHub-hosted) to avoid
2230
- # consuming self-hosted fleet capacity for trivial checks. The agent job and safe_outputs
2231
- # stay on agents-arc. So a worker may name both pools.
2232
- allowed_pools="${want} ${PLUMBING_POOL}"
2233
- if [ "$worker_name" = "agent-release" ]; then
2234
- if [ "$got" != "$want" ]; then
2235
- POOL_OK=0
2236
- echo "FAIL: ${worker_name} names runner pool(s) '${got}' but must name only '${want}'" >&2
2237
- fi
2238
- else
2239
- # Every pool named must be in the allowed set; agents-arc must be present (the agent job).
2240
- ok=1
2241
- for p in $got; do
2242
- case " $allowed_pools " in *" $p "*) ;; *) ok=0 ;; esac
2243
- done
2244
- if ! echo "$got" | grep -qw "$AGENT_POOL"; then
2245
- # visual-verify gets its agent runs-on from a shared import, not from the .md file,
2246
- # so the pool check only sees the subject gate job on RunnerLandingZone.
2247
- if [ "$worker_name" = "agent-visual-verify" ] && echo "$got" | grep -qw "$PLUMBING_POOL"; then
2248
- :
2249
- else
2250
- ok=0
2251
- fi
2252
- fi
2253
- if [ "$ok" -ne 1 ]; then
2254
- POOL_OK=0
2255
- echo "FAIL: ${worker_name} names runner pool(s) '${got}' but must name only '${AGENT_POOL}' and/or '${PLUMBING_POOL}' (with at least ${AGENT_POOL})" >&2
2228
+ # The package owns which pool every job runs on, and since 0.28.17 every job in
2229
+ # every worker runs on agents-arc, release included. RunnerLandingZone is still
2230
+ # accepted for the occasional GitHub-hosted gate job, but the agent pool must be
2231
+ # present so a worker cannot drift onto a pool no runner carries.
2232
+ allowed_pools="${AGENT_POOL} ${PLUMBING_POOL}"
2233
+ ok=1
2234
+ for p in $got; do
2235
+ case " $allowed_pools " in *" $p "*) ;; *) ok=0 ;; esac
2236
+ done
2237
+ if ! echo "$got" | grep -qw "$AGENT_POOL"; then
2238
+ # visual-verify gets its agent runs-on from a shared import, not from the .md file,
2239
+ # so the pool check only sees the subject gate job on RunnerLandingZone.
2240
+ if [ "$worker_name" = "agent-visual-verify" ] && echo "$got" | grep -qw "$PLUMBING_POOL"; then
2241
+ :
2242
+ else
2243
+ ok=0
2256
2244
  fi
2257
2245
  fi
2246
+ if [ "$ok" -ne 1 ]; then
2247
+ POOL_OK=0
2248
+ echo "FAIL: ${worker_name} names runner pool(s) '${got}' but must name only '${AGENT_POOL}' and/or '${PLUMBING_POOL}' (with at least ${AGENT_POOL})" >&2
2249
+ fi
2258
2250
  done
2259
2251
 
2260
2252
  router_pools="$(pools_named "$ROUTER_YML" | tr '\n' ' ' | sed 's/ $//')"
2261
- if [ "$router_pools" != "$PLUMBING_POOL" ]; then
2253
+ if ! echo "$router_pools" | grep -qw "$AGENT_POOL"; then
2262
2254
  POOL_OK=0
2263
- echo "FAIL: the router names runner pool(s) '${router_pools}' but must name only '${PLUMBING_POOL}'" >&2
2255
+ echo "FAIL: the router names runner pool(s) '${router_pools}' but must name only '${AGENT_POOL}' and/or '${PLUMBING_POOL}' (with at least ${AGENT_POOL})" >&2
2264
2256
  fi
2265
2257
 
2266
2258
  # And the pool must not be reintroduced as a per-consumer value: that is the mechanism that let