@plainconceptsplatform/workflows 0.4.4 → 0.4.6

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.
@@ -43,6 +43,7 @@ export async function installCatalog(repositoryPath, options = {}) {
43
43
  processedContents = injectStackIntoWorkers(processedContents, defaults);
44
44
  processedContents = transformOpencodeFiles(processedContents, options.inspection);
45
45
  }
46
+ processedContents = await preserveConsumerWorkerEnv(repositoryPath, processedContents);
46
47
  const updates = [...processedContents.entries()]
47
48
  .filter(([target]) => filtered.find((file) => file.target === target)?.managed ?? true)
48
49
  .map(([target, content]) => ({ target, content }));
@@ -62,6 +63,43 @@ function injectStackIntoWorkers(files, defaults) {
62
63
  }
63
64
  return result;
64
65
  }
66
+ async function preserveConsumerWorkerEnv(repositoryPath, files) {
67
+ const result = new Map(files);
68
+ for (const [target, content] of result) {
69
+ if (!target.startsWith(".github/workflows/agent-") || !target.endsWith(".md"))
70
+ continue;
71
+ const existingPath = join(repositoryPath, target);
72
+ if (!await exists(existingPath))
73
+ continue;
74
+ result.set(target, mergeWorkerEnv(content, await readFile(existingPath, "utf8")));
75
+ }
76
+ return result;
77
+ }
78
+ function mergeWorkerEnv(packageContent, consumerContent) {
79
+ const consumerEnv = workerEnvValues(consumerContent);
80
+ let result = packageContent.replace(/^ ([A-Z][A-Z0-9_]*): .+$/gm, (line, key) => consumerEnv.has(key) ? ` ${key}: ${consumerEnv.get(key)}` : line);
81
+ const endpoint = engineEndpoint(consumerContent);
82
+ if (endpoint !== undefined) {
83
+ result = result.replace(/^ OPENAI_BASE_URL: .+$/m, ` OPENAI_BASE_URL: ${endpoint}`);
84
+ }
85
+ return result;
86
+ }
87
+ function workerEnvValues(content) {
88
+ const frontmatter = /^---\r?\n([\s\S]*?)\r?\n---/m.exec(content)?.[1];
89
+ const envBlock = frontmatter === undefined ? undefined : /^env:\r?\n((?: .*\r?\n?)*)/m.exec(frontmatter)?.[1];
90
+ const values = new Map();
91
+ if (envBlock === undefined)
92
+ return values;
93
+ for (const line of envBlock.split(/\r?\n/)) {
94
+ const match = /^ ([A-Z][A-Z0-9_]*): (.+)$/.exec(line);
95
+ if (match !== null)
96
+ values.set(match[1], match[2]);
97
+ }
98
+ return values;
99
+ }
100
+ function engineEndpoint(content) {
101
+ return /^ OPENAI_BASE_URL: (.+)$/m.exec(content)?.[1];
102
+ }
65
103
  function transformOpencodeFiles(files, inspection) {
66
104
  const result = new Map(files);
67
105
  for (const [key, content] of result) {
@@ -286,6 +286,19 @@ describe("catalog installation", () => {
286
286
  .resolves.toBe("consumer compiler\n");
287
287
  await expect(readFile(join(repositoryPath, ".husky", "pre-commit"), "utf8")).rejects.toThrow();
288
288
  });
289
+ it("preserves consumer-specific worker environment values during a forced update", async () => {
290
+ const sourcePath = await createDirectory({
291
+ "actions/check/action.yml": "name: Check\n",
292
+ "workflows/agent-check.md": "---\nenv:\n VERIFY_COMMANDS: \"package verify\"\n REPO_RULES: \"package rules\"\n---\nengine:\n env:\n OPENAI_BASE_URL: https://forge.plainconcepts.com/v1\n",
293
+ "scripts/compile-agent-workflows.mjs": "compile\n",
294
+ "templates/opencode/opencode.ci.json": "{}\n",
295
+ });
296
+ const repositoryPath = await createDirectory({
297
+ ".github/workflows/agent-check.md": "---\nenv:\n VERIFY_COMMANDS: \"consumer verify\"\n REPO_RULES: \"consumer rules\"\n---\nengine:\n env:\n OPENAI_BASE_URL: https://consumer.example/v1\n",
298
+ });
299
+ await installCatalog(repositoryPath, { force: true, sourcePath });
300
+ await expect(readFile(join(repositoryPath, ".github/workflows/agent-check.md"), "utf8")).resolves.toContain(" REPO_RULES: \"consumer rules\"\n---\nengine:\n env:\n OPENAI_BASE_URL: https://consumer.example/v1\n");
301
+ });
289
302
  it("applies staged generated locks with managed sources", async () => {
290
303
  const sourcePath = await createDirectory({
291
304
  "actions/check/action.yml": "package action\n",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plainconceptsplatform/workflows",
3
- "version": "0.4.4",
3
+ "version": "0.4.6",
4
4
  "description": "Install and update Platform GitHub agentic workflows.",
5
5
  "keywords": [
6
6
  "github-actions",