@makerx/yoke 0.9.0 → 0.10.0

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 (3) hide show
  1. package/README.md +1 -1
  2. package/dist/cli.js +23 -21
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -23,7 +23,7 @@ yoke sync --user # ~/.claude/skills
23
23
 
24
24
  - `/pr` raises a PR with a short What/Why/(How) description.
25
25
  - `/review [number]` reviews a PR with Claude and Codex, combines their findings and offers to post them. [Configure](src/features/review/README.md#settings).
26
- - `/review-ci` adds a workflow that reviews each PR in CI and helps set its secrets. [Details](src/features/review/README.md#ci).
26
+ - `/review-ci` adds a workflow that reviews each PR in CI and helps set its variable and secret. [Details](src/features/review/README.md#ci).
27
27
 
28
28
  ## CLI
29
29
 
package/dist/cli.js CHANGED
@@ -7,7 +7,7 @@ import { Command } from "commander";
7
7
  // package.json
8
8
  var package_default = {
9
9
  name: "@makerx/yoke",
10
- version: "0.9.0",
10
+ version: "0.10.0",
11
11
  description: "Lean, user-invoked Claude Code skills for MakerX AI-assisted delivery, plus the CLI they call.",
12
12
  license: "MIT",
13
13
  author: "MakerX",
@@ -627,10 +627,10 @@ function buildOverride({ harness, model }, provider) {
627
627
  // src/features/review/ci.ts
628
628
  var reviewWorkflowRef = "MakerXStudio/yoke/.github/workflows/review.yml@main";
629
629
  var callerWorkflowPath = join3(".github", "workflows", "review-pr.yml");
630
- var baseUrlSecret = "REVIEW_CI_BASE_URL";
630
+ var baseUrlVariable = "REVIEW_CI_BASE_URL";
631
631
  var apiKeySecret = "REVIEW_CI_API_KEY";
632
632
  function workflowSecrets({ entra }) {
633
- return entra ? [baseUrlSecret] : [baseUrlSecret, apiKeySecret];
633
+ return entra ? [] : [apiKeySecret];
634
634
  }
635
635
  function entraInputs({ azureClientId, azureTenantId, environment }, provider, errors) {
636
636
  const clientId = azureClientId?.trim();
@@ -686,6 +686,7 @@ function yamlValue(value) {
686
686
  return /^[\w./:@-]+$/.test(value) && !/^([-+.\d_eE]+|0[xo][\da-f]+|true|false|yes|no|on|off|y|n|null|~)$/i.test(value) ? value : JSON.stringify(value);
687
687
  }
688
688
  function renderCallerWorkflow(workflow) {
689
+ const secrets = workflowSecrets(workflow);
689
690
  return [
690
691
  "name: Review PR",
691
692
  "",
@@ -703,19 +704,20 @@ function renderCallerWorkflow(workflow) {
703
704
  ` uses: ${reviewWorkflowRef}`,
704
705
  " with:",
705
706
  ...workflow.inputs.map(([name, value]) => ` ${name}: ${yamlValue(value)}`),
706
- " secrets:",
707
- ...workflowSecrets(workflow).map((secret2) => ` ${secret2}: \${{ secrets.${secret2} }}`),
707
+ ` base-url: \${{ vars.${baseUrlVariable} }}`,
708
+ ...secrets.length > 0 ? [" secrets:", ...secrets.map((secret2) => ` ${secret2}: \${{ secrets.${secret2} }}`)] : [],
708
709
  ""
709
710
  ].join("\n");
710
711
  }
711
712
  function shellQuote(value) {
712
713
  return `'${value.replaceAll("'", `'\\''`)}'`;
713
714
  }
714
- function secretCommands(settings, workflow) {
715
+ function setupCommands(settings, workflow) {
715
716
  const baseUrl = settings[`${workflow.provider}.baseUrl`];
716
- return workflowSecrets(workflow).map(
717
- (secret2) => secret2 === baseUrlSecret && baseUrl ? `gh secret set ${secret2} --body ${shellQuote(baseUrl)}` : `gh secret set ${secret2}`
718
- );
717
+ return [
718
+ `gh variable set ${baseUrlVariable}${baseUrl ? ` --body ${shellQuote(baseUrl)}` : ""}`,
719
+ ...workflowSecrets(workflow).map((secret2) => `gh secret set ${secret2}`)
720
+ ];
719
721
  }
720
722
  var githubOidcIssuer = "https://token.actions.githubusercontent.com";
721
723
  var entraTokenExchangeAudience = "api://AzureADTokenExchange";
@@ -780,12 +782,12 @@ function entraSetup({ clientId, environment }, repo) {
780
782
  }
781
783
  function reviewCiReport(outcome, settings, workflow, repo) {
782
784
  const action = outcome === "wrote" ? "wrote" : "kept";
783
- const secrets = workflowSecrets(workflow);
785
+ const reads = [`variable ${baseUrlVariable}`, ...workflowSecrets(workflow).map((secret2) => `secret ${secret2}`)];
784
786
  return [
785
787
  `${action} ${callerWorkflowPath}`,
786
788
  "",
787
- `The workflow reads ${secrets.join(" and ")}. Set ${secrets.length > 1 ? "them" : "it"} on the repo (or the org) with:`,
788
- ...secretCommands(settings, workflow).map((command) => ` ${command}`),
789
+ `The workflow reads ${reads.join(" and ")}. Set ${reads.length > 1 ? "them" : "it"} on the repo (or the org) with:`,
790
+ ...setupCommands(settings, workflow).map((command) => ` ${command}`),
789
791
  ...workflow.entra ? entraSetup(workflow.entra, repo()) : [],
790
792
  "",
791
793
  "Commit and push the workflow; each PR opened from this repo then gets a review."
@@ -938,7 +940,7 @@ This change adds or edits a workflow that calls \`MakerXStudio/yoke/.github/work
938
940
 
939
941
  Real defects in it are still findings, such as:
940
942
 
941
- - Passing every secret with \`secrets: inherit\` instead of only \`REVIEW_CI_BASE_URL\` and \`REVIEW_CI_API_KEY\`.
943
+ - Passing every secret with \`secrets: inherit\` instead of only \`REVIEW_CI_API_KEY\` (plus \`REVIEW_CI_BASE_URL\` from callers that still pass the URL as a secret).
942
944
  - An input the reusable workflow does not declare.
943
945
  - No \`permissions:\` block limiting the token to \`contents: read\` and \`pull-requests: write\`, plus \`id-token: write\` with \`azure-client-id\`. The reusable workflow sets no permissions of its own, so the caller's block is the only limit on the token its agents run with.
944
946
  `;
@@ -1179,8 +1181,8 @@ async function reportFailure(pr2, reason, ui, deps) {
1179
1181
 
1180
1182
  // src/features/review/slots.ts
1181
1183
  var slotNames = ["reviewer1", "reviewer2", "synthesis"];
1182
- function notSet(key, secret2, placeholder, env) {
1183
- return isCi(env) ? `Secret ${secret2} is not set` : `${key} is not set; ${howToSet(key, placeholder)}`;
1184
+ function notSet(key, ciName, placeholder, env) {
1185
+ return isCi(env) ? `${ciName} is not set` : `${key} is not set; ${howToSet(key, placeholder)}`;
1184
1186
  }
1185
1187
  function readProvider(settings, kind, env = process.env) {
1186
1188
  const baseUrlKey = `${kind}.baseUrl`;
@@ -1191,8 +1193,8 @@ function readProvider(settings, kind, env = process.env) {
1191
1193
  if (baseUrl && token) return { kind, baseUrl, token };
1192
1194
  if (baseUrl && apiKey) return { kind, baseUrl, apiKey };
1193
1195
  return [
1194
- baseUrl ? null : notSet(baseUrlKey, baseUrlSecret, "<url>", env),
1195
- apiKey || token ? null : notSet(apiKeyKey, apiKeySecret, "<key>", env)
1196
+ baseUrl ? null : notSet(baseUrlKey, `Variable ${baseUrlVariable}`, "<url>", env),
1197
+ apiKey || token ? null : notSet(apiKeyKey, `Secret ${apiKeySecret}`, "<key>", env)
1196
1198
  ].filter((error) => error !== null);
1197
1199
  }
1198
1200
  function readSpec(settings, slot, errors) {
@@ -2183,7 +2185,7 @@ If \`yoke\` is not found, run \`npm i -g @makerx/yoke\` and retry.
2183
2185
  // src/features/review/ciSkill.ts
2184
2186
  var reviewCiSkill = {
2185
2187
  name: "review-ci",
2186
- description: "Add yoke's adversarial PR review workflow to this repo and set the secrets it needs.",
2188
+ description: "Add yoke's adversarial PR review workflow to this repo and set the variable and secret it needs.",
2187
2189
  disableModelInvocation: true,
2188
2190
  userLevel: true,
2189
2191
  body: `
@@ -2191,13 +2193,13 @@ Run \`yoke review-ci $ARGUMENTS\`. If it reports that a model is required, run \
2191
2193
 
2192
2194
  With \`--provider foundry\`, if the Foundry resource has local (API key) auth disabled or the user prefers Entra, rerun with \`--azure-client-id\` and \`--azure-tenant-id\` of the Entra app the job signs in as, plus \`--environment\` if the job should run in a GitHub environment. Ask the user for these values; don't guess them.
2193
2195
 
2194
- Then set the secrets it printed. Run \`gh secret list\` first; if a secret is missing, ask whether it is already set at the org level before setting it on the repo.
2195
- - \`REVIEW_CI_BASE_URL\` is not secret: confirm the URL with the user and run the printed command.
2196
+ Then set the variable and secret it printed. Run \`gh variable list\` and \`gh secret list\` first; if one is missing, ask whether it is already set at the org level before setting it on the repo.
2197
+ - \`REVIEW_CI_BASE_URL\` is a variable, not a secret: confirm the URL with the user and run the printed \`gh variable set\` command.
2196
2198
  - \`REVIEW_CI_API_KEY\` must never enter this conversation: ask the user to run \`gh secret set REVIEW_CI_API_KEY\` in their own terminal, outside this session, and paste the key at its prompt. With Entra auth there is no API key to set.
2197
2199
 
2198
2200
  With Entra auth, show the user the federated credential it printed (issuer, audience, subject) and the \`az ad app federated-credential create\` command, and ask whether to run it or whether they will add the credential in the Azure portal. The app also needs the Cognitive Services User role on the Foundry resource, and the environment, if given, must exist on the repo.
2199
2201
 
2200
- Finish by running \`gh secret list\` and telling the user to commit and push the workflow file.
2202
+ Finish by running \`gh variable list\` and \`gh secret list\` and telling the user to commit and push the workflow file.
2201
2203
 
2202
2204
  If \`yoke\` is not found, run \`npm i -g @makerx/yoke\` and retry.
2203
2205
  `
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@makerx/yoke",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Lean, user-invoked Claude Code skills for MakerX AI-assisted delivery, plus the CLI they call.",
5
5
  "license": "MIT",
6
6
  "author": "MakerX",