@theholocron/cli 2.0.0-alpha.73 → 2.0.0-alpha.74
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/dist/cli.mjs +79 -9
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -483,9 +483,12 @@ var PluginLoader = class {
|
|
|
483
483
|
throw new LoaderError(`failed to import \`${tuple.packageName}\` for capability \`${key}\`: ${err instanceof Error ? err.message : String(err)}`);
|
|
484
484
|
});
|
|
485
485
|
if (isPluginModule(mod)) {
|
|
486
|
+
const effectiveToken = this.context.cliTokens?.[tuple.provider] ?? this.context.cliToken;
|
|
486
487
|
const factory = mod.createPlugin({
|
|
487
488
|
...this.projectDefaults(),
|
|
488
489
|
...this.context,
|
|
490
|
+
...effectiveToken !== void 0 ? { cliToken: effectiveToken } : {},
|
|
491
|
+
cliTokens: void 0,
|
|
489
492
|
...tuple.options
|
|
490
493
|
}).capabilities[key];
|
|
491
494
|
if (typeof factory !== "function") throw new LoaderError(`\`${tuple.packageName}\` does not implement the \`${key}\` capability`);
|
|
@@ -913,7 +916,7 @@ var lint_default$1 = "name: Lint\n\non: # yamllint disable-line rule:truthy\n w
|
|
|
913
916
|
var release_default$1 = "name: Release\n\n# Semantic-release with OIDC Trusted Publishing — no NPM_TOKEN required.\n# The calling repo must have a .releaserc.json that configures branches,\n# plugins, and any publish options. npm@11+ is installed to support OIDC.\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n inputs:\n run-build:\n description: Run `pnpm build` before releasing\n type: boolean\n required: false\n default: true\n secrets:\n SYNC_TOKEN:\n description: >\n Optional PAT with Contents write access. Required when the default\n branch is protected by a ruleset — github.token cannot push through\n rulesets, but a PAT with admin bypass can. Falls back to github.token.\n required: false\n\njobs:\n release:\n name: Semantic release\n permissions:\n contents: write\n id-token: write\n issues: write\n pull-requests: write\n runs-on: ubuntu-latest\n timeout-minutes: 30\n # Do not cancel in-progress releases — a partial release is worse than a slow one.\n concurrency:\n group: release-${{ github.ref }}\n cancel-in-progress: false\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n with:\n fetch-depth: 0\n # Use SYNC_TOKEN when available — git push (tags, release commits)\n # uses the checkout credential, not GITHUB_TOKEN env var. The\n # built-in github.token cannot push through branch protection rulesets.\n token: ${{ secrets.SYNC_TOKEN || github.token }}\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - name: Configure git identity\n run: |\n GIT_NAME=$(gh api user --jq .name 2>/dev/null || echo \"github-actions[bot]\")\n GIT_EMAIL=$(gh api user --jq '\"\\(.id)+\\(.login)@users.noreply.github.com\"' 2>/dev/null || echo \"41898282+github-actions[bot]@users.noreply.github.com\")\n git config --global user.name \"$GIT_NAME\"\n git config --global user.email \"$GIT_EMAIL\"\n git config --global format.signoff true\n env:\n GH_TOKEN: ${{ secrets.SYNC_TOKEN || github.token }}\n\n - run: npm install -g npm@11 sigstore\n name: Upgrade npm for OIDC support\n # sigstore is required by libnpmpublish/provenance.js at module parse\n # time — before any config takes effect. Some npm 11.x builds stopped\n # bundling it; installing it globally into the same prefix ensures it\n # resolves regardless of npm version. (Discovered 2026-07-09.)\n\n - run: pnpm build\n name: Build\n if: ${{ inputs.run-build == true }}\n\n - run: npx semantic-release\n name: Release\n env:\n # Prefer SYNC_TOKEN (a PAT with Contents write) when available —\n # the built-in github.token cannot push to protected default branches\n # because rulesets block non-PAT pushes. Falls back to github.token\n # for repos without branch protection.\n GITHUB_TOKEN: ${{ secrets.SYNC_TOKEN || github.token }}\n NPM_CONFIG_PROVENANCE: true\n";
|
|
914
917
|
//#endregion
|
|
915
918
|
//#region src/templates/workflows/review.yml
|
|
916
|
-
var review_default$1 = "name: Review\n\n# ReviewDog is the annotation layer — posts inline PR diff annotations.\n# Runs on pull_request only: inline annotations require PR context,\n# and branch protection ensures all changes go through PRs anyway.\n# super-linter (lint.yml) is the CI gate covering push + PR events.\n# Gitleaks and YAML are intentionally duplicated: super-linter gates\n# merges; ReviewDog surfaces exact line annotations in the PR diff.\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n\nconcurrency:\n group: review-${{ github.workflow }}-${{ github.ref }}\n cancel-in-progress: true\n\njobs:\n reviewdog:\n name: Review PRs\n runs-on: ubuntu-latest\n timeout-minutes: 20\n permissions:\n contents: read\n checks: write\n pull-requests: write\n\n steps:\n - name: Checkout repository\n uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n with:\n fetch-depth: 0\n\n - name: Setup\n if: ${{ hashFiles('pnpm-lock.yaml') != '' }}\n uses: theholocron/.github/.github/actions/setup@main\n\n - name: Install ReviewDog\n uses: reviewdog/action-setup@d8a7baabd7f3e8544ee4dbde3ee41d0011c3a93f # v1\n with:\n reviewdog_version: latest\n\n # Detect which tools are relevant for this repo, excluding node_modules.\n # hashFiles('**/*') recurses into node_modules/.pnpm and produces false\n # positives for repos that don't own those file types.\n # -print -quit stops find after the first match without a pipe, avoiding\n # the SIGPIPE/pipefail exit-141 that find|head-1 triggers under\n # GitHub Actions' default bash --noprofile --norc -e -o pipefail mode.\n - name: Detect project features\n id: detect\n shell: bash\n run: |\n has() { find . -not -path '*/node_modules/*' -name \"$1\" -print -quit 2>/dev/null | grep -q .; }\n has_ext() { find . -not -path '*/node_modules/*' -name \"$1\" -print -quit 2>/dev/null | grep -q .; }\n { { has 'eslint.config.js' || has 'eslint.config.mjs' || has 'eslint.config.cjs' || \\\n has 'eslint.config.ts' || has '.eslintrc' || has '.eslintrc.js' || \\\n has '.eslintrc.cjs' || has '.eslintrc.json' || has '.eslintrc.yaml' || \\\n has '.eslintrc.yml'; } && grep -qF '\"eslint\":' package.json 2>/dev/null; } && echo \"eslint=true\" >> \"$GITHUB_OUTPUT\" || echo \"eslint=false\" >> \"$GITHUB_OUTPUT\"\n { has 'tsconfig.json' && grep -qF '\"typescript\":' package.json 2>/dev/null; } && echo \"tsconfig=true\" >> \"$GITHUB_OUTPUT\" || echo \"tsconfig=false\" >> \"$GITHUB_OUTPUT\"\n has_ext '*.sh' && echo \"shell=true\" >> \"$GITHUB_OUTPUT\" || echo \"shell=false\" >> \"$GITHUB_OUTPUT\"\n has 'Dockerfile' || has_ext '*.Dockerfile' || has 'Containerfile' && \\\n echo \"docker=true\" >> \"$GITHUB_OUTPUT\" || echo \"docker=false\" >> \"$GITHUB_OUTPUT\"\n has_ext '.env*' && echo \"dotenv=true\" >> \"$GITHUB_OUTPUT\" || echo \"dotenv=false\" >> \"$GITHUB_OUTPUT\"\n has_ext '*.md' && echo \"markdown=true\" >> \"$GITHUB_OUTPUT\" || echo \"markdown=false\" >> \"$GITHUB_OUTPUT\"\n\n #\n # Always applicable\n #\n\n - name: Gitleaks (secrets)\n uses: reviewdog/action-gitleaks@2b7b5685e3e3eecddab5d30cfa04f18123031421 # v1\n with:\n reporter: github-pr-check\n gitleaks_flags: --log-opts=${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}\n\n - name: YamlLint\n if: ${{ hashFiles('yamllint.config.yml') != '' }}\n uses: reviewdog/action-yamllint@b5f7217d8c815ae374d1d55840d5e569d82f01f0 # v1\n with:\n reporter: github-pr-check\n yamllint_flags: -c ${{ github.workspace }}/yamllint.config.yml ${{ github.workspace }}\n\n - name: ActionLint (GitHub Actions)\n if: ${{ hashFiles('.github/workflows/*.yml', '.github/workflows/*.yaml') != '' }}\n uses: reviewdog/action-actionlint@6fb7acc99f4a1008869fa8a0f09cfca740837d9d # v1\n with:\n reporter: github-pr-check\n\n #\n # TypeScript / JavaScript\n #\n\n - name: ESLint\n if: steps.detect.outputs.eslint == 'true'\n uses: reviewdog/action-eslint@556a3fdaf8b4201d4d74d406013386aa4f7dab96 # v1.34.0\n with:\n reporter: github-pr-check\n eslint_flags: .\n\n - name: TypeScript\n if: steps.detect.outputs.tsconfig == 'true'\n uses: EPMatt/reviewdog-action-tsc@63d923a3c5b4497671940b8874f58a404e2351b5 # v1\n with:\n reporter: github-pr-check\n\n #\n # Shell\n #\n\n - name: ShellCheck\n if: steps.detect.outputs.shell == 'true'\n uses: reviewdog/action-shellcheck@4c07458293ac342d477251099501a718ae5ef86e # v1\n with:\n reporter: github-pr-check\n fail_level: none\n\n #\n # Docker\n #\n\n - name: Hadolint\n if: steps.detect.outputs.docker == 'true'\n uses: reviewdog/action-hadolint@1b2cfa6ba72072ad35158d7ff3aa49bbdc03506d # v1\n with:\n reporter: github-pr-check\n fail_level: none\n\n #\n # Environment files\n #\n\n - name: dotenv-linter\n if: steps.detect.outputs.dotenv == 'true'\n uses: dotenv-linter/action-dotenv-linter@afde61cfda2ecffe7bea35837b6f20b956c88689 # v3.0.0\n with:\n reporter: github-code-suggestions\n\n #\n # Documentation\n #\n\n - name: Alex (inclusive language)\n if: steps.detect.outputs.markdown == 'true'\n uses: reviewdog/action-alex@347481655add010a2ae302df34b57c9bcfa0d6e4 # v1\n with:\n reporter: github-pr-check\n";
|
|
919
|
+
var review_default$1 = "name: Review\n\n# ReviewDog is the annotation layer — posts inline PR diff annotations.\n# Runs on pull_request only: inline annotations require PR context,\n# and branch protection ensures all changes go through PRs anyway.\n# super-linter (lint.yml) is the CI gate covering push + PR events.\n# Gitleaks and YAML are intentionally duplicated: super-linter gates\n# merges; ReviewDog surfaces exact line annotations in the PR diff.\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n\nconcurrency:\n group: review-${{ github.workflow }}-${{ github.ref }}\n cancel-in-progress: true\n\njobs:\n reviewdog:\n name: Review PRs\n runs-on: ubuntu-latest\n timeout-minutes: 20\n permissions:\n contents: read\n checks: write\n pull-requests: write\n\n steps:\n - name: Checkout repository\n uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n with:\n fetch-depth: 0\n\n - name: Setup\n if: ${{ hashFiles('pnpm-lock.yaml') != '' }}\n uses: theholocron/.github/.github/actions/setup@main\n\n - name: Install ReviewDog\n uses: reviewdog/action-setup@d8a7baabd7f3e8544ee4dbde3ee41d0011c3a93f # v1\n with:\n reviewdog_version: latest\n\n # Detect which tools are relevant for this repo, excluding node_modules.\n # hashFiles('**/*') recurses into node_modules/.pnpm and produces false\n # positives for repos that don't own those file types.\n # -print -quit stops find after the first match without a pipe, avoiding\n # the SIGPIPE/pipefail exit-141 that find|head-1 triggers under\n # GitHub Actions' default bash --noprofile --norc -e -o pipefail mode.\n - name: Detect project features\n id: detect\n shell: bash\n run: |\n has() { find . -not -path '*/node_modules/*' -name \"$1\" -print -quit 2>/dev/null | grep -q .; }\n has_ext() { find . -not -path '*/node_modules/*' -name \"$1\" -print -quit 2>/dev/null | grep -q .; }\n { { has 'eslint.config.js' || has 'eslint.config.mjs' || has 'eslint.config.cjs' || \\\n has 'eslint.config.ts' || has '.eslintrc' || has '.eslintrc.js' || \\\n has '.eslintrc.cjs' || has '.eslintrc.json' || has '.eslintrc.yaml' || \\\n has '.eslintrc.yml'; } && grep -qF '\"eslint\":' package.json 2>/dev/null; } && echo \"eslint=true\" >> \"$GITHUB_OUTPUT\" || echo \"eslint=false\" >> \"$GITHUB_OUTPUT\"\n { has 'tsconfig.json' && grep -qF '\"typescript\":' package.json 2>/dev/null; } && echo \"tsconfig=true\" >> \"$GITHUB_OUTPUT\" || echo \"tsconfig=false\" >> \"$GITHUB_OUTPUT\"\n has_ext '*.sh' && echo \"shell=true\" >> \"$GITHUB_OUTPUT\" || echo \"shell=false\" >> \"$GITHUB_OUTPUT\"\n has 'Dockerfile' || has_ext '*.Dockerfile' || has 'Containerfile' && \\\n echo \"docker=true\" >> \"$GITHUB_OUTPUT\" || echo \"docker=false\" >> \"$GITHUB_OUTPUT\"\n has_ext '.env*' && echo \"dotenv=true\" >> \"$GITHUB_OUTPUT\" || echo \"dotenv=false\" >> \"$GITHUB_OUTPUT\"\n has_ext '*.md' && echo \"markdown=true\" >> \"$GITHUB_OUTPUT\" || echo \"markdown=false\" >> \"$GITHUB_OUTPUT\"\n\n #\n # Always applicable\n #\n\n - name: Gitleaks (secrets)\n uses: reviewdog/action-gitleaks@2b7b5685e3e3eecddab5d30cfa04f18123031421 # v1\n with:\n reporter: github-pr-check\n tool_name: \"Review / gitleaks\"\n gitleaks_flags: --log-opts=${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}\n\n - name: YamlLint\n if: ${{ hashFiles('yamllint.config.yml') != '' }}\n uses: reviewdog/action-yamllint@b5f7217d8c815ae374d1d55840d5e569d82f01f0 # v1\n with:\n reporter: github-pr-check\n tool_name: \"Review / yamllint\"\n yamllint_flags: -c ${{ github.workspace }}/yamllint.config.yml ${{ github.workspace }}\n\n - name: ActionLint (GitHub Actions)\n if: ${{ hashFiles('.github/workflows/*.yml', '.github/workflows/*.yaml') != '' }}\n uses: reviewdog/action-actionlint@6fb7acc99f4a1008869fa8a0f09cfca740837d9d # v1\n with:\n reporter: github-pr-check\n tool_name: \"Review / actionlint\"\n\n #\n # TypeScript / JavaScript\n #\n\n - name: ESLint\n if: steps.detect.outputs.eslint == 'true'\n uses: reviewdog/action-eslint@556a3fdaf8b4201d4d74d406013386aa4f7dab96 # v1.34.0\n with:\n reporter: github-pr-check\n tool_name: \"Review / eslint\"\n eslint_flags: .\n\n - name: TypeScript\n if: steps.detect.outputs.tsconfig == 'true'\n uses: EPMatt/reviewdog-action-tsc@63d923a3c5b4497671940b8874f58a404e2351b5 # v1\n with:\n reporter: github-pr-check\n tool_name: \"Review / tsc\"\n\n #\n # Shell\n #\n\n - name: ShellCheck\n if: steps.detect.outputs.shell == 'true'\n uses: reviewdog/action-shellcheck@4c07458293ac342d477251099501a718ae5ef86e # v1\n with:\n reporter: github-pr-check\n tool_name: \"Review / shellcheck\"\n fail_level: none\n\n #\n # Docker\n #\n\n - name: Hadolint\n if: steps.detect.outputs.docker == 'true'\n uses: reviewdog/action-hadolint@1b2cfa6ba72072ad35158d7ff3aa49bbdc03506d # v1\n with:\n reporter: github-pr-check\n tool_name: \"Review / hadolint\"\n fail_level: none\n\n #\n # Environment files\n #\n\n - name: dotenv-linter\n if: steps.detect.outputs.dotenv == 'true'\n uses: dotenv-linter/action-dotenv-linter@afde61cfda2ecffe7bea35837b6f20b956c88689 # v3.0.0\n with:\n reporter: github-code-suggestions\n\n #\n # Documentation\n #\n\n - name: Alex (inclusive language)\n if: steps.detect.outputs.markdown == 'true'\n uses: reviewdog/action-alex@347481655add010a2ae302df34b57c9bcfa0d6e4 # v1\n with:\n reporter: github-pr-check\n tool_name: \"Review / alex\"\n";
|
|
917
920
|
//#endregion
|
|
918
921
|
//#region src/templates/workflows/stale.yml
|
|
919
922
|
var stale_default$1 = "name: Stale\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n inputs:\n days-before-stale:\n description: Days of inactivity before an issue is marked stale\n type: number\n required: false\n default: 30\n days-before-close:\n description: Days of inactivity after stale label before closing\n type: number\n required: false\n default: 5\n\njobs:\n stale:\n name: Mark stale issues and pull requests\n permissions:\n contents: write\n issues: write\n pull-requests: write\n runs-on: ubuntu-latest\n timeout-minutes: 10\n steps:\n - uses: actions/stale@1e223db275d687790206a7acac4d1a11bd6fe629 # v10.4.0\n name: Run Stale\n with:\n close-issue-message: >\n This issue was closed because it has been stalled for\n ${{ inputs.days-before-close }} days with no activity.\n days-before-close: ${{ inputs.days-before-close }}\n days-before-stale: ${{ inputs.days-before-stale }}\n exempt-all-pr-milestones: true\n stale-issue-label: wontfix\n stale-issue-message: >\n This issue is stale because it has been open ${{ inputs.days-before-stale }}\n days with no activity. Remove the stale label or comment, or this will be\n closed in ${{ inputs.days-before-close }} days.\n stale-pr-label: wontfix\n stale-pr-message: >\n This PR is stale because it has been open ${{ inputs.days-before-stale }}\n days with no activity. Remove the stale label or comment, or this will be\n closed in ${{ inputs.days-before-close }} days.\n";
|
|
@@ -4072,15 +4075,68 @@ async function fileExists(path) {
|
|
|
4072
4075
|
}
|
|
4073
4076
|
}
|
|
4074
4077
|
//#endregion
|
|
4078
|
+
//#region src/token-args.ts
|
|
4079
|
+
var TokenParseError = class extends Error {
|
|
4080
|
+
name = "TokenParseError";
|
|
4081
|
+
};
|
|
4082
|
+
/**
|
|
4083
|
+
* Converts raw --token CLI values into a typed result.
|
|
4084
|
+
*
|
|
4085
|
+
* Bare form: --token ghp_xxx → { cliToken: "ghp_xxx" }
|
|
4086
|
+
* Keyed form: --token github=ghp_xxx → { cliTokens: { github: "ghp_xxx" } }
|
|
4087
|
+
* Mixed: --token github=ghp_xxx --token v_yyy
|
|
4088
|
+
* → { cliToken: "v_yyy", cliTokens: { github: "ghp_xxx" } }
|
|
4089
|
+
*
|
|
4090
|
+
* Values may contain "=" (e.g. base64 strings) — only the first "=" is treated as a separator.
|
|
4091
|
+
*/
|
|
4092
|
+
function parseTokenArgs(tokens) {
|
|
4093
|
+
if (tokens.length === 0) return {};
|
|
4094
|
+
const cliTokens = {};
|
|
4095
|
+
const bare = [];
|
|
4096
|
+
for (const raw of tokens) {
|
|
4097
|
+
const eqIdx = raw.indexOf("=");
|
|
4098
|
+
if (eqIdx === -1) {
|
|
4099
|
+
bare.push(raw);
|
|
4100
|
+
continue;
|
|
4101
|
+
}
|
|
4102
|
+
const vendor = raw.slice(0, eqIdx);
|
|
4103
|
+
const value = raw.slice(eqIdx + 1);
|
|
4104
|
+
if (vendor.trim() === "") throw new TokenParseError(`invalid --token value "${raw}": vendor name must not be empty`);
|
|
4105
|
+
if (/\s/.test(vendor)) throw new TokenParseError(`invalid --token value "${raw}": vendor name must not contain whitespace`);
|
|
4106
|
+
if (value === "") throw new TokenParseError(`invalid --token value "${raw}": token value must not be empty`);
|
|
4107
|
+
cliTokens[vendor] = value;
|
|
4108
|
+
}
|
|
4109
|
+
if (bare.length > 1) throw new TokenParseError(`only one bare --token value is allowed; got ${bare.length.toString()} — use vendor=value form for multiple tokens`);
|
|
4110
|
+
const result = {};
|
|
4111
|
+
if (bare.length === 1) result.cliToken = bare[0];
|
|
4112
|
+
if (Object.keys(cliTokens).length > 0) result.cliTokens = cliTokens;
|
|
4113
|
+
return result;
|
|
4114
|
+
}
|
|
4115
|
+
//#endregion
|
|
4075
4116
|
//#region src/cli.ts
|
|
4076
4117
|
const { version: CLI_VERSION } = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf-8"));
|
|
4118
|
+
/** Parses --token values and returns the context spread, or null on parse error (exits with code 1). */
|
|
4119
|
+
function tokenContext(rawTokens) {
|
|
4120
|
+
if (!rawTokens?.length) return {};
|
|
4121
|
+
try {
|
|
4122
|
+
return parseTokenArgs(rawTokens);
|
|
4123
|
+
} catch (err) {
|
|
4124
|
+
if (err instanceof TokenParseError) {
|
|
4125
|
+
console.error(`--token: ${err.message}`);
|
|
4126
|
+
process.exitCode = 1;
|
|
4127
|
+
return null;
|
|
4128
|
+
}
|
|
4129
|
+
throw err;
|
|
4130
|
+
}
|
|
4131
|
+
}
|
|
4077
4132
|
await yargs(hideBin(process.argv)).scriptName("holocron").usage("$0 <command> [options]").option("dry-run", {
|
|
4078
4133
|
type: "boolean",
|
|
4079
4134
|
default: false,
|
|
4080
4135
|
describe: "Print what would be mutated without calling capability mutators. Commands branch on this; read-only commands ignore it."
|
|
4081
4136
|
}).option("token", {
|
|
4082
4137
|
type: "string",
|
|
4083
|
-
|
|
4138
|
+
array: true,
|
|
4139
|
+
describe: "Vendor token override for plugins. Bare form: --token <value> (fallback for all plugins, single-plugin commands). Keyed form: --token vendor=value (targets a specific provider; repeat for each). Example: --token github=ghp_xxx --token vercel=v_yyy"
|
|
4084
4140
|
}).option("cwd", {
|
|
4085
4141
|
type: "string",
|
|
4086
4142
|
default: process.cwd(),
|
|
@@ -4091,26 +4147,30 @@ await yargs(hideBin(process.argv)).scriptName("holocron").usage("$0 <command> [o
|
|
|
4091
4147
|
type: "string",
|
|
4092
4148
|
describe: "Repo coords (\"owner/name\"). Defaults to plugin-specific resolution."
|
|
4093
4149
|
}), async (argv) => {
|
|
4150
|
+
const tokens = tokenContext(argv.token);
|
|
4151
|
+
if (!tokens) return;
|
|
4094
4152
|
if ((await runDoctor({
|
|
4095
4153
|
loaded: await loadConfig(argv.cwd),
|
|
4096
4154
|
context: {
|
|
4097
4155
|
repoRoot: argv.cwd,
|
|
4098
4156
|
dryRun: argv.dryRun,
|
|
4099
4157
|
...argv.repo ? { repo: argv.repo } : {},
|
|
4100
|
-
...
|
|
4158
|
+
...tokens
|
|
4101
4159
|
}
|
|
4102
4160
|
})).summary.fail > 0) process.exitCode = 1;
|
|
4103
4161
|
}).command("setup", "Apply infra setup actions across every configured capability", (y) => y.option("repo", {
|
|
4104
4162
|
type: "string",
|
|
4105
4163
|
describe: "Repo coords (\"owner/name\"). Defaults to plugin-specific resolution."
|
|
4106
4164
|
}), async (argv) => {
|
|
4165
|
+
const tokens = tokenContext(argv.token);
|
|
4166
|
+
if (!tokens) return;
|
|
4107
4167
|
if ((await runSetup({
|
|
4108
4168
|
loaded: await loadConfig(argv.cwd),
|
|
4109
4169
|
context: {
|
|
4110
4170
|
repoRoot: argv.cwd,
|
|
4111
4171
|
dryRun: argv.dryRun,
|
|
4112
4172
|
...argv.repo ? { repo: argv.repo } : {},
|
|
4113
|
-
...
|
|
4173
|
+
...tokens
|
|
4114
4174
|
}
|
|
4115
4175
|
})).summary.fail > 0) process.exitCode = 1;
|
|
4116
4176
|
}).command("skills", "Manage agent skills from the @theholocron/skills registry", (y) => y.command("install", "Copy skills from @theholocron/skills into .agents/ with agent symlinks", () => {}, async (argv) => {
|
|
@@ -4163,6 +4223,8 @@ await yargs(hideBin(process.argv)).scriptName("holocron").usage("$0 <command> [o
|
|
|
4163
4223
|
default: "repo",
|
|
4164
4224
|
describe: "Scope: \"repo\" (default), \"env=<name>\", or \"org=<name>\""
|
|
4165
4225
|
}), async (argv) => {
|
|
4226
|
+
const tokens = tokenContext(argv.token);
|
|
4227
|
+
if (!tokens) return;
|
|
4166
4228
|
const scopeArg = argv.scope;
|
|
4167
4229
|
const scope = parseScope(scopeArg);
|
|
4168
4230
|
if ((await runSecretSet({
|
|
@@ -4170,7 +4232,7 @@ await yargs(hideBin(process.argv)).scriptName("holocron").usage("$0 <command> [o
|
|
|
4170
4232
|
context: {
|
|
4171
4233
|
repoRoot: argv.cwd,
|
|
4172
4234
|
dryRun: argv.dryRun,
|
|
4173
|
-
...
|
|
4235
|
+
...tokens
|
|
4174
4236
|
},
|
|
4175
4237
|
name: argv.name,
|
|
4176
4238
|
...argv.value ? { value: argv.value } : {},
|
|
@@ -4190,12 +4252,14 @@ await yargs(hideBin(process.argv)).scriptName("holocron").usage("$0 <command> [o
|
|
|
4190
4252
|
default: ["production", "preview"],
|
|
4191
4253
|
describe: "Deployment targets to sync to. Defaults to production + preview."
|
|
4192
4254
|
}), async (argv) => {
|
|
4255
|
+
const tokens = tokenContext(argv.token);
|
|
4256
|
+
if (!tokens) return;
|
|
4193
4257
|
if ((await runSecretsSync({
|
|
4194
4258
|
loaded: await loadConfig(argv.cwd),
|
|
4195
4259
|
context: {
|
|
4196
4260
|
repoRoot: argv.cwd,
|
|
4197
4261
|
dryRun: argv.dryRun,
|
|
4198
|
-
...
|
|
4262
|
+
...tokens
|
|
4199
4263
|
},
|
|
4200
4264
|
environmentId: argv.environmentId,
|
|
4201
4265
|
...argv.projectId ? { projectId: argv.projectId } : {},
|
|
@@ -4214,12 +4278,14 @@ await yargs(hideBin(process.argv)).scriptName("holocron").usage("$0 <command> [o
|
|
|
4214
4278
|
choices: ["production", "staging"],
|
|
4215
4279
|
describe: "Named environment to deploy into. Omit for a branch preview."
|
|
4216
4280
|
}), async (argv) => {
|
|
4281
|
+
const tokens = tokenContext(argv.token);
|
|
4282
|
+
if (!tokens) return;
|
|
4217
4283
|
if ((await runDeploy({
|
|
4218
4284
|
loaded: await loadConfig(argv.cwd),
|
|
4219
4285
|
context: {
|
|
4220
4286
|
repoRoot: argv.cwd,
|
|
4221
4287
|
dryRun: argv.dryRun,
|
|
4222
|
-
...
|
|
4288
|
+
...tokens
|
|
4223
4289
|
},
|
|
4224
4290
|
projectId: argv.projectId,
|
|
4225
4291
|
branch: argv.branch,
|
|
@@ -4257,13 +4323,15 @@ await yargs(hideBin(process.argv)).scriptName("holocron").usage("$0 <command> [o
|
|
|
4257
4323
|
type: "string",
|
|
4258
4324
|
describe: "Repo coords (\"owner/name\"). Defaults to plugin-specific resolution."
|
|
4259
4325
|
}), async (argv) => {
|
|
4326
|
+
const tokens = tokenContext(argv.token);
|
|
4327
|
+
if (!tokens) return;
|
|
4260
4328
|
if ((await runSync({
|
|
4261
4329
|
loaded: await loadConfig(argv.cwd),
|
|
4262
4330
|
context: {
|
|
4263
4331
|
repoRoot: argv.cwd,
|
|
4264
4332
|
dryRun: argv.dryRun,
|
|
4265
4333
|
...argv.repo ? { repo: argv.repo } : {},
|
|
4266
|
-
...
|
|
4334
|
+
...tokens
|
|
4267
4335
|
},
|
|
4268
4336
|
...argv.steps && argv.steps.length > 0 ? { steps: argv.steps } : {}
|
|
4269
4337
|
})).summary.fail > 0) process.exitCode = 1;
|
|
@@ -4286,7 +4354,9 @@ await yargs(hideBin(process.argv)).scriptName("holocron").usage("$0 <command> [o
|
|
|
4286
4354
|
describe: "Write generated files to this local directory instead of pushing (for validation)"
|
|
4287
4355
|
}), async (argv) => {
|
|
4288
4356
|
const outputDir = argv["output-dir"];
|
|
4289
|
-
const
|
|
4357
|
+
const parsed = tokenContext(argv.token);
|
|
4358
|
+
if (!parsed) return;
|
|
4359
|
+
const token = outputDir ? "no-token-needed" : parsed.cliTokens?.["github"] ?? parsed.cliToken ?? process.env.GITHUB_TOKEN ?? process.env.HOLOCRON_GITHUB_TOKEN;
|
|
4290
4360
|
if (!token) {
|
|
4291
4361
|
console.error("sync-github: GitHub token required — pass --token or set GITHUB_TOKEN");
|
|
4292
4362
|
process.exitCode = 1;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theholocron/cli",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.74",
|
|
4
4
|
"description": "The Holocron CLI — a pluggable, capability-based orchestrator for spinning up and operating software projects.",
|
|
5
5
|
"homepage": "https://github.com/theholocron/holocron/tree/main/packages/cli#readme",
|
|
6
6
|
"bugs": "https://github.com/theholocron/holocron/issues",
|