@theholocron/cli 5.0.0-alpha.91 → 5.0.0-alpha.93

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.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.mjs","names":["getKeyringToken","defaultImporter","SKIP_DIRS","defaultWalkFiles","SKIP_DIRS","defaultWalkFiles","preflight","defaultExec","deriveDefaults","render","render","render","render","render","render","render","render","render","render","render","render","render","render","render","render","render","renderPackageJson","renderTsconfigJson","renderVitestConfig","renderEslintConfig","renderTsdownConfig","renderReadme","renderAuth","renderRest","renderVerifyToken","renderPluginIndex","renderCapability","renderHelpers","renderAuthTest","renderRestTest","renderVerifyTokenTest","renderCapabilityTest","renderIndexTest","renderValidateScript","deriveDefaults","defaultExec","printNextSteps","defaultExec","alexrc","createIgnoreConfig","workflowHeader","alexignore","createConfig","workflowHeader","commitMsgBody","createConfig","workflowHeader","createConfig","workflowHeader","editorconfigBody","createConfig","editorconfigChecker","createConfig","workflowHeader","preCommitBody","createConfig","workflowHeader","prePushBody","createConfig","workflowHeader","prepareCommitMsgBody","workflowHeader","yamllintBody","yamlignoreBody","decisionsTemplate","ProviderApiError","ProviderApiError","workflowHeader","labelerConfig","dependabotConfig","dcoConfig","sentimentBotConfig","createAlexrc","createAlexignore","createYamllint","createYamlignore","createEditorconfig","createEditorconfigChecker","createDevmoji","createPrepareCommitMsg","createCommitMsg","createPrePush","createPreCommit","FETCH_TIMEOUT_MS"],"sources":["../src/env.ts","../src/auth/keyring.ts","../src/auth/auth-resolver.ts","../src/auth/token-args.ts","../src/plugin/capabilities.ts","../src/config/config.ts","../src/logger.ts","../src/plugin/loader.ts","../src/plugin/workspace.ts","../src/ui/progress.ts","../src/ui/style.ts","../src/commands/auth.ts","../src/commands/cleanup-preview.ts","../src/commands/clone.ts","../src/commands/contexts.ts","../src/commands/deploy.ts","../src/commands/doctor.ts","../src/commands/new.ts","../src/commands/npm-bump-versions.ts","../src/commands/plugin-create/template-inputs.ts","../src/commands/plugin-create/templates/auth.ts","../src/commands/plugin-create/templates/auth-test.ts","../src/commands/plugin-create/templates/capability.ts","../src/commands/plugin-create/templates/capability-test.ts","../src/commands/plugin-create/templates/eslint-config.ts","../src/commands/plugin-create/templates/helpers.ts","../src/commands/plugin-create/templates/index-test.ts","../src/commands/plugin-create/templates/package-json.ts","../src/commands/plugin-create/templates/plugin-index.ts","../src/commands/plugin-create/templates/readme.ts","../src/commands/plugin-create/templates/rest.ts","../src/commands/plugin-create/templates/rest-test.ts","../src/commands/plugin-create/templates/tsconfig-json.ts","../src/commands/plugin-create/templates/tsdown-config.ts","../src/commands/plugin-create/templates/validate-script.ts","../src/commands/plugin-create/templates/verify-token.ts","../src/commands/plugin-create/templates/verify-token-test.ts","../src/commands/plugin-create/templates/vitest-config.ts","../src/commands/plugin-create/index.ts","../src/commands/publish.ts","../src/commands/secret-set.ts","../src/commands/secrets-sync.ts","../src/commands/setup/derived-properties.ts","../src/commands/setup/labels.ts","../src/templates/config.yml","../src/utils/create-header.ts","../src/templates/configs/alexjs/alexignore","../src/templates/configs/alexjs/alexrc.json","../src/templates/configs/alexjs/create-config.ts","../src/templates/configs/commit-msg/commit-msg","../src/templates/configs/commit-msg/create-config.ts","../src/templates/configs/devmoji/create-config.ts","../src/templates/configs/editorconfig/editorconfig","../src/templates/configs/editorconfig/create-config.ts","../src/templates/configs/editorconfig-checker/editorconfig-checker.json","../src/templates/configs/editorconfig-checker/create-config.ts","../src/templates/configs/pre-commit/pre-commit","../src/templates/configs/pre-commit/create-config.ts","../src/templates/configs/pre-push/pre-push","../src/templates/configs/pre-push/create-config.ts","../src/templates/configs/prepare-commit-msg/prepare-commit-msg","../src/templates/configs/prepare-commit-msg/create-config.ts","../src/templates/configs/yamllint/.yamlignore","../src/templates/configs/yamllint/.yamllint.yml","../src/templates/configs/yamllint/create-config.ts","../src/templates/dco.yml","../src/templates/dependabot.yml","../src/templates/labeler.yml","../src/templates/decisions-template.md","../src/commands/setup/agent-prompts-data.ts","../src/commands/setup/agent-prompts.ts","../src/commands/setup/branch-protection.ts","../src/commands/setup/engineering.ts","../src/commands/setup/repo-settings.ts","../src/commands/setup/run-step.ts","../src/commands/setup/skills.ts","../src/commands/setup/run-setup.ts","../src/commands/skills.ts","../src/commands/sync-readme.ts","../src/commands/sync-wiki.ts","../src/commands/sync.ts","../src/telemetry/resolve.ts","../src/telemetry.ts","../src/commands/sync-github.ts","../src/commands/upgrade-deps.ts","../src/commands/upgrade-node.ts","../src/commit-lint/lint-message.ts","../src/commit-lint/lint-commit-msg-file.ts","../src/config/load-config.ts","../src/interactive-menu.ts","../src/update-notifier.ts","../src/cli.ts"],"sourcesContent":["import { createEnvLookup } from \"@theholocron/env-utils\";\n\nexport type { EnvLookup as CliEnv } from \"@theholocron/env-utils\";\n\n/** Singleton env for simple global lookups throughout the CLI. */\nexport const env = createEnvLookup();\n\n/**\n * Create an injectable env for commands that accept a fake env in tests.\n * Pass `input.env` when available, falls back to `process.env`.\n */\nexport function makeEnv(source?: Record<string, string | undefined>) {\n\treturn createEnvLookup(source);\n}\n","/**\n * Keyring-backed bootstrap credential store.\n *\n * Every holocron plugin's bootstrap token (the one it needs before it\n * can talk to its vendor's API) can be stored in the OS keyring under\n * a single reverse-DNS service scope. Managed via `holocron auth`\n * subcommands; consulted at position 4 in every plugin's auth\n * precedence chain (after --token / HOLOCRON_<X>_TOKEN / <native>_TOKEN).\n *\n * See `docs/wiki/specifications/tech-auth-bootstrap.spec.md` for the design rationale.\n *\n * Failure model: keyring access is best-effort. Platforms without a\n * supported credential store (some Linux CI images, sandboxed\n * environments) will throw from the underlying library. Every export\n * here catches and returns a null/empty result rather than propagating\n * — the plugin's precedence chain then falls through to\n * env-var-only paths, which is exactly how CI is meant to work.\n */\n\nimport { Entry, findCredentials } from \"@napi-rs/keyring\";\n\nconst SERVICE = \"com.theholocron.cli\";\n\n/**\n * Store or overwrite a bootstrap token for a provider. Returns true on\n * success, false when the underlying keyring is unsupported or errored.\n */\nexport function setToken(provider: string, token: string): boolean {\n\ttry {\n\t\tnew Entry(SERVICE, provider).setPassword(token);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Read the bootstrap token for a provider. Returns `null` for both\n * \"not stored\" and \"keyring unavailable\" — callers can treat them the\n * same way (fall through to env-var precedence).\n */\nexport function getToken(provider: string): string | null {\n\ttry {\n\t\treturn new Entry(SERVICE, provider).getPassword();\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Delete a stored token. Returns true when a token was removed, false\n * when there was nothing to delete or the keyring is unavailable.\n * Distinguishing the two cases isn't worth the surface area — the\n * command output makes the situation clear either way.\n */\nexport function deleteToken(provider: string): boolean {\n\ttry {\n\t\treturn new Entry(SERVICE, provider).deletePassword();\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * List provider slugs with a stored token in this service scope.\n * Uses the library's `findCredentials(service)` — supported on all\n * platforms the underlying credential store supports.\n */\nexport function listStoredProviders(): string[] {\n\ttry {\n\t\treturn findCredentials(SERVICE).map((c) => c.account);\n\t} catch {\n\t\treturn [];\n\t}\n}\n","// Re-exported from @theholocron/http — the canonical home for HTTP primitives.\n// createResolveToken is wrapped here to inject the keyring backend so plugins\n// don't need to pass it explicitly.\nimport {\n\tAuthError,\n\tcreateResolveToken as _createResolveToken,\n\ttype ResolveTokenConfig as _ResolveTokenConfig,\n\ttype ResolveTokenInput,\n} from \"@theholocron/http-client\";\n\nimport { makeEnv } from \"../env.js\";\nimport { getToken as getKeyringToken } from \"./keyring.js\";\n\nexport { AuthError, type ResolveTokenInput };\n\nexport type ResolveTokenConfig = Omit<_ResolveTokenConfig, \"getKeyringToken\">;\n\n/** Wraps `createResolveToken` from `@theholocron/http` and injects the\n * system keyring so plugins stay at a one-liner call site. */\nexport function createResolveToken(config: ResolveTokenConfig): (input?: ResolveTokenInput) => string {\n\treturn _createResolveToken({ ...config, getKeyringToken });\n}\n\nexport interface FeatureResolverConfig {\n\t/** Env var name for this feature, e.g. `\"HOLOCRON_ISSUES_TOKEN\"`. */\n\tenvName: string;\n\t/** Keyring account key, e.g. `\"github.issues\"`. */\n\tkeyringKey: string;\n}\n\n/**\n * Build a strict, single-feature token resolver.\n *\n * Resolution chain: `--token flag → envName env var → keyring(keyringKey)`.\n * No broad-token fallback — if the feature-specific token is absent the\n * operation fails with a message naming the exact env var to set.\n */\nexport function createFeatureResolver(config: FeatureResolverConfig): (input?: ResolveTokenInput) => string {\n\treturn function resolveFeatureToken(input: ResolveTokenInput = {}): string {\n\t\tconst env = makeEnv(input.env);\n\t\tconst keyring = input.keyring ?? getKeyringToken;\n\t\tconst token = input.cliToken || env.get(config.envName) || keyring(config.keyringKey);\n\t\tif (!token) {\n\t\t\tthrow new AuthError(\n\t\t\t\t`no GitHub token found for this operation. Pass --token <PAT>, ` +\n\t\t\t\t\t`set ${config.envName}, or run: holocron auth set ${config.keyringKey} <PAT>`\n\t\t\t);\n\t\t}\n\t\treturn token;\n\t};\n}\n","export class TokenParseError extends Error {\n\toverride name = \"TokenParseError\";\n}\n\nexport interface ParsedTokenArgs {\n\t/** Set when a bare (unkeyed) --token value was passed. Used as fallback for all plugins. */\n\tcliToken?: string;\n\t/** Set when one or more vendor=value pairs were passed. */\n\tcliTokens?: Record<string, string>;\n}\n\n/**\n * Converts raw --token CLI values into a typed result.\n *\n * Bare form: --token ghp_xxx → { cliToken: \"ghp_xxx\" }\n * Keyed form: --token github=ghp_xxx → { cliTokens: { github: \"ghp_xxx\" } }\n * Mixed: --token github=ghp_xxx --token v_yyy\n * → { cliToken: \"v_yyy\", cliTokens: { github: \"ghp_xxx\" } }\n *\n * Values may contain \"=\" (e.g. base64 strings) — only the first \"=\" is treated as a separator.\n */\nexport function parseTokenArgs(tokens: string[]): ParsedTokenArgs {\n\tif (tokens.length === 0) return {};\n\n\tconst cliTokens: Record<string, string> = {};\n\tconst bare: string[] = [];\n\n\tfor (const raw of tokens) {\n\t\tconst eqIdx = raw.indexOf(\"=\");\n\n\t\tif (eqIdx === -1) {\n\t\t\tbare.push(raw);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst vendor = raw.slice(0, eqIdx);\n\t\tconst value = raw.slice(eqIdx + 1);\n\n\t\tif (vendor.trim() === \"\") {\n\t\t\tthrow new TokenParseError(`invalid --token value \"${raw}\": vendor name must not be empty`);\n\t\t}\n\t\tif (/\\s/.test(vendor)) {\n\t\t\tthrow new TokenParseError(`invalid --token value \"${raw}\": vendor name must not contain whitespace`);\n\t\t}\n\t\tif (value === \"\") {\n\t\t\tthrow new TokenParseError(`invalid --token value \"${raw}\": token value must not be empty`);\n\t\t}\n\n\t\tcliTokens[vendor] = value;\n\t}\n\n\tif (bare.length > 1) {\n\t\tthrow new TokenParseError(\n\t\t\t`only one bare --token value is allowed; got ${bare.length.toString()} — use vendor=value form for multiple tokens`\n\t\t);\n\t}\n\n\tconst result: ParsedTokenArgs = {};\n\tif (bare.length === 1) result.cliToken = bare[0];\n\tif (Object.keys(cliTokens).length > 0) result.cliTokens = cliTokens;\n\treturn result;\n}\n","/**\n * Capability interfaces — the contracts that providers implement.\n *\n * Each capability has a stable key (`'source'`, `'ci'`, …) and a\n * cardinality (`'single'` = one provider; `'many'` = several active\n * at once). The cardinality is part of the type contract via\n * `CardinalityFor<K>` so config resolution + command code can branch\n * statically.\n *\n * See `docs/wiki/specifications/tech-architecture.spec.md` for the design narrative\n * (issue: #74).\n */\n\nexport type CapabilityKey =\n\t| \"source\"\n\t| \"ci\"\n\t| \"secrets\"\n\t| \"environments\"\n\t| \"issues\"\n\t| \"deployment\"\n\t| \"storage\"\n\t| \"auth\"\n\t| \"vault\"\n\t| \"dns\"\n\t| \"tooling\"\n\t| \"notifications\"\n\t| \"analytics\"\n\t| \"errors\"\n\t| \"logs\"\n\t| \"wiki\"\n\t| \"workers\";\n\nexport type Cardinality = \"single\" | \"many\";\n\nexport const CARDINALITY = {\n\tsource: \"single\",\n\tci: \"single\",\n\tsecrets: \"single\",\n\tenvironments: \"single\",\n\tissues: \"single\",\n\tdeployment: \"single\",\n\tstorage: \"single\",\n\tauth: \"single\",\n\tvault: \"single\",\n\tdns: \"single\",\n\ttooling: \"many\",\n\tnotifications: \"many\",\n\tanalytics: \"many\",\n\terrors: \"single\",\n\tlogs: \"single\",\n\twiki: \"single\",\n\tworkers: \"single\",\n} as const satisfies Record<CapabilityKey, Cardinality>;\n\n/**\n * No capabilities are strictly required — repos without secrets (e.g. org\n * community health repos) legitimately omit vault. Plugins validate their\n * own requirements at call time.\n */\nexport const REQUIRED_CAPABILITIES: readonly CapabilityKey[] = [] as const;\n\n// ───────────────────────────────────────────────────────────────────────\n// Common shapes\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface ProviderIdentity {\n\treadonly key: CapabilityKey;\n\treadonly providerName: string;\n}\n\nexport { ProviderApiError } from \"@theholocron/http-client\";\n\n// ───────────────────────────────────────────────────────────────────────\n// source — repos, branches, PRs, rulesets, settings, workflow files\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface Ruleset {\n\tid: number;\n\tname: string;\n\tenforcement: \"active\" | \"evaluate\" | \"disabled\";\n\ttarget?: string;\n}\n\nexport interface RepoSettings {\n\tallow_squash_merge?: boolean;\n\tallow_merge_commit?: boolean;\n\tallow_rebase_merge?: boolean;\n\tallow_auto_merge?: boolean;\n\t/** Always suggest updating PR branches when the base branch has new commits. */\n\tallow_update_branch?: boolean;\n\tdelete_branch_on_merge?: boolean;\n\tdefault_branch?: string;\n\thas_issues?: boolean;\n\thas_discussions?: boolean;\n\thas_projects?: boolean;\n\thas_wiki?: boolean;\n}\n\nexport interface RepoRef {\n\towner: string;\n\tname: string;\n\tdefaultBranch: string;\n}\n\nexport interface LabelDef {\n\treadonly name: string;\n\treadonly color: string;\n\treadonly description: string;\n}\n\nexport type TeamPermission = \"pull\" | \"triage\" | \"push\" | \"maintain\" | \"admin\";\n\n/** Shorthand `\"slug\"` defaults to `push` permission. */\nexport type TeamEntry = string | { slug: string; permission: TeamPermission };\n\nexport interface Source extends ProviderIdentity {\n\treadonly key: \"source\";\n\n\t/** Auth sanity-check. Throws ProviderApiError on auth failure. */\n\twhoami(): Promise<{ login: string }>;\n\n\tgetRepo(): Promise<RepoRef>;\n\n\t// Rulesets / branch protection\n\tlistRulesets(): Promise<Ruleset[]>;\n\tcreateRuleset(payload: Record<string, unknown>): Promise<Ruleset>;\n\tupdateRuleset(id: number, payload: Record<string, unknown>): Promise<Ruleset>;\n\n\t// Repo settings\n\tupdateRepoSettings(settings: RepoSettings): Promise<void>;\n\n\t/**\n\t * Classic branch protection — fallback for private repos on free plans\n\t * where the Rulesets API (requires Team+) returns 403.\n\t */\n\tprotectBranch(branch: string, payload: Record<string, unknown>): Promise<void>;\n\n\t// Security toggles (idempotent; flip-or-noop)\n\tenableVulnerabilityAlerts(): Promise<void>;\n\tenableAutomatedSecurityFixes(): Promise<void>;\n\tenableSecretScanning(): Promise<void>;\n\tenablePrivateVulnerabilityReporting(): Promise<void>;\n\t/**\n\t * Enables the dependency graph and automatic dependency snapshot\n\t * submission. Also enables secret-scanning validity checks and\n\t * non-provider pattern detection — these require GitHub Advanced\n\t * Security at the org level; the call is accepted but may be a no-op\n\t * until that is configured.\n\t */\n\tenableDependencyGraph(): Promise<void>;\n\n\t/**\n\t * Enables CodeQL default setup with the extended query suite and\n\t * `threat_model: all` (scans both remote and local exploit paths).\n\t * Triggers a new analysis run; returns the run id.\n\t */\n\tenableCodeScanning(): Promise<string>;\n\n\t/**\n\t * Disables CodeQL default setup. Required when the repo uses an advanced\n\t * CodeQL workflow instead — GitHub rejects SARIF from advanced workflows\n\t * while default setup is active.\n\t */\n\tdisableDefaultCodeScanning(): Promise<void>;\n\n\t// Workflow files — local YAML files in `.github/workflows/` (or\n\t// equivalent). These are conceptually repo content; providers may\n\t// throw `NotImplementedError` if the underlying VCS has no notion\n\t// of declarative CI files.\n\tlistWorkflowFiles(): Promise<string[]>;\n\treadWorkflowFile(name: string): Promise<string | null>;\n\twriteWorkflowFile(name: string, contents: string): Promise<void>;\n\tremoveWorkflowFile(name: string): Promise<void>;\n\n\t/**\n\t * Write an arbitrary file relative to the repo root. Used for\n\t * provisioning config files that live outside `.github/workflows/`\n\t * (e.g. `.github/dependabot.yml`).\n\t */\n\twriteRepoFile(path: string, contents: string): Promise<void>;\n\n\t/**\n\t * Idempotently sync repo labels to a canonical set. Creates missing\n\t * labels, patches color/description drift, deletes stale labels.\n\t * Optional — providers that have no label concept omit this.\n\t */\n\tsyncLabels?(canonical: ReadonlyArray<LabelDef>, stale: ReadonlyArray<string>): Promise<string>;\n\n\t/**\n\t * Set org-level custom property values on the repo. `string[]` for\n\t * `multi_select` properties, plain `string` for everything else.\n\t * Optional — providers that don't support custom properties omit this.\n\t */\n\tsyncProperties?(values: Record<string, string | string[]>): Promise<string>;\n\n\t/**\n\t * Replace the repo's topic set with the supplied list.\n\t * Optional — providers that don't support topics omit this.\n\t */\n\tsyncTopics?(topics: string[]): Promise<string>;\n\n\t/**\n\t * Sync GitHub team repository access. String shorthand defaults to `push`.\n\t * Optional — providers without a team concept omit this.\n\t */\n\tsyncTeams?(teams: TeamEntry[]): Promise<string>;\n\n\t/**\n\t * Set the repository description.\n\t * Optional — providers that don't support setting descriptions omit this.\n\t */\n\tsyncDescription?(description: string): Promise<string>;\n\n\t/**\n\t * Set the repository homepage URL (the \"Website\" field on the repo landing page).\n\t * Optional — providers that don't support setting a homepage omit this.\n\t */\n\tsyncHomepage?(homepage: string): Promise<string>;\n\n\t/**\n\t * Fetch a pull request by number. The `repo` override lets callers look up\n\t * a PR in a different repo than the one the plugin is scoped to — useful\n\t * when the cleanup command targets another repo's PR (e.g. docs PR from\n\t * the holocron repo context).\n\t * Optional — providers without a PR concept omit this.\n\t */\n\tgetPullRequest?(number: number, repo?: string): Promise<PullRequest>;\n\n\t/**\n\t * Enable or update GitHub Pages for the repository.\n\t * Idempotent: POST to create, PUT to update existing settings.\n\t * Requires HOLOCRON_DEPLOY_TOKEN (pages:write + repo scope) — passed\n\t * explicitly because it is a different PAT from the main admin token.\n\t * Optional — providers without a Pages concept omit this.\n\t */\n\tconfigurePages?(config: PagesConfig, token: string): Promise<void>;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// Pages\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface PagesConfig {\n\t/** GitHub Pages build source. */\n\tbuild: \"workflow\" | \"branch\";\n\t/**\n\t * Custom domain / CNAME (e.g. \"docs.theholocron.dev\").\n\t * When set and `homepage` is absent in holocron.config, setup derives\n\t * homepage as `https://{domain}/`.\n\t */\n\tdomain?: string;\n\t/** Enforce HTTPS. Only effective once the custom domain is DNS-verified. */\n\thttps?: boolean;\n}\n\nexport interface PullRequest {\n\tnumber: number;\n\ttitle: string;\n\t/** \"open\" | \"closed\" — GitHub marks merged PRs as \"closed\". */\n\tstate: \"open\" | \"closed\";\n\t/** True when the PR was merged (as opposed to closed without merging). */\n\tmerged: boolean;\n\t/** The head branch name (e.g. \"fix/my-change\"). */\n\tbranch: string;\n\turl: string;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// ci — workflow runs (history + status only)\n// ───────────────────────────────────────────────────────────────────────\n\nexport type CiRunStatus = \"queued\" | \"in_progress\" | \"completed\" | \"cancelled\" | \"failure\" | \"success\" | \"skipped\";\n\nexport interface CiRun {\n\tid: string | number;\n\tworkflowName: string;\n\tbranch: string;\n\tsha: string;\n\tstatus: CiRunStatus;\n\turl: string;\n\tstartedAt: string;\n\tcompletedAt?: string;\n}\n\nexport interface CiRunFilter {\n\tbranch?: string;\n\tstatus?: CiRunStatus;\n\tlimit?: number;\n}\n\nexport interface Ci extends ProviderIdentity {\n\treadonly key: \"ci\";\n\tlistRuns(filter?: CiRunFilter): Promise<CiRun[]>;\n\tgetRun(id: string | number): Promise<CiRun>;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// secrets — CI/platform secrets sync destination (multi-scope)\n// ───────────────────────────────────────────────────────────────────────\n\nexport type SecretScope =\n\t{ kind: \"repo\" } | { kind: \"environment\"; name: string } | { kind: \"organization\"; name: string };\n\nexport interface Secrets extends ProviderIdentity {\n\treadonly key: \"secrets\";\n\n\t/** List secret NAMES (not values) at the given scope. */\n\tlistSecrets(scope: SecretScope): Promise<string[]>;\n\n\t/** Idempotent upsert. Adapter handles encryption. */\n\tsetSecret(scope: SecretScope, name: string, value: string): Promise<void>;\n\n\tdeleteSecret(scope: SecretScope, name: string): Promise<void>;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// environments — named deployment environments\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface EnvironmentReviewer {\n\ttype: \"User\" | \"Team\";\n\t/** Numeric id — GitHub's reviewer API silently ignores login strings. */\n\tid: number;\n}\n\nexport interface Environment {\n\tname: string;\n\treviewers?: EnvironmentReviewer[];\n\twaitTimer?: number;\n\tpreventSelfReview?: boolean;\n}\n\nexport interface Environments extends ProviderIdentity {\n\treadonly key: \"environments\";\n\tlistEnvironments(): Promise<Environment[]>;\n\tupsertEnvironment(env: Environment): Promise<void>;\n\tdeleteEnvironment(name: string): Promise<void>;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// issues — tracker\n// ───────────────────────────────────────────────────────────────────────\n\nexport type LifecycleSlot = \"inProgress\" | \"inReview\" | \"done\";\n\nexport type StatusCategory = \"open\" | \"in-progress\" | \"in-review\" | \"done\" | \"other\";\n\nexport interface TrackerUser {\n\tid: string;\n\tdisplayName: string;\n\temailAddress?: string;\n}\n\nexport interface Issue {\n\t/** Human-readable key — \"#42\" for GitHub, \"RANDO-42\" for Jira. */\n\tkey: string;\n\t/** Internal opaque id. */\n\tid: string;\n\tsummary: string;\n\tbody?: string;\n\tstatus: string;\n\tstatusCategory: StatusCategory;\n\tassignee: TrackerUser | null;\n\tupdated: string;\n\turl?: string;\n}\n\nexport interface IssueSearchFilter {\n\t/** Restrict to issues assigned to a specific id, or 'currentUser'. */\n\tassignee?: string | \"currentUser\";\n\t/** Exclude issues in the `done` category. */\n\topenOnly?: boolean;\n\t/** Max number of issues to return. Adapters apply a sensible default. */\n\tlimit?: number;\n}\n\nexport interface LifecycleResult {\n\t/** False when no API write happened (already at target state). */\n\ttransitioned: boolean;\n\t/** Status name the issue is in after this call. */\n\tstatus: string;\n\t/** Adapter-specific note (e.g., \"label set\" / \"closed (completed)\"). */\n\tvia?: string;\n}\n\nexport interface TrackerDoctorReport {\n\t/** \"Authenticated as ...\" subject for the spinner. */\n\tauthedAs: string;\n\t/** Free-form \"Project: RANDO\" / \"Repo: rando-id/rando\" identifier. */\n\tprojectLabel: string;\n\t/** Status values the adapter exposes. */\n\tstatuses: Array<{ name: string; category: StatusCategory }>;\n\t/**\n\t * Per-lifecycle-slot readiness check. `resolved` indicates whether\n\t * the configured value actually maps to something the tracker\n\t * recognizes; the `note` is the rendered explanation.\n\t */\n\tlifecycle: Array<{\n\t\tslot: LifecycleSlot;\n\t\tvalue: string | null;\n\t\tresolved: boolean;\n\t\tnote: string;\n\t}>;\n}\n\nexport interface Issues extends ProviderIdentity {\n\treadonly key: \"issues\";\n\n\t/** Currently-authenticated user. */\n\tgetMyself(): Promise<TrackerUser>;\n\n\tsearch(filter: IssueSearchFilter): Promise<Issue[]>;\n\tget(key: string): Promise<Issue>;\n\n\tcreate(input: {\n\t\tsummary: string;\n\t\tbody?: string;\n\t\tlabels?: string[];\n\t\t/** Numeric id or exact title (case-insensitive). */\n\t\tmilestone?: string;\n\t}): Promise<{ key: string }>;\n\n\t/** Idempotent — `transitioned: false` if the issue is already at the target. */\n\ttransition(key: string, slot: LifecycleSlot): Promise<LifecycleResult>;\n\n\tcomment(key: string, body: string): Promise<void>;\n\n\tdoctor(): Promise<TrackerDoctorReport>;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// deployment — preview/prod deploy targets\n// ───────────────────────────────────────────────────────────────────────\n\n/** Env-var scope on the deploy platform. */\nexport type DeploymentTarget = \"development\" | \"preview\" | \"production\";\n\n/**\n * Named deployment trigger target — `undefined` means a branch\n * preview (no named environment).\n */\nexport type DeploymentTrigger = \"production\" | \"staging\";\n\nexport interface DeploymentProject {\n\tid: string;\n\tname: string;\n\tframework?: string;\n\t/** True when the project is linked to a Git provider. */\n\tgitLinked?: boolean;\n\trootDirectory?: string | null;\n}\n\nexport interface DeploymentProjectSettings {\n\tpreviewDeploymentsDisabled?: boolean;\n\t/** Vercel-specific: whether the GitHub integration creates deployments\n\t * for every push (false → only on-demand triggers). */\n\tgitProviderCreateDeployments?: boolean;\n}\n\nexport interface DeploymentRecord {\n\tid: string;\n\turl: string;\n\t/** Branch this deployment was made from (null if not git-sourced). */\n\tbranch: string | null;\n\t/** Named environment if one was targeted; undefined for branch previews. */\n\ttarget?: DeploymentTrigger;\n\tstatus: \"queued\" | \"building\" | \"ready\" | \"error\" | \"cancelled\";\n\tcreatedAt?: string;\n}\n\n/** Config for `Deployment.deployFunction()` — source files, not a Git ref. */\nexport interface DeployFunctionConfig {\n\t/**\n\t * Files to deploy, keyed by path relative to the project root (e.g.\n\t * `\"api/webhook.js\"`, `\"package.json\"`). Content is plain text — the\n\t * provider handles any wire-format encoding.\n\t */\n\tfiles: Record<string, string>;\n\t/**\n\t * Named deployment target. Omit for a preview deployment — same\n\t * semantics as `triggerDeployment`'s `target`.\n\t */\n\ttarget?: DeploymentTrigger;\n}\n\nexport interface DeployFunctionResult {\n\tdeploymentId: string;\n\turl: string;\n}\n\nexport interface Deployment extends ProviderIdentity {\n\treadonly key: \"deployment\";\n\t/**\n\t * Custom domain declared in the deployment provider's configuration.\n\t * `holocron setup` attaches it to the configured project and hands any\n\t * returned verification record to the `dns` capability.\n\t */\n\treadonly domain?: string;\n\n\tlistProjects(): Promise<DeploymentProject[]>;\n\t/** Create if missing, otherwise return existing. Idempotent. */\n\tensureProject(input: {\n\t\tname: string;\n\t\tframework?: string;\n\t\t/** \"owner/repo\" — passed when linking to a Git provider. */\n\t\trepo?: string;\n\t\trootDirectory?: string;\n\t}): Promise<DeploymentProject>;\n\n\tupdateProjectSettings(projectId: string, settings: DeploymentProjectSettings): Promise<DeploymentProject>;\n\n\t// Env vars on the deploy platform (Vercel-style: per-target).\n\tlistEnvVars(projectId: string, target: DeploymentTarget): Promise<string[]>;\n\tsetEnvVar(projectId: string, target: DeploymentTarget, name: string, value: string): Promise<void>;\n\n\t/**\n\t * Kick off a deployment of the given branch. Omit `target` for a\n\t * branch preview; pass `'production'` / `'staging'` to deploy into\n\t * a named environment.\n\t */\n\ttriggerDeployment(input: {\n\t\tprojectId: string;\n\t\tbranch: string;\n\t\ttarget?: DeploymentTrigger;\n\t}): Promise<DeploymentRecord>;\n\n\tgetDeployment(deploymentId: string): Promise<DeploymentRecord>;\n\n\t/**\n\t * Deploy (or update) a project directly from source files, bypassing\n\t * Git entirely — the non-git counterpart to `triggerDeployment`, for a\n\t * consumer with no repo to link (a webhook receiver shipped as an npm\n\t * package, for instance, rather than deployed from its own Git\n\t * history). `projectId` may be a project name for providers that\n\t * accept either. Optional — providers without a files-based deploy API\n\t * omit this (e.g. Cloudflare Pages, git-source only today).\n\t */\n\tdeployFunction?(projectId: string, config: DeployFunctionConfig): Promise<DeployFunctionResult>;\n\n\t/**\n\t * List preview deployments for a specific branch alias (e.g. \"repo-pr-42\").\n\t * Optional — providers that don't support listing by branch omit this.\n\t */\n\tlistPreviewDeployments?(projectId: string, branch: string): Promise<DeploymentRecord[]>;\n\n\t/**\n\t * Delete specific preview deployments by id. Returns the count deleted.\n\t * Optional — providers that don't support deletion omit this.\n\t */\n\tdeletePreviewDeployments?(projectId: string, deploymentIds: string[]): Promise<number>;\n\n\t/**\n\t * Add a custom domain (or wildcard) to the project. Idempotent — no-op\n\t * when the domain is already present. Optional: providers without a\n\t * custom domain API omit this.\n\t *\n\t * Returns the DNS record needed to finish verification — `null` when\n\t * the domain is already verified, or when the provider's API doesn't\n\t * surface DNS-challenge details at all (e.g. Cloudflare Pages, whose\n\t * custom-domain flow doesn't expose the same per-request verification\n\t * handshake Vercel's does). Callers hand a non-null result straight\n\t * to `dns.upsertRecord(result.zone, result.record)` — the exact\n\t * pattern `setup` already uses for `Wiki.dnsRecord()`.\n\t */\n\tensureCustomDomain?(projectId: string, hostname: string): Promise<DnsRecordRequest | null>;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// storage — DB / object / file store\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface StorageBranch {\n\tid: string;\n\tname: string;\n\t/** Parent branch id; null for the root/main branch. */\n\tparentId: string | null;\n\tcreatedAt: string;\n}\n\nexport interface ConnectionStringOptions {\n\t/** Use the pooled (PgBouncer) URL when available. Defaults to false. */\n\tpooled?: boolean;\n}\n\nexport interface Storage extends ProviderIdentity {\n\treadonly key: \"storage\";\n\n\t/**\n\t * Connection string for the given scope. Scope is provider-specific:\n\t *\n\t * - branch-based providers (Neon, PlanetScale): scope = branch\n\t * name or id\n\t * - flat providers (single Postgres instance): scope is ignored\n\t *\n\t * Callers (or the orchestrator) decide how a deploy target maps to\n\t * a scope; the storage plugin doesn't own that mapping.\n\t */\n\tgetConnectionString(scope: string, options?: ConnectionStringOptions): Promise<string>;\n\n\t// Branch operations (optional — flat providers can omit).\n\tlistBranches?(): Promise<StorageBranch[]>;\n\tcreateBranch?(input: { name: string; from?: string }): Promise<StorageBranch>;\n\tdestroyBranch?(branch: string): Promise<void>;\n\t/** Restore one branch to match another (e.g., reset preview → main). */\n\tresetBranch?(input: { branch: string; from: string }): Promise<void>;\n\n\t/**\n\t * Provider-specific feature toggle. For Postgres providers this is\n\t * `CREATE EXTENSION IF NOT EXISTS ...` per branch.\n\t */\n\tenableExtension?(input: { branch: string; extension: string }): Promise<void>;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// auth — identity provider\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface AuthDescription {\n\tprovider: string;\n\t/** Env-var names the app needs at runtime (CLERK_PUBLISHABLE_KEY, etc.). */\n\tenvKeys: string[];\n}\n\nexport interface AuthIdentity {\n\tprovider: string;\n\t/** Provider-specific health signal (user count, role, account name, etc.). */\n\tdetails?: Record<string, unknown>;\n}\n\nexport interface AuthUser {\n\tid: string;\n\temail: string;\n}\n\nexport interface CreateAuthUserInput {\n\temail: string;\n\tpassword: string;\n\tfirstName?: string;\n\tlastName?: string;\n}\n\nexport interface WebhookDashboardInfo {\n\turl: string;\n}\n\nexport interface Auth extends ProviderIdentity {\n\treadonly key: \"auth\";\n\n\t/** Env-var keys the runtime app needs. */\n\tdescribe(): Promise<AuthDescription>;\n\n\t/** Reachability probe — proves the configured key works. */\n\twhoami(): Promise<AuthIdentity>;\n\n\t// Optional capabilities — providers implement what they support.\n\n\t/** Idempotent webhook backend provisioning (Clerk: Svix app). */\n\tensureWebhookApp?(): Promise<{ alreadyExists: boolean }>;\n\n\t/** Deep-link to the provider's webhook config dashboard. */\n\tgetWebhookDashboardUrl?(): Promise<WebhookDashboardInfo>;\n\n\t/** Seed a user (test fixtures, admin bootstrap). */\n\tcreateUser?(input: CreateAuthUserInput): Promise<AuthUser>;\n\n\t/** Wire the auth provider's webhook into the project's repo. */\n\tsyncWebhook?(input: { repo: string; secretRef: string }): Promise<void>;\n}\n\n// ── Normalized webhook events (cross-provider sync) ──────────────────\n//\n// Plugins implementing `auth` may also expose a `parseWebhook` utility\n// (NOT a capability method — exported alongside the plugin's\n// createPlugin) that translates the vendor's webhook payload into one\n// of these normalized event shapes. Your app's webhook handler then\n// reads the normalized event and is vendor-agnostic:\n//\n// import { parseWebhook } from '@theholocron/holocron-plugin-clerk'\n// import type { AuthEvent } from '@theholocron/cli'\n//\n// app.post('/webhooks/clerk', async (req) => {\n// const event: AuthEvent = await parseWebhook({\n// body: req.body,\n// headers: req.headers,\n// signingSecret: process.env.CLERK_WEBHOOK_SECRET!,\n// })\n// await db.users.upsert(event.user)\n// })\n//\n// Swap clerk for another auth plugin → change one import line; the\n// handler logic stays the same.\n\nexport type AuthEventType = \"user.created\" | \"user.updated\" | \"user.deleted\";\n\nexport interface NormalizedAuthUser {\n\tid: string;\n\temail: string;\n\tfirstName?: string | null;\n\tlastName?: string | null;\n\t/** Provider-native fields preserved verbatim for consumers that need them. */\n\traw?: Record<string, unknown>;\n}\n\nexport interface AuthEvent {\n\ttype: AuthEventType;\n\tuser: NormalizedAuthUser;\n\t/** ISO timestamp of when the event occurred. */\n\toccurredAt: string;\n}\n\nexport interface ParseWebhookInput {\n\t/** Raw request body (string or Buffer). */\n\tbody: string | Buffer;\n\t/** Incoming HTTP headers — needed for signature verification. */\n\theaders: Record<string, string | string[] | undefined>;\n\t/** The signing secret the auth provider issued for this webhook endpoint. */\n\tsigningSecret: string;\n}\n\nexport class WebhookVerificationError extends Error {\n\toverride name = \"WebhookVerificationError\";\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// vault — REQUIRED source-of-truth for secrets\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface EnsureResult {\n\t/** True when the resource already existed (idempotent no-op). */\n\talreadyExists: boolean;\n}\n\nexport interface Vault extends ProviderIdentity {\n\treadonly key: \"vault\";\n\n\t/**\n\t * Read a secret by reference. The reference format is\n\t * provider-specific (1P: \"op://Vault/Item/field\"; HashiCorp Vault:\n\t * \"kv/path#field\"; etc.). Adapters validate the reference shape.\n\t */\n\tread(reference: string): Promise<string>;\n\n\t/** Write or update a secret. */\n\twrite(reference: string, value: string): Promise<void>;\n\n\t/** List secret keys available to the project. */\n\tlist(): Promise<string[]>;\n\n\t/**\n\t * Optional environment notion within the vault (e.g., 1P\n\t * Environments — named KEY=VALUE bundles). Adapters without\n\t * environments return [].\n\t */\n\tenvironments?(): Promise<string[]>;\n\n\t/**\n\t * Optional bulk read of an environment's KEY=VALUE pairs. Powers\n\t * the `holocron secrets sync` flow where the orchestrator pulls a\n\t * whole environment from the vault then fans the values out to\n\t * destinations (CI secrets, deployment env vars, local .env).\n\t */\n\treadEnvironment?(environmentId: string): Promise<Record<string, string>>;\n\n\t/**\n\t * Optional — create the top-level project container in the vault\n\t * if it does not exist. Idempotent: `alreadyExists: true` when the\n\t * project was already there. Providers whose data model has no\n\t * project notion (or that gate this behind a paid tier) omit this.\n\t */\n\tensureProject?(name: string): Promise<EnsureResult>;\n\n\t/**\n\t * Optional — create a named environment/config inside a project\n\t * (e.g., Doppler config `dev` / `stg` / `prd`). Idempotent.\n\t * Providers whose data model has a single flat namespace omit this.\n\t */\n\tensureEnvironment?(project: string, name: string): Promise<EnsureResult>;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// dns — DNS record management\n// ───────────────────────────────────────────────────────────────────────\n\nexport type DnsRecordType = \"A\" | \"AAAA\" | \"CNAME\" | \"TXT\" | \"MX\" | \"NS\" | \"SRV\" | \"CAA\";\n\nexport interface DnsRecord {\n\tid?: string;\n\ttype: DnsRecordType;\n\tname: string;\n\tcontent: string;\n\tttl?: number;\n\tpriority?: number;\n\tproxied?: boolean;\n}\n\n/**\n * A DNS record a capability wants created, plus which zone it belongs\n * to — the shape `Wiki.dnsRecord()` and `Deployment.ensureCustomDomain()`\n * both hand off to `Dns.upsertRecord()`. Not tied to either capability;\n * any provider that needs \"here's a record, go create it\" returns this.\n */\nexport interface DnsRecordRequest {\n\t/** Zone apex passed as the first argument to `dns.upsertRecord`. */\n\tzone: string;\n\trecord: DnsRecord;\n}\n\nexport interface Dns extends ProviderIdentity {\n\treadonly key: \"dns\";\n\tlistRecords(domain: string): Promise<DnsRecord[]>;\n\tupsertRecord(domain: string, record: DnsRecord): Promise<DnsRecord>;\n\tdeleteRecord(domain: string, id: string): Promise<void>;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// errors — error tracking / crash reporting\n// logs — structured log aggregation\n//\n// Both are self-contained: they activate at runtime from env vars alone\n// (`HOLOCRON_SENTRY_DSN`, `HOLOCRON_AXIOM_TOKEN` + `HOLOCRON_AXIOM_DATASET`)\n// with no provider entry in `holocron.config`. The provider entry only\n// enables `holocron setup` provisioning and `holocron doctor` checks.\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface Errors extends ProviderIdentity {\n\treadonly key: \"errors\";\n\t/** Returns the env var names the app reads at runtime for this provider. */\n\tdescribe(): Promise<{ provider: string; envKeys: string[] }>;\n\twhoami?(): Promise<{ org: string }>;\n\tensureProject?(input: { name: string; platform?: string }): Promise<{ dsn: string; alreadyExists: boolean }>;\n}\n\nexport interface Logs extends ProviderIdentity {\n\treadonly key: \"logs\";\n\t/** Returns the env var names the app reads at runtime for this provider. */\n\tdescribe(): Promise<{ provider: string; envKeys: string[] }>;\n\t/** Verify the token by fetching the target dataset's info. */\n\twhoami?(): Promise<{ ok: boolean; dataset: string }>;\n\t/** Create the aggregation dataset if it does not already exist. Idempotent. */\n\tensureDataset?(name: string): Promise<{ alreadyExists: boolean }>;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// Multi-provider capabilities — many can be active at once\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface ToolingDoctorReport {\n\tok: boolean;\n\tmessage: string;\n}\n\nexport interface Tooling extends ProviderIdentity {\n\treadonly key: \"tooling\";\n\n\t/** Sync the tool's authoritative state from the repo. */\n\tsync(): Promise<void>;\n\n\tdoctor(): Promise<ToolingDoctorReport>;\n}\n\nexport interface Notifications extends ProviderIdentity {\n\treadonly key: \"notifications\";\n\n\t/**\n\t * Send a message. `channel` is provider-specific (Slack channel id,\n\t * Discord webhook url-name, etc.); adapters resolve from config.\n\t */\n\tsend(channel: string, message: string): Promise<void>;\n}\n\nexport interface Analytics extends ProviderIdentity {\n\treadonly key: \"analytics\";\n\t/** Returns the env var names the app reads at runtime for this provider. */\n\tdescribe(): Promise<{ provider: string; envKeys: string[] }>;\n\twhoami?(): Promise<{ org: string }>;\n\tensureProject?(name: string): Promise<{ token: string; alreadyExists: boolean }>;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// wiki — engineering knowledge publishing platform\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface WikiProvisionOpts {\n\t/** Project display name used in the wiki title (e.g. \"Holocron\"). */\n\tname?: string;\n}\n\n/**\n * Reverse-proxy configuration returned by `Wiki.proxyConfig()`.\n * Used by `setup` to deploy a Worker that forwards traffic to the wiki\n * provider's ingress with the required headers injected.\n */\nexport interface WikiProxyConfig {\n\t/** Proxy target URL (e.g. \"https://app.buildwithfern.com\"). */\n\ttarget: string;\n\t/** Headers injected on every proxied request. */\n\theaders: Record<string, string>;\n}\n\n/**\n * Engineering wiki provider.\n *\n * A swappable provider for publishing the `docs/decisions/` and\n * `docs/engineering/` surfaces as a browsable, access-controlled site.\n * Local-only providers (fern, mintlify) write config files; remote\n * providers (github) make API calls.\n */\nexport interface Wiki extends ProviderIdentity {\n\treadonly key: \"wiki\";\n\t/** Provision the wiki — write config files or call the provider API. */\n\tprovision(opts?: WikiProvisionOpts): Promise<string>;\n\t/**\n\t * DNS record needed for the custom domain, when one is configured.\n\t * Returns null when no custom domain is set.\n\t * Called by `setup` to provision the CNAME via the `dns` capability.\n\t */\n\tdnsRecord?(): DnsRecordRequest | null;\n\t/**\n\t * Reverse-proxy config when the wiki provider requires a Worker-level\n\t * proxy in addition to the CNAME. Returns null when no proxy is needed.\n\t * Called by `setup` to deploy the proxy via the `workers` capability.\n\t */\n\tproxyConfig?(): WikiProxyConfig | null;\n}\n\n/** Config for `Workers.deployScript()` — an arbitrary Worker, not a generated reverse-proxy. */\nexport interface DeployScriptConfig {\n\t/** The full Worker script source — a single ES module (`export default { fetch(...) {...} }`). */\n\tcode: string;\n\t/**\n\t * Secret bindings — `env.<name>` in the deployed Worker. Values are\n\t * write-only; the provider never echoes them back, here or anywhere else.\n\t */\n\tsecrets?: Record<string, string>;\n\t/**\n\t * Route pattern(s) this Worker should serve (e.g.\n\t * `\"sentinel.theholocron.dev/*\"`). Omit for a Worker reached only via\n\t * its `*.workers.dev` URL.\n\t */\n\troutes?: string[];\n}\n\nexport interface DeployScriptResult {\n\t/** The deployed script's name at the provider. */\n\tscriptName: string;\n}\n\n/**\n * Edge Worker management capability.\n *\n * Deploys and manages Worker scripts. `upsertProxy` is the existing,\n * narrower case `setup` uses to wire wiki custom-domain reverse-proxies;\n * `deployScript` is the general case — any Worker, any code, its own\n * secrets — for a consumer that isn't a reverse-proxy (a webhook\n * receiver, for instance).\n */\nexport interface Workers extends ProviderIdentity {\n\treadonly key: \"workers\";\n\t/**\n\t * Deploy (or update) a reverse-proxy Worker for `hostname`.\n\t * Forwards all `hostname/*` requests to `config.target`, injecting\n\t * `config.headers` on each request.\n\t */\n\tupsertProxy(hostname: string, config: WikiProxyConfig): Promise<void>;\n\t/** Deploy (or update) an arbitrary Worker script, optionally with secrets and routes. */\n\tdeployScript(name: string, config: DeployScriptConfig): Promise<DeployScriptResult>;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// Capability map (key → implementation type) + cardinality helpers\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface CapabilityImpls {\n\tsource: Source;\n\tci: Ci;\n\tsecrets: Secrets;\n\tenvironments: Environments;\n\tissues: Issues;\n\tdeployment: Deployment;\n\tstorage: Storage;\n\tauth: Auth;\n\tvault: Vault;\n\tdns: Dns;\n\ttooling: Tooling;\n\tnotifications: Notifications;\n\tanalytics: Analytics;\n\terrors: Errors;\n\tlogs: Logs;\n\twiki: Wiki;\n\tworkers: Workers;\n}\n\nexport type CardinalityFor<K extends CapabilityKey> = (typeof CARDINALITY)[K];\n\n/** Resolved runtime shape: single → one impl; many → array. */\nexport type ResolvedCapability<K extends CapabilityKey> =\n\tCardinalityFor<K> extends \"many\" ? CapabilityImpls[K][] : CapabilityImpls[K];\n\nexport function isMulti<K extends CapabilityKey>(key: K): CardinalityFor<K> extends \"many\" ? true : false {\n\treturn (CARDINALITY[key] === \"many\") as CardinalityFor<K> extends \"many\" ? true : false;\n}\n","/**\n * `holocron.config.json` schema, parser, and provider resolution.\n *\n * ESLint-style entry forms:\n *\n * \"source\": \"github\" ← single, short\n * \"deployment\": [\"vercel\", { team: \"rando\" }] ← single, with options\n * \"notifications\": [\"slack\", \"discord\"] ← multi, short\n * \"notifications\": [\n * [\"slack\", { channel: \"#ops\" }],\n * [\"discord\", { webhook: \"env:HOOK\" }]\n * ] ← multi, with options\n *\n * Discriminator: an array entry is a `[provider, options]` tuple when\n * the length is 2 AND element[1] is a non-array, non-null object.\n * Otherwise it's a multi-provider list (string[] or tuple[]).\n *\n * Validation rules:\n * - `vault` is REQUIRED (every project has secrets somewhere)\n * - Entries for `'many'` capabilities are normalized to an array of\n * normalized tuples; entries for `'single'` capabilities are\n * normalized to one tuple\n * - Tokens / secret values never appear in config — providers read\n * them from env (or pull from `vault` at runtime)\n */\n\nimport type { LogLevel } from \"@theholocron/observability/core\";\n\nimport {\n\ttype CapabilityKey,\n\tCARDINALITY,\n\ttype PagesConfig,\n\tREQUIRED_CAPABILITIES,\n\ttype TeamEntry,\n\ttype TeamPermission,\n} from \"../plugin/capabilities.js\";\n\n/** Structured-logging config. The Axiom **token** never lives here — only in\n * env vars or the OS keyring — but the non-secret dataset name may. */\nexport interface LogConfig {\n\t/**\n\t * Default log level. The lowest-priority level source: `--verbose` /\n\t * `--quiet` and `HOLOCRON_LOG_LEVEL` both outrank it.\n\t */\n\tlevel?: LogLevel;\n\t/**\n\t * Axiom log-shipping. Set `axiom.dataset` to opt local runs into Axiom\n\t * without exporting `HOLOCRON_AXIOM_DATASET` — the CLI then pairs it with\n\t * the token from `HOLOCRON_AXIOM_TOKEN` / `AXIOM_TOKEN` or the OS keyring\n\t * (`holocron auth set axiom[.<org>] <TOKEN>`). Env vars still win. In CI,\n\t * prefer the `HOLOCRON_AXIOM_DATASET` variable.\n\t */\n\taxiom?: {\n\t\t/** Target Axiom dataset, e.g. `\"holocron-local\"`. */\n\t\tdataset?: string;\n\t};\n}\n\n/**\n * CLI self-telemetry config — the committed, reviewable override layer over the\n * env-var + shipped-fallback activation (ADR-0007 / ADR-0008). No secret lives\n * here; the Sentry DSN and PostHog key come from env vars or ship as fallbacks.\n *\n * Precedence: `HOLOCRON_TELEMETRY=false` (env) → `telemetry.enabled` (this) →\n * default on. `enabled` never *re-enables* what the env var turned off.\n */\nexport interface TelemetryConfig {\n\t/**\n\t * Repo-level opt-out — the committed peer of `HOLOCRON_TELEMETRY=false`.\n\t * `false` installs the no-op sinks for the whole run. Default on.\n\t */\n\tenabled?: boolean;\n\t/**\n\t * Usage-analytics provider. `\"none\"` disables PostHog usage analytics while\n\t * leaving error reporting (Sentry) untouched. Default `\"posthog\"`.\n\t */\n\tanalytics?: \"posthog\" | \"none\";\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// Raw config (what users write in holocron.config.json)\n// ───────────────────────────────────────────────────────────────────────\n\nexport type ProviderOptions = Record<string, unknown>;\n\n/**\n * The shape a capability config package's default export must satisfy.\n * Config packages let teams share a pre-bundled provider + options across\n * repos (Level 1 of the shareable-configs story, issue #75).\n *\n * @example\n * // @acme/holocron-vault/index.ts\n * import type { CapabilityConfigPackage } from '@theholocron/cli'\n * export default {\n * provider: '1password',\n * options: { vault: 'acme-app' },\n * } satisfies CapabilityConfigPackage\n */\nexport interface CapabilityConfigPackage {\n\tprovider: string;\n\toptions?: ProviderOptions;\n}\n\nexport type SingleEntry = string | [provider: string, options: ProviderOptions];\n\nexport type MultiEntry = Array<string | [provider: string, options: ProviderOptions]>;\n\nexport type RawProviderEntry = SingleEntry | MultiEntry;\n\nexport type RawProvidersConfig = Partial<Record<CapabilityKey, RawProviderEntry>>;\n\nexport type RepoProtection = \"balanced\" | \"strict\" | \"none\";\n\nexport type { PagesConfig, TeamEntry, TeamPermission };\n\n/**\n * Raw `docs` config as written by the user. `build` is optional so the\n * field can be declared without committing to a build type yet; setup\n * will error if `docs` is present but `build` is absent.\n */\nexport interface DocsConfig {\n\t/**\n\t * GitHub Pages build source.\n\t * \"workflow\" → GitHub Actions (PUT { build_type: \"workflow\" })\n\t * \"branch\" → classic gh-pages branch (PUT { build_type: \"legacy\", source: { branch: \"gh-pages\", path: \"/\" } })\n\t * When absent, Pages is not managed by `holocron setup`.\n\t */\n\tbuild?: \"workflow\" | \"branch\";\n\t/**\n\t * Custom domain / CNAME (e.g. \"docs.theholocron.dev\").\n\t * When set and `homepage` is not explicitly provided, setup derives\n\t * `homepage` as `https://{domain}/` for package.json and the repo website field.\n\t */\n\tdomain?: string;\n\t/** Enforce HTTPS. Only effective once the custom domain is DNS-verified. */\n\thttps?: boolean;\n}\n\nexport interface RepoProperties {\n\tlifecycle?: \"active\" | \"experimental\" | \"deprecated\";\n\topen_source?: boolean;\n\truntime_environment?: \"node\" | \"browser\" | \"universal\" | \"none\";\n\tuses_external_packages?: boolean;\n}\n\nexport interface RepoConfig {\n\t/** \"owner/name\" — the GitHub repository coordinate. Derived from the git remote when absent. */\n\tname?: string;\n\t/**\n\t * GitHub's repo-level default branch (`HEAD`) — what a fresh clone checks\n\t * out, what `gh pr create`/the compare UI target by default, and what\n\t * Sentinel's `validateConfig()` reads (D6: the App only ever reads config\n\t * from the repo's default branch, never a PR ref, as a security boundary\n\t * — never widen that to read PR branches instead of fixing this field).\n\t * Synced by `holocron setup`. Omit to leave GitHub's current setting\n\t * untouched — most repos never need this. Exists for a repo using a\n\t * `main`/`alpha` prerelease-channel split (CLAUDE.md's Releases section)\n\t * where active development happens on a non-`main` branch: set this to\n\t * that branch so Sentinel validates against what's actually being\n\t * developed, then change it back once that branch merges to `main` for a\n\t * stable cut and stops being the active branch.\n\t */\n\tdefaultBranch?: string;\n\t/**\n\t * Branch protection preset applied by `holocron setup`. When omitted,\n\t * no protection is applied and no `branch_protection_level` property is set.\n\t * Required-status-check contexts for `\"strict\"` are derived from the task\n\t * manifest — `{ required: true }` tasks + top-level `extraRequiredChecks`\n\t * (see `astromech.requiredChecks()`).\n\t */\n\tprotection?: RepoProtection;\n\t/**\n\t * GitHub teams granted repository access. Synced by `holocron setup`, which\n\t * also writes `.github/CODEOWNERS` for teams with write-or-higher permission.\n\t * String shorthand defaults to `push` (Write).\n\t */\n\tteams?: TeamEntry[];\n\t/** GitHub topics set on the repository. */\n\ttopics?: string[];\n\t/** GitHub custom properties synced to the org dashboard. */\n\tproperties?: RepoProperties;\n}\n\nexport interface AppConfig {\n\tname: string;\n\tpath: string;\n\tkind?: string;\n}\n\nexport interface DoctorConfig {\n\tchecks?: string[];\n}\n\nexport interface EnvConfig {\n\t/**\n\t * Namespace prefixes used by this project's env vars.\n\t * Listed from least- to most-specific (cascade model — last wins).\n\t * Tooling reads this to generate `.env.example`, validate required\n\t * vars, and produce documentation.\n\t *\n\t * @example\n\t * // Project-only prefix\n\t * namespaces: [\"CLI_TEMPLATE\"]\n\t *\n\t * // Org-wide defaults + project-specific overrides\n\t * namespaces: [\"HOLOCRON\", \"MY_CLI\"]\n\t */\n\tnamespaces?: string[];\n}\n\n/**\n * A single Chromatic project entry in a monorepo `run-chromatic` config.\n * Each entry produces one matrix job in CI, publishing to a separate Chromatic project.\n *\n * The `tokenName` maps to a repository secret named `CHROMATIC_PROJECT_TOKEN_<TOKENNAME>`.\n * Additional fields correspond to chromaui/action inputs and are passed through directly.\n *\n * @see https://www.chromatic.com/docs/monorepos/\n */\nexport interface ChromaticProjectConfig {\n\t/**\n\t * Secret suffix. The CI job reads `CHROMATIC_PROJECT_TOKEN_<tokenName>`.\n\t * Must be uppercase (e.g. `\"WEB\"`, `\"UI\"`).\n\t */\n\ttokenName: string;\n\t/**\n\t * Path to run the Chromatic build from, relative to the repo root.\n\t * Typically the package directory (e.g. `\"apps/web\"`, `\"packages/ui\"`).\n\t */\n\tworkingDir: string;\n\t/**\n\t * Script name to build Storybook. Defaults to `\"build:storybook\"`.\n\t * Must accept `--output-dir` pass-through (use `turbo run … --` at root).\n\t */\n\tbuildScript?: string;\n\t/**\n\t * Path to the Storybook folder relative to `workingDir`, for TurboSnap.\n\t * Tells Chromatic where to find `.storybook/` when the Storybook config\n\t * is in a subdirectory. Corresponds to `--storybook-base-dir`.\n\t */\n\tstorybookBaseDir?: string;\n\t/**\n\t * Glob patterns of files/dirs that should NOT trigger a TurboSnap bailout\n\t * when changed. Useful for ignoring non-UI changes in a monorepo\n\t * (e.g. `\"./packages/!(ui)/**\"` to focus TurboSnap on the UI package).\n\t * Corresponds to `--untraced`. Accepts a single glob string or array.\n\t */\n\tuntraced?: string | string[];\n\t/**\n\t * Glob patterns matching story files to snapshot. When set, only matching\n\t * stories are captured. Corresponds to `--only-story-files`.\n\t * Cannot be combined with `onlyStoryNames`.\n\t */\n\tonlyStoryFiles?: string;\n\t/**\n\t * Exit with code 0 even when visual changes are detected.\n\t * Useful during initial setup before baselines are approved.\n\t * Corresponds to `--exit-zero-on-changes`.\n\t */\n\texitZeroOnChanges?: boolean;\n}\n\n/**\n * A single Storybook app in a deploy workflow config.\n * `name` becomes the sandbox sub-path (`_site/sandbox/<name>/`).\n * `path` is the working directory relative to the repo root; defaults to `\".\"` (repo root) when omitted.\n */\nexport interface StorybookDeployProject {\n\tname?: string;\n\tpath?: string;\n}\n\n/**\n * Typed `with:` inputs for reusable workflows.\n *\n * `run-chromatic` accepts either a plain boolean (single-project) or a\n * `ChromaticProjectConfig[]` object (multi-project monorepo).\n *\n * `docs` / `storybook` are high-level deploy shorthand that `holocron setup`\n * translates to `type` / `storybook-projects` before writing the thin caller.\n * They also drive automatic `paths:` derivation so you never need to write\n * `paths:` manually for deploy entries.\n */\nexport type WorkflowWithConfig = Record<string, unknown> & {\n\t\"run-chromatic\"?: boolean | { projects: ChromaticProjectConfig[] };\n\t/**\n\t * Docs deployment shorthand. `true` uses the org-standard `docs/` directory;\n\t * `{ path: \"custom\" }` uses a custom directory. Both derive a `paths:` entry automatically.\n\t */\n\tdocs?: true | { path: string };\n\t/** Storybook apps to deploy alongside docs. Each entry's `path` is appended to `paths:`. */\n\tstorybook?: StorybookDeployProject[];\n};\n\n/**\n * A `tasks` manifest entry in object form. A bare string entry is shorthand\n * for `{ name, ci: true, local: true }`.\n */\nexport interface TaskEntryConfig {\n\tname: string;\n\twith?: WorkflowWithConfig;\n\tpaths?: string[];\n\tlinters?: string[];\n\t/** Emit a `.github/workflows/<name>.yml` thin caller + include in `holocron ci`. Default `true`. */\n\tci?: boolean;\n\t/** Write a `package.json` script + let `holocron run <name>` resolve the task. Default `true`. */\n\tlocal?: boolean;\n\t/** The task's CI check context is a required status check + part of `holocron ci`'s default run. */\n\trequired?: boolean;\n}\n\nexport interface HolocronConfig {\n\t/** Project name. Derived from package.json when absent. */\n\tname?: string;\n\tdescription?: string;\n\t/** Project homepage URL. Synced to package.json#homepage and the GitHub repo's website field by `holocron sync`. */\n\thomepage?: string;\n\t/**\n\t * Active org name for namespaced keyring lookup. When set, token resolution\n\t * tries `<service>.<org>` before the unnamespaced `<service>` fallback, so\n\t * a single machine can hold credentials for multiple GitHub orgs without\n\t * collision. Overridden by `--org` CLI flag or `HOLOCRON_ORG` env var.\n\t */\n\torg?: string;\n\t/**\n\t * Org canonical domain (e.g. `\"theholocron.dev\"`). Subdomains are derived\n\t * from this — `preview: true` on a deploy workflow resolves the preview base\n\t * domain as `preview.<domain>`, giving URLs like `<repo>-pr-<n>.<domain>`.\n\t */\n\tdomain?: string;\n\t/**\n\t * Repository identity and metadata. When set, `PluginLoader` injects\n\t * `repo.name` into every plugin's `RuntimeContext.repo` so plugins that\n\t * need a repo (github, etc.) don't require `--repo` on every invocation.\n\t * `--repo` on the command line still overrides.\n\t */\n\trepo?: RepoConfig;\n\t/**\n\t * The task manifest — what this repo runs. Each entry is a task name\n\t * (backed by a reusable workflow in `theholocron/.github`), or the object\n\t * form to pass `with:` inputs. `@theholocron/astromech` reads this as the\n\t * single source for `holocron run` / `holocron ci` / the generated CI\n\t * workflows / `package.json` scripts.\n\t *\n\t * Supported values (intent-facing vocabulary — epic #672, D3):\n\t * \"verification.unitTests\" | \"verification.typeSafety\" | \"verification.performance\" |\n\t * \"sourceQuality.staticAnalysis\" | \"sourceQuality.formatting\" |\n\t * \"sourceQuality.structuredDataValidation\" | \"sourceQuality.deadCodeAnalysis\" |\n\t * \"security.secretDetection\" | \"security.codeScanning\" |\n\t * \"delivery.build\" | \"delivery.publish\" | \"delivery.deploy\" | \"delivery.bundleSize\" |\n\t * \"platform.repoSync\" | \"platform.commitStandards\" | \"platform.repoValidation\" |\n\t * \"knowledge.wiki\" | \"knowledge.docs\" | \"knowledge.components\" |\n\t * \"review\" | \"tag\" | \"stale\" | \"greetings\" | \"dependencies\" | \"bookkeeping\"\n\t *\n\t * `holocron setup` writes `.github/workflows/<name>.yml` for each entry,\n\t * calling the corresponding reusable workflow in `theholocron/.github`.\n\t * Files are overwritten on each run — they are generated artifacts.\n\t *\n\t * ### delivery.deploy / knowledge.docs / knowledge.components\n\t * `delivery.deploy` uses `docs` and/or `storybook` in `with:` — setup\n\t * derives `paths:` automatically. `docs: true` uses the org-standard\n\t * `docs/` directory; `docs: { path: \"custom\" }` overrides it.\n\t * `knowledge.docs` / `knowledge.components` are the same underlying\n\t * mechanism, each dedicated to exactly one type — they imply the\n\t * corresponding shorthand, so a repo using them never has to spell out\n\t * `docs: true` / `storybook: […]` itself.\n\t *\n\t * ```ts\n\t * // Docs only (standard layout)\n\t * { name: \"delivery.deploy\", with: { docs: true } }\n\t * // …or equivalently, the dedicated task:\n\t * \"knowledge.docs\"\n\t *\n\t * // Docs + monorepo storybooks\n\t * {\n\t * name: \"delivery.deploy\",\n\t * with: {\n\t * docs: true,\n\t * storybook: [\n\t * { name: \"web\", path: \"apps/web\" },\n\t * { name: \"ui\", path: \"packages/ui\" },\n\t * ],\n\t * },\n\t * }\n\t *\n\t * // Non-standard docs location\n\t * { name: \"delivery.deploy\", with: { docs: { path: \"packages/site\" } } }\n\t * ```\n\t *\n\t * ### run-chromatic\n\t * For a single-project repo, use `\"run-chromatic\": true` with a\n\t * `CHROMATIC_PROJECT_TOKEN` repository secret.\n\t *\n\t * For monorepos with multiple Storybooks, use the object form:\n\t * ```ts\n\t * \"run-chromatic\": {\n\t * projects: [\n\t * { tokenName: \"WEB\", workingDir: \"apps/web\" },\n\t * { tokenName: \"UI\", workingDir: \"packages/ui\" },\n\t * ]\n\t * }\n\t * ```\n\t * Each `tokenName` maps to a repository secret named\n\t * `CHROMATIC_PROJECT_TOKEN_<TOKENNAME>`. `holocron setup` expands this\n\t * to the flat `run-chromatic: true` + `chromatic-projects: <json>` inputs\n\t * that the reusable workflow accepts.\n\t *\n\t * @example\n\t * [\"sourceQuality.staticAnalysis\", { \"name\": \"delivery.publish\", \"with\": { \"run-build\": false } }]\n\t * { \"name\": \"delivery.deploy\", \"with\": { \"docs\": true } }\n\t */\n\ttasks?: Array<string | TaskEntryConfig>;\n\t/**\n\t * Opt out of `holocron sync`'s `package.json` script writes. Default `true`.\n\t */\n\tsyncScripts?: boolean;\n\t/**\n\t * The command the synced `\"holocron\"` `package.json` script runs. Default\n\t * `\"holocron\"` (the installed bin). This repo overrides it to run its own\n\t * build (`\"node packages/cli/dist/cli.mjs\"`).\n\t */\n\tholocronScript?: string;\n\t/**\n\t * Required status-check contexts not backed by a `required` task (codecov\n\t * gates, the bundle-build check, …). `holocron setup` appends these to the\n\t * task-derived list from `astromech.requiredChecks()`.\n\t */\n\textraRequiredChecks?: string[];\n\t/**\n\t * Git hooks `holocron setup` installs. `true` / `{ prePush: true }` writes\n\t * `.husky/pre-push` (runs `holocron ci` before every push); `false` /\n\t * `{ prePush: false }` opts out. Omitted → on for `protection: \"strict\"`,\n\t * off otherwise. `--hooks` / `--no-hooks` on `holocron setup` override.\n\t */\n\thooks?: boolean | { prePush?: boolean };\n\tproviders: RawProvidersConfig;\n\tapps?: AppConfig[];\n\tdoctor?: DoctorConfig;\n\t/**\n\t * Agent runtime that determines where skills are installed by `holocron setup`.\n\t * Skills are installed to `.agents/skills/<name>/` (canonical) with a\n\t * relative symlink at the agent-specific path:\n\t * - `\"claude\"` → `.claude/skills/<name>` → `../../.agents/skills/<name>`\n\t * - `\"codex\"` | `\"gemini\"` → logged as unsupported; skipped gracefully.\n\t */\n\tagent?: \"claude\" | \"codex\" | \"gemini\";\n\t/**\n\t * Skill names from `@theholocron/skills` to install during `holocron setup`.\n\t * Installed paths are gitignored and managed by setup — do not commit them.\n\t *\n\t * @example\n\t * [\"git-safety\", \"pr-workflow\", \"commit-standards\"]\n\t */\n\tskills?: string[];\n\t/**\n\t * GitHub Pages configuration. When present, `holocron setup` calls the\n\t * Pages API using `HOLOCRON_DEPLOY_TOKEN` (requires `pages:write` + `repo` scope).\n\t * When absent, Pages is left as-is.\n\t *\n\t * @example\n\t * { build: \"workflow\", domain: \"docs.theholocron.dev\", https: true }\n\t */\n\tdocs?: DocsConfig;\n\t/**\n\t * Environment variable namespace configuration.\n\t * Declares the prefix(es) this project uses for its env vars so that\n\t * tooling can generate `.env.example`, validate required vars, and\n\t * produce accurate documentation without hard-coding prefix strings.\n\t *\n\t * @example\n\t * { namespaces: [\"HOLOCRON\", \"MY_CLI\"] }\n\t */\n\tenv?: EnvConfig;\n\t/**\n\t * Structured-logging config. Only the level belongs here — Axiom\n\t * credentials come from env vars, never a committed file.\n\t *\n\t * @example\n\t * { level: \"debug\" }\n\t */\n\tlog?: LogConfig;\n\t/**\n\t * CLI self-telemetry override layer. Env var (`HOLOCRON_TELEMETRY=false`)\n\t * still wins; this is the committed way to opt a repo out or drop usage\n\t * analytics while keeping error reporting.\n\t *\n\t * @example\n\t * { enabled: false }\n\t * { analytics: \"none\" }\n\t */\n\ttelemetry?: TelemetryConfig;\n\t/**\n\t * ESLint bundle option overrides that Sentinel's centralized static-\n\t * analysis check (holocron#849) can't otherwise see. Bucket 1 checks\n\t * never read a PR's own committed files for config — this is the\n\t * declared source of truth Sentinel reads instead, so its check stays\n\t * in sync with what each package's own `eslint.config.ts` already\n\t * enforces locally and in CI.\n\t */\n\teslint?: EslintConfig;\n}\n\n/**\n * Repo-root-relative directories treated as browser-targeted for eslint's\n * node-builtins compatibility checks — mirrors\n * `@theholocron/eslint-config`'s `library({ browserPackages })` option.\n * Only needed for a package whose own `eslint.config.ts` already declares\n * `browserPackages` (a deliberate outlier, not the norm — see that\n * package's own config file for why).\n *\n * @example\n * { browserPackages: [\"packages/github-client/src/app-auth\"] }\n */\nexport interface EslintConfig {\n\tbrowserPackages?: string[];\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// Resolved config (what the runtime sees after parsing)\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface ResolvedTuple {\n\tprovider: string;\n\t/** Resolved package name (`@theholocron/holocron-plugin-<provider>` for short refs). */\n\tpackageName: string;\n\toptions: ProviderOptions;\n}\n\nexport type ResolvedProviderEntry =\n\t{ cardinality: \"single\"; tuple: ResolvedTuple } | { cardinality: \"many\"; tuples: ResolvedTuple[] };\n\nexport type ResolvedProvidersConfig = Partial<Record<CapabilityKey, ResolvedProviderEntry>>;\n\nexport interface ResolvedHolocronConfig {\n\tname: string;\n\tdescription?: string;\n\thomepage?: string;\n\torg?: string;\n\tdomain?: string;\n\trepo?: RepoConfig;\n\ttasks?: Array<string | TaskEntryConfig>;\n\tsyncScripts?: boolean;\n\tholocronScript?: string;\n\textraRequiredChecks?: string[];\n\thooks?: boolean | { prePush?: boolean };\n\tproviders: ResolvedProvidersConfig;\n\tapps: AppConfig[];\n\tdoctor: DoctorConfig;\n\tagent?: \"claude\" | \"codex\" | \"gemini\";\n\tskills?: string[];\n\t/** Resolved Pages config. `build` is guaranteed present when this field exists. */\n\tdocs?: PagesConfig;\n\tenv?: EnvConfig;\n\tlog?: LogConfig;\n\ttelemetry?: TelemetryConfig;\n\teslint?: EslintConfig;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// Errors\n// ───────────────────────────────────────────────────────────────────────\n\nexport class ConfigError extends Error {\n\toverride name = \"ConfigError\";\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// Helpers\n// ───────────────────────────────────────────────────────────────────────\n\nconst PLUGIN_PREFIX = \"@theholocron/holocron-plugin-\";\nconst COMMUNITY_PREFIX = \"holocron-plugin-\";\n\n/**\n * Resolve `\"github\"` → `\"@theholocron/holocron-plugin-github\"`.\n * Fully-qualified names (scoped or not) are honored verbatim, which\n * is how third-party plugins published outside the org work.\n */\nexport function resolvePluginPackage(provider: string): string {\n\tif (!provider) throw new ConfigError(\"provider name is empty\");\n\tif (provider.startsWith(\"@\")) return provider;\n\tif (provider.startsWith(COMMUNITY_PREFIX)) return provider;\n\tif (provider.includes(\"/\")) return provider;\n\treturn PLUGIN_PREFIX + provider;\n}\n\n/** A bare `[provider, options]` tuple, with both elements present? */\nfunction isOptionsTuple(value: unknown): value is [string, ProviderOptions] {\n\tif (!Array.isArray(value)) return false;\n\tif (value.length !== 2) return false;\n\tif (typeof value[0] !== \"string\") return false;\n\tconst opt = value[1];\n\treturn typeof opt === \"object\" && opt !== null && !Array.isArray(opt);\n}\n\nfunction normalizeEntry(entry: string | [string, ProviderOptions]): ResolvedTuple {\n\tif (typeof entry === \"string\") {\n\t\treturn { provider: entry, packageName: resolvePluginPackage(entry), options: {} };\n\t}\n\tconst [provider, options] = entry;\n\treturn { provider, packageName: resolvePluginPackage(provider), options };\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// Parse / resolve\n// ───────────────────────────────────────────────────────────────────────\n\nexport function resolveEntry(key: CapabilityKey, raw: RawProviderEntry): ResolvedProviderEntry {\n\tconst cardinality = CARDINALITY[key];\n\n\t// Single short form: \"github\"\n\tif (typeof raw === \"string\") {\n\t\tif (cardinality === \"many\") {\n\t\t\tthrow new ConfigError(`\\`${key}\\` accepts multiple providers; wrap a single one in an array: [\"${raw}\"]`);\n\t\t}\n\t\treturn { cardinality: \"single\", tuple: normalizeEntry(raw) };\n\t}\n\n\tif (!Array.isArray(raw)) {\n\t\tthrow new ConfigError(`\\`${key}\\` entry must be a string or array, got ${typeof raw}`);\n\t}\n\n\t// Single options tuple: [\"vercel\", { team: \"rando\" }]\n\tif (isOptionsTuple(raw)) {\n\t\tif (cardinality === \"many\") {\n\t\t\t// Same shape, but cardinality forces multi — promote to one-element list\n\t\t\treturn { cardinality: \"many\", tuples: [normalizeEntry(raw)] };\n\t\t}\n\t\treturn { cardinality: \"single\", tuple: normalizeEntry(raw) };\n\t}\n\n\t// Multi list — array of strings, tuples, or a mix\n\tif (cardinality === \"single\") {\n\t\tthrow new ConfigError(\n\t\t\t`\\`${key}\\` accepts exactly one provider; got a multi-provider list with ${raw.length} entries`\n\t\t);\n\t}\n\n\tconst tuples = raw.map((entry, idx) => {\n\t\tif (typeof entry === \"string\") return normalizeEntry(entry);\n\t\tif (isOptionsTuple(entry)) return normalizeEntry(entry);\n\t\tthrow new ConfigError(`\\`${key}[${idx}]\\` must be a provider string or [provider, options] tuple`);\n\t});\n\n\treturn { cardinality: \"many\", tuples };\n}\n\nexport function resolveConfig(raw: HolocronConfig): ResolvedHolocronConfig {\n\tif (!raw.name) {\n\t\tthrow new ConfigError(\"`name` is required\");\n\t}\n\tif (!raw.providers || typeof raw.providers !== \"object\") {\n\t\tthrow new ConfigError(\"`providers` block is required\");\n\t}\n\n\tconst providers: ResolvedProvidersConfig = {};\n\tfor (const [key, entry] of Object.entries(raw.providers)) {\n\t\tif (entry === undefined) continue;\n\t\tproviders[key as CapabilityKey] = resolveEntry(key as CapabilityKey, entry as RawProviderEntry);\n\t}\n\n\tfor (const required of REQUIRED_CAPABILITIES) {\n\t\tif (!providers[required]) {\n\t\t\tthrow new ConfigError(`required capability \\`${required}\\` is missing from providers`);\n\t\t}\n\t}\n\n\t// Validate docs and narrow build to required\n\tlet docs: PagesConfig | undefined;\n\tif (raw.docs !== undefined) {\n\t\tif (!raw.docs.build) {\n\t\t\tthrow new ConfigError(\"`docs.build` is required when `docs` is set\");\n\t\t}\n\t\tdocs = raw.docs as PagesConfig;\n\t}\n\n\t// Derive homepage from docs.domain when not explicitly set\n\tconst homepage = raw.homepage ?? (docs?.domain ? `https://${docs.domain}/` : undefined);\n\n\treturn {\n\t\tname: raw.name,\n\t\tdescription: raw.description,\n\t\thomepage,\n\t\torg: raw.org,\n\t\tdomain: raw.domain,\n\t\trepo: raw.repo,\n\t\ttasks: raw.tasks,\n\t\tsyncScripts: raw.syncScripts,\n\t\tholocronScript: raw.holocronScript,\n\t\textraRequiredChecks: raw.extraRequiredChecks,\n\t\thooks: raw.hooks,\n\t\tproviders,\n\t\tapps: raw.apps ?? [],\n\t\tdoctor: raw.doctor ?? {},\n\t\tagent: raw.agent,\n\t\tskills: raw.skills,\n\t\tdocs,\n\t\tenv: raw.env,\n\t\tlog: raw.log,\n\t\ttelemetry: raw.telemetry,\n\t\teslint: raw.eslint,\n\t};\n}\n","/**\n * CLI-side wiring for `@theholocron/observability/logger`.\n *\n * `logger` is the operational-output channel — internal state, debug\n * traces, errors, structured context that routes to Axiom. It runs in\n * parallel to `print` (user-facing UX output) and does not replace it.\n */\n\nimport type { Logger, LogLevel } from \"@theholocron/observability/core\";\nimport type { AxiomTransportConfig } from \"@theholocron/observability/logger\";\nimport { createLogger, parseLogLevel, resolveAxiomFromEnv } from \"@theholocron/observability/logger\";\n\nimport { getToken } from \"./auth/keyring.js\";\nimport { env } from \"./env.js\";\n\n/**\n * Resolve the explicit level to hand to `createLogger`, in priority order:\n *\n * 1. `--verbose` → `\"debug\"` 2. `--quiet` → `\"error\"`\n * 3. `HOLOCRON_LOG_LEVEL` env var\n * 4. `holocron.config` `log.level` (`configLevel`)\n *\n * Returns `undefined` when nothing applies — `createLogger` then defaults\n * to `\"info\"`. Resolving the full chain here (rather than passing\n * `configLevel` straight through) keeps config below the env var.\n */\nexport function resolveLogLevel(\n\targv: { verbose?: boolean; quiet?: boolean },\n\tconfigLevel?: LogLevel\n): LogLevel | undefined {\n\tif (argv.verbose) return \"debug\";\n\tif (argv.quiet) return \"error\";\n\treturn parseLogLevel(env.get(\"HOLOCRON_LOG_LEVEL\")) ?? configLevel;\n}\n\nlet root: { logger: Logger; runId: string } | undefined;\nlet rootLevel: LogLevel | undefined;\nlet rootCommand: string | undefined;\nlet rootAxiomKey: string | undefined;\n\nexport interface BuildCliLoggerOpts {\n\t/** Active command name — bound on the root as `command` for every line. */\n\tcommand?: string;\n\t/** `holocron.config` `log.level`, from a handler that has loaded a config. */\n\tconfigLevel?: LogLevel;\n\t/**\n\t * `holocron.config` `log.axiom.dataset` — the non-secret Axiom dataset\n\t * name. Paired with a keyring token when the env vars are absent.\n\t */\n\tconfigAxiomDataset?: string;\n\t/**\n\t * Resolved org (`--org` → `HOLOCRON_ORG` → config `org`) for the\n\t * namespaced keyring lookup (`axiom.<org>` before bare `axiom`).\n\t */\n\torg?: string;\n}\n\n/**\n * Resolve Axiom credentials for the CLI. Env vars win — same contract as\n * `@theholocron/observability`'s `resolveAxiomFromEnv`. Failing that, the CLI-only\n * bridge pairs the OS-keyring token (`axiom.<org>` then bare `axiom`) with a\n * dataset from `HOLOCRON_AXIOM_DATASET` / `AXIOM_DATASET` or\n * `holocron.config` `log.axiom.dataset`. Returns `undefined` unless both a\n * token and a dataset are found.\n */\nfunction resolveCliAxiom(opts: BuildCliLoggerOpts): AxiomTransportConfig | undefined {\n\tconst fromEnv = resolveAxiomFromEnv();\n\tif (fromEnv) return fromEnv;\n\n\tconst dataset = env.get(\"HOLOCRON_AXIOM_DATASET\") || env.get(\"AXIOM_DATASET\") || opts.configAxiomDataset;\n\tif (!dataset) return undefined;\n\n\tconst org = opts.org ?? env.get(\"HOLOCRON_ORG\");\n\tconst token = (org ? getToken(`axiom.${org}`) : null) ?? getToken(\"axiom\");\n\treturn token ? { dataset, token } : undefined;\n}\n\n/**\n * The process-wide root logger. Built once (from `cli.ts`'s middleware,\n * with the command name + flags + env). Rebuilt at most once more when a\n * command's handler supplies `holocron.config` context the flag/env-only\n * first pass could not have known — `log.level` (unless `--verbose` /\n * `--quiet` already fixed it) or `log.axiom.dataset` + the resolved org\n * for a keyring-backed Axiom transport. That rebuild generates a fresh\n * `runId`, which is harmless: nothing logs between the middleware and the\n * handler.\n */\nexport function buildCliLogger(\n\targv: { verbose?: boolean; quiet?: boolean },\n\topts: BuildCliLoggerOpts = {}\n): { logger: Logger; runId: string } {\n\tconst { command, configLevel } = opts;\n\tif (command) rootCommand = command;\n\tconst level = resolveLogLevel(argv, configLevel);\n\tconst axiom = resolveCliAxiom(opts);\n\tconst axiomKey = axiom?.dataset;\n\tconst rebuildForConfig = configLevel !== undefined && level !== rootLevel && !argv.verbose && !argv.quiet;\n\tconst rebuildForAxiom = axiomKey !== undefined && axiomKey !== rootAxiomKey;\n\tif (!root || rebuildForConfig || rebuildForAxiom) {\n\t\tconst built = createLogger({ ...(level ? { level } : {}), ...(axiom ? { axiom } : {}) });\n\t\troot = {\n\t\t\tlogger: rootCommand ? built.logger.child({ command: rootCommand }) : built.logger,\n\t\t\trunId: built.runId,\n\t\t};\n\t\trootLevel = level;\n\t\trootAxiomKey = axiomKey;\n\t}\n\treturn root;\n}\n\n/** Lazily-memoized `Logger` for module-level call sites with no `argv` in scope. */\nexport function getLogger(): Logger {\n\treturn (root ??= createLogger()).logger;\n}\n\n/** The current root logger's correlation id, if a root has been built. */\nexport function getRunId(): string | undefined {\n\treturn root?.runId;\n}\n\n/** Test hook — drop the memoized root so the next call rebuilds it. */\nexport function resetCliLogger(): void {\n\troot = undefined;\n\trootLevel = undefined;\n\trootCommand = undefined;\n\trootAxiomKey = undefined;\n}\n","/**\n * `PluginLoader` — loads provider plugins per the resolved config and\n * builds a typed capability registry the runtime can query.\n *\n * Flow:\n * 1. Walk `config.providers[*]` from `resolveConfig()`\n * 2. For each entry, dynamic-import the resolved package name\n * (`@theholocron/holocron-plugin-<provider>` by default)\n * 3. Call the package's exported `createPlugin(options)` to get a\n * plugin object whose `capabilities` map holds factories\n * 4. Invoke the matching capability factory and stash the impl in\n * the registry — single-cardinality entries hold one impl,\n * many-cardinality entries hold an array\n *\n * A package may instead export a capability config (see\n * `CapabilityConfigPackage` in config.ts). The loader detects the shape\n * at import time and re-resolves to the underlying plugin, merging the\n * preset options with any per-project overrides from the config file\n * (project options win, mirroring ESLint's `extends` precedence).\n *\n * Loader keeps NO knowledge of vendor tokens. Each plugin reads its\n * own env vars (`HOLOCRON_ADMIN_TOKEN`, `HOLOCRON_VERCEL_TOKEN`, etc.)\n * inside its `createPlugin`. That keeps the loader vendor-agnostic\n * and the auth story per-plugin explicit.\n *\n * `importer` is injectable so tests don't need real network or\n * sibling packages installed.\n */\n\nimport { createRequire } from \"node:module\";\nimport { pathToFileURL } from \"node:url\";\n\nimport type { CapabilityConfigPackage, ResolvedHolocronConfig, ResolvedTuple } from \"../config/config.js\";\nimport { resolvePluginPackage } from \"../config/config.js\";\nimport type { CapabilityKey, CardinalityFor, ResolvedCapability } from \"./capabilities.js\";\nimport { CARDINALITY } from \"./capabilities.js\";\n\n/**\n * Per-invocation context every plugin receives, on top of its own\n * config-time options. Kept intentionally narrow.\n */\nexport interface RuntimeContext {\n\t/** \"owner/name\" — the repo this invocation is operating on. */\n\trepo?: string;\n\t/** Absolute path to the working repo root. */\n\trepoRoot: string;\n\t/**\n\t * When true, commands print what they WOULD mutate instead of\n\t * actually calling capability mutators. Set by the global\n\t * `--dry-run` flag. Capabilities themselves are unaware — the check\n\t * lives at the command layer.\n\t */\n\tdryRun?: boolean;\n\t/**\n\t * Token passed via bare `--token <value>`. Used as fallback for all\n\t * plugins when no matching entry exists in `cliTokens`.\n\t */\n\tcliToken?: string;\n\t/**\n\t * Per-provider tokens from `--token vendor=value` pairs. The loader\n\t * routes each entry to the matching plugin (by `tuple.provider`) as\n\t * its `cliToken`, falling back to `cliToken` for unmatched providers.\n\t * Plugins never receive this map — they always see a single `cliToken`.\n\t */\n\tcliTokens?: Record<string, string>;\n\t/**\n\t * Active org name for namespaced keyring lookup. Resolved from\n\t * `--org` flag → `HOLOCRON_ORG` env var → `org` in config, then\n\t * injected here so plugins receive it via their options\n\t * (which extend `ResolveTokenInput`) without any per-plugin change.\n\t */\n\torg?: string;\n}\n\n/**\n * The shape every plugin's default-or-named export must satisfy:\n * `createPlugin(opts)` returns an object with capability factories.\n */\nexport interface LoadedPlugin {\n\tname: string;\n\tcapabilities: Partial<{\n\t\t[K in CapabilityKey]: () => unknown;\n\t}>;\n}\n\nexport interface PluginModule {\n\tcreatePlugin: (opts: Record<string, unknown>) => LoadedPlugin;\n}\n\n/** Returns `unknown` — the loader type-narrows inside `loadOne`. */\nexport type PluginImporter = (packageName: string) => Promise<unknown>;\n\nexport class LoaderError extends Error {\n\toverride name = \"LoaderError\";\n}\n\n/** A provider that could not be loaded — missing token, bad package, unimplemented capability. */\nexport interface PluginLoadFailure {\n\tkey: CapabilityKey;\n\tprovider: string;\n\tpackageName: string;\n\terror: Error;\n}\n\nexport class PluginLoader {\n\tprivate readonly registry = new Map<CapabilityKey, unknown>();\n\tprivate readonly failures: PluginLoadFailure[] = [];\n\n\tconstructor(\n\t\tprivate readonly config: ResolvedHolocronConfig,\n\t\tprivate readonly context: RuntimeContext,\n\t\tprivate readonly importer: PluginImporter = defaultImporter\n\t) {}\n\n\t/**\n\t * Imports every configured plugin and builds the capability registry.\n\t *\n\t * Never throws for a single plugin's failure — a missing vendor token,\n\t * an uninstalled package, or an unimplemented capability records a\n\t * {@link PluginLoadFailure} and the load continues. This is the\n\t * \"soft-skip over hard-fail\" contract: a command that needs a\n\t * capability learns it is absent via `has()` / `get()` (which\n\t * re-surfaces the original error), and orchestrators report the skip\n\t * in their summary. Inspect {@link loadFailures} for the full list.\n\t */\n\tasync load(): Promise<void> {\n\t\tconst entries = Object.entries(this.config.providers) as Array<\n\t\t\t[CapabilityKey, ResolvedHolocronConfig[\"providers\"][CapabilityKey]]\n\t\t>;\n\n\t\tfor (const [key, entry] of entries) {\n\t\t\tif (!entry) continue;\n\t\t\tif (entry.cardinality === \"single\") {\n\t\t\t\ttry {\n\t\t\t\t\tthis.registry.set(key, await this.loadOne(key, entry.tuple));\n\t\t\t\t} catch (err) {\n\t\t\t\t\tthis.recordFailure(key, entry.tuple, err);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst impls: unknown[] = [];\n\t\t\t\tfor (const tuple of entry.tuples) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\timpls.push(await this.loadOne(key, tuple));\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tthis.recordFailure(key, tuple, err);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (impls.length > 0) this.registry.set(key, impls);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate recordFailure(key: CapabilityKey, tuple: ResolvedTuple, err: unknown): void {\n\t\tthis.failures.push({\n\t\t\tkey,\n\t\t\tprovider: tuple.provider,\n\t\t\tpackageName: tuple.packageName,\n\t\t\terror: err instanceof Error ? err : new Error(String(err)),\n\t\t});\n\t}\n\n\t/** Providers that failed to load during {@link load}. Empty on a clean load. */\n\tloadFailures(): readonly PluginLoadFailure[] {\n\t\treturn this.failures;\n\t}\n\n\t/**\n\t * Type-safe lookup. Single-cardinality keys return one impl;\n\t * many-cardinality keys return an array. `ResolvedCapability<K>`\n\t * encodes the split via the `CARDINALITY` map.\n\t */\n\tget<K extends CapabilityKey>(key: K): ResolvedCapability<K> {\n\t\tconst impl = this.registry.get(key);\n\t\tif (impl === undefined) {\n\t\t\t// If the plugin was configured but failed to load, re-surface the\n\t\t\t// original error (e.g. `AuthError: no Vercel token found`) rather\n\t\t\t// than a generic \"not loaded\" — single-capability commands then\n\t\t\t// give the operator an actionable message.\n\t\t\tconst failure = this.failures.find((f) => f.key === key);\n\t\t\tif (failure) throw failure.error;\n\t\t\tthrow new LoaderError(`capability \\`${key}\\` is not loaded — is it declared in holocron.config.json?`);\n\t\t}\n\t\treturn impl as ResolvedCapability<K>;\n\t}\n\n\t/** Whether a capability has been loaded. */\n\thas<K extends CapabilityKey>(key: K): boolean {\n\t\treturn this.registry.has(key);\n\t}\n\n\t/** All capability keys currently loaded. Useful for the doctor command. */\n\tloadedKeys(): CapabilityKey[] {\n\t\treturn Array.from(this.registry.keys());\n\t}\n\n\t/** Internal — invoke a plugin's capability factory and return the impl. */\n\tprivate async loadOne(key: CapabilityKey, tuple: ResolvedTuple): Promise<unknown> {\n\t\tconst mod = await this.importer(tuple.packageName).catch((err: unknown) => {\n\t\t\tthrow new LoaderError(\n\t\t\t\t`failed to import \\`${tuple.packageName}\\` for capability \\`${key}\\`: ${\n\t\t\t\t\terr instanceof Error ? err.message : String(err)\n\t\t\t\t}`\n\t\t\t);\n\t\t});\n\n\t\t// Plugin package: exports createPlugin(opts) → { capabilities }\n\t\tif (isPluginModule(mod)) {\n\t\t\t// Resolve the effective token for this specific plugin.\n\t\t\t// cliTokens[provider] wins over the bare cliToken fallback.\n\t\t\tconst effectiveToken = this.context.cliTokens?.[tuple.provider] ?? this.context.cliToken;\n\n\t\t\t// Precedence (later wins): project-level defaults from config →\n\t\t\t// runtime context (CLI flags: --repo, --token) → per-plugin\n\t\t\t// resolved token → tuple options (per-plugin overrides in config).\n\t\t\t// cliTokens is explicitly cleared so the map never reaches plugins.\n\t\t\tconst plugin = mod.createPlugin({\n\t\t\t\t...this.projectDefaults(),\n\t\t\t\t...this.context,\n\t\t\t\t...(effectiveToken !== undefined ? { cliToken: effectiveToken } : {}),\n\t\t\t\tcliTokens: undefined,\n\t\t\t\t...tuple.options,\n\t\t\t});\n\t\t\tconst factory = plugin.capabilities[key];\n\t\t\tif (typeof factory !== \"function\") {\n\t\t\t\tthrow new LoaderError(`\\`${tuple.packageName}\\` does not implement the \\`${key}\\` capability`);\n\t\t\t}\n\t\t\treturn factory();\n\t\t}\n\n\t\t// Capability config package: default export is { provider, options? }.\n\t\t// Re-resolve to the underlying plugin; preset options are the base,\n\t\t// per-project tuple options override them (ESLint extends precedence).\n\t\tif (isCapabilityConfigModule(mod)) {\n\t\t\tconst cap = (mod as { default: CapabilityConfigPackage }).default;\n\t\t\treturn this.loadOne(key, {\n\t\t\t\tprovider: cap.provider,\n\t\t\t\tpackageName: resolvePluginPackage(cap.provider),\n\t\t\t\toptions: { ...cap.options, ...tuple.options },\n\t\t\t});\n\t\t}\n\n\t\tthrow new LoaderError(\n\t\t\t`\\`${tuple.packageName}\\` does not export \\`createPlugin(options)\\` or a capability config ({ provider, options? })`\n\t\t);\n\t}\n\n\t/**\n\t * Project-level defaults that get merged into every plugin's options\n\t * unless overridden by the CLI context or per-plugin tuple options.\n\t * See `docs/wiki/specifications/tech-setup-and-config.spec.md` §Design.\n\t */\n\tprivate projectDefaults(): Partial<RuntimeContext> {\n\t\tconst defaults: Partial<RuntimeContext> = {};\n\t\tif (this.config.repo?.name) defaults.repo = this.config.repo.name;\n\t\treturn defaults;\n\t}\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────\n\n/** Default importer — resolves from cwd first so the global CLI finds project plugins. */\nconst defaultImporter: PluginImporter = async (pkg) => {\n\ttry {\n\t\tconst localRequire = createRequire(process.cwd() + \"/\");\n\t\tconst resolved = localRequire.resolve(pkg);\n\t\treturn import(pathToFileURL(resolved).href);\n\t} catch {\n\t\treturn import(pkg);\n\t}\n};\n\nfunction isPluginModule(mod: unknown): mod is PluginModule {\n\treturn typeof (mod as PluginModule).createPlugin === \"function\";\n}\n\nfunction isCapabilityConfigModule(mod: unknown): mod is { default: CapabilityConfigPackage } {\n\tconst def = (mod as { default?: unknown }).default;\n\treturn typeof (def as CapabilityConfigPackage)?.provider === \"string\";\n}\n\n/** Convenience re-export so callers can compute counts without importing CARDINALITY directly. */\nexport function cardinalityOf<K extends CapabilityKey>(key: K): CardinalityFor<K> {\n\treturn CARDINALITY[key];\n}\n","/**\n * The `workspace`-context guard.\n *\n * A `workspace` command (`sync`, `setup`, `doctor`, …) needs the\n * configured providers' `@theholocron/holocron-plugin-*` packages to\n * resolve. From a bare `npm i -g @theholocron/cli` they don't, and the\n * {@link PluginLoader} — which soft-skips every failure — leaves the\n * command with an empty registry and a stack of `Cannot find package`\n * errors.\n *\n * {@link assertPluginsResolvable} turns that specific situation (every\n * provider failed, and every failure is a module-resolution failure)\n * into one actionable {@link WorkspaceContextError} the CLI prints\n * instead of a stack trace. Any other mix — some plugins loaded, or a\n * failure that's an auth/token error rather than a missing package —\n * is left alone for the command's own soft-skip reporting.\n *\n * Spec: `docs/wiki/specifications/tech-cli-execution-contexts.spec.md`\n * (theholocron/holocron#576).\n */\n\nimport { LoaderError, type PluginLoader } from \"./loader.js\";\n\n/**\n * Raised when a `workspace` command runs somewhere its provider plugins\n * cannot be resolved — the \"you're on a global install\" case. Carries the\n * unresolved package names so the message can be specific.\n */\nexport class WorkspaceContextError extends Error {\n\toverride name = \"WorkspaceContextError\";\n\treadonly command: string;\n\treadonly packages: readonly string[];\n\n\tconstructor(command: string, packages: readonly string[]) {\n\t\tconst [first, ...rest] = packages;\n\t\tconst subject =\n\t\t\trest.length > 0\n\t\t\t\t? `${first} (and ${rest.length} other${rest.length === 1 ? \"\" : \"s\"})`\n\t\t\t\t: (first ?? \"its plugins\");\n\t\tsuper(\n\t\t\t`\\`${command}\\` needs ${subject}, but no plugin package resolves here.\\n` +\n\t\t\t\t`Run it from a repo that has the \\`@theholocron/holocron-plugin-*\\` packages as devDependencies, ` +\n\t\t\t\t`or \\`pnpm exec holocron ${command}\\`. A global install can't resolve them — see ` +\n\t\t\t\t`https://theholocron.github.io/holocron/execution-contexts`\n\t\t);\n\t\tthis.command = command;\n\t\tthis.packages = packages;\n\t}\n}\n\n/**\n * A raw \"package isn't installed here\" error from `import()` /\n * `require.resolve` — `ERR_MODULE_NOT_FOUND` / `MODULE_NOT_FOUND`, or the\n * \"Cannot find package/module\" message Node prints for it.\n */\nexport function isModuleNotFound(err: unknown): boolean {\n\tif (!(err instanceof Error)) return false;\n\tconst code = (err as NodeJS.ErrnoException).code;\n\tif (code === \"ERR_MODULE_NOT_FOUND\" || code === \"MODULE_NOT_FOUND\") return true;\n\treturn /Cannot find (?:package|module)|MODULE_NOT_FOUND/.test(err.message);\n}\n\n/** Did this failure come from the dynamic `import()` not finding the package? */\nfunction isImportFailure(err: Error): boolean {\n\treturn err instanceof LoaderError && err.message.startsWith(\"failed to import\");\n}\n\n/**\n * Throw {@link WorkspaceContextError} when a loaded `PluginLoader` shows\n * the global-install signature: nothing in the registry, at least one\n * failure, and *every* failure is a missing-package error. A no-op in\n * every other case (some capability loaded, non-import failure, or no\n * providers configured at all).\n *\n * Call it right after `await loader.load()` in a `workspace` command.\n */\nexport function assertPluginsResolvable(loader: PluginLoader, command: string): void {\n\tif (loader.loadedKeys().length > 0) return;\n\tconst failures = loader.loadFailures();\n\tif (failures.length === 0) return;\n\tif (!failures.every((f) => isImportFailure(f.error))) return;\n\n\tconst packages = [...new Set(failures.map((f) => f.packageName))];\n\tthrow new WorkspaceContextError(command, packages);\n}\n","import ora from \"ora\";\n\n/**\n * Runs `fn`, showing an ora spinner for its duration in TTY environments.\n * In non-TTY environments (CI, pipes, tests) the spinner is skipped entirely.\n */\nexport async function withSpinner<T>(label: string, fn: () => Promise<T>): Promise<T> {\n\tif (!process.stdout.isTTY) {\n\t\treturn fn();\n\t}\n\tconst spinner = ora(label).start();\n\ttry {\n\t\tconst result = await fn();\n\t\tspinner.succeed();\n\t\treturn result;\n\t} catch (err) {\n\t\tspinner.fail();\n\t\tthrow err;\n\t}\n}\n","import chalk from \"chalk\";\n\nexport const style = {\n\tsuccess: (msg: string) => `${chalk.green(\"✓\")} ${msg}`,\n\twarn: (msg: string) => `${chalk.yellow(\"⚠\")} ${msg}`,\n\tfail: (msg: string) => `${chalk.red(\"✗\")} ${msg}`,\n\tstep: (msg: string) => `${chalk.cyan(\"→\")} ${msg}`,\n\thint: (msg: string) => chalk.dim(msg),\n\tdim: (msg: string) => chalk.dim(msg),\n\theader: (msg: string) => chalk.bold(msg),\n};\n","/**\n * `holocron auth <subcommand>` — manage bootstrap credentials in the\n * OS keyring.\n *\n * Subcommands:\n * auth set <provider> [token] verify + store\n * auth unset <provider> remove\n * auth check <provider> re-verify a stored token\n * auth list every provider with a stored entry\n *\n * See `docs/wiki/specifications/tech-auth-bootstrap.spec.md`.\n *\n * Verification lives in each plugin as a top-level `verifyToken(token)`\n * export. The auth command dynamically imports\n * `@theholocron/holocron-plugin-<provider>` and calls it. Plugins that\n * don't export `verifyToken` can still store — with a warning — because\n * \"no verify path\" shouldn't block credential storage.\n */\n\nimport { createRequire } from \"node:module\";\nimport { pathToFileURL } from \"node:url\";\n\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport { deleteToken, getToken, listStoredProviders, setToken } from \"../auth/keyring.js\";\nimport { resolvePluginPackage } from \"../config/config.js\";\nimport { makeEnv } from \"../env.js\";\nimport { getLogger } from \"../logger.js\";\nimport { isModuleNotFound } from \"../plugin/workspace.js\";\nimport { withSpinner } from \"../ui/progress.js\";\nimport { style } from \"../ui/style.js\";\n\n// ── Plugin-level export shapes (mirrored on every plugin) ────────────\n\nexport interface VerifyTokenSuccess {\n\tok: true;\n\t/** \"workplace: acme\" / \"user: cnewton@x\" — surfaced in success output. */\n\tsubject: string;\n}\n\nexport interface VerifyTokenFailure {\n\tok: false;\n\t/** Reason the token was rejected. Surfaces to the operator. */\n\tmessage: string;\n}\n\nexport type VerifyTokenResult = VerifyTokenSuccess | VerifyTokenFailure;\n\ninterface AuthPluginModule {\n\tverifyToken?: (token: string) => Promise<VerifyTokenResult>;\n\t/** One-line hint printed when no token was supplied. */\n\tAUTH_HINT?: string;\n}\n\nexport type AuthImporter = (packageName: string) => Promise<AuthPluginModule>;\n\nconst defaultImporter: AuthImporter = async (pkg) => {\n\ttry {\n\t\tconst localRequire = createRequire(process.cwd() + \"/\");\n\t\tconst resolved = localRequire.resolve(pkg);\n\t\treturn (await import(pathToFileURL(resolved).href)) as AuthPluginModule;\n\t} catch {\n\t\treturn (await import(pkg)) as AuthPluginModule;\n\t}\n};\n\n// ── Common types ─────────────────────────────────────────────────────\n\nexport type AuthPrint = (line: string) => void;\n\nexport interface AuthCommandStatus {\n\tstatus: \"ok\" | \"fail\" | \"skip\";\n\tmessage?: string;\n}\n\n// ── Token resolution ─────────────────────────────────────────────────\n\n/**\n * Resolve a token from (positional → HOLOCRON_<X> → vendor-native env).\n * Keyring is NOT consulted here — `auth set` writes TO the keyring, so\n * pulling FROM it would just re-store the same value.\n */\nexport function resolveAuthSetToken(input: {\n\tprovider: string;\n\tpositional?: string;\n\tenv?: NodeJS.ProcessEnv;\n}): string | null {\n\tconst e = makeEnv(input.env);\n\tconst upper = input.provider.toUpperCase();\n\tconst holocronKey = `HOLOCRON_${upper}_TOKEN`;\n\treturn input.positional || e.get(holocronKey) || e.get(`${upper}_TOKEN`) || null;\n}\n\n// ── Subcommands ──────────────────────────────────────────────────────\n\nexport interface RunAuthSetInput {\n\tprovider: string;\n\tpositional?: string;\n\tenv?: NodeJS.ProcessEnv;\n\timporter?: AuthImporter;\n\tprint?: AuthPrint;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n\t/** When set, stores the token under `<provider>.<org>` in the keyring. */\n\torg?: string;\n}\n\nexport async function runAuthSet(input: RunAuthSetInput): Promise<AuthCommandStatus> {\n\tconst print = input.print ?? ((l: string) => console.log(l));\n\tconst logger = input.logger ?? getLogger();\n\tconst importer = input.importer ?? defaultImporter;\n\tconst { provider } = input;\n\tconst keyringKey = input.org ? `${provider}.${input.org}` : provider;\n\n\tconst token = resolveAuthSetToken({ provider, positional: input.positional, env: input.env });\n\n\t// Feature sub-keys (e.g. \"github.read\") are stored directly — there is no\n\t// per-feature plugin package to load for verification.\n\tconst isFeatureKey = provider.includes(\".\");\n\tconst packageName = isFeatureKey ? null : resolvePluginPackage(provider);\n\n\tif (!token) {\n\t\tprint(style.fail(`no token supplied for \\`${keyringKey}\\`.`));\n\t\tprint(style.hint(` pass as positional arg: holocron auth set ${provider} <token>`));\n\t\tif (!isFeatureKey) {\n\t\t\tprint(\n\t\t\t\tstyle.hint(` or via env: HOLOCRON_${provider.toUpperCase()}_TOKEN / ${provider.toUpperCase()}_TOKEN`)\n\t\t\t);\n\t\t\tconst hint = await tryLoadHint(importer, packageName!);\n\t\t\tif (hint) {\n\t\t\t\tprint(style.hint(` hint: ${hint}`));\n\t\t\t}\n\t\t}\n\t\tlogger.warn({ provider, keyringKey, reason: \"no token supplied\" }, `auth set: ${keyringKey}`);\n\t\treturn { status: \"fail\", message: \"no token supplied\" };\n\t}\n\n\t// Verify via the plugin if it exports verifyToken (skipped for feature sub-keys).\n\tlet subject: string | undefined;\n\tif (!isFeatureKey && packageName) {\n\t\ttry {\n\t\t\tconst module = await importer(packageName);\n\t\t\tif (typeof module.verifyToken === \"function\") {\n\t\t\t\tconst verified = await module.verifyToken(token);\n\t\t\t\tif (!verified.ok) {\n\t\t\t\t\tprint(style.fail(`token rejected by ${provider}: ${verified.message}`));\n\t\t\t\t\tif (module.AUTH_HINT) print(style.hint(` hint: ${module.AUTH_HINT}`));\n\t\t\t\t\tlogger.warn(\n\t\t\t\t\t\t{ provider, keyringKey, verified: false, reason: verified.message },\n\t\t\t\t\t\t`auth set: ${keyringKey}`\n\t\t\t\t\t);\n\t\t\t\t\treturn { status: \"fail\", message: verified.message };\n\t\t\t\t}\n\t\t\t\tsubject = verified.subject;\n\t\t\t} else {\n\t\t\t\tprint(style.warn(`${provider} plugin has no verifyToken; storing without verification`));\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\tprint(style.warn(`cannot verify token — failed to load ${packageName}: ${msg}`));\n\t\t\tprint(\n\t\t\t\tstyle.hint(` storing token anyway; run 'holocron auth check ${provider}' once the plugin is installed`)\n\t\t\t);\n\t\t}\n\t}\n\n\tconst stored = setToken(keyringKey, token);\n\tif (!stored) {\n\t\tprint(style.fail(`keyring unavailable — token not stored. Use env vars instead.`));\n\t\tlogger.warn({ provider, keyringKey, reason: \"keyring unavailable\" }, `auth set: ${keyringKey}`);\n\t\treturn { status: \"fail\", message: \"keyring unavailable\" };\n\t}\n\n\tprint(style.success(`stored ${keyringKey} token${subject ? ` (${subject})` : \"\"}`));\n\tlogger.info(\n\t\t{ provider, keyringKey, verified: subject !== undefined, ...(subject ? { subject } : {}), status: \"ok\" },\n\t\t`auth set: ${keyringKey}`\n\t);\n\treturn { status: \"ok\", ...(subject ? { message: subject } : {}) };\n}\n\nexport interface RunAuthUnsetInput {\n\tprovider: string;\n\tprint?: AuthPrint;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n}\n\nexport function runAuthUnset(input: RunAuthUnsetInput): AuthCommandStatus {\n\tconst print = input.print ?? ((l: string) => console.log(l));\n\tconst logger = input.logger ?? getLogger();\n\tconst removed = deleteToken(input.provider);\n\tif (removed) {\n\t\tprint(style.success(`removed ${input.provider} token`));\n\t\tlogger.info({ provider: input.provider, status: \"ok\" }, `auth unset: ${input.provider}`);\n\t\treturn { status: \"ok\" };\n\t}\n\tprint(style.dim(`no stored token for ${input.provider}`));\n\tlogger.info({ provider: input.provider, status: \"skip\" }, `auth unset: ${input.provider}`);\n\treturn { status: \"skip\", message: \"nothing to remove\" };\n}\n\nexport interface RunAuthCheckInput {\n\tprovider: string;\n\timporter?: AuthImporter;\n\tprint?: AuthPrint;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n\t/** Set to false to suppress the ora spinner (e.g. when called from runAuthList). */\n\tshowSpinner?: boolean;\n\t/** When set, checks the token stored under `<provider>.<org>` in the keyring. */\n\torg?: string;\n}\n\nexport async function runAuthCheck(input: RunAuthCheckInput): Promise<AuthCommandStatus> {\n\tconst print = input.print ?? ((l: string) => console.log(l));\n\tconst logger = input.logger ?? getLogger();\n\tconst importer = input.importer ?? defaultImporter;\n\tconst { provider } = input;\n\tconst keyringKey = input.org ? `${provider}.${input.org}` : provider;\n\n\tconst token = getToken(keyringKey);\n\tif (!token) {\n\t\tprint(style.dim(`no stored token for ${keyringKey}`));\n\t\tlogger.info({ provider, keyringKey, status: \"skip\", reason: \"no stored token\" }, `auth check: ${keyringKey}`);\n\t\treturn { status: \"skip\", message: \"no stored token\" };\n\t}\n\n\t// Feature sub-keys have no plugin to verify against — report stored only.\n\tif (provider.includes(\".\")) {\n\t\tprint(style.success(`${keyringKey}: token stored (feature key — no plugin verification)`));\n\t\treturn { status: \"ok\", message: \"stored\" };\n\t}\n\n\tconst packageName = resolvePluginPackage(provider);\n\ttry {\n\t\tconst module = await importer(packageName);\n\t\tif (typeof module.verifyToken !== \"function\") {\n\t\t\tprint(style.warn(`${keyringKey}: token stored (plugin has no verifyToken; can't confirm validity)`));\n\t\t\treturn { status: \"ok\", message: \"stored, unverified\" };\n\t\t}\n\t\tconst verify = () => module.verifyToken!(token);\n\t\tconst verified =\n\t\t\tinput.showSpinner !== false ? await withSpinner(`Verifying ${keyringKey} token…`, verify) : await verify();\n\t\tif (verified.ok) {\n\t\t\tprint(style.success(`${keyringKey}: ok — ${verified.subject}`));\n\t\t\tlogger.info(\n\t\t\t\t{ provider, keyringKey, verified: true, subject: verified.subject, status: \"ok\" },\n\t\t\t\t`auth check: ${keyringKey}`\n\t\t\t);\n\t\t\treturn { status: \"ok\", message: verified.subject };\n\t\t}\n\t\tprint(style.fail(`${keyringKey}: rejected — ${verified.message}`));\n\t\tif (module.AUTH_HINT) print(style.hint(` hint: ${module.AUTH_HINT}`));\n\t\tlogger.warn(\n\t\t\t{ provider, keyringKey, verified: false, reason: verified.message, status: \"fail\" },\n\t\t\t`auth check: ${keyringKey}`\n\t\t);\n\t\treturn { status: \"fail\", message: verified.message };\n\t} catch (err) {\n\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t// Global install: the plugin package isn't resolvable here. `auth set` /\n\t\t// `auth list` already work plugin-free — `auth check` degrades to the\n\t\t// same \"we have a token, we just can't confirm it\" report rather than\n\t\t// failing outright (theholocron/holocron#576).\n\t\tif (isModuleNotFound(err)) {\n\t\t\tprint(style.warn(`${keyringKey}: token present — verification skipped (plugin not available here)`));\n\t\t\tlogger.info(\n\t\t\t\t{ provider, keyringKey, status: \"ok\", reason: \"plugin not resolvable\" },\n\t\t\t\t`auth check: ${keyringKey}`\n\t\t\t);\n\t\t\treturn { status: \"ok\", message: \"stored, unverified (plugin not available)\" };\n\t\t}\n\t\tprint(style.fail(`${keyringKey}: cannot verify — ${msg}`));\n\t\tlogger.warn({ provider, keyringKey, reason: msg, status: \"fail\" }, `auth check: ${keyringKey}`);\n\t\treturn { status: \"fail\", message: msg };\n\t}\n}\n\nexport interface RunAuthListInput {\n\timporter?: AuthImporter;\n\tprint?: AuthPrint;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n}\n\nexport async function runAuthList(input: RunAuthListInput = {}): Promise<AuthCommandStatus> {\n\tconst print = input.print ?? ((l: string) => console.log(l));\n\tconst logger = input.logger ?? getLogger();\n\tconst importer = input.importer ?? defaultImporter;\n\tconst providers = listStoredProviders();\n\n\tif (providers.length === 0) {\n\t\tprint(style.dim(\"no stored tokens.\"));\n\t\tprint(style.hint(\"run: holocron auth set <provider> <token>\"));\n\t\tlogger.info({ providers: 0 }, \"auth list: done\");\n\t\treturn { status: \"ok\", message: \"none\" };\n\t}\n\n\tlet ok = 0;\n\tlet fail = 0;\n\tfor (const provider of providers.sort()) {\n\t\tconst check = await runAuthCheck({ provider, importer, print: () => {}, logger, showSpinner: false });\n\t\tconst label = `${provider}${check.message ? ` — ${check.message}` : \"\"}`;\n\t\tif (check.status === \"ok\") {\n\t\t\tok += 1;\n\t\t\tprint(` ${style.success(label)}`);\n\t\t} else if (check.status === \"fail\") {\n\t\t\tfail += 1;\n\t\t\tprint(` ${style.fail(label)}`);\n\t\t} else print(` ${style.dim(`· ${label}`)}`);\n\t}\n\tlogger.info({ providers: providers.length, ok, fail }, \"auth list: done\");\n\treturn { status: \"ok\" };\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────\n\nasync function tryLoadHint(importer: AuthImporter, packageName: string): Promise<string | null> {\n\ttry {\n\t\tconst module = await importer(packageName);\n\t\treturn module.AUTH_HINT ?? null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n","import { checkbox } from \"@inquirer/prompts\";\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport type { LoadedConfig } from \"../config/load-config.js\";\nimport { getLogger } from \"../logger.js\";\nimport type { Deployment, DeploymentRecord, PullRequest, Source } from \"../plugin/capabilities.js\";\nimport { PluginLoader, type RuntimeContext } from \"../plugin/loader.js\";\nimport { assertPluginsResolvable } from \"../plugin/workspace.js\";\nimport { style } from \"../ui/style.js\";\n\nexport interface RunCleanupPreviewInput {\n\tloaded: LoadedConfig;\n\tcontext: RuntimeContext;\n\t/** PR number to look up on the source provider. */\n\tprNumber: number;\n\t/**\n\t * \"owner/name\" override — when provided, the PR is looked up in this repo\n\t * instead of the one the source plugin is scoped to.\n\t */\n\trepo?: string;\n\t/** Cloudflare Pages project name (e.g. \"theholocron-preview\"). */\n\tproject: string;\n\tloader?: PluginLoader;\n\tprint?: (line: string) => void;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n}\n\nexport interface CleanupPreviewReport {\n\tpr: PullRequest;\n\t/** Branch alias used to query Cloudflare (e.g. \"holocron-pr-42\"). */\n\tbranch: string;\n\tfound: number;\n\tdeleted: number;\n\tstatus: \"ok\" | \"none\" | \"aborted\" | \"fail\";\n\tmessage?: string;\n}\n\nfunction prStateLabel(pr: PullRequest): string {\n\tif (pr.merged) return style.success(\"merged\");\n\tif (pr.state === \"closed\") return style.dim(\"closed (not merged)\");\n\treturn style.warn(\"open\");\n}\n\nexport async function runCleanupPreview(input: RunCleanupPreviewInput): Promise<CleanupPreviewReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\t// c8 ignore next -- real PluginLoader construction is integration-level; unit tests always supply loader\n\tconst loader = input.loader ?? new PluginLoader(input.loaded.resolved, input.context);\n\tawait loader.load();\n\tassertPluginsResolvable(loader, \"cleanup-preview\");\n\tlogger.info({ pr: input.prNumber, project: input.project }, \"cleanup-preview: start\");\n\n\t// ── 1. Look up the PR ───────────────────────────────────────────────\n\tif (!loader.has(\"source\")) {\n\t\tthrow new Error(\"source capability is not configured — add a source provider to holocron.config.json\");\n\t}\n\tconst source = loader.get(\"source\") as Source;\n\tif (!source.getPullRequest) {\n\t\tthrow new Error(`${source.providerName} source provider does not support getPullRequest`);\n\t}\n\n\tlet pr: PullRequest;\n\ttry {\n\t\tpr = await source.getPullRequest(input.prNumber, input.repo);\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to fetch PR #${input.prNumber}: ${message}`, { cause: err });\n\t}\n\n\t// Derive the Cloudflare branch alias from the repo name and PR number.\n\t// Matches the convention the deploy-preview workflow uses:\n\t// --branch ${{ github.event.repository.name }}-pr-${{ github.event.pull_request.number }}\n\tconst repoName = (input.repo ?? input.loaded.resolved.repo?.name ?? \"\").split(\"/\").pop()!;\n\tconst branch = `${repoName}-pr-${pr.number}`;\n\n\tprint(\"\");\n\tprint(`${style.header(`PR #${pr.number}`)} — ${pr.title}`);\n\tprint(` Status : ${prStateLabel(pr)} | Branch : ${style.dim(pr.branch)}`);\n\tprint(` URL : ${style.dim(pr.url)}`);\n\tprint(` CF alias : ${style.dim(branch)}`);\n\tprint(\"\");\n\n\t// ── 2. List deployments ─────────────────────────────────────────────\n\tif (!loader.has(\"deployment\")) {\n\t\tthrow new Error(\"deployment capability is not configured — add a deployment provider to holocron.config.json\");\n\t}\n\tconst deploy = loader.get(\"deployment\") as Deployment;\n\tif (!deploy.listPreviewDeployments || !deploy.deletePreviewDeployments) {\n\t\tthrow new Error(`${deploy.providerName} deployment provider does not support preview cleanup`);\n\t}\n\n\tlet deployments: DeploymentRecord[];\n\ttry {\n\t\tdeployments = await deploy.listPreviewDeployments(input.project, branch);\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to list deployments: ${message}`, { cause: err });\n\t}\n\n\tif (deployments.length === 0) {\n\t\tprint(style.dim(`No deployments found for branch ${branch}.`));\n\t\tlogger.info({ pr: pr.number, branch, found: 0, deleted: 0, status: \"none\" }, \"cleanup-preview: done\");\n\t\treturn { pr, branch, found: 0, deleted: 0, status: \"none\" };\n\t}\n\n\tprint(`Found ${deployments.length} deployment${deployments.length === 1 ? \"\" : \"s\"} for ${style.dim(branch)}:`);\n\tprint(\"\");\n\n\tif (pr.state === \"open\") {\n\t\tprint(\n\t\t\tstyle.warn(\n\t\t\t\t`PR #${pr.number} is still open. Deleting its preview deployments will break the live preview link.`\n\t\t\t)\n\t\t);\n\t\tprint(style.warn(\"Nothing is pre-selected — check the deployments you want to remove.\"));\n\t\tprint(\"\");\n\t}\n\n\t// ── 3. Interactive selection ────────────────────────────────────────\n\tconst choices = deployments.map((d) => {\n\t\tconst label = d.id.includes(\":\") ? d.id.split(\":\").pop()! : d.id;\n\t\tconst date = d.createdAt ? style.dim(d.createdAt.slice(0, 10)) : \"\";\n\t\treturn {\n\t\t\tname: `${label} ${date} ${style.dim(d.url)}`,\n\t\t\tvalue: d.id,\n\t\t\tchecked: pr.state !== \"open\",\n\t\t};\n\t});\n\n\tlet selected: string[];\n\ttry {\n\t\tselected = await checkbox({\n\t\t\tmessage: \"Select deployments to delete (space to toggle, a to select all, enter to confirm):\",\n\t\t\tchoices,\n\t\t});\n\t} catch {\n\t\t// Ctrl-C\n\t\tprint(style.dim(\"Aborted.\"));\n\t\treturn { pr, branch, found: deployments.length, deleted: 0, status: \"aborted\" };\n\t}\n\n\tif (selected.length === 0) {\n\t\tprint(style.dim(\"Nothing selected — no deployments deleted.\"));\n\t\treturn { pr, branch, found: deployments.length, deleted: 0, status: \"aborted\" };\n\t}\n\n\t// ── 4. Delete ───────────────────────────────────────────────────────\n\tprint(\"\");\n\ttry {\n\t\tconst count = await deploy.deletePreviewDeployments(input.project, selected);\n\t\tprint(style.success(`Deleted ${count} deployment${count === 1 ? \"\" : \"s\"}.`));\n\t\tlogger.info(\n\t\t\t{ pr: pr.number, branch, found: deployments.length, deleted: count, status: \"ok\" },\n\t\t\t\"cleanup-preview: done\"\n\t\t);\n\t\treturn { pr, branch, found: deployments.length, deleted: count, status: \"ok\" };\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tprint(style.fail(message));\n\t\tlogger.warn(\n\t\t\t{ pr: pr.number, branch, found: deployments.length, reason: message, status: \"fail\" },\n\t\t\t\"cleanup-preview: done\"\n\t\t);\n\t\treturn { pr, branch, found: deployments.length, deleted: 0, status: \"fail\", message };\n\t}\n}\n","import { spawnSync } from \"node:child_process\";\nimport { existsSync, mkdirSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\n\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport { getLogger } from \"../logger.js\";\nimport { style } from \"../ui/style.js\";\n\nfunction encodeTokenForGitHttpAuth(token: string): string {\n\tconst trimmed = token.trim();\n\tif (!trimmed) throw new Error(\"empty token\");\n\t// eslint-disable-next-line no-control-regex\n\tif (/[\\u0000-\\u001F\\u007F\\s]/.test(trimmed)) {\n\t\tthrow new Error(\"token contains whitespace or control characters\");\n\t}\n\treturn encodeURIComponent(trimmed);\n}\n\ninterface GitHubRepo {\n\tname: string;\n\tfull_name: string;\n\tclone_url: string;\n\tarchived: boolean;\n}\n\ntype ExecFn = (cmd: string, args: string[], opts: { cwd: string }) => { status: number | null };\n\nexport interface RunCloneInput {\n\torg: string;\n\t/** Parent directory to clone into. Defaults to ~/Code/<org>. */\n\tdir?: string;\n\ttoken: string;\n\tdryRun?: boolean;\n\tfetch?: typeof globalThis.fetch;\n\texec?: ExecFn;\n\tprint?: (line: string) => void;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n}\n\nexport interface CloneReport {\n\tstatus: \"ok\" | \"fail\" | \"dry-run\";\n\tcloned: number;\n\tskipped: number;\n\tfailed: number;\n\tmessage?: string;\n}\n\nasync function listOrgRepos(org: string, token: string, fetchFn: typeof globalThis.fetch): Promise<GitHubRepo[]> {\n\tconst repos: GitHubRepo[] = [];\n\tlet url: string | null = `https://api.github.com/orgs/${org}/repos?per_page=100&type=all`;\n\n\twhile (url) {\n\t\tconst res = await fetchFn(url, {\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\tAccept: \"application/vnd.github+json\",\n\t\t\t\t\"X-GitHub-Api-Version\": \"2022-11-28\",\n\t\t\t},\n\t\t});\n\n\t\tif (!res.ok) {\n\t\t\tthrow new Error(`GitHub API ${res.status}: ${res.statusText} — check that the token has org:read scope`);\n\t\t}\n\n\t\trepos.push(...((await res.json()) as GitHubRepo[]));\n\n\t\tconst link = res.headers.get(\"link\");\n\t\tconst next = link?.match(/<([^>]+)>;\\s*rel=\"next\"/);\n\t\turl = next ? next[1] : null;\n\t}\n\n\treturn repos;\n}\n\nexport async function runClone(input: RunCloneInput): Promise<CloneReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst fetchFn = input.fetch ?? globalThis.fetch;\n\tconst dryRun = input.dryRun ?? false;\n\tconst targetDir = resolve(input.dir ?? join(homedir(), \"Code\", input.org));\n\tlogger.info({ org: input.org, targetDir, dryRun: dryRun || undefined }, \"clone: start\");\n\tconst exec: ExecFn =\n\t\tinput.exec ??\n\t\t((cmd, args, opts) => {\n\t\t\tconst r = spawnSync(cmd, args, { cwd: opts.cwd, stdio: \"inherit\" });\n\t\t\treturn { status: r.status };\n\t\t});\n\n\tprint(style.header(`Holocron clone — org=${input.org} → ${targetDir}${dryRun ? \" (dry-run)\" : \"\"}`));\n\n\tif (!existsSync(targetDir)) {\n\t\tif (dryRun) {\n\t\t\tprint(style.dim(` would create ${targetDir}`));\n\t\t} else {\n\t\t\tmkdirSync(targetDir, { recursive: true });\n\t\t}\n\t}\n\n\tlet repos: GitHubRepo[];\n\ttry {\n\t\trepos = await listOrgRepos(input.org, input.token, fetchFn);\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tlogger.warn({ org: input.org, reason: message }, \"clone: failed to list org repos\");\n\t\treturn { status: \"fail\", cloned: 0, skipped: 0, failed: 0, message };\n\t}\n\n\tlet cloned = 0;\n\tlet skipped = 0;\n\tlet failed = 0;\n\n\tfor (const repo of repos) {\n\t\t// Strip leading dot so hidden repos (e.g. .github) are visible in Finder.\n\t\tconst dirName = repo.name.startsWith(\".\") ? repo.name.slice(1) : repo.name;\n\t\tconst dest = join(targetDir, dirName);\n\n\t\tif (existsSync(dest)) {\n\t\t\tprint(style.dim(` skip ${repo.full_name}`));\n\t\t\tskipped++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (dryRun) {\n\t\t\tprint(style.dim(` would clone ${repo.full_name} → ${dest}`));\n\t\t\tcloned++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tprint(style.step(` clone ${repo.full_name}`));\n\t\tconst { clone_url } = repo;\n\t\tif (!clone_url.startsWith(\"https://github.com/\")) {\n\t\t\tprint(style.fail(` failed ${repo.full_name} — unexpected clone URL: ${clone_url}`));\n\t\t\tfailed++;\n\t\t\tcontinue;\n\t\t}\n\t\tlet encodedToken: string;\n\t\ttry {\n\t\t\tencodedToken = encodeTokenForGitHttpAuth(input.token);\n\t\t} catch (err) {\n\t\t\tprint(\n\t\t\t\tstyle.fail(\n\t\t\t\t\t` failed ${repo.full_name} — invalid token format: ${err instanceof Error ? err.message : String(err)}`\n\t\t\t\t)\n\t\t\t);\n\t\t\tfailed++;\n\t\t\tcontinue;\n\t\t}\n\t\tconst authedUrl = `https://x-access-token:${encodedToken}@github.com/${clone_url.slice(\"https://github.com/\".length)}`;\n\t\tconst result = exec(\"git\", [\"clone\", \"--\", authedUrl, dest], { cwd: targetDir });\n\n\t\tif (result.status !== 0) {\n\t\t\tprint(style.fail(` failed ${repo.full_name}`));\n\t\t\tfailed++;\n\t\t} else {\n\t\t\tprint(style.success(` cloned ${repo.name}`));\n\t\t\tcloned++;\n\t\t}\n\t}\n\n\tconst summary = `${cloned} cloned, ${skipped} skipped, ${failed} failed`;\n\tprint(\n\t\tdryRun\n\t\t\t? style.dim(`\\n dry-run: ${summary}`)\n\t\t\t: failed > 0\n\t\t\t\t? style.fail(`\\n ${summary}`)\n\t\t\t\t: style.success(`\\n ${summary}`)\n\t);\n\n\tconst status = dryRun ? \"dry-run\" : failed > 0 ? \"fail\" : \"ok\";\n\tlogger[failed > 0 ? \"warn\" : \"info\"]({ org: input.org, status, cloned, skipped, failed }, \"clone: done\");\n\treturn { status, cloned, skipped, failed };\n}\n","/**\n * Every command's **execution context** — the single source of truth for\n * how much of a repo a command needs around it to do its job.\n *\n * `npm i -g @theholocron/cli` gives you the binary and nothing else: no\n * `holocron.config`, no plugin packages. A large slice of the command\n * surface is fine with that; the rest needs a repo, and a few need the\n * provider plugins resolvable as well. Tagging each command lets the CLI\n *\n * 1. fail a `workspace` command **gracefully** when the plugins can't be\n * resolved (see {@link ../plugin/workspace.js}), instead of leaking a\n * raw `Cannot find package '@theholocron/holocron-plugin-*'`, and\n * 2. group `holocron --help` / the docs by what a bare global install\n * actually gets you.\n *\n * Spec: `docs/wiki/specifications/tech-cli-execution-contexts.spec.md`\n * (theholocron/holocron#576). Shared with the interactive-menu registry\n * (theholocron/holocron#438).\n */\n\nexport type ExecutionContext = \"global\" | \"repo-aware\" | \"workspace\";\n\n/**\n * Command → context. Keys are the command name as it lands in yargs'\n * `argv._` — the full path for sub-commands (`\"auth set\"`, `\"upgrade\n * node\"`), the bare verb otherwise.\n *\n * - **`global`** — needs nothing but the CLI binary. Works anywhere.\n * - **`repo-aware`** — reads `./holocron.config` + `./package.json`\n * relative to cwd, but never touches the plugin loader.\n * - **`workspace`** — needs the configured providers' plugin packages to\n * resolve (devDeps in a repo, or `pnpm exec`).\n */\nexport const COMMAND_CONTEXTS = {\n\tversion: \"global\",\n\tclone: \"global\",\n\tnew: \"global\",\n\t\"upgrade node\": \"global\",\n\t\"upgrade deps\": \"global\",\n\t\"plugin create\": \"global\",\n\t\"auth set\": \"global\",\n\t\"auth unset\": \"global\",\n\t\"auth list\": \"global\",\n\t// `auth check` loads a plugin to verify, but degrades to \"token present,\n\t// verification skipped\" when the plugin isn't resolvable — so it's usable\n\t// from a global install. See `runAuthCheck`.\n\t\"auth check\": \"global\",\n\t\"bump-versions\": \"global\",\n\tpublish: \"global\",\n\t\"skills install\": \"global\",\n\t\"skills remove\": \"global\",\n\t\"skills update\": \"global\",\n\t\"lint commit-msg\": \"global\",\n\n\trun: \"repo-aware\",\n\tci: \"repo-aware\",\n\t\"config show\": \"repo-aware\",\n\t// Writes README + package.json metadata from config; never loads a plugin.\n\t\"sync-readme\": \"repo-aware\",\n\n\tdoctor: \"workspace\",\n\tsetup: \"workspace\",\n\t\"secret set\": \"workspace\",\n\t\"secrets sync\": \"workspace\",\n\tdeploy: \"workspace\",\n\t\"cleanup-preview\": \"workspace\",\n\tsync: \"workspace\",\n\t// Pushes generated templates to theholocron/.github — needs the holocron\n\t// monorepo checkout (not plugins), so only ever run with `pnpm exec`.\n\t\"sync-github\": \"workspace\",\n} as const satisfies Record<string, ExecutionContext>;\n\n/**\n * The context for a command name from `argv._`. Falls back to the leading\n * verb (`\"auth foo\"` → `\"auth\"`) and finally `undefined` for a name the\n * map doesn't know — callers treat unknown as \"don't guard\".\n */\nexport function contextForCommand(name: string): ExecutionContext | undefined {\n\tconst map = COMMAND_CONTEXTS as Record<string, ExecutionContext>;\n\tif (map[name]) return map[name];\n\tconst verb = name.split(\" \")[0] ?? \"\";\n\treturn map[verb];\n}\n\n/** Command names in a given context, in registration order. */\nexport function commandsInContext(context: ExecutionContext): string[] {\n\treturn Object.entries(COMMAND_CONTEXTS)\n\t\t.filter(([, c]) => c === context)\n\t\t.map(([name]) => name);\n}\n","/**\n * `holocron deploy` — trigger a deployment via the configured\n * `deployment` capability.\n *\n * Two modes, one command: `runDeploy` (the default — a Git branch,\n * `triggerDeployment()`) and `runDeployFromFiles` (`--files <dir>` —\n * a local directory of source files, `deployFunction()`, no linked\n * repo required — for a consumer with no Git history to deploy from,\n * e.g. Sentinel, shipped as an npm package). Separate functions, not\n * one branching `runDeploy`, because their inputs genuinely differ\n * (`branch` vs `dir`) and their result shapes differ too\n * (`DeploymentRecord` carries `status`/`branch`; `DeployFunctionResult`\n * is deliberately minimal, same as `DeployScriptResult` for Workers).\n *\n * Errors clearly when `deployment` isn't loaded (no provider declared\n * in `holocron.config.json`), or when the configured provider doesn't\n * implement `deployFunction` (it's optional on `Deployment` — not\n * every provider has a files-based deploy API).\n *\n * Dry-run skips the actual deploy call but still verifies the\n * deployment capability (and, for `--files`, `deployFunction`) is\n * present, so operators can sanity-check the wiring without spinning\n * up a build.\n */\n\nimport { readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { join, relative, sep } from \"node:path\";\n\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport type { LoadedConfig } from \"../config/load-config.js\";\nimport { getLogger } from \"../logger.js\";\nimport type { DeployFunctionResult, Deployment, DeploymentRecord, DeploymentTrigger } from \"../plugin/capabilities.js\";\nimport { PluginLoader, type RuntimeContext } from \"../plugin/loader.js\";\nimport { assertPluginsResolvable } from \"../plugin/workspace.js\";\nimport { withSpinner } from \"../ui/progress.js\";\nimport { style } from \"../ui/style.js\";\n\nexport type DeployPrintLine = (line: string) => void;\n\n/**\n * Provider `url` fields (Vercel's REST API, at least) come back as bare\n * hostnames — `\"my-app.vercel.app\"`, no scheme — which terminals don't\n * linkify and browsers won't navigate to unmodified. Printed output\n * should be a URL a human can click/paste; structured log fields keep\n * the raw provider value as-is.\n */\nfunction withScheme(url: string): string {\n\treturn /^https?:\\/\\//.test(url) ? url : `https://${url}`;\n}\n\nexport interface RunDeployInput {\n\tloaded: LoadedConfig;\n\tcontext: RuntimeContext;\n\t/** Vendor project id (e.g., Vercel prj_*). Required. */\n\tprojectId: string;\n\t/** Git branch to deploy. */\n\tbranch: string;\n\t/** Named target — `undefined` means branch preview. */\n\ttarget?: DeploymentTrigger;\n\tloader?: PluginLoader;\n\tprint?: DeployPrintLine;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n}\n\nexport interface DeployReport {\n\t/** Null in dry-run mode (no actual deployment was triggered). */\n\tdeployment: DeploymentRecord | null;\n\tstatus: \"ok\" | \"fail\" | \"dry-run\";\n\tmessage?: string;\n}\n\nexport async function runDeploy(input: RunDeployInput): Promise<DeployReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst loader = input.loader ?? new PluginLoader(input.loaded.resolved, input.context);\n\tawait loader.load();\n\tassertPluginsResolvable(loader, \"deploy\");\n\n\tconst dryRun = input.context.dryRun ?? false;\n\tlogger.info(\n\t\t{\n\t\t\tbranch: input.branch,\n\t\t\ttarget: input.target ?? \"preview\",\n\t\t\tprojectId: input.projectId,\n\t\t\tdryRun: dryRun || undefined,\n\t\t},\n\t\t\"deploy: start\"\n\t);\n\n\tprint(\n\t\tstyle.header(\n\t\t\t`Holocron deploy — branch=${input.branch}${\n\t\t\t\tinput.target ? `, target=${input.target}` : \" (preview)\"\n\t\t\t}${dryRun ? \" (dry-run)\" : \"\"}`\n\t\t)\n\t);\n\n\tif (!loader.has(\"deployment\")) {\n\t\tthrow new Error(\n\t\t\t\"deployment capability is not configured — add a `deployment` provider to holocron.config.json\"\n\t\t);\n\t}\n\tconst deploy = loader.get(\"deployment\") as Deployment;\n\n\tif (dryRun) {\n\t\tconst message = `would: ${deploy.providerName}.triggerDeployment(projectId=${input.projectId}, branch=${input.branch}${\n\t\t\tinput.target ? `, target=${input.target}` : \"\"\n\t\t})`;\n\t\tprint(` ${style.dim(`… ${message}`)}`);\n\t\treturn { deployment: null, status: \"dry-run\", message };\n\t}\n\n\ttry {\n\t\tconst record = await withSpinner(`Deploying ${input.branch}${input.target ? ` → ${input.target}` : \"\"}…`, () =>\n\t\t\tdeploy.triggerDeployment({\n\t\t\t\tprojectId: input.projectId,\n\t\t\t\tbranch: input.branch,\n\t\t\t\t...(input.target ? { target: input.target } : {}),\n\t\t\t})\n\t\t);\n\t\tprint(` ${style.success(`${record.status} — ${withScheme(record.url)}`)}`);\n\t\tlogger.info({ status: record.status, url: record.url, id: record.id }, \"deploy: triggered\");\n\t\treturn { deployment: record, status: \"ok\" };\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tprint(` ${style.fail(message)}`);\n\t\tlogger.warn({ branch: input.branch, reason: message }, \"deploy: failed\");\n\t\treturn { deployment: null, status: \"fail\", message };\n\t}\n}\n\n// ── deploy --files (deployFunction) ─────────────────────────────────────\n\nexport interface RunDeployFromFilesInput {\n\tloaded: LoadedConfig;\n\tcontext: RuntimeContext;\n\t/** Vendor project id (e.g., Vercel prj_*). Required. */\n\tprojectId: string;\n\t/** Local directory to deploy — walked recursively. Files are keyed by\n\t * their path relative to this directory, POSIX-separated. */\n\tdir: string;\n\t/** Named target — `undefined` means preview. */\n\ttarget?: DeploymentTrigger;\n\tloader?: PluginLoader;\n\tprint?: DeployPrintLine;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n\t/** Injectable for testing. */\n\twalkFiles?: (dir: string) => string[];\n\treadFile?: (path: string) => string;\n}\n\nexport interface DeployFilesReport {\n\t/** Null in dry-run mode or on failure — no actual deployment was created. */\n\tdeployment: DeployFunctionResult | null;\n\tstatus: \"ok\" | \"fail\" | \"dry-run\";\n\tmessage?: string;\n}\n\n// Deliberately no \"dist\" here, unlike holocron new's own file-walker this\n// was modeled on: --files exists specifically to deploy build output, so\n// a directory literally named \"dist\" is exactly what a caller usually\n// means to include, not exclude.\nconst SKIP_DIRS = new Set([\".git\", \"node_modules\", \".turbo\"]);\n\n/** Recursively lists absolute file paths under `dir`, skipping VCS/tooling noise. */\nfunction defaultWalkFiles(dir: string): string[] {\n\tconst results: string[] = [];\n\tfor (const entry of readdirSync(dir)) {\n\t\tif (SKIP_DIRS.has(entry)) continue;\n\t\tconst full = join(dir, entry);\n\t\tconst stat = statSync(full);\n\t\tif (stat.isDirectory()) results.push(...defaultWalkFiles(full));\n\t\telse if (stat.isFile()) results.push(full);\n\t}\n\treturn results;\n}\n\n/** `holocron deploy --files <dir>` — the non-git counterpart to `runDeploy`. */\nexport async function runDeployFromFiles(input: RunDeployFromFilesInput): Promise<DeployFilesReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst loader = input.loader ?? new PluginLoader(input.loaded.resolved, input.context);\n\tawait loader.load();\n\tassertPluginsResolvable(loader, \"deploy\");\n\n\tconst dryRun = input.context.dryRun ?? false;\n\tconst walkFiles = input.walkFiles ?? defaultWalkFiles;\n\tconst readFile = input.readFile ?? ((p: string) => readFileSync(p, \"utf8\"));\n\n\tconst files: Record<string, string> = {};\n\tfor (const abs of walkFiles(input.dir)) {\n\t\tconst rel = relative(input.dir, abs).split(sep).join(\"/\");\n\t\tfiles[rel] = readFile(abs);\n\t}\n\tconst fileCount = Object.keys(files).length;\n\n\tlogger.info(\n\t\t{\n\t\t\tdir: input.dir,\n\t\t\tfileCount,\n\t\t\ttarget: input.target ?? \"preview\",\n\t\t\tprojectId: input.projectId,\n\t\t\tdryRun: dryRun || undefined,\n\t\t},\n\t\t\"deploy: start (files)\"\n\t);\n\n\tprint(\n\t\tstyle.header(\n\t\t\t`Holocron deploy — files=${input.dir} (${fileCount} file${fileCount === 1 ? \"\" : \"s\"})${\n\t\t\t\tinput.target ? `, target=${input.target}` : \" (preview)\"\n\t\t\t}${dryRun ? \" (dry-run)\" : \"\"}`\n\t\t)\n\t);\n\n\tif (!loader.has(\"deployment\")) {\n\t\tthrow new Error(\n\t\t\t\"deployment capability is not configured — add a `deployment` provider to holocron.config.json\"\n\t\t);\n\t}\n\tconst deploy = loader.get(\"deployment\") as Deployment;\n\tif (!deploy.deployFunction) {\n\t\tthrow new Error(\n\t\t\t`deployment provider \"${deploy.providerName}\" does not support deploying from files — deployFunction() is not implemented`\n\t\t);\n\t}\n\n\tif (dryRun) {\n\t\tconst message = `would: ${deploy.providerName}.deployFunction(projectId=${input.projectId}, files=${fileCount}${\n\t\t\tinput.target ? `, target=${input.target}` : \"\"\n\t\t})`;\n\t\tprint(` ${style.dim(`… ${message}`)}`);\n\t\treturn { deployment: null, status: \"dry-run\", message };\n\t}\n\n\ttry {\n\t\tconst result = await withSpinner(\n\t\t\t`Deploying ${fileCount} file${fileCount === 1 ? \"\" : \"s\"} from ${input.dir}…`,\n\t\t\t() => deploy.deployFunction!(input.projectId, { files, ...(input.target ? { target: input.target } : {}) })\n\t\t);\n\t\tprint(` ${style.success(withScheme(result.url))}`);\n\t\tlogger.info({ url: result.url, id: result.deploymentId }, \"deploy: triggered (files)\");\n\t\treturn { deployment: result, status: \"ok\" };\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tprint(` ${style.fail(message)}`);\n\t\tlogger.warn({ dir: input.dir, reason: message }, \"deploy: failed (files)\");\n\t\treturn { deployment: null, status: \"fail\", message };\n\t}\n}\n","/**\n * `holocron doctor` — load the config, instantiate every capability,\n * print a per-capability readiness report.\n *\n * Each capability gets a smoke check appropriate to its surface:\n * source → `whoami()`\n * issues → `doctor()` (rich report)\n * secrets → `listSecrets({ kind: 'repo' })`\n * ci → `listRuns({ limit: 1 })`\n * errors → `describe()`\n * logs → `whoami()` (dataset reachability) or `describe()`\n * others → just \"loaded\" (no smoke endpoint defined yet)\n *\n * Output is plain text via a passed-in `print` function so tests can\n * capture lines without ANSI / spinner noise.\n */\n\nimport type { LoadedConfig } from \"../config/load-config.js\";\nimport { getLogger } from \"../logger.js\";\nimport type { Auth, Ci, Errors, Issues, Logs, Secrets, Source, Vault } from \"../plugin/capabilities.js\";\nimport { CARDINALITY } from \"../plugin/capabilities.js\";\nimport { PluginLoader, type RuntimeContext } from \"../plugin/loader.js\";\nimport { assertPluginsResolvable } from \"../plugin/workspace.js\";\nimport { withSpinner } from \"../ui/progress.js\";\nimport { style } from \"../ui/style.js\";\n\nexport type DoctorPrintLine = (line: string) => void;\n\nexport type DoctorStatus = \"ok\" | \"fail\" | \"skip\";\n\nexport interface DoctorRow {\n\tcapability: string;\n\tprovider: string;\n\tstatus: DoctorStatus;\n\tmessage: string;\n}\n\nexport interface DoctorReport {\n\trows: DoctorRow[];\n\tsummary: { ok: number; fail: number; skip: number };\n}\n\nexport interface RunDoctorInput {\n\tloaded: LoadedConfig;\n\tcontext: RuntimeContext;\n\t/** Lets tests inject mock plugins; defaults to native dynamic import. */\n\tloader?: PluginLoader;\n\tprint?: DoctorPrintLine;\n}\n\nexport async function runDoctor(input: RunDoctorInput): Promise<DoctorReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst loader = input.loader ?? new PluginLoader(input.loaded.resolved, input.context);\n\tawait withSpinner(\"Loading plugins…\", () => loader.load());\n\t// A global install has no plugin packages to resolve — say so plainly\n\t// instead of printing a report that's all \"Cannot find package\" rows.\n\tassertPluginsResolvable(loader, \"doctor\");\n\n\tconst rows: DoctorRow[] = [];\n\tconst config = input.loaded.resolved;\n\n\tprint(style.header(`Holocron doctor — ${config.name}`));\n\tprint(style.dim(` config: ${input.loaded.filepath}`));\n\tprint(\"\");\n\n\t// Providers that never loaded (missing token, package not installed) —\n\t// the most actionable rows in the report.\n\tfor (const failure of loader.loadFailures()) {\n\t\trows.push({\n\t\t\tcapability: failure.key,\n\t\t\tprovider: failure.provider,\n\t\t\tstatus: \"fail\",\n\t\t\tmessage: failure.error.message,\n\t\t});\n\t}\n\n\tfor (const key of loader.loadedKeys()) {\n\t\tconst cardinality = CARDINALITY[key];\n\t\tconst entry = config.providers[key];\n\t\tconst providers =\n\t\t\tentry?.cardinality === \"many\"\n\t\t\t\t? entry.tuples.map((t) => t.provider)\n\t\t\t\t: entry?.cardinality === \"single\"\n\t\t\t\t\t? [entry.tuple.provider]\n\t\t\t\t\t: [];\n\n\t\tif (cardinality === \"many\") {\n\t\t\tconst impls = loader.get(key) as unknown as unknown[];\n\t\t\timpls.forEach((_impl, idx) => {\n\t\t\t\trows.push({\n\t\t\t\t\tcapability: key,\n\t\t\t\t\tprovider: providers[idx] ?? \"?\",\n\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\tmessage: \"loaded (no smoke check defined for this capability)\",\n\t\t\t\t});\n\t\t\t});\n\t\t} else {\n\t\t\tconst impl = loader.get(key) as unknown;\n\t\t\tconst row = await smokeCheck(key, providers[0] ?? \"?\", impl);\n\t\t\trows.push(row);\n\t\t}\n\t}\n\n\tconst log = getLogger();\n\t// Render rows\n\tfor (const row of rows) {\n\t\tlog[row.status === \"fail\" ? \"warn\" : \"info\"](\n\t\t\t{ capability: row.capability, provider: row.provider, status: row.status, detail: row.message },\n\t\t\t`doctor: ${row.capability}`\n\t\t);\n\t\tconst label = `${pad(row.capability, 14)} via ${pad(row.provider, 14)} ${row.message}`;\n\t\tif (row.status === \"ok\") print(` ${style.success(label)}`);\n\t\telse if (row.status === \"fail\") print(` ${style.fail(label)}`);\n\t\telse print(` ${style.dim(`· ${label}`)}`);\n\t}\n\n\tconst summary = rows.reduce(\n\t\t(acc, r) => {\n\t\t\tacc[r.status] += 1;\n\t\t\treturn acc;\n\t\t},\n\t\t{ ok: 0, fail: 0, skip: 0 }\n\t);\n\n\tconst summaryLine = `${summary.ok} ok, ${summary.fail} fail, ${summary.skip} skipped`;\n\tprint(\"\");\n\tprint(summary.fail > 0 ? style.fail(summaryLine) : style.success(summaryLine));\n\n\treturn { rows, summary };\n}\n\n// ── smoke checks ────────────────────────────────────────────────────\n\nasync function smokeCheck(key: string, provider: string, impl: unknown): Promise<DoctorRow> {\n\ttry {\n\t\tswitch (key) {\n\t\t\tcase \"source\": {\n\t\t\t\tconst result = await (impl as Source).whoami();\n\t\t\t\treturn mk(key, provider, \"ok\", `whoami: ${result.login}`);\n\t\t\t}\n\t\t\tcase \"issues\": {\n\t\t\t\tconst report = await (impl as Issues).doctor();\n\t\t\t\treturn mk(\n\t\t\t\t\tkey,\n\t\t\t\t\tprovider,\n\t\t\t\t\t\"ok\",\n\t\t\t\t\t`${report.authedAs} / ${report.projectLabel} (${countResolvedLifecycle(report)})`\n\t\t\t\t);\n\t\t\t}\n\t\t\tcase \"secrets\": {\n\t\t\t\tconst names = await (impl as Secrets).listSecrets({ kind: \"repo\" });\n\t\t\t\treturn mk(key, provider, \"ok\", `repo secrets: ${names.length} configured`);\n\t\t\t}\n\t\t\tcase \"ci\": {\n\t\t\t\tconst runs = await (impl as Ci).listRuns({ limit: 1 });\n\t\t\t\treturn mk(\n\t\t\t\t\tkey,\n\t\t\t\t\tprovider,\n\t\t\t\t\t\"ok\",\n\t\t\t\t\truns.length === 0 ? \"no recent runs\" : `most recent: ${runs[0]!.workflowName} (${runs[0]!.status})`\n\t\t\t\t);\n\t\t\t}\n\t\t\tcase \"vault\": {\n\t\t\t\tconst keys = await (impl as Vault).list();\n\t\t\t\treturn mk(key, provider, \"ok\", `${keys.length} keys available`);\n\t\t\t}\n\t\t\tcase \"auth\": {\n\t\t\t\tconst desc = await (impl as Auth).describe();\n\t\t\t\treturn mk(key, provider, \"ok\", `provider: ${desc.provider}; env keys: ${desc.envKeys.join(\", \")}`);\n\t\t\t}\n\t\t\tcase \"errors\": {\n\t\t\t\tconst desc = await (impl as Errors).describe();\n\t\t\t\treturn mk(key, provider, \"ok\", `provider: ${desc.provider}; env keys: ${desc.envKeys.join(\", \")}`);\n\t\t\t}\n\t\t\tcase \"logs\": {\n\t\t\t\tconst logs = impl as Logs;\n\t\t\t\tconst desc = await logs.describe();\n\t\t\t\tif (logs.whoami) {\n\t\t\t\t\tconst who = await logs.whoami();\n\t\t\t\t\treturn mk(key, provider, who.ok ? \"ok\" : \"fail\", `dataset: ${who.dataset}`);\n\t\t\t\t}\n\t\t\t\treturn mk(key, provider, \"ok\", `provider: ${desc.provider}; env keys: ${desc.envKeys.join(\", \")}`);\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn mk(key, provider, \"skip\", \"loaded (no smoke check defined for this capability)\");\n\t\t}\n\t} catch (err) {\n\t\treturn mk(key, provider, \"fail\", err instanceof Error ? err.message : String(err));\n\t}\n}\n\nfunction countResolvedLifecycle(report: Awaited<ReturnType<Issues[\"doctor\"]>>): string {\n\tconst resolved = report.lifecycle.filter((l) => l.resolved).length;\n\treturn `${resolved}/${report.lifecycle.length} lifecycle slots ready`;\n}\n\nfunction mk(capability: string, provider: string, status: DoctorStatus, message: string): DoctorRow {\n\treturn { capability, provider, status, message };\n}\n\nfunction pad(s: string, width: number): string {\n\treturn s.length >= width ? s : s + \" \".repeat(width - s.length);\n}\n","/**\n * `holocron new <type> <name>` — create a GitHub repo from a template and\n * bootstrap it by replacing all template-slug casing variants with the new\n * project name, then generate a `holocron.config.ts` from the answers given\n * during the interactive wizard.\n *\n * Flow:\n * 1. Preflight — verify `gh` CLI is available.\n * 2. Resolve type, name, description, homepage, vault/deployment/agent options.\n * 3. `gh repo create <org>/<name> --template <org>/<type>-template --private --clone`\n * → clones to `<cwd>/<name>/`\n * 4. Detect template slug from cloned package.json.\n * 5. Replace all casing variants of the slug across every text file.\n * 6. Replace `<description>` and `<homepage>` placeholders.\n * 7. Generate and write `holocron.config.ts` based on wizard answers.\n * 8. Commit the patched files (-s for DCO).\n * 9. Unless --no-verify: `pnpm install` in the new repo.\n * 10. Print next steps.\n */\n\nimport { execFileSync, spawnSync } from \"node:child_process\";\nimport { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\n\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport { env } from \"../env.js\";\nimport { getLogger } from \"../logger.js\";\n\n// ── Public API ────────────────────────────────────────────────────────\n\nexport type VaultProvider = \"doppler\" | \"1password\" | \"infisical\" | \"none\";\nexport type DeploymentProvider = \"vercel\" | \"none\";\nexport type AgentChoice = \"claude\" | \"none\";\nexport type RuntimeEnvironment = \"node\" | \"browser\" | \"universal\" | \"none\";\n\nexport interface RunNewInput {\n\ttype: string;\n\tname: string;\n\tdescription?: string;\n\thomepage?: string;\n\tvaultProvider?: VaultProvider;\n\tvaultProject?: string;\n\tvaultConfig?: string;\n\tdeploymentProvider?: DeploymentProvider;\n\tagent?: AgentChoice;\n\truntimeEnvironment?: RuntimeEnvironment;\n\tprotection?: string;\n\topenSource?: boolean;\n\tusesExternalPackages?: boolean;\n\ttopics?: string[];\n\tskills?: string[];\n\t/** Mark the new repo as a GitHub template repository. */\n\tisTemplate?: boolean;\n\t/** GitHub org that owns both the template and the new repo. Default: \"theholocron\". */\n\torg?: string;\n\t/** GitHub admin token forwarded to `holocron setup` during verify. */\n\ttoken?: string;\n\tdryRun?: boolean;\n\tnoVerify?: boolean;\n\t/** Parent directory where the repo will be cloned. Default: process.cwd(). */\n\tcwd?: string;\n\tprint?: (line: string) => void;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n\t/** Injectable subprocess runner for testing. */\n\texec?: (cmd: string, args: string[], opts: { cwd: string; stdio: \"inherit\"; env?: Record<string, string> }) => void;\n\t/** Injectable file writer for testing. */\n\twriteFile?: (filepath: string, content: string) => void;\n\t/** Injectable file reader for testing (returns utf-8 string). */\n\treadFile?: (filepath: string) => string;\n\t/** Injectable directory walker for testing (returns absolute paths). */\n\twalkFiles?: (dir: string) => string[];\n}\n\nexport interface NewReport {\n\tstatus: \"ok\" | \"fail\" | \"dry-run\";\n\trepoDir?: string;\n\tfilesPatched?: string[];\n\tmessage?: string;\n}\n\nexport class NewError extends Error {\n\toverride name = \"NewError\";\n}\n\n// ── Case derivation ───────────────────────────────────────────────────\n\nfunction cap(word: string): string {\n\treturn word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();\n}\n\n/**\n * Derive all common casing variants of a kebab-case slug (e.g.\n * \"cli-template\") and map each to the corresponding form of a\n * kebab-case name (e.g. \"my-tool\").\n *\n * Returns search→replacement pairs, deduplicating single-word slugs\n * that would otherwise produce identical entries.\n */\nexport function deriveVariants(slug: string, name: string): Array<[string, string]> {\n\tconst sw = slug.split(\"-\");\n\tconst nw = name.split(\"-\");\n\n\tconst pairs: Array<[string, string]> = [\n\t\t[slug, name],\n\t\t[sw.join(\"_\"), nw.join(\"_\")],\n\t\t[sw.join(\"_\").toUpperCase(), nw.join(\"_\").toUpperCase()],\n\t\t[sw.map(cap).join(\"\"), nw.map(cap).join(\"\")],\n\t\t[sw[0]!.toLowerCase() + sw.slice(1).map(cap).join(\"\"), nw[0]!.toLowerCase() + nw.slice(1).map(cap).join(\"\")],\n\t\t[sw.map(cap).join(\" \"), nw.map(cap).join(\" \")],\n\t];\n\n\tconst seen = new Set<string>();\n\treturn pairs.filter(([s]) => {\n\t\tif (seen.has(s)) return false;\n\t\tseen.add(s);\n\t\treturn true;\n\t});\n}\n\n// ── Input helpers ─────────────────────────────────────────────────────\n\n/** Validate a repo name: must be lowercase kebab-case. Returns `true` on success or an error string. */\nexport function validateRepoName(v: string): true | string {\n\treturn /^[a-z][a-z0-9-]*$/.test(v.trim()) ? true : \"Must be lowercase kebab-case (e.g. my-tool)\";\n}\n\n/** Parse a comma-separated topics string into a trimmed, non-empty array. */\nexport function parseTopics(raw: string | undefined): string[] {\n\treturn raw\n\t\t? String(raw)\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((t) => t.trim())\n\t\t\t\t.filter(Boolean)\n\t\t: [];\n}\n\n// ── Config generation ─────────────────────────────────────────────────\n\nexport interface HolocronConfigOptions {\n\tname: string;\n\ttype: string;\n\torg?: string;\n\tdescription?: string;\n\thomepage?: string;\n\tvaultProvider?: VaultProvider;\n\tvaultProject?: string;\n\tvaultConfig?: string;\n\tdeploymentProvider?: DeploymentProvider;\n\tagent?: AgentChoice;\n\truntimeEnvironment?: RuntimeEnvironment;\n\tprotection?: string;\n\topenSource?: boolean;\n\tusesExternalPackages?: boolean;\n\ttopics?: string[];\n\tskills?: string[];\n}\n\n/**\n * Generate the content of `holocron.config.ts` for a newly-scaffolded repo.\n * Uses the `node()` preset from `@theholocron/holocron-config` as the baseline\n * and layers in the provider/agent choices made during the wizard.\n */\nexport function generateHolocronConfig(opts: HolocronConfigOptions): string {\n\tconst lines: string[] = [\n\t\t`import { defineConfig } from \"@theholocron/cli\";`,\n\t\t`import { compose, node, typecheck } from \"@theholocron/holocron-config\";`,\n\t\t``,\n\t\t// `compose(node(), typecheck())` is the org baseline preset — the full\n\t\t// task manifest (lint/test/typecheck required, security/review/… ) rides\n\t\t// in via `...preset`, so `holocron setup` can derive CodeQL mode and the\n\t\t// required-check contexts. See theholocron/holocron#642.\n\t\t`const preset = compose(node(), typecheck());`,\n\t\t`export default defineConfig({`,\n\t\t`\\t...preset,`,\n\t];\n\n\tif (opts.description) lines.push(`\\tdescription: ${JSON.stringify(opts.description)},`);\n\tif (opts.homepage) lines.push(`\\thomepage: ${JSON.stringify(opts.homepage)},`);\n\n\tconst topics = opts.topics?.length ? opts.topics : [];\n\tconst hasRuntimeOverride = opts.runtimeEnvironment != null && opts.runtimeEnvironment !== \"node\";\n\tconst hasFullRepo = opts.org != null;\n\n\tif (hasFullRepo) {\n\t\t// Full explicit repo block when org is known (always the case from the CLI).\n\t\tconst repoName = `${opts.org}/${opts.name}`;\n\t\tlines.push(`\\trepo: {`);\n\t\tlines.push(`\\t\\t...preset.repo,`);\n\t\tlines.push(`\\t\\tname: ${JSON.stringify(repoName)},`);\n\t\tlines.push(`\\t\\tteams: [{ slug: \"gatekeepers\", permission: \"maintain\" }],`);\n\t\tlines.push(`\\t\\ttopics: ${JSON.stringify(topics)},`);\n\t\tif (opts.protection && opts.protection !== \"strict\") {\n\t\t\tlines.push(`\\t\\tprotection: ${JSON.stringify(opts.protection)},`);\n\t\t}\n\t\tconst propParts: string[] = [];\n\t\tif (hasRuntimeOverride) propParts.push(`runtime_environment: ${JSON.stringify(opts.runtimeEnvironment)}`);\n\t\tif (opts.openSource === false) propParts.push(`open_source: false`);\n\t\tif (opts.usesExternalPackages === false) propParts.push(`uses_external_packages: false`);\n\t\tif (propParts.length > 0) {\n\t\t\tlines.push(`\\t\\tproperties: { ...preset.repo?.properties, ${propParts.join(\", \")} },`);\n\t\t}\n\t\tlines.push(`\\t},`);\n\t} else if (topics.length > 0 || hasRuntimeOverride) {\n\t\tlines.push(`\\trepo: {`);\n\t\tlines.push(`\\t\\t...preset.repo,`);\n\t\tif (topics.length > 0) lines.push(`\\t\\ttopics: ${JSON.stringify(topics)},`);\n\t\tif (hasRuntimeOverride) {\n\t\t\tlines.push(\n\t\t\t\t`\\t\\tproperties: { ...preset.repo?.properties, runtime_environment: ${JSON.stringify(opts.runtimeEnvironment)} },`\n\t\t\t);\n\t\t}\n\t\tlines.push(`\\t},`);\n\t}\n\t// else: `...preset` already carries `repo` — no explicit block needed.\n\n\tconst hasVault = opts.vaultProvider && opts.vaultProvider !== \"none\";\n\tconst hasDeployment = opts.deploymentProvider && opts.deploymentProvider !== \"none\";\n\n\tif (hasVault || hasDeployment) {\n\t\tlines.push(`\\tproviders: {`);\n\t\tlines.push(`\\t\\t...preset.providers,`);\n\t\tif (opts.vaultProvider === \"doppler\") {\n\t\t\tconst proj = JSON.stringify(opts.vaultProject ?? opts.name);\n\t\t\tconst cfg = JSON.stringify(opts.vaultConfig ?? \"dev\");\n\t\t\tlines.push(`\\t\\tvault: [\"doppler\", { project: ${proj}, config: ${cfg} }],`);\n\t\t} else if (opts.vaultProvider === \"1password\") {\n\t\t\tconst vault = JSON.stringify(opts.vaultProject ?? opts.name);\n\t\t\tlines.push(`\\t\\tvault: [\"1password\", { vault: ${vault} }],`);\n\t\t} else if (opts.vaultProvider === \"infisical\") {\n\t\t\tconst proj = JSON.stringify(opts.vaultProject ?? opts.name);\n\t\t\tlines.push(`\\t\\tvault: [\"infisical\", { project: ${proj} }],`);\n\t\t}\n\t\tif (opts.deploymentProvider === \"vercel\") {\n\t\t\tlines.push(`\\t\\tdeployment: \"vercel\",`);\n\t\t}\n\t\tlines.push(`\\t},`);\n\t}\n\t// else: `...preset` already carries `providers`.\n\n\tif (opts.agent && opts.agent !== \"none\") {\n\t\tlines.push(`\\tagent: ${JSON.stringify(opts.agent)},`);\n\t}\n\n\tif (opts.skills?.length) {\n\t\tlines.push(`\\tskills: ${JSON.stringify(opts.skills)},`);\n\t}\n\n\tlines.push(`});`);\n\tlines.push(``);\n\n\treturn lines.join(\"\\n\");\n}\n\n// ── File discovery ────────────────────────────────────────────────────\n\nconst SKIP_DIRS = new Set([\".git\", \"node_modules\", \"dist\", \".turbo\"]);\n\nfunction defaultWalkFiles(dir: string): string[] {\n\tconst results: string[] = [];\n\tfor (const entry of readdirSync(dir)) {\n\t\tif (SKIP_DIRS.has(entry)) continue;\n\t\tconst full = path.join(dir, entry);\n\t\tconst stat = statSync(full);\n\t\tif (stat.isDirectory()) results.push(...defaultWalkFiles(full));\n\t\telse if (stat.isFile()) results.push(full);\n\t}\n\treturn results;\n}\n\nfunction isBinary(content: string): boolean {\n\tfor (let i = 0; i < Math.min(content.length, 8000); i++) {\n\t\tif (content.charCodeAt(i) === 0) return true;\n\t}\n\treturn false;\n}\n\n// ── Patching ──────────────────────────────────────────────────────────\n\nfunction patchFiles(\n\tdir: string,\n\tvariants: Array<[string, string]>,\n\tdescription: string | undefined,\n\thomepage: string | undefined,\n\truntimeEnvironment: string | undefined,\n\tprint: (line: string) => void,\n\treadFn: (p: string) => string,\n\twriteFn: (p: string, c: string) => void,\n\twalkFn: (d: string) => string[]\n): string[] {\n\tconst patched: string[] = [];\n\tfor (const filepath of walkFn(dir)) {\n\t\tlet content: string;\n\t\ttry {\n\t\t\tcontent = readFn(filepath);\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\t\tif (isBinary(content)) continue;\n\n\t\tconst original = content;\n\t\tfor (const [search, replacement] of variants) {\n\t\t\tcontent = content.split(search).join(replacement);\n\t\t}\n\t\tif (description !== undefined) {\n\t\t\tcontent = content.split(\"<description>\").join(description);\n\t\t\t// Also replace the content of <!-- holocron:description --> blocks so\n\t\t\t// the README description marker is updated even when the template has\n\t\t\t// real prose rather than a bare <description> placeholder.\n\t\t\tcontent = content.replace(\n\t\t\t\t/(<!-- holocron:description -->)[\\s\\S]*?(<!-- \\/holocron:description -->)/g,\n\t\t\t\t`$1\\n${description}\\n$2`\n\t\t\t);\n\t\t}\n\t\tif (homepage !== undefined) {\n\t\t\tcontent = content.split(\"<homepage>\").join(homepage);\n\t\t}\n\t\tif (runtimeEnvironment !== undefined) {\n\t\t\tcontent = content.split(\"<runtime_environment>\").join(runtimeEnvironment);\n\t\t}\n\t\t// Strip template-only blocks — sections relevant only to the template\n\t\t// repo itself (e.g. \"Getting Started\" scaffolding instructions) that\n\t\t// should not appear in projects generated from the template.\n\t\tcontent = content.replace(\n\t\t\t/\\n?<!-- holocron:template-only -->[\\s\\S]*?<!-- \\/holocron:template-only -->\\n?/g,\n\t\t\t\"\"\n\t\t);\n\n\t\tif (content !== original) {\n\t\t\twriteFn(filepath, content);\n\t\t\tprint(` ✓ ${path.relative(dir, filepath)}`);\n\t\t\tpatched.push(filepath);\n\t\t}\n\t}\n\treturn patched;\n}\n\n// ── Preflight ─────────────────────────────────────────────────────────\n\nfunction preflight(): void {\n\tconst result = spawnSync(\"gh\", [\"--version\"], { encoding: \"utf8\" });\n\tif (result.error != null || result.status !== 0) {\n\t\tthrow new NewError(\"`gh` CLI is not installed or not on PATH. Install it from https://cli.github.com\");\n\t}\n}\n\n// ── Defaults ──────────────────────────────────────────────────────────\n\nfunction defaultExec(\n\tcmd: string,\n\targs: string[],\n\topts: { cwd: string; stdio: \"inherit\"; env?: Record<string, string> }\n): void {\n\texecFileSync(cmd, args, {\n\t\tcwd: opts.cwd,\n\t\tstdio: opts.stdio,\n\t\t...(opts.env && Object.keys(opts.env).length > 0 ? { env: { ...process.env, ...opts.env } } : {}),\n\t});\n}\n\nfunction keychainLookup(key: string): string | undefined {\n\tconst result = spawnSync(\"security\", [\"find-generic-password\", \"-s\", \"com.theholocron.cli\", \"-a\", key, \"-w\"], {\n\t\tencoding: \"utf8\",\n\t});\n\treturn result.status === 0 ? result.stdout?.trim() || undefined : undefined;\n}\n\nfunction defaultReadFile(filepath: string): string {\n\treturn readFileSync(filepath, \"utf-8\");\n}\n\nfunction defaultWriteFile(filepath: string, content: string): void {\n\tmkdirSync(path.dirname(filepath), { recursive: true });\n\twriteFileSync(filepath, content, \"utf-8\");\n}\n\n// ── Orchestrator ──────────────────────────────────────────────────────\n\nexport async function runNew(input: RunNewInput): Promise<NewReport> {\n\tconst cwd = input.cwd ?? process.cwd();\n\tconst org = input.org ?? \"theholocron\";\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst execFn = input.exec ?? defaultExec;\n\tconst readFn = input.readFile ?? defaultReadFile;\n\tconst writeFn = input.writeFile ?? defaultWriteFile;\n\tconst walkFn = input.walkFiles ?? defaultWalkFiles;\n\n\tpreflight();\n\n\tconst templateRepo = `${org}/${input.type}-template`;\n\tconst newRepo = `${org}/${input.name}`;\n\tconst repoDir = path.join(cwd, input.name);\n\tlogger.info({ repo: newRepo, template: templateRepo, dryRun: input.dryRun || undefined }, \"new: start\");\n\n\tif (input.dryRun) {\n\t\tprint(` Would create ${newRepo} from template ${templateRepo}`);\n\t\tprint(` Would clone to ${repoDir}`);\n\t\tprint(` Would patch all casing variants of \"${input.type}-template\" → \"${input.name}\"`);\n\t\tif (input.description) print(` Would replace <description> → \"${input.description}\"`);\n\t\tif (input.homepage) print(` Would replace <homepage> → \"${input.homepage}\"`);\n\t\tif (input.runtimeEnvironment) print(` Would replace <runtime_environment> → \"${input.runtimeEnvironment}\"`);\n\t\tprint(` Would generate holocron.config.ts`);\n\t\tlogger.info({ repo: newRepo, status: \"dry-run\" }, \"new: done\");\n\t\treturn { status: \"dry-run\" };\n\t}\n\n\tif (existsSync(repoDir)) {\n\t\tthrow new NewError(`\\`${repoDir}\\` already exists — delete it or pick a different name.`);\n\t}\n\n\tprint(` Creating ${newRepo} from template ${templateRepo}…`);\n\tconst visibility = input.openSource ? \"--public\" : \"--private\";\n\ttry {\n\t\texecFn(\"gh\", [\"repo\", \"create\", newRepo, `--template=${templateRepo}`, visibility, \"--clone\"], {\n\t\t\tcwd,\n\t\t\tstdio: \"inherit\",\n\t\t});\n\t} catch (err) {\n\t\tthrow new NewError(`gh repo create failed: ${err instanceof Error ? err.message : String(err)}`);\n\t}\n\n\tif (input.isTemplate) {\n\t\ttry {\n\t\t\texecFn(\"gh\", [\"repo\", \"edit\", newRepo, \"--template=true\"], { cwd, stdio: \"inherit\" });\n\t\t} catch {\n\t\t\t// non-fatal — template flag can be set manually in repo settings\n\t\t}\n\t}\n\n\t// gh repo create --template does not reliably honor --public/--private on all\n\t// plan/org combinations, so set visibility explicitly after creation.\n\ttry {\n\t\texecFn(\"gh\", [\"repo\", \"edit\", newRepo, `--visibility=${input.openSource ? \"public\" : \"private\"}`], {\n\t\t\tcwd,\n\t\t\tstdio: \"inherit\",\n\t\t});\n\t} catch {\n\t\t// non-fatal — visibility can be changed manually in repo settings\n\t}\n\n\t// Detect template slug from cloned package.json\n\tlet templateSlug = `${input.type}-template`;\n\tconst pkgJsonPath = path.join(repoDir, \"package.json\");\n\tif (existsSync(pkgJsonPath)) {\n\t\ttry {\n\t\t\tconst pkg = JSON.parse(readFn(pkgJsonPath)) as { name?: string };\n\t\t\tif (typeof pkg.name === \"string\") {\n\t\t\t\ttemplateSlug = pkg.name.split(\"/\").at(-1) || templateSlug;\n\t\t\t}\n\t\t} catch {\n\t\t\t// fall back to derived slug\n\t\t}\n\t}\n\n\tprint(` Detected template slug: ${templateSlug}`);\n\tprint(` Patching files…`);\n\n\tconst variants = deriveVariants(templateSlug, input.name);\n\t// Prepend the full org/slug pair so GitHub URLs and scoped package names\n\t// use the correct org. Must come before the slug-only pairs so it takes\n\t// priority — e.g. \"@theholocron/node-template\" becomes \"@<org>/<name>\"\n\t// rather than \"@theholocron/<name>\".\n\tvariants.unshift([`theholocron/${templateSlug}`, `${org}/${input.name}`]);\n\tconst filesPatched = patchFiles(\n\t\trepoDir,\n\t\tvariants,\n\t\tinput.description,\n\t\tinput.homepage,\n\t\tinput.runtimeEnvironment,\n\t\tprint,\n\t\treadFn,\n\t\twriteFn,\n\t\twalkFn\n\t);\n\n\tprint(` ${filesPatched.length} file${filesPatched.length === 1 ? \"\" : \"s\"} patched`);\n\n\t// Always overwrite description and homepage in package.json directly,\n\t// regardless of whether the template used placeholders or real values.\n\tif (input.description !== undefined || input.homepage !== undefined) {\n\t\ttry {\n\t\t\tconst pkg = JSON.parse(readFn(pkgJsonPath)) as Record<string, unknown>;\n\t\t\tif (input.description !== undefined) pkg[\"description\"] = input.description;\n\t\t\tif (input.homepage !== undefined) pkg[\"homepage\"] = input.homepage;\n\t\t\twriteFn(pkgJsonPath, JSON.stringify(pkg, null, 2) + \"\\n\");\n\t\t\tprint(` ✓ package.json (description/homepage)`);\n\t\t} catch {\n\t\t\t// non-fatal — placeholder replacement already covered it\n\t\t}\n\t}\n\n\t// Update the root tsconfig.json \"display\" field by parsing the JSON directly\n\t// rather than relying on a <display_name> placeholder. Templates can use their\n\t// real human-readable display name; we always overwrite it with the title-case\n\t// of the new repo name on scaffolding.\n\tconst displayName = input.name.split(\"-\").map(cap).join(\" \");\n\tconst rootTsconfigPath = path.join(repoDir, \"tsconfig.json\");\n\ttry {\n\t\tconst tsconfig = JSON.parse(readFn(rootTsconfigPath)) as Record<string, unknown>;\n\t\tif (typeof tsconfig[\"display\"] === \"string\") {\n\t\t\ttsconfig[\"display\"] = displayName;\n\t\t\twriteFn(rootTsconfigPath, JSON.stringify(tsconfig, null, 2) + \"\\n\");\n\t\t\tprint(` ✓ tsconfig.json (display)`);\n\t\t}\n\t} catch {\n\t\t// non-fatal — no tsconfig or no display field\n\t}\n\n\t// Generate and write holocron.config.ts\n\tconst configContent = generateHolocronConfig({\n\t\tname: input.name,\n\t\ttype: input.type,\n\t\torg,\n\t\tdescription: input.description,\n\t\thomepage: input.homepage,\n\t\tvaultProvider: input.vaultProvider,\n\t\tvaultProject: input.vaultProject,\n\t\tvaultConfig: input.vaultConfig,\n\t\tdeploymentProvider: input.deploymentProvider,\n\t\tagent: input.agent,\n\t\truntimeEnvironment: input.runtimeEnvironment,\n\t\tprotection: input.protection,\n\t\topenSource: input.openSource,\n\t\tusesExternalPackages: input.usesExternalPackages,\n\t\ttopics: input.topics,\n\t\tskills: input.skills,\n\t});\n\tconst configPath = path.join(repoDir, \"holocron.config.ts\");\n\twriteFn(configPath, configContent);\n\tprint(` Generated holocron.config.ts`);\n\n\texecFn(\"git\", [\"add\", \"-A\"], { cwd: repoDir, stdio: \"inherit\" });\n\texecFn(\"git\", [\"commit\", \"-s\", \"-m\", `chore: bootstrap from ${templateSlug}`], {\n\t\tcwd: repoDir,\n\t\tstdio: \"inherit\",\n\t});\n\n\tif (!input.noVerify) {\n\t\tprint(\"\");\n\t\tprint(\" Installing dependencies…\");\n\t\ttry {\n\t\t\texecFn(\"pnpm\", [\"install\"], { cwd: repoDir, stdio: \"inherit\" });\n\t\t} catch (err) {\n\t\t\tprint(` ✗ pnpm install failed — ${err instanceof Error ? err.message : String(err)}`);\n\t\t\treturn {\n\t\t\t\tstatus: \"fail\",\n\t\t\t\trepoDir,\n\t\t\t\tfilesPatched,\n\t\t\t\tmessage: \"pnpm install failed; inspect output above\",\n\t\t\t};\n\t\t}\n\n\t\tprint(\"\");\n\t\tprint(\" Running holocron setup…\");\n\t\ttry {\n\t\t\tconst setupArgs: string[] = [\"setup\"];\n\t\t\tconst setupEnv: Record<string, string> = {};\n\n\t\t\t// Admin token: drives rulesets, repo settings, workflows, Pages.\n\t\t\t// Prefer the value forwarded via --token; fall back to keychain.\n\t\t\tconst adminToken = input.token ?? keychainLookup(\"github.admin\");\n\t\t\tif (adminToken) setupArgs.push(\"--token\", adminToken);\n\n\t\t\t// Org token: drives team assignments and custom properties.\n\t\t\t// Skip keychain if already in env (subprocess inherits it anyway).\n\t\t\tif (!env.get(\"HOLOCRON_ORG_TOKEN\")) {\n\t\t\t\tconst orgToken = keychainLookup(\"github.org\");\n\t\t\t\tif (orgToken) setupEnv[\"HOLOCRON_ORG_TOKEN\"] = orgToken;\n\t\t\t}\n\n\t\t\t// Deploy token: drives GitHub Pages configuration.\n\t\t\tif (!env.get(\"HOLOCRON_DEPLOY_TOKEN\")) {\n\t\t\t\tconst deployToken = keychainLookup(\"github.deploy\");\n\t\t\t\tif (deployToken) setupEnv[\"HOLOCRON_DEPLOY_TOKEN\"] = deployToken;\n\t\t\t}\n\n\t\t\texecFn(\"holocron\", setupArgs, { cwd: repoDir, stdio: \"inherit\", env: setupEnv });\n\t\t} catch {\n\t\t\tprint(\" ✗ holocron setup failed — run it manually after checking your config\");\n\t\t}\n\t}\n\n\tprint(\"\");\n\tprint(` Scaffolded ${newRepo} (${filesPatched.length} file${filesPatched.length === 1 ? \"\" : \"s\"} patched).`);\n\tprint(\"\");\n\tprint(\" Next:\");\n\tprint(` 1. cd ${repoDir}`);\n\tif (input.noVerify) {\n\t\tprint(` 2. pnpm install`);\n\t\tprint(` 3. holocron setup # wire up secrets, teams, labels, etc.`);\n\t\tprint(` 4. git push -u origin HEAD`);\n\t} else {\n\t\tprint(` 2. git push -u origin HEAD`);\n\t}\n\n\tlogger.info({ repo: newRepo, repoDir, filesPatched, status: \"ok\" }, \"new: done\");\n\treturn { status: \"ok\", repoDir, filesPatched };\n}\n","import { readdirSync, readFileSync, statSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport { getLogger } from \"../logger.js\";\n\nexport interface RunNpmBumpVersionsInput {\n\t/** Next version string (e.g., \"4.2.0\" or \"2.0.0-alpha.1\"). */\n\tversion: string;\n\t/** Working directory (monorepo root). Defaults to process.cwd(). */\n\tcwd?: string;\n\t/** Print what would change without writing anything. */\n\tdryRun?: boolean;\n\tprint?: (line: string) => void;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n\t/** Injectable for testing. */\n\treadFile?: (path: string) => string;\n\twriteFile?: (path: string, content: string) => void;\n\tlistDir?: (path: string) => string[];\n\tisDir?: (path: string) => boolean;\n}\n\nexport type BumpVersionsStatus = \"ok\" | \"fail\" | \"dry-run\";\n\nexport interface NpmBumpVersionsReport {\n\tstatus: BumpVersionsStatus;\n\tbumped: readonly string[];\n\tskipped: readonly string[];\n\tmessage?: string;\n}\n\nexport async function runNpmBumpVersions(input: RunNpmBumpVersionsInput): Promise<NpmBumpVersionsReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst cwd = input.cwd ?? process.cwd();\n\tconst { version, dryRun = false } = input;\n\tconst readFile = input.readFile ?? ((p: string) => readFileSync(p, \"utf8\"));\n\tconst writeFile = input.writeFile ?? ((p: string, c: string) => writeFileSync(p, c));\n\tconst listDir = input.listDir ?? ((p: string) => readdirSync(p) as string[]);\n\tconst isDir = input.isDir ?? ((p: string) => statSync(p).isDirectory());\n\n\tconst bumped: string[] = [];\n\tconst skipped: string[] = [];\n\n\tprint(`Bumping monorepo to ${version}${dryRun ? \" (dry-run)\" : \"\"}…`);\n\tlogger.info({ version, dryRun: dryRun || undefined }, \"npm bump-versions: start\");\n\n\tfunction bumpFile(absPath: string, label: string): void {\n\t\tlet pkg: Record<string, unknown>;\n\t\ttry {\n\t\t\tpkg = JSON.parse(readFile(absPath)) as Record<string, unknown>;\n\t\t} catch {\n\t\t\tprint(` ✗ could not parse ${label}`);\n\t\t\treturn;\n\t\t}\n\t\tconst old = pkg.version as string;\n\t\tif (!dryRun) {\n\t\t\tpkg.version = version;\n\t\t\twriteFile(absPath, JSON.stringify(pkg, null, 2) + \"\\n\");\n\t\t}\n\t\tprint(` ${dryRun ? \"~\" : \"✓\"} ${label}: ${old} → ${version}`);\n\t\tbumped.push(label);\n\t}\n\n\t// Root is always bumped — private means \"don't publish\", not \"don't version\".\n\tbumpFile(join(cwd, \"package.json\"), \"root\");\n\n\tconst packagesDir = join(cwd, \"packages\");\n\tlet entries: string[];\n\ttry {\n\t\tentries = listDir(packagesDir);\n\t} catch {\n\t\t// No packages/ dir — single-package repo; root bump is sufficient.\n\t\tconst status = dryRun ? \"dry-run\" : \"ok\";\n\t\tlogger.info({ version, status, bumped: bumped.length, skipped: skipped.length }, \"npm bump-versions: done\");\n\t\treturn { status, bumped, skipped };\n\t}\n\n\tfor (const entry of entries) {\n\t\tconst pkgDir = join(packagesDir, entry);\n\t\ttry {\n\t\t\tif (!isDir(pkgDir)) continue;\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\t\tconst pkgFile = join(pkgDir, \"package.json\");\n\t\tlet pkg: Record<string, unknown>;\n\t\ttry {\n\t\t\tpkg = JSON.parse(readFile(pkgFile)) as Record<string, unknown>;\n\t\t} catch {\n\t\t\tprint(` ! skipping packages/${entry}: no package.json or malformed JSON`);\n\t\t\tcontinue;\n\t\t}\n\t\tif (pkg.private) {\n\t\t\tprint(` · skipping private package packages/${entry}`);\n\t\t\tskipped.push(`packages/${entry}`);\n\t\t\tcontinue;\n\t\t}\n\t\tbumpFile(pkgFile, `packages/${entry}`);\n\t}\n\n\tconst status = dryRun ? \"dry-run\" : \"ok\";\n\tlogger.info({ version, status, bumped: bumped.length, skipped: skipped.length }, \"npm bump-versions: done\");\n\treturn { status, bumped, skipped };\n}\n","/**\n * Shared input record for every template module.\n *\n * Every template exports `(inputs: TemplateInputs) => string` and reads\n * from this record. Keeping the surface small + typechecked lets the\n * templates stay dumb string builders while the command layer handles\n * normalization + defaulting from user input.\n */\n\nimport type { CapabilityKey } from \"../../plugin/capabilities.js\";\n\nexport interface TemplateInputs {\n\t/** Package slug — e.g., \"clerk\". Lowercase, kebab-case. */\n\tslug: string;\n\t/** Vendor display name — e.g., \"Clerk\". PascalCase. */\n\tvendorName: string;\n\t/** Vendor slug UPPERCASED — e.g., \"CLERK\". Used for env var names + class prefixes. */\n\tvendorUpper: string;\n\t/** Capability the plugin implements — one of the 14 known keys. */\n\tcapability: CapabilityKey;\n\t/** Capability implementation class name — e.g., \"ClerkAuth\". PascalCase. */\n\tcapabilityClass: string;\n\t/** Holocron-namespaced env var — defaults to `HOLOCRON_<VENDOR_UPPER>_TOKEN`. */\n\ttokenEnv: string;\n\t/** Vendor-native env var — e.g., \"CLERK_SECRET_KEY\". */\n\tvendorEnv: string;\n\t/** REST base URL — e.g., \"https://api.clerk.com/v1\". */\n\tbaseUrl: string;\n\t/** Transport. Only \"rest\" is supported in Phase 1 (spec: #77). */\n\ttransport: \"rest\";\n}\n\n/** Derive the standard defaults from a slug + vendor name. */\nexport function deriveDefaults(input: {\n\tslug: string;\n\tvendorName: string;\n\tcapability: CapabilityKey;\n}): Pick<TemplateInputs, \"vendorUpper\" | \"capabilityClass\" | \"tokenEnv\" | \"transport\"> {\n\tconst vendorUpper = input.slug.toUpperCase().replace(/-/g, \"_\");\n\tconst capability = input.capability;\n\tconst capabilityClass = `${input.vendorName}${capability.charAt(0).toUpperCase() + capability.slice(1)}`;\n\treturn {\n\t\tvendorUpper,\n\t\tcapabilityClass,\n\t\ttokenEnv: `HOLOCRON_${vendorUpper}_TOKEN`,\n\t\ttransport: \"rest\",\n\t};\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(inputs: TemplateInputs): string {\n\treturn `import { AuthError, createResolveToken, type ResolveTokenInput } from \"@theholocron/cli\";\n\nexport { AuthError };\nexport type { ResolveTokenInput };\n\nexport const resolveToken = createResolveToken({\n\\tenvName: \"${inputs.tokenEnv}\",\n\\tvendorEnvName: \"${inputs.vendorEnv}\",\n\\tkeyringService: \"${inputs.slug}\",\n\\terrorMessage:\n\\t\\t\"no ${inputs.vendorName} token found. Pass --token <TOKEN>, set ${inputs.tokenEnv} / ${inputs.vendorEnv}, \" +\n\\t\\t\"or run: holocron auth set ${inputs.slug} <TOKEN>\",\n});\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(inputs: TemplateInputs): string {\n\treturn `import { describe, expect, it } from \"vitest\";\n\nimport { AuthError, resolveToken } from \"../auth.js\";\n\nconst noKeyring = () => null;\n\ndescribe(\"resolveToken\", () => {\n\tit(\"prefers --token over env vars + keyring\", () => {\n\t\texpect(\n\t\t\tresolveToken({\n\t\t\t\tcliToken: \"flag\",\n\t\t\t\tenv: { ${inputs.tokenEnv}: \"hlc\", ${inputs.vendorEnv}: \"vendor\" },\n\t\t\t\tkeyring: () => \"kr\",\n\t\t\t})\n\t\t).toBe(\"flag\");\n\t});\n\n\tit(\"prefers ${inputs.tokenEnv} over ${inputs.vendorEnv}\", () => {\n\t\texpect(\n\t\t\tresolveToken({\n\t\t\t\tenv: { ${inputs.tokenEnv}: \"hlc\", ${inputs.vendorEnv}: \"vendor\" },\n\t\t\t\tkeyring: noKeyring,\n\t\t\t})\n\t\t).toBe(\"hlc\");\n\t});\n\n\tit(\"falls back to ${inputs.vendorEnv} when ${inputs.tokenEnv} is unset\", () => {\n\t\texpect(resolveToken({ env: { ${inputs.vendorEnv}: \"vendor\" }, keyring: noKeyring })).toBe(\"vendor\");\n\t});\n\n\tit(\"falls back to keyring when env vars are unset\", () => {\n\t\texpect(resolveToken({ env: {}, keyring: (p) => (p === \"${inputs.slug}\" ? \"kr\" : null) })).toBe(\"kr\");\n\t});\n\n\tit(\"throws AuthError with a helpful message when nothing is set\", () => {\n\t\ttry {\n\t\t\tresolveToken({ env: {}, keyring: noKeyring });\n\t\t\tthrow new Error(\"should have thrown\");\n\t\t} catch (err) {\n\t\t\texpect(err).toBeInstanceOf(AuthError);\n\t\t\texpect((err as Error).message).toMatch(/${inputs.tokenEnv}/);\n\t\t\texpect((err as Error).message).toMatch(/holocron auth set ${inputs.slug}/);\n\t\t}\n\t});\n});\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(inputs: TemplateInputs): string {\n\tconst clientClass = `${inputs.vendorName}RestClient`;\n\tconst capabilityInterface = inputs.capability.charAt(0).toUpperCase() + inputs.capability.slice(1);\n\treturn `/**\n * \\`${inputs.capability}\\` capability for ${inputs.vendorName}.\n *\n * Methods are STUBS — implement them against ${inputs.vendorName}'s\n * REST API per the \\`${capabilityInterface}\\` interface contract in\n * \\`@theholocron/cli\\`.\n *\n * TODO once you've stubbed the interface methods, restore the type\n * import + \\`implements\\` clause:\n * import type { ${capabilityInterface} } from \"@theholocron/cli\";\n * export class ${inputs.capabilityClass} implements ${capabilityInterface} { ... }\n */\n\nimport type { ${clientClass} } from \"../rest.js\";\n\nexport class ${inputs.capabilityClass} {\n\treadonly key = \"${inputs.capability}\" as const;\n\treadonly providerName = \"${inputs.slug}\";\n\n\tconstructor(private readonly rest: () => ${clientClass}) {}\n\n\t// TODO: implement the ${capabilityInterface} interface methods\n\t// (see \\`packages/cli/src/capabilities/index.ts\\`). Each method\n\t// should hit a specific ${inputs.vendorName} REST endpoint via\n\t// \\`this.rest().request(...)\\` — call the thunk so the token is\n\t// resolved lazily. Once methods are stubbed, add\n\t// \\`implements ${capabilityInterface}\\` to the class declaration\n\t// above and remove the \\`as unknown as\\` cast in src/index.ts.\n}\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(inputs: TemplateInputs): string {\n\tconst clientClass = `${inputs.vendorName}RestClient`;\n\treturn `import { describe, it } from \"vitest\";\n\nimport { ${inputs.capabilityClass} } from \"../capabilities/${inputs.capability}.js\";\nimport { ${clientClass} } from \"../rest.js\";\nimport { stubFetch } from \"./helpers.js\";\n\n// Stub client used by the constructor smoke test. Real capability\n// tests replace this with per-method stubs once implementations land.\nfunction makeCapability() {\n\tconst stub = stubFetch([]);\n\tconst rest = new ${clientClass}({ token: \"t\", fetch: stub.fetch });\n\treturn new ${inputs.capabilityClass}(() => rest);\n}\n\ndescribe(\"${inputs.capabilityClass}\", () => {\n\tit(\"constructs with a REST client\", () => {\n\t\tmakeCapability();\n\t});\n\n\t// TODO: implement one test per ${inputs.capability} capability method\n\t// as you fill in the class stubs. See other plugins for reference\n\t// patterns:\n\t// - REST behaviors (URL / method / body / query) via \\`stub.calls\\`\n\t// - Error paths via \\`stubFetch([{ status: 4xx, body: {...} }])\\`\n\t// - Idempotency (409 handling for ensure* methods, if applicable)\n\tit.todo(\"implement per-method tests\");\n});\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(_inputs: TemplateInputs): string {\n\treturn `import root from \"../../eslint.config.js\";\n\nexport default [\n\t...root,\n\t{\n\t\tignores: [\"dist/**\", \"coverage/**\"],\n\t},\n];\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(_inputs: TemplateInputs): string {\n\treturn `import { vi, type Mock } from \"vitest\";\n\nexport interface FetchCall {\n\turl: string;\n\tmethod: string;\n\theaders: Record<string, string>;\n\tbody: unknown;\n}\n\nexport interface FetchStub {\n\tfetch: typeof fetch;\n\tcalls: FetchCall[];\n\tmock: Mock;\n}\n\nexport function stubFetch(responses: Array<{ status?: number; body?: unknown; text?: string }>): FetchStub {\n\tconst calls: FetchCall[] = [];\n\tlet i = 0;\n\tconst mock = vi.fn(async (input: string | URL, init?: RequestInit) => {\n\t\tconst url = typeof input === \"string\" ? input : input.toString();\n\t\tconst body = typeof init?.body === \"string\" ? safeJsonParse(init.body) : (init?.body ?? null);\n\t\tcalls.push({\n\t\t\turl,\n\t\t\tmethod: (init?.method ?? \"GET\").toUpperCase(),\n\t\t\theaders: (init?.headers as Record<string, string>) ?? {},\n\t\t\tbody,\n\t\t});\n\t\tconst next = responses[i++] ?? { status: 200, body: {} };\n\t\tconst status = next.status ?? 200;\n\t\tif (status === 204 || status === 205 || status === 304) {\n\t\t\treturn new Response(null, { status });\n\t\t}\n\t\tconst text = next.text ?? (typeof next.body === \"string\" ? next.body : JSON.stringify(next.body ?? {}));\n\t\treturn new Response(text, { status });\n\t});\n\treturn { fetch: mock as unknown as typeof fetch, calls, mock };\n}\n\nfunction safeJsonParse(s: string): unknown {\n\ttry {\n\t\treturn JSON.parse(s);\n\t} catch {\n\t\treturn s;\n\t}\n}\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(inputs: TemplateInputs): string {\n\treturn `import { describe, expect, it } from \"vitest\";\n\nimport { AUTH_HINT, createPlugin } from \"../index.js\";\nimport { stubFetch } from \"./helpers.js\";\n\ndescribe(\"createPlugin\", () => {\n\tit(\"wires the ${inputs.capability} capability against the given fetch + token\", () => {\n\t\tconst stub = stubFetch([]);\n\t\tconst plugin = createPlugin({\n\t\t\tcliToken: \"test-token\",\n\t\t\tfetch: stub.fetch,\n\t\t});\n\t\texpect(plugin.name).toBe(\"@theholocron/holocron-plugin-${inputs.slug}\");\n\t\texpect(typeof plugin.capabilities.${inputs.capability}).toBe(\"function\");\n\t});\n});\n\ndescribe(\"AUTH_HINT\", () => {\n\tit(\"mentions the holocron auth set command\", () => {\n\t\texpect(AUTH_HINT).toMatch(/holocron auth set ${inputs.slug}/);\n\t});\n});\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(inputs: TemplateInputs): string {\n\treturn (\n\t\tJSON.stringify(\n\t\t\t{\n\t\t\t\tname: `@theholocron/holocron-plugin-${inputs.slug}`,\n\t\t\t\tversion: \"2.0.0-alpha.1\",\n\t\t\t\tdescription: `Holocron plugin for ${inputs.vendorName}. Implements the ${inputs.capability} capability against ${inputs.vendorName}'s REST API, plus exports verifyToken + AUTH_HINT for \\`holocron auth\\`.`,\n\t\t\t\thomepage: `https://github.com/theholocron/holocron/tree/main/packages/holocron-plugin-${inputs.slug}#readme`,\n\t\t\t\tbugs: \"https://github.com/theholocron/holocron/issues\",\n\t\t\t\trepository: {\n\t\t\t\t\ttype: \"git\",\n\t\t\t\t\turl: \"git+https://github.com/theholocron/holocron.git\",\n\t\t\t\t\tdirectory: `packages/holocron-plugin-${inputs.slug}`,\n\t\t\t\t},\n\t\t\t\tlicense: \"MIT\",\n\t\t\t\tauthor: \"Newton Koumantzelis\",\n\t\t\t\ttype: \"module\",\n\t\t\t\tmain: \"./src/index.ts\",\n\t\t\t\texports: { \".\": \"./src/index.ts\" },\n\t\t\t\tscripts: {\n\t\t\t\t\t// delivery.build stays a direct tool invocation, never `holocron\n\t\t\t\t\t// run` — it's what produces the holocron binary, so it can never\n\t\t\t\t\t// depend on holocron already existing. The other three tasks are\n\t\t\t\t\t// safe to gateway through holocron: this template already\n\t\t\t\t\t// declares @theholocron/cli as a real devDependency below, giving\n\t\t\t\t\t// turbo the edge it needs to build cli (and transitively\n\t\t\t\t\t// astromech) before this package's own script ever runs.\n\t\t\t\t\t\"delivery.build\": \"tsdown\",\n\t\t\t\t\t\"sourceQuality.staticAnalysis\": \"holocron run sourceQuality.staticAnalysis --\",\n\t\t\t\t\t\"verification.typeSafety\": \"holocron run verification.typeSafety --\",\n\t\t\t\t\t\"verification.unitTests\": \"holocron run verification.unitTests --\",\n\t\t\t\t\t\"test:watch\": \"vitest\",\n\t\t\t\t\tvalidate: \"tsx scripts/validate.mjs\",\n\t\t\t\t},\n\t\t\t\tpeerDependencies: { \"@theholocron/cli\": \"workspace:*\" },\n\t\t\t\tdevDependencies: {\n\t\t\t\t\t\"@theholocron/cli\": \"workspace:*\",\n\t\t\t\t\t\"@theholocron/tsconfig\": \"catalog:\",\n\t\t\t\t\t\"@tsconfig/node-lts\": \"catalog:\",\n\t\t\t\t\t\"@vitest/coverage-v8\": \"catalog:\",\n\t\t\t\t\teslint: \"catalog:\",\n\t\t\t\t\tglobals: \"catalog:\",\n\t\t\t\t\ttypescript: \"catalog:\",\n\t\t\t\t\tvitest: \"catalog:\",\n\t\t\t\t\ttsdown: \"catalog:\",\n\t\t\t\t\ttsx: \"catalog:\",\n\t\t\t\t},\n\t\t\t\tpublishConfig: {\n\t\t\t\t\taccess: \"public\",\n\t\t\t\t\tmain: \"./dist/index.mjs\",\n\t\t\t\t\ttypes: \"./dist/index.d.mts\",\n\t\t\t\t\texports: {\n\t\t\t\t\t\t\".\": {\n\t\t\t\t\t\t\ttypes: \"./dist/index.d.mts\",\n\t\t\t\t\t\t\timport: \"./dist/index.mjs\",\n\t\t\t\t\t\t\tdefault: \"./dist/index.mjs\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tfiles: [\"dist\", \"README.md\"],\n\t\t\t},\n\t\t\tnull,\n\t\t\t\"\\t\"\n\t\t) + \"\\n\"\n\t);\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(inputs: TemplateInputs): string {\n\tconst clientClass = `${inputs.vendorName}RestClient`;\n\t// Camel-case capability name is used as the factory function name.\n\tconst capabilityInterface = inputs.capability.charAt(0).toUpperCase() + inputs.capability.slice(1);\n\treturn `/**\n * \\`@theholocron/holocron-plugin-${inputs.slug}\\` — entrypoint.\n *\n * Implements the \\`${inputs.capability}\\` capability against ${inputs.vendorName}'s\n * REST API. Also exports \\`verifyToken\\` + \\`AUTH_HINT\\` for\n * \\`holocron auth\\`. See README for auth + config docs.\n *\n * TODO: once you fill in the ${inputs.capabilityClass} methods and add\n * \\`implements ${capabilityInterface}\\` to the class, add the type import:\n * import type { ${capabilityInterface} } from \"@theholocron/cli\";\n * and set \\`: ${capabilityInterface}\\` as the factory return type below.\n */\n\nimport { resolveToken, type ResolveTokenInput } from \"./auth.js\";\nimport { ${inputs.capabilityClass} } from \"./capabilities/${inputs.capability}.js\";\nimport { ${clientClass} } from \"./rest.js\";\n\nexport interface ${inputs.vendorName}PluginOptions extends ResolveTokenInput {\n\t/** Override base URL for tests. */\n\tbaseUrl?: string;\n\t/** Override \\`fetch\\` for tests. */\n\tfetch?: typeof fetch;\n}\n\nexport interface PluginContext {\n\toptions: ${inputs.vendorName}PluginOptions;\n\t/** Memoized client — the token is resolved on first use, not at plugin load. */\n\trest: () => ${clientClass};\n}\n\nexport function createContext(options: ${inputs.vendorName}PluginOptions): PluginContext {\n\tlet rest: ${clientClass} | undefined;\n\treturn {\n\t\toptions,\n\t\trest: () => {\n\t\t\tif (rest) return rest;\n\t\t\tconst restOpts: ConstructorParameters<typeof ${clientClass}>[0] = { token: resolveToken(options) };\n\t\t\tif (options.baseUrl !== undefined) restOpts.baseUrl = options.baseUrl;\n\t\t\tif (options.fetch !== undefined) restOpts.fetch = options.fetch;\n\t\t\treturn (rest = new ${clientClass}(restOpts));\n\t\t},\n\t};\n}\n\nexport function ${inputs.capability}(ctx: PluginContext) {\n\t// Return type inferred at scaffold time — the class doesn't yet\n\t// \\`implements ${capabilityInterface}\\`. Add the type import + the\n\t// \\`: ${capabilityInterface}\\` annotation once methods are stubbed.\n\treturn new ${inputs.capabilityClass}(ctx.rest);\n}\n\nexport function createPlugin(options: ${inputs.vendorName}PluginOptions) {\n\tconst ctx = createContext(options);\n\treturn {\n\t\tname: \"@theholocron/holocron-plugin-${inputs.slug}\",\n\t\tcapabilities: {\n\t\t\t${inputs.capability}: () => ${inputs.capability}(ctx),\n\t\t},\n\t};\n}\n\n/**\n * One-line hint printed by \\`holocron auth set ${inputs.slug}\\` when no\n * token is supplied or the supplied token is rejected. Edit this to\n * point operators at the specific ${inputs.vendorName} docs path for\n * generating a token.\n */\nexport const AUTH_HINT =\n\t\"generate a ${inputs.vendorName} API token, then run: holocron auth set ${inputs.slug} <TOKEN>\";\n\n// ── Public re-exports ────────────────────────────────────────────────\n\nexport * from \"./auth.js\";\nexport { ${clientClass} } from \"./rest.js\";\nexport { ${inputs.capabilityClass} } from \"./capabilities/${inputs.capability}.js\";\nexport { verifyToken } from \"./verify-token.js\";\nexport type { VerifyTokenResult, VerifyTokenSuccess, VerifyTokenFailure } from \"./verify-token.js\";\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(inputs: TemplateInputs): string {\n\treturn `<!-- editorconfig-checker-disable-file -->\n\n# \\`@theholocron/holocron-plugin-${inputs.slug}\\`\n\n${inputs.vendorName} plugin for [Holocron](../cli). Implements the\n\\`${inputs.capability}\\` capability against [${inputs.vendorName}'s REST API](${inputs.baseUrl}),\nplus exports \\`verifyToken\\` + \\`AUTH_HINT\\` for use by \\`holocron auth\\`.\n\n## Install\n\n\\`\\`\\`bash\npnpm add -D @theholocron/holocron-plugin-${inputs.slug}@alpha\n\\`\\`\\`\n\n## Auth\n\nToken resolution order (matches the standard 4-step precedence set by\n\\`docs/wiki/specifications/tech-auth-bootstrap.spec.md\\`):\n\n1. \\`--token <TOKEN>\\` flag on the holocron invocation\n2. \\`${inputs.tokenEnv}\\` env var (preferred — explicit intent)\n3. \\`${inputs.vendorEnv}\\` env var (${inputs.vendorName}-native)\n4. **Keyring** — \\`com.theholocron.cli\\` service, account \\`${inputs.slug}\\`\n5. \\`AuthError\\` naming all four options + the bootstrap hint\n\n## Setup\n\n\\`\\`\\`bash\n# Generate a ${inputs.vendorName} API token (see vendor docs), then:\nholocron auth set ${inputs.slug} <TOKEN>\nholocron auth check ${inputs.slug} # verify\n\\`\\`\\`\n\n## Config\n\n\\`\\`\\`jsonc\n{\n\t\"providers\": {\n\t\t\"${inputs.capability}\": \"${inputs.slug}\",\n\t},\n}\n\\`\\`\\`\n\nPlugin options extend \\`ResolveTokenInput\\` — add whatever ${inputs.vendorName}-\nspecific options you need here (project id, workspace slug, etc.) via\nthe tuple form:\n\n\\`\\`\\`jsonc\n{\n\t\"providers\": {\n\t\t\"${inputs.capability}\": [\"${inputs.slug}\", { \"baseUrl\": \"${inputs.baseUrl}\" }],\n\t},\n}\n\\`\\`\\`\n\n## What's implemented\n\nTODO: fill in as capability methods land.\n\n## Status\n\n**\\`v2.0.0-alpha.1\\`** — scaffolded via \\`holocron plugin create\\`.\nNot yet published; capability methods are stubs.\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(inputs: TemplateInputs): string {\n\tconst factoryName = `create${inputs.vendorName}RestClient`;\n\treturn `import { createRestClient, type RequestOptions, type RestClient } from \"@theholocron/cli\";\n\nexport type { RequestOptions, RestClient };\n\nexport function ${factoryName}(opts: {\n\\ttoken: string;\n\\tbaseUrl?: string;\n\\tfetch?: typeof fetch;\n}): RestClient {\n\\treturn createRestClient({\n\\t\\tbaseUrl: opts.baseUrl ?? \"${inputs.baseUrl}\",\n\\t\\ttoken: opts.token,\n\\t\\tvendor: \"${inputs.vendorName}\",\n\\t\\tfetch: opts.fetch,\n\\t});\n}\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(inputs: TemplateInputs): string {\n\tconst factoryName = `create${inputs.vendorName}RestClient`;\n\treturn `import { ProviderApiError } from \"@theholocron/cli\";\nimport { describe, expect, it } from \"vitest\";\n\nimport { ${factoryName} } from \"../rest.js\";\nimport { stubFetch } from \"./helpers.js\";\n\ndescribe(\"${factoryName}\", () => {\n\\tit(\"sends bearer + accept headers and returns the parsed body\", async () => {\n\\t\\tconst stub = stubFetch([{ status: 200, body: { ok: true } }]);\n\\t\\tconst client = ${factoryName}({ token: \"t\", fetch: stub.fetch });\n\\t\\tconst res = await client.request<{ ok: boolean }>(\"/me\");\n\\t\\texpect(res.ok).toBe(true);\n\\t\\texpect(stub.calls[0]?.headers[\"authorization\"]).toBe(\"Bearer t\");\n\\t\\texpect(stub.calls[0]?.headers[\"accept\"]).toBe(\"application/json\");\n\\t});\n\n\\tit(\"serializes body as JSON and sets content-type when present\", async () => {\n\\t\\tconst stub = stubFetch([{ status: 200, body: {} }]);\n\\t\\tconst client = ${factoryName}({ token: \"t\", fetch: stub.fetch });\n\\t\\tawait client.request<unknown>(\"/resource\", { method: \"POST\", body: { name: \"demo\" } });\n\\t\\texpect(stub.calls[0]?.method).toBe(\"POST\");\n\\t\\texpect(stub.calls[0]?.headers[\"content-type\"]).toBe(\"application/json\");\n\\t\\texpect(stub.calls[0]?.body).toEqual({ name: \"demo\" });\n\\t});\n\n\\tit(\"returns undefined on 204\", async () => {\n\\t\\tconst stub = stubFetch([{ status: 204 }]);\n\\t\\tconst client = ${factoryName}({ token: \"t\", fetch: stub.fetch });\n\\t\\texpect(await client.request<unknown>(\"/whatever\")).toBeUndefined();\n\\t});\n\n\\tit(\"throws ProviderApiError with the HTTP status on non-2xx\", async () => {\n\\t\\tconst stub = stubFetch([{ status: 401, body: { messages: [\"invalid\"] } }]);\n\\t\\tconst client = ${factoryName}({ token: \"bad\", fetch: stub.fetch });\n\\t\\tconst err = await client.request<unknown>(\"/me\").catch((e: unknown) => e);\n\\t\\texpect(err).toBeInstanceOf(ProviderApiError);\n\\t\\texpect((err as ProviderApiError).status).toBe(401);\n\\t});\n\n\\tit(\"wraps transport-level failures with status 0\", async () => {\n\\t\\tconst throwing: typeof fetch = async () => { throw new TypeError(\"fetch failed\"); };\n\\t\\tconst client = ${factoryName}({ token: \"t\", fetch: throwing });\n\\t\\tconst err = await client.request<unknown>(\"/me\").catch((e: unknown) => e);\n\\t\\texpect(err).toBeInstanceOf(ProviderApiError);\n\\t\\texpect((err as ProviderApiError).status).toBe(0);\n\\t});\n\n\\tit(\"trims trailing slashes from the base URL\", () => {\n\\t\\tconst client = ${factoryName}({ token: \"t\", baseUrl: \"${inputs.baseUrl}//\" });\n\\t\\texpect(client.baseUrl).toBe(\"${inputs.baseUrl}\");\n\\t});\n});\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(inputs: TemplateInputs): string {\n\treturn (\n\t\tJSON.stringify(\n\t\t\t{\n\t\t\t\tdisplay: `Holocron Plugin: ${inputs.vendorName}`,\n\t\t\t\textends: \"@tsconfig/node-lts/tsconfig.json\",\n\t\t\t\tcompilerOptions: {\n\t\t\t\t\tbaseUrl: \"./\",\n\t\t\t\t\toutDir: \"./dist\",\n\t\t\t\t\tpaths: { \"@/*\": [\"./src/*\"] },\n\t\t\t\t},\n\t\t\t\tinclude: [\"src/**/*.ts\"],\n\t\t\t\texclude: [\"node_modules\", \"dist\"],\n\t\t\t},\n\t\t\tnull,\n\t\t\t\"\\t\"\n\t\t) + \"\\n\"\n\t);\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(_inputs: TemplateInputs): string {\n\treturn `import { defineConfig } from \"tsdown\";\n\nexport default defineConfig({\n\tentry: [\"src/index.ts\"],\n\tformat: \"esm\",\n\tdts: true,\n\tclean: true,\n\tdeps: { neverBundle: [/^@theholocron\\\\//] },\n});\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\n/**\n * Scaffolds `scripts/validate.mjs` — a smoke-test the operator runs\n * against a live vendor account to verify the plugin's REST endpoints,\n * auth, and response parsing all work in reality (the unit tests only\n * exercise stubbed HTTP responses). READ-ONLY BY DESIGN.\n *\n * Convention: every plugin ships this script + a matching `validate`\n * entry in `package.json`'s scripts block, so operators run\n * `pnpm --filter @theholocron/holocron-plugin-<slug> validate`.\n * Capability-specific args (project id, workspace, etc.) come from\n * positional command-line arguments; the plugin author fills in the\n * exact shape per their vendor.\n *\n * Includes a `hintFor(message)` helper the operator customizes with\n * vendor-specific \"here's the likely fix\" guidance for common error\n * shapes (401 / 403 / 404 / network / 5xx). Points users at docs and\n * setup steps rather than leaving them staring at a raw stack trace.\n */\nexport function render(inputs: TemplateInputs): string {\n\treturn `#!/usr/bin/env node\n/**\n * Read-only smoke test for @theholocron/holocron-plugin-${inputs.slug} against\n * a live ${inputs.vendorName} account.\n *\n * READ-ONLY BY DESIGN. Never calls write(), or bootstrap methods\n * (\\`ensureProject\\`, \\`ensureEnvironment\\`, etc.). Any ERROR line means\n * the plugin needs adjusting — the \\`hintFor\\` helper below points at\n * the most likely fix per error shape.\n *\n * Auth: reads the ${inputs.vendorName} token from holocron's keyring —\n * you must have run \\`pnpm holocron auth set ${inputs.slug} <TOKEN>\\` first.\n *\n * Usage:\n * pnpm --filter @theholocron/holocron-plugin-${inputs.slug} validate <arg1> [arg2] ...\n *\n * TODO: replace the positional args below with whatever your\n * capability's methods need (e.g., project id, environment slug,\n * secret name). Adapt the test steps to your capability's method\n * surface. Model on \\`packages/holocron-plugin-infisical/scripts/validate.mjs\\`.\n */\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars -- filled in by operator\nimport { AuthError, createPlugin, resolveToken, verifyToken } from \"../src/index.ts\";\n\nconst args = process.argv.slice(2);\n\nif (args.length === 0) {\n\tconsole.error(\"usage: pnpm --filter @theholocron/holocron-plugin-${inputs.slug} validate <args>\");\n\tprocess.exit(2);\n}\n\n// Use the plugin's own auth resolution so the validate script honors\n// the same 4-step precedence as the plugin's runtime:\n// --token → ${inputs.tokenEnv} → ${inputs.vendorEnv} → keyring\n// (--token isn't available here since this is a bare Node script;\n// the other three all work.)\nlet token;\ntry {\n\ttoken = resolveToken();\n} catch (err) {\n\tif (err instanceof AuthError) {\n\t\tconsole.error(err.message);\n\t\tconsole.error(\" see: packages/holocron-plugin-${inputs.slug}/README.md#setup\");\n\t\tprocess.exit(2);\n\t}\n\tthrow err;\n}\n\nconsole.log(\"Validating @theholocron/holocron-plugin-${inputs.slug} (READ-ONLY)\");\nconsole.log(\"\");\n\n// ── 1. verifyToken ─────────────────────────────────────────────────\nconsole.log(\"[1/N] verifyToken\");\nconst verifyResult = await verifyToken(token);\nconsole.log(\\` \\${verifyResult.ok ? \"✓\" : \"✗\"} \\${JSON.stringify(verifyResult)}\\`);\nif (!verifyResult.ok) {\n\tconst hint = hintFor(verifyResult.message);\n\tif (hint) console.log(\\` hint: \\${hint}\\`);\n}\nconsole.log(\"\");\n\n// ── 2..N. capability method calls ──────────────────────────────────\n// TODO: implement one \\`runStep\\`-wrapped call per meaningful read-side\n// capability method. Model on the infisical validate.mjs. Never call\n// write / ensure* / other mutating paths.\n//\n// Example:\n// console.log(\"[2/N] vault.list()\");\n// await runStep(async () => {\n// const keys = await vault.list();\n// console.log(\\` ✓ \\${keys.length} secrets\\`);\n// });\n\nconsole.log(\"Done. Fill in capability method calls above before shipping.\");\n\n// ── helpers ────────────────────────────────────────────────────────\n\n/** Wrap a capability call, print ERROR + hint on failure. */\nasync function runStep(body) {\n\ttry {\n\t\tawait body();\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tconsole.log(\\` ✗ ERROR: \\${message}\\`);\n\t\tconst hint = hintFor(message);\n\t\tif (hint) console.log(\\` hint: \\${hint}\\`);\n\t}\n}\n\n/**\n * Point the operator at the most likely fix based on the error shape.\n * Generic defaults below — CUSTOMIZE per your vendor's docs URLs and\n * common permission/config gotchas.\n */\nfunction hintFor(message) {\n\tif (/→ 401/.test(message)) {\n\t\treturn \"token invalid — regenerate per ${inputs.vendorName}'s docs (see README §Setup)\";\n\t}\n\tif (/→ 403/.test(message)) {\n\t\treturn \"token authenticates but lacks scope — check the token/identity has permissions on the resource\";\n\t}\n\tif (/→ 404/.test(message)) {\n\t\treturn \"endpoint or resource not found — verify your positional args match a real resource\";\n\t}\n\tif (/fetch failed|status: 0|network/i.test(message)) {\n\t\treturn \"network error — check the base URL (${inputs.baseUrl}) and connectivity\";\n\t}\n\tif (/→ 5\\\\d\\\\d/.test(message)) {\n\t\treturn \"server error — vendor-side. Retry, and check the vendor's status page if persistent\";\n\t}\n\treturn null;\n}\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(inputs: TemplateInputs): string {\n\tconst clientClass = `${inputs.vendorName}RestClient`;\n\treturn `/**\n * \\`verifyToken\\` — plugin-level export used by \\`holocron auth set\\` +\n * \\`holocron auth check\\`. Hits a lightweight whoami-style endpoint\n * and translates the response into the normalized \\`VerifyTokenResult\\`\n * shape.\n *\n * Kept as a standalone function (not a capability method) so the auth\n * command can call it without initializing the full plugin — plugin\n * construction requires an already-resolved token, which is exactly\n * what we don't have yet at bootstrap time.\n *\n * TODO: replace \\`/me\\` with the ${inputs.vendorName} equivalent of a\n * \"check my token\" endpoint. Common shapes: \\`/user\\`, \\`/whoami\\`,\n * \\`/me\\`, \\`/account\\`.\n */\n\nimport { ${clientClass} } from \"./rest.js\";\n\nexport interface VerifyTokenSuccess {\n\tok: true;\n\tsubject: string;\n}\n\nexport interface VerifyTokenFailure {\n\tok: false;\n\tmessage: string;\n}\n\nexport type VerifyTokenResult = VerifyTokenSuccess | VerifyTokenFailure;\n\ninterface MeResponse {\n\t/** Adjust to whatever ${inputs.vendorName}'s whoami endpoint returns. */\n\tname?: string;\n\temail?: string;\n\tid?: string;\n}\n\nexport interface VerifyTokenOptions {\n\tbaseUrl?: string;\n\tfetch?: typeof fetch;\n}\n\nexport async function verifyToken(token: string, opts: VerifyTokenOptions = {}): Promise<VerifyTokenResult> {\n\tconst restOpts: ConstructorParameters<typeof ${clientClass}>[0] = { token };\n\tif (opts.baseUrl !== undefined) restOpts.baseUrl = opts.baseUrl;\n\tif (opts.fetch !== undefined) restOpts.fetch = opts.fetch;\n\tconst rest = new ${clientClass}(restOpts);\n\ttry {\n\t\tconst me = await rest.request<MeResponse>(\"/me\");\n\t\t// Optional chaining because \\`me\\` is \\`undefined\\` on 204 / empty body.\n\t\tconst subject = me?.email ?? me?.name ?? me?.id ?? \"unknown\";\n\t\treturn { ok: true, subject: \\`user @ \\${subject}\\` };\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\treturn { ok: false, message };\n\t}\n}\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(_inputs: TemplateInputs): string {\n\treturn `import { describe, expect, it } from \"vitest\";\n\nimport { verifyToken } from \"../verify-token.js\";\nimport { stubFetch } from \"./helpers.js\";\n\ndescribe(\"verifyToken\", () => {\n\tit(\"returns ok with a subject when /me returns 200\", async () => {\n\t\tconst stub = stubFetch([{ status: 200, body: { email: \"user@example.com\" } }]);\n\t\tconst result = await verifyToken(\"token\", { fetch: stub.fetch });\n\t\texpect(result.ok).toBe(true);\n\t\tif (result.ok) {\n\t\t\texpect(result.subject).toMatch(/user@example.com/);\n\t\t}\n\t});\n\n\tit(\"returns ok:false with the error message on 401\", async () => {\n\t\tconst stub = stubFetch([{ status: 401, body: { messages: [\"Invalid token\"] } }]);\n\t\tconst result = await verifyToken(\"bad\", { fetch: stub.fetch });\n\t\texpect(result.ok).toBe(false);\n\t\tif (!result.ok) {\n\t\t\texpect(result.message).toMatch(/→ 401/);\n\t\t}\n\t});\n\n\tit(\"returns ok:false when the network layer throws\", async () => {\n\t\tconst throwing: typeof fetch = async () => {\n\t\t\tthrow new TypeError(\"network down\");\n\t\t};\n\t\tconst result = await verifyToken(\"t\", { fetch: throwing });\n\t\texpect(result.ok).toBe(false);\n\t\tif (!result.ok) {\n\t\t\texpect(result.message).toMatch(/network down/);\n\t\t}\n\t});\n});\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(_inputs: TemplateInputs): string {\n\treturn `import { defineConfig } from \"vitest/config\";\n\nexport default defineConfig({\n\ttest: {\n\t\tenvironment: \"node\",\n\t\tglobals: false,\n\t\tcoverage: {\n\t\t\tprovider: \"v8\",\n\t\t\treporter: [\"text\", \"html\", \"json-summary\"],\n\t\t\tinclude: [\"src/**/*.ts\"],\n\t\t\texclude: [\"src/**/__tests__/**\", \"src/**/*.test.ts\", \"src/index.ts\"],\n\t\t\tthresholds: { lines: 0, functions: 0, branches: 0, statements: 0 },\n\t\t},\n\t},\n});\n`;\n}\n","/**\n * `holocron plugin create <slug> <vendor>` — scaffold a new plugin\n * package matching the proven template.\n *\n * Design: see `docs/wiki/specifications/tool-plugin-create.spec.md`.\n *\n * Flow:\n * 1. Preflight — verify CWD is a workspace root (pnpm-workspace.yaml\n * + packages/ dir present).\n * 2. Slug collision — packages/holocron-plugin-<slug>/ must not exist.\n * 3. Capability sanity — must be one of the 14 known keys; warn for\n * many-cardinality caps.\n * 4. Generate — for each template, write to\n * packages/holocron-plugin-<slug>/<path>.\n * 5. Verify (unless --no-verify) — runs pnpm install +\n * pnpm --filter <pkg> typecheck lint test.\n * 6. Print next steps.\n */\n\nimport { execFileSync } from \"node:child_process\";\nimport { existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\n\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport { getLogger } from \"../../logger.js\";\nimport type { CapabilityKey } from \"../../plugin/capabilities.js\";\nimport { CARDINALITY } from \"../../plugin/capabilities.js\";\nimport { deriveDefaults, type TemplateInputs } from \"./template-inputs.js\";\nimport { render as renderAuth } from \"./templates/auth.js\";\nimport { render as renderAuthTest } from \"./templates/auth-test.js\";\nimport { render as renderCapability } from \"./templates/capability.js\";\nimport { render as renderCapabilityTest } from \"./templates/capability-test.js\";\nimport { render as renderEslintConfig } from \"./templates/eslint-config.js\";\nimport { render as renderHelpers } from \"./templates/helpers.js\";\nimport { render as renderIndexTest } from \"./templates/index-test.js\";\nimport { render as renderPackageJson } from \"./templates/package-json.js\";\nimport { render as renderPluginIndex } from \"./templates/plugin-index.js\";\nimport { render as renderReadme } from \"./templates/readme.js\";\nimport { render as renderRest } from \"./templates/rest.js\";\nimport { render as renderRestTest } from \"./templates/rest-test.js\";\nimport { render as renderTsconfigJson } from \"./templates/tsconfig-json.js\";\nimport { render as renderTsdownConfig } from \"./templates/tsdown-config.js\";\nimport { render as renderValidateScript } from \"./templates/validate-script.js\";\nimport { render as renderVerifyToken } from \"./templates/verify-token.js\";\nimport { render as renderVerifyTokenTest } from \"./templates/verify-token-test.js\";\nimport { render as renderVitestConfig } from \"./templates/vitest-config.js\";\n\n// ── Public API ──────────────────────────────────────────────────────\n\n// ── Wizard resolver ───────────────────────────────────────────────────\n\nexport interface PluginCreateWizardArgs {\n\tcapability?: string;\n\tvendorEnv?: string;\n\tbaseUrl?: string;\n}\n\nexport interface PluginCreateWizardPrompts {\n\tselectCapability: () => Promise<string>;\n\tinputVendorEnv: () => Promise<string>;\n\tinputBaseUrl: () => Promise<string>;\n}\n\n/**\n * Resolve `capability`, `vendorEnv`, and `baseUrl` from argv or by calling\n * the supplied prompt functions for any that are absent. Extracted from\n * `cli.ts` so the resolution logic is unit-testable.\n */\nexport async function resolvePluginCreateInputs(\n\targs: PluginCreateWizardArgs,\n\tprompts: PluginCreateWizardPrompts\n): Promise<{ capability: CapabilityKey; vendorEnv: string; baseUrl: string }> {\n\tconst capability = (args.capability ?? (await prompts.selectCapability())) as CapabilityKey;\n\tconst vendorEnv = args.vendorEnv ?? (await prompts.inputVendorEnv());\n\tconst baseUrl = args.baseUrl ?? (await prompts.inputBaseUrl());\n\treturn { capability, vendorEnv, baseUrl };\n}\n\n// ── Run input / report ────────────────────────────────────────────────\n\nexport interface RunPluginCreateInput {\n\t/** Package slug, e.g., \"clerk\". Kebab-case. */\n\tslug: string;\n\t/** Vendor display name, e.g., \"Clerk\". PascalCase. */\n\tvendorName: string;\n\t/** Capability the plugin implements — one of the 14 known keys. */\n\tcapability: CapabilityKey;\n\t/** Vendor-native env var, e.g., \"CLERK_SECRET_KEY\". */\n\tvendorEnv: string;\n\t/** REST base URL, e.g., \"https://api.clerk.com/v1\". */\n\tbaseUrl: string;\n\t/** Optional token env override. Defaults to `HOLOCRON_<VENDOR>_TOKEN`. */\n\ttokenEnv?: string;\n\t/** Print steps without writing files. */\n\tdryRun?: boolean;\n\t/** Skip the post-scaffold pnpm install/typecheck/lint/test. */\n\tnoVerify?: boolean;\n\t/** Working directory (workspace root). Defaults to `process.cwd()`. */\n\tcwd?: string;\n\t/** Injection point for tests / dry-run wiring. Defaults to fs write. */\n\twriteFile?: (filepath: string, content: string) => void;\n\t/** Print fn — captures orchestrator output. Defaults to console.log. */\n\tprint?: (line: string) => void;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n\t/** Injectable subprocess runner for testing. Defaults to execFileSync. */\n\texec?: (cmd: string, args: string[], opts: { cwd: string; stdio: \"inherit\" }) => void;\n}\n\nexport interface PluginCreateReport {\n\tstatus: \"ok\" | \"fail\";\n\tpackagePath: string;\n\tfilesWritten: string[];\n\tmessage?: string;\n}\n\nexport class PluginCreateError extends Error {\n\toverride name = \"PluginCreateError\";\n}\n\n// ── Templates registry ──────────────────────────────────────────────\n\ninterface TemplateEntry {\n\t/** Path relative to the plugin package root. */\n\tpath: string;\n\trender: (inputs: TemplateInputs) => string;\n}\n\nconst TEMPLATES: TemplateEntry[] = [\n\t// Config (5)\n\t{ path: \"package.json\", render: renderPackageJson },\n\t{ path: \"tsconfig.json\", render: renderTsconfigJson },\n\t{ path: \"vitest.config.ts\", render: renderVitestConfig },\n\t{ path: \"eslint.config.js\", render: renderEslintConfig },\n\t{ path: \"tsdown.config.ts\", render: renderTsdownConfig },\n\t// Docs (1)\n\t{ path: \"README.md\", render: renderReadme },\n\t// Source (5) — capability path uses the dynamic capability slug.\n\t{ path: \"src/auth.ts\", render: renderAuth },\n\t{ path: \"src/rest.ts\", render: renderRest },\n\t{ path: \"src/verify-token.ts\", render: renderVerifyToken },\n\t{ path: \"src/index.ts\", render: renderPluginIndex },\n\t{ path: \"src/capabilities/{{capability}}.ts\", render: renderCapability },\n\t// Tests (6)\n\t{ path: \"src/__tests__/helpers.ts\", render: renderHelpers },\n\t{ path: \"src/__tests__/auth.test.ts\", render: renderAuthTest },\n\t{ path: \"src/__tests__/rest.test.ts\", render: renderRestTest },\n\t{ path: \"src/__tests__/verify-token.test.ts\", render: renderVerifyTokenTest },\n\t{ path: \"src/__tests__/{{capability}}.test.ts\", render: renderCapabilityTest },\n\t{ path: \"src/__tests__/index.test.ts\", render: renderIndexTest },\n\t// Live-account validation script (1) — read-only smoke test.\n\t{ path: \"scripts/validate.mjs\", render: renderValidateScript },\n];\n\n/** Replace `{{capability}}` in a template path with the actual capability key. */\nfunction resolvePath(template: string, inputs: TemplateInputs): string {\n\treturn template.replace(/\\{\\{capability\\}\\}/g, inputs.capability);\n}\n\n// ── Orchestrator ────────────────────────────────────────────────────\n\nexport function runPluginCreate(input: RunPluginCreateInput): PluginCreateReport {\n\tconst cwd = input.cwd ?? process.cwd();\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst write = input.writeFile ?? defaultWrite;\n\n\tpreflight(cwd);\n\tvalidateSlug(input.slug);\n\tvalidateVendorName(input.vendorName);\n\n\tconst packageDir = path.join(cwd, \"packages\", `holocron-plugin-${input.slug}`);\n\tif (existsSync(packageDir)) {\n\t\tthrow new PluginCreateError(`\\`${packageDir}\\` already exists — edit in place or pick a different slug.`);\n\t}\n\n\tvalidateCapability(input.capability, print);\n\n\tconst derived = deriveDefaults({\n\t\tslug: input.slug,\n\t\tvendorName: input.vendorName,\n\t\tcapability: input.capability,\n\t});\n\tconst inputs: TemplateInputs = {\n\t\tslug: input.slug,\n\t\tvendorName: input.vendorName,\n\t\tvendorUpper: derived.vendorUpper,\n\t\tcapability: input.capability,\n\t\tcapabilityClass: derived.capabilityClass,\n\t\ttokenEnv: input.tokenEnv ?? derived.tokenEnv,\n\t\tvendorEnv: input.vendorEnv,\n\t\t// Normalize: strip trailing slashes so the embedded value in the\n\t\t// generated rest-test.ts matches what the client trims at runtime.\n\t\tbaseUrl: trimTrailingSlashes(input.baseUrl),\n\t\ttransport: derived.transport,\n\t};\n\n\tconst filesWritten: string[] = [];\n\tprint(`Scaffolding @theholocron/holocron-plugin-${inputs.slug}${input.dryRun ? \" (dry-run)\" : \"\"}`);\n\tprint(` → ${packageDir}`);\n\tlogger.info(\n\t\t{ slug: inputs.slug, capability: inputs.capability, dryRun: input.dryRun || undefined },\n\t\t\"plugin create: start\"\n\t);\n\tfor (const template of TEMPLATES) {\n\t\tconst resolvedPath = resolvePath(template.path, inputs);\n\t\tconst filepath = path.join(packageDir, resolvedPath);\n\t\tconst content = template.render(inputs);\n\t\tif (input.dryRun) {\n\t\t\tprint(` … would write ${resolvedPath} (${content.length} bytes)`);\n\t\t} else {\n\t\t\twrite(filepath, content);\n\t\t\tprint(` ✓ ${resolvedPath}`);\n\t\t}\n\t\tfilesWritten.push(resolvedPath);\n\t}\n\n\tif (!input.dryRun && !input.noVerify) {\n\t\tconst execFn = input.exec ?? defaultExec;\n\t\tconst pkg = `@theholocron/holocron-plugin-${inputs.slug}`;\n\t\tprint(\"\");\n\t\tprint(\" Verifying scaffold…\");\n\t\ttry {\n\t\t\texecFn(\"pnpm\", [\"install\", \"--frozen-lockfile=false\"], { cwd, stdio: \"inherit\" });\n\t\t\texecFn(\"pnpm\", [\"--filter\", pkg, \"verification.typeSafety\"], { cwd, stdio: \"inherit\" });\n\t\t\texecFn(\"pnpm\", [\"--filter\", pkg, \"sourceQuality.staticAnalysis\"], { cwd, stdio: \"inherit\" });\n\t\t\texecFn(\"pnpm\", [\"--filter\", pkg, \"verification.unitTests\"], { cwd, stdio: \"inherit\" });\n\t\t\tprint(\" ✓ scaffold verified\");\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\t\tprint(` ✗ verify failed — ${message}`);\n\t\t\tlogger.warn(\n\t\t\t\t{ slug: inputs.slug, files: filesWritten.length, reason: message, status: \"fail\" },\n\t\t\t\t\"plugin create: done\"\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tstatus: \"fail\",\n\t\t\t\tpackagePath: packageDir,\n\t\t\t\tfilesWritten,\n\t\t\t\tmessage: \"post-scaffold verify failed; inspect output above\",\n\t\t\t};\n\t\t}\n\t}\n\n\tif (!input.dryRun) {\n\t\tprintNextSteps(print, inputs);\n\t}\n\n\tlogger.info(\n\t\t{\n\t\t\tslug: inputs.slug,\n\t\t\tcapability: inputs.capability,\n\t\t\tfiles: filesWritten.length,\n\t\t\tstatus: input.dryRun ? \"dry-run\" : \"ok\",\n\t\t},\n\t\t\"plugin create: done\"\n\t);\n\treturn { status: \"ok\", packagePath: packageDir, filesWritten };\n}\n\n// ── Internals ───────────────────────────────────────────────────────\n\nfunction preflight(cwd: string): void {\n\tif (!existsSync(path.join(cwd, \"pnpm-workspace.yaml\"))) {\n\t\tthrow new PluginCreateError(\n\t\t\t`\\`pnpm-workspace.yaml\\` not found in \\`${cwd}\\`. Run \\`holocron plugin create\\` from the monorepo root.`\n\t\t);\n\t}\n\tif (!existsSync(path.join(cwd, \"packages\"))) {\n\t\tthrow new PluginCreateError(`\\`packages/\\` directory not found in \\`${cwd}\\`.`);\n\t}\n}\n\n/**\n * npm-package-name conventions: kebab-case, starts with lowercase\n * letter. Rejecting numeric-prefixed slugs also sidesteps the\n * `env.HOLOCRON_1FOO_TOKEN` invalid-identifier trap in the auth\n * template.\n */\nconst SLUG_RE = /^[a-z][a-z0-9-]*$/;\n\nfunction validateSlug(slug: string): void {\n\tif (!SLUG_RE.test(slug)) {\n\t\tthrow new PluginCreateError(\n\t\t\t`invalid slug \"${slug}\" — must be kebab-case: lowercase letter followed by lowercase letters, digits, or hyphens. ` +\n\t\t\t\t`Examples: \"clerk\", \"cloud-flare\", \"doppler\".`\n\t\t);\n\t}\n}\n\n/** PascalCase — starts with uppercase, alphanumeric only. */\nconst VENDOR_NAME_RE = /^[A-Z][a-zA-Z0-9]*$/;\n\nfunction validateVendorName(name: string): void {\n\tif (!VENDOR_NAME_RE.test(name)) {\n\t\tthrow new PluginCreateError(\n\t\t\t`invalid vendor name \"${name}\" — must be PascalCase: starts with uppercase, alphanumeric only. ` +\n\t\t\t\t`Examples: \"Clerk\", \"CloudFlare\", \"Doppler\".`\n\t\t);\n\t}\n}\n\n/**\n * Trim trailing slashes with a plain loop (no regex — matches the\n * rest.ts template's own trimming to stay ReDoS-safe under CodeQL).\n */\nfunction trimTrailingSlashes(url: string): string {\n\tlet out = url;\n\twhile (out.endsWith(\"/\")) out = out.slice(0, -1);\n\treturn out;\n}\n\nfunction validateCapability(capability: CapabilityKey, print: (line: string) => void): void {\n\tif (!(capability in CARDINALITY)) {\n\t\tthrow new PluginCreateError(\n\t\t\t`\\`${capability}\\` is not a known capability. See \\`packages/cli/src/capabilities/index.ts\\`.`\n\t\t);\n\t}\n\tif (CARDINALITY[capability] === \"many\") {\n\t\tprint(\n\t\t\t` ! ${capability} is a many-cardinality capability — multiple providers can be active at once. ` +\n\t\t\t\t\"Confirm your config wiring accordingly.\"\n\t\t);\n\t}\n}\n\nfunction defaultWrite(filepath: string, content: string): void {\n\tmkdirSync(path.dirname(filepath), { recursive: true });\n\twriteFileSync(filepath, content, \"utf8\");\n}\n\nfunction defaultExec(cmd: string, args: string[], opts: { cwd: string; stdio: \"inherit\" }): void {\n\texecFileSync(cmd, args, { cwd: opts.cwd, stdio: opts.stdio });\n}\n\nfunction printNextSteps(print: (line: string) => void, inputs: TemplateInputs): void {\n\tprint(\"\");\n\tprint(` Scaffolded @theholocron/holocron-plugin-${inputs.slug} (18 files).`);\n\tprint(\"\");\n\tprint(\" Next:\");\n\tprint(\n\t\t` 1. pnpm install # picks up the workspace package`\n\t);\n\tprint(` 2. pnpm --filter @theholocron/holocron-plugin-${inputs.slug} typecheck # green`);\n\tprint(` 3. pnpm --filter @theholocron/holocron-plugin-${inputs.slug} lint # green`);\n\tprint(\n\t\t` 4. pnpm --filter @theholocron/holocron-plugin-${inputs.slug} test # green (stubs pass, real tests are it.todo)`\n\t);\n\tprint(` 5. Implement ${inputs.capabilityClass} methods in src/capabilities/${inputs.capability}.ts`);\n\tprint(` 6. Replace it.todo(...) with real tests in src/__tests__/${inputs.capability}.test.ts`);\n\tprint(\" 7. Commit + push when capability is functionally complete.\");\n}\n","/**\n * `holocron publish --initial` — bottles up the chicken-and-egg bootstrap\n * that every new npm-published holocron monorepo hits.\n *\n * npm requires a package to exist before Trusted Publishing can be\n * configured on it. So the first publish has to happen outside the OIDC\n * flow — a browser-auth session (`npm login --auth-type=web`) or an\n * ephemeral automation token. This command drives the login step itself\n * (when `npm whoami` shows you're not authenticated), runs the publish\n * step, and tells you exactly what to do next.\n *\n * Workflow:\n *\n * $ pnpm install --frozen-lockfile\n * $ pnpm build\n * $ pnpm exec tsx packages/cli/src/cli.ts publish --initial\n *\n * `npm login --auth-type=web` runs automatically the first time — no\n * separate manual step. `pnpm install` + `pnpm build` stay outside the\n * command (no pnpm-inside-pnpm).\n *\n * `--initial` is required today — this command only implements the\n * bootstrap publish. A non-initial `holocron publish` (for a manual publish\n * outside the semantic-release/OIDC steady state) isn't built yet; the flag\n * exists so the surface doesn't need another rename when it is.\n *\n * If `NPM_TOKEN` is detected in env, the command prints a final\n * \"revoke this token at <url>\" reminder — same pattern as `rando vc\n * setup` for the ephemeral GH admin PAT.\n */\n\nimport { spawnSync } from \"node:child_process\";\nimport { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport { type CliEnv, makeEnv } from \"../env.js\";\nimport { getLogger } from \"../logger.js\";\n\nexport type PublishPrint = (line: string) => void;\n\nexport type PublishExecResult = {\n\texitCode: number;\n\tstdout: string;\n\tstderr: string;\n};\n\nexport interface RunPublishInput {\n\t/** Working directory (the monorepo or package root). Defaults to process.cwd(). */\n\tcwd?: string;\n\t/** Distribution tag for the publish. Defaults to `'alpha'`. */\n\ttag?: string;\n\t/** Skip the actual publish; print what would happen. */\n\tdryRun?: boolean;\n\t/**\n\t * One-time password (TOTP) from your authenticator app. Required if\n\t * your npm account has \"Require 2FA for read and write\" enabled.\n\t * Reused across all sequential publishes — they fire within a few\n\t * seconds, comfortably inside the TOTP window.\n\t */\n\totp?: string;\n\tprint?: PublishPrint;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n\t/**\n\t * Injectable command runner. Defaults to `spawnSync` with\n\t * `stdio: ['inherit', 'pipe', 'pipe']` so interactive prompts\n\t * (e.g., npm OTP) still work.\n\t *\n\t * Returns exit code + captured stdout/stderr.\n\t */\n\texec?: (cmd: string, args: string[], opts: { cwd: string }) => Promise<PublishExecResult>;\n\t/**\n\t * Injectable `npm login --auth-type=web` runner, invoked when `npm\n\t * whoami` shows no authenticated session. Fully `stdio: 'inherit'` (not\n\t * `exec`'s captured-output shape) — the browser flow prints a URL and\n\t * waits, and the operator needs to see that live. Defaults to a real\n\t * `spawnSync`.\n\t */\n\tlogin?: (cwd: string) => Promise<{ exitCode: number }>;\n\t/** Env vars; passed in for testability. Defaults to process.env. */\n\tenv?: NodeJS.ProcessEnv;\n\t/**\n\t * Override the list of package names shown in the Trusted Publisher\n\t * next-steps output. Auto-discovered from packages/*\\/package.json\n\t * (or the root package.json for a single-package repo) when omitted.\n\t */\n\tpackages?: readonly string[];\n\t/**\n\t * Override the repo name shown in the Trusted Publisher next-steps\n\t * output. Auto-detected from `git remote get-url origin` when omitted.\n\t */\n\trepoName?: string;\n}\n\nexport type PublishStatus = \"ok\" | \"fail\" | \"dry-run\";\n\nexport interface PublishReport {\n\tstatus: PublishStatus;\n\tmessage?: string;\n\t/** Packages that the publish step targeted. */\n\tpackageNames: readonly string[];\n}\n\nexport interface RunSyncTrustInput {\n\t/** Working directory (the monorepo or package root). Defaults to process.cwd(). */\n\tcwd?: string;\n\t/** The workflow filename npm's Trusted Publisher config currently points at. */\n\toldFile: string;\n\t/** The workflow filename to migrate every package's Trusted Publisher config to. */\n\tnewFile: string;\n\t/** `owner/repo` for the GitHub Trusted Publisher config. Defaults to `theholocron/holocron`. */\n\trepo?: string;\n\t/** Skip the actual npm calls; print what would happen. */\n\tdryRun?: boolean;\n\tprint?: PublishPrint;\n\tlogger?: Logger;\n\t/** Injectable command runner — same shape as `RunPublishInput['exec']`. */\n\texec?: (cmd: string, args: string[], opts: { cwd: string }) => Promise<PublishExecResult>;\n\t/** Override the list of package names. Auto-discovered when omitted. */\n\tpackages?: readonly string[];\n}\n\nexport interface SyncTrustPackageResult {\n\tname: string;\n\tstatus: \"ok\" | \"skipped\" | \"needs-auth\" | \"fail\";\n\tmessage?: string;\n}\n\nexport interface SyncTrustReport {\n\tstatus: PublishStatus;\n\tmessage?: string;\n\tpackages: readonly SyncTrustPackageResult[];\n}\n\ninterface NpmTrustEntry {\n\tid?: string;\n\tfile?: string;\n}\ninterface NpmTrustError {\n\terror?: { code?: string; authUrl?: string };\n}\n\n/**\n * `holocron publish --sync-trust <old-file> <new-file>` — bulk-migrates npm\n * Trusted Publisher (OIDC) config to a new workflow filename across every\n * public package. See issue #689 / `scripts/npm-trust-migrate.sh` (the\n * shell-script prototype this supersedes) for the full \"why\": npm ties\n * Trusted Publisher to a workflow FILENAME per package, so renaming the\n * release workflow breaks OIDC publish (`ENEEDAUTH`) until every package's\n * config is updated to match.\n *\n * Requires npm@11.15.0+ (`npm trust`) — always shells out through\n * `npx -y npm@latest` regardless of the locally-installed npm version.\n *\n * npm's `trust` mutations — and reads, once a short-lived OTP grant lapses —\n * require a fresh interactive browser 2FA approval (an `EOTP` error with an\n * `authUrl`). No token bypasses this (npm's own docs: Granular Access Tokens\n * with the bypass-2FA option are explicitly unsupported for trust commands).\n * This command can't drive that browser step itself, so on the first `EOTP`\n * it stops immediately, prints the `authUrl`, and returns — the operator\n * approves it and re-runs; already-migrated packages are skipped on the next\n * pass, so it's safe to resume from wherever it stopped.\n */\nexport async function runSyncTrust(input: RunSyncTrustInput): Promise<SyncTrustReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst cwd = input.cwd ?? process.cwd();\n\tconst repo = input.repo ?? \"theholocron/holocron\";\n\tconst dryRun = input.dryRun ?? false;\n\tconst exec = input.exec ?? defaultExec;\n\tconst packageNames = input.packages ?? discoverPublicPackages(cwd);\n\tconst npm = \"npx\";\n\tconst npmArgs = [\"-y\", \"npm@latest\"];\n\n\tprint(`Holocron publish --sync-trust${dryRun ? \" (dry-run)\" : \"\"}`);\n\tprint(` ${input.oldFile} -> ${input.newFile} (repo: ${repo})`);\n\tprint(` ${packageNames.length} public packages`);\n\tprint(\"\");\n\tlogger.info({ oldFile: input.oldFile, newFile: input.newFile, packages: packageNames.length }, \"sync-trust: start\");\n\n\tif (packageNames.length === 0) {\n\t\tconst message = \"nothing to sync (no packages/* and root package.json is private or unnamed)\";\n\t\tprint(` ✗ ${message}`);\n\t\treturn { status: \"fail\", message, packages: [] };\n\t}\n\n\tif (dryRun) {\n\t\tfor (const name of packageNames) print(` … would sync ${name}`);\n\t\treturn { status: \"dry-run\", message: \"dry-run — no npm calls made\", packages: [] };\n\t}\n\n\tconst results: SyncTrustPackageResult[] = [];\n\n\tfor (const name of packageNames) {\n\t\tprint(`=== ${name} ===`);\n\t\tconst listResult = await exec(npm, [...npmArgs, \"trust\", \"list\", name, \"--json\"], { cwd });\n\t\tconst parsed = parseJson(listResult.stdout);\n\n\t\tif (isEotp(parsed)) {\n\t\t\tconst authUrl = (parsed as NpmTrustError).error?.authUrl ?? \"\";\n\t\t\tprint(` needs fresh 2FA — open and approve: ${authUrl}`);\n\t\t\tprint(\" then re-run; already-migrated packages are skipped.\");\n\t\t\tresults.push({ name, status: \"needs-auth\", message: authUrl });\n\t\t\tlogger.warn({ package: name, authUrl }, \"sync-trust: needs auth, stopping\");\n\t\t\treturn { status: \"fail\", message: \"npm 2FA grant needed — see printed authUrl\", packages: results };\n\t\t}\n\n\t\tconst entry = parsed as NpmTrustEntry;\n\t\tif (entry.file === input.newFile) {\n\t\t\tprint(` already on ${input.newFile}, skipping`);\n\t\t\tresults.push({ name, status: \"skipped\" });\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (entry.id) {\n\t\t\tprint(` revoking existing trust (file=${entry.file ?? \"?\"}, id=${entry.id})`);\n\t\t\tconst revoke = await exec(npm, [...npmArgs, \"trust\", \"revoke\", name, \"--id\", entry.id, \"-y\"], { cwd });\n\t\t\tif (revoke.exitCode !== 0 && isEotp(parseJson(revoke.stdout))) {\n\t\t\t\tconst authUrl = (parseJson(revoke.stdout) as NpmTrustError).error?.authUrl ?? \"\";\n\t\t\t\tprint(` needs fresh 2FA — open and approve: ${authUrl}`);\n\t\t\t\tresults.push({ name, status: \"needs-auth\", message: authUrl });\n\t\t\t\treturn { status: \"fail\", message: \"npm 2FA grant needed — see printed authUrl\", packages: results };\n\t\t\t}\n\t\t} else {\n\t\t\tprint(\" no existing trust config found\");\n\t\t}\n\n\t\tprint(` creating trust: ${input.newFile}`);\n\t\tconst create = await exec(\n\t\t\tnpm,\n\t\t\t[\n\t\t\t\t...npmArgs,\n\t\t\t\t\"trust\",\n\t\t\t\t\"github\",\n\t\t\t\tname,\n\t\t\t\t\"--repo\",\n\t\t\t\trepo,\n\t\t\t\t\"--file\",\n\t\t\t\tinput.newFile,\n\t\t\t\t\"--allow-publish\",\n\t\t\t\t\"--allow-stage-publish\",\n\t\t\t\t\"-y\",\n\t\t\t],\n\t\t\t{ cwd }\n\t\t);\n\t\tif (create.exitCode === 0) {\n\t\t\tprint(\" ✓ ok\");\n\t\t\tresults.push({ name, status: \"ok\" });\n\t\t} else {\n\t\t\tconst createParsed = parseJson(create.stdout);\n\t\t\tif (isEotp(createParsed)) {\n\t\t\t\tconst authUrl = (createParsed as NpmTrustError).error?.authUrl ?? \"\";\n\t\t\t\tprint(` needs fresh 2FA — open and approve: ${authUrl}`);\n\t\t\t\tresults.push({ name, status: \"needs-auth\", message: authUrl });\n\t\t\t\treturn { status: \"fail\", message: \"npm 2FA grant needed — see printed authUrl\", packages: results };\n\t\t\t}\n\t\t\tconst message = create.stderr.trim() || create.stdout.trim() || `exit ${create.exitCode}`;\n\t\t\tprint(` ✗ FAILED: ${message}`);\n\t\t\tresults.push({ name, status: \"fail\", message });\n\t\t}\n\t}\n\n\tconst failed = results.filter((r) => r.status === \"fail\");\n\tlogger.info({ ok: results.filter((r) => r.status === \"ok\").length, failed: failed.length }, \"sync-trust: done\");\n\treturn {\n\t\tstatus: failed.length > 0 ? \"fail\" : \"ok\",\n\t\t...(failed.length > 0 ? { message: `${failed.length} package(s) failed` } : {}),\n\t\tpackages: results,\n\t};\n}\n\nfunction parseJson(raw: string): unknown {\n\ttry {\n\t\treturn JSON.parse(raw) as unknown;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction isEotp(parsed: unknown): boolean {\n\treturn (\n\t\ttypeof parsed === \"object\" &&\n\t\tparsed !== null &&\n\t\t\"error\" in parsed &&\n\t\t(parsed as NpmTrustError).error?.code === \"EOTP\"\n\t);\n}\n\nexport async function runPublish(input: RunPublishInput = {}): Promise<PublishReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst cwd = input.cwd ?? process.cwd();\n\tconst tag = input.tag ?? \"alpha\";\n\tconst dryRun = input.dryRun ?? false;\n\tconst otp = input.otp;\n\tconst env = makeEnv(input.env);\n\tconst exec = input.exec ?? defaultExec;\n\tconst login = input.login ?? defaultLogin;\n\n\t// Two repo layouts: a monorepo (`packages/*`, this repo's own shape) and a\n\t// single package at the root (most `node-template` scaffolds — no\n\t// `packages/` dir). `pnpm -r --filter=./packages/*` silently matches zero\n\t// workspaces in the latter and exits 0 — build the right invocation for\n\t// whichever layout is on disk. Shared between dry-run preview and the\n\t// real call so what we print is exactly what we'd run.\n\tconst isMonorepo = hasPackagesDir(cwd);\n\tconst publishArgs = [\n\t\t...(isMonorepo ? [\"-r\", \"--filter=./packages/*\"] : []),\n\t\t\"publish\",\n\t\t\"--access\",\n\t\t\"public\",\n\t\t\"--no-git-checks\",\n\t\t\"--tag\",\n\t\ttag,\n\t\t...(otp ? [\"--otp\", otp] : []),\n\t];\n\n\tprint(`Holocron publish --initial${dryRun ? \" (dry-run)\" : \"\"}`);\n\tprint(` cwd: ${cwd}`);\n\tprint(` tag: ${tag}`);\n\tlogger.info({ tag, dryRun: dryRun || undefined }, \"publish --initial: start\");\n\tif (otp) print(` otp: <${otp.length} chars>`);\n\tprint(\"\");\n\n\t// ── 1. Verify npm auth — log in automatically if not ────────────────\n\tprint(\" → verifying npm auth (`npm whoami`)…\");\n\tlet whoami = await exec(\"npm\", [\"whoami\"], { cwd });\n\tif (whoami.exitCode !== 0) {\n\t\tprint(\" not authenticated — running `npm login --auth-type=web`…\");\n\t\tlogger.info({}, \"publish --initial: npm login\");\n\t\tconst loginResult = await login(cwd);\n\t\tif (loginResult.exitCode !== 0) {\n\t\t\tconst message = \"npm login failed. Run `npm login --auth-type=web` (or `npm login`) manually, then re-run.\";\n\t\t\tprint(` ✗ ${message}`);\n\t\t\tconst packageNames = input.packages ?? discoverPublicPackages(cwd);\n\t\t\tlogger.warn({ reason: \"npm login failed\" }, \"publish --initial: done\");\n\t\t\treturn { status: \"fail\", message, packageNames };\n\t\t}\n\t\twhoami = await exec(\"npm\", [\"whoami\"], { cwd });\n\t\tif (whoami.exitCode !== 0) {\n\t\t\tconst message = \"npm login completed but `npm whoami` still fails — check your npm account.\";\n\t\t\tprint(` ✗ ${message}`);\n\t\t\tconst packageNames = input.packages ?? discoverPublicPackages(cwd);\n\t\t\tlogger.warn({ reason: \"npm whoami still fails after login\" }, \"publish --initial: done\");\n\t\t\treturn { status: \"fail\", message, packageNames };\n\t\t}\n\t}\n\tconst whoamiName = whoami.stdout.trim() || \"<unknown>\";\n\tprint(` ✓ authed as ${whoamiName}`);\n\n\t// ── 2. Resolve dynamic values needed for next-steps ─────────────────\n\tconst packageNames = input.packages ?? discoverPublicPackages(cwd);\n\tconst repoName = input.repoName ?? (await resolveRepoName(cwd, exec));\n\n\t// A `pnpm --filter=./packages/*` (or a bare `pnpm publish`) that matches\n\t// nothing still exits 0 — catch the no-op before it's mistaken for\n\t// success. Applies to dry-run too: the point is to diagnose the\n\t// misconfiguration, not just the real publish.\n\tif (packageNames.length === 0) {\n\t\tconst message = \"nothing to publish (no packages/* and root package.json is private or unnamed)\";\n\t\tprint(` ✗ ${message}`);\n\t\tlogger.warn({ reason: message }, \"publish --initial: done\");\n\t\treturn { status: \"fail\", message, packageNames };\n\t}\n\n\t// ── 3. Publish ──────────────────────────────────────────────────────\n\tif (dryRun) {\n\t\tprint(\"\");\n\t\tprint(\" … (dry-run) skipping actual publish\");\n\t\tprint(` would run: pnpm ${publishArgs.join(\" \")}`);\n\t\tprintNextSteps(print, env, packageNames, repoName);\n\t\tlogger.info({ tag, status: \"dry-run\", packages: packageNames.length }, \"publish --initial: done\");\n\t\treturn { status: \"dry-run\", message: \"dry-run — no publish executed\", packageNames };\n\t}\n\n\tprint(\"\");\n\tprint(\" → publishing all public @theholocron/* packages…\");\n\tconst publish = await exec(\"pnpm\", publishArgs, { cwd });\n\tif (publish.exitCode !== 0) {\n\t\tconst message = `publish failed (exit ${publish.exitCode}): ${publish.stderr.trim() || publish.stdout.trim() || \"no output\"}`;\n\t\tprint(` ✗ ${message}`);\n\t\t// Detect EOTP and surface the --otp hint right at the failure.\n\t\tif (publish.stdout.includes(\"EOTP\") || publish.stderr.includes(\"EOTP\")) {\n\t\t\tprint(\"\");\n\t\t\tprint(\" → hint: your npm account requires 2FA for writes. Re-run with `--otp <code>`:\");\n\t\t\tprint(` pnpm exec tsx packages/cli/src/cli.ts publish --initial --otp <6-digit-code>`);\n\t\t}\n\t\tlogger.warn({ tag, reason: message }, \"publish --initial: done\");\n\t\treturn { status: \"fail\", message, packageNames };\n\t}\n\tprint(\" ✓ publish complete\");\n\n\t// ── 4. Next-step reminders ──────────────────────────────────────────\n\tprintNextSteps(print, env, packageNames, repoName);\n\tlogger.info({ tag, status: \"ok\", packages: packageNames.length }, \"publish --initial: done\");\n\treturn { status: \"ok\", packageNames };\n}\n\nexport interface RunSteadyPublishInput {\n\t/** Working directory (the monorepo or package root). Defaults to process.cwd(). */\n\tcwd?: string;\n\t/** Distribution tag for the publish. Defaults to `'latest'` (steady-state releases are stable by default; `--initial`'s bootstrap default is `'alpha'`). */\n\ttag?: string;\n\t/** Skip the actual publish; print what would happen. */\n\tdryRun?: boolean;\n\totp?: string;\n\tprint?: PublishPrint;\n\tlogger?: Logger;\n\texec?: (cmd: string, args: string[], opts: { cwd: string }) => Promise<PublishExecResult>;\n\tenv?: NodeJS.ProcessEnv;\n\t/** Override the list of package names/versions. Auto-discovered when omitted. */\n\tpackages?: readonly PublicPackageEntry[];\n\t/** Add `--provenance`. Defaults to `true` — every steady-state publish runs in CI under OIDC, where provenance is free and expected. */\n\tprovenance?: boolean;\n\t/**\n\t * Check `npm view <pkg>@<version>` before publishing each package and\n\t * skip it if that exact version already exists, instead of one bulk\n\t * `pnpm -r publish`. For repos that ship many independently-versioned\n\t * packages where a release doesn't bump every one of them (this repo's\n\t * own lockstep-bump model doesn't need it — every package always gets a\n\t * new version together). Defaults to `false`.\n\t */\n\tskipAlreadyPublished?: boolean;\n}\n\n/**\n * `holocron publish` (no `--initial`) — the steady-state publish\n * `exec.publishCmd` in `release.config.ts` should call, replacing each\n * repo's hand-typed `pnpm -r --filter=./packages/* publish ...` shell (which\n * differs, today, only in monorepo-vs-single-package, provenance on/off, and\n * whether a repo needs to skip already-published packages) with one uniform\n * invocation. Part of the config-resolution workstream, #676 — see\n * `.notes/tech-config-resolution.spec.md`.\n *\n * Deliberately does not do the `--initial` bootstrap dance (npm\n * login-if-needed, Trusted Publisher next-steps printout) — a steady-state\n * publish runs in CI, authenticated via OIDC automatically, no interactive\n * step involved. Reuses `hasPackagesDir()`'s monorepo-vs-single-package\n * detection rather than duplicating it.\n */\nexport async function runSteadyPublish(input: RunSteadyPublishInput = {}): Promise<PublishReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst cwd = input.cwd ?? process.cwd();\n\tconst tag = input.tag ?? \"latest\";\n\tconst dryRun = input.dryRun ?? false;\n\tconst otp = input.otp;\n\tconst exec = input.exec ?? defaultExec;\n\tconst provenance = input.provenance ?? true;\n\tconst skipAlreadyPublished = input.skipAlreadyPublished ?? false;\n\tconst entries = input.packages ?? discoverPublicPackageEntries(cwd);\n\tconst packageNames = entries.map((e) => e.name);\n\n\tprint(`Holocron publish${dryRun ? \" (dry-run)\" : \"\"}`);\n\tprint(` cwd: ${cwd}`);\n\tprint(` tag: ${tag}`);\n\tprint(` provenance: ${provenance}`);\n\tif (skipAlreadyPublished) print(\" skip-already-published: true\");\n\tlogger.info({ tag, provenance, skipAlreadyPublished, dryRun: dryRun || undefined }, \"publish: start\");\n\tif (otp) print(` otp: <${otp.length} chars>`);\n\tprint(\"\");\n\n\tif (entries.length === 0) {\n\t\tconst message = \"nothing to publish (no packages/* and root package.json is private or unnamed)\";\n\t\tprint(` ✗ ${message}`);\n\t\tlogger.warn({ reason: message }, \"publish: done\");\n\t\treturn { status: \"fail\", message, packageNames };\n\t}\n\n\tconst baseFlags = [\"--access\", \"public\", \"--no-git-checks\", \"--tag\", tag, ...(provenance ? [\"--provenance\"] : [])];\n\tconst otpFlags = otp ? [\"--otp\", otp] : [];\n\n\tif (dryRun) {\n\t\tprint(\"\");\n\t\tif (skipAlreadyPublished) {\n\t\t\tfor (const entry of entries) {\n\t\t\t\tprint(` … would check ${entry.name}@${entry.version}, publish if not already on npm`);\n\t\t\t}\n\t\t} else {\n\t\t\tconst isMonorepo = hasPackagesDir(cwd);\n\t\t\tconst args = [...(isMonorepo ? [\"-r\", \"--filter=./packages/*\"] : []), \"publish\", ...baseFlags, ...otpFlags];\n\t\t\tprint(` … (dry-run) skipping actual publish`);\n\t\t\tprint(` would run: pnpm ${args.join(\" \")}`);\n\t\t}\n\t\tlogger.info({ tag, status: \"dry-run\", packages: entries.length }, \"publish: done\");\n\t\treturn { status: \"dry-run\", message: \"dry-run — no publish executed\", packageNames };\n\t}\n\n\tif (skipAlreadyPublished) {\n\t\tprint(\" → publishing packages not already on npm…\");\n\t\tfor (const entry of entries) {\n\t\t\tconst view = await exec(\"npm\", [\"view\", `${entry.name}@${entry.version}`, \"version\"], { cwd });\n\t\t\tif (view.exitCode === 0 && view.stdout.trim()) {\n\t\t\t\tprint(` skip ${entry.name}@${entry.version} (already published)`);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst publish = await exec(\"pnpm\", [\"--filter\", entry.dir, \"publish\", ...baseFlags, ...otpFlags], { cwd });\n\t\t\tif (publish.exitCode !== 0) {\n\t\t\t\tconst message = `publish failed for ${entry.name}@${entry.version} (exit ${publish.exitCode}): ${publish.stderr.trim() || publish.stdout.trim() || \"no output\"}`;\n\t\t\t\tprint(` ✗ ${message}`);\n\t\t\t\tlogger.warn({ tag, package: entry.name, reason: message }, \"publish: done\");\n\t\t\t\treturn { status: \"fail\", message, packageNames };\n\t\t\t}\n\t\t\tprint(` ✓ ${entry.name}@${entry.version}`);\n\t\t}\n\t\tlogger.info({ tag, status: \"ok\", packages: entries.length }, \"publish: done\");\n\t\treturn { status: \"ok\", packageNames };\n\t}\n\n\tprint(\" → publishing all public @theholocron/* packages…\");\n\tconst isMonorepo = hasPackagesDir(cwd);\n\tconst args = [...(isMonorepo ? [\"-r\", \"--filter=./packages/*\"] : []), \"publish\", ...baseFlags, ...otpFlags];\n\tconst publish = await exec(\"pnpm\", args, { cwd });\n\tif (publish.exitCode !== 0) {\n\t\tconst message = `publish failed (exit ${publish.exitCode}): ${publish.stderr.trim() || publish.stdout.trim() || \"no output\"}`;\n\t\tprint(` ✗ ${message}`);\n\t\tif (publish.stdout.includes(\"EOTP\") || publish.stderr.includes(\"EOTP\")) {\n\t\t\tprint(\"\");\n\t\t\tprint(\" → hint: your npm account requires 2FA for writes. Re-run with `--otp <code>`:\");\n\t\t\tprint(` pnpm exec holocron publish --otp <6-digit-code>`);\n\t\t}\n\t\tlogger.warn({ tag, reason: message }, \"publish: done\");\n\t\treturn { status: \"fail\", message, packageNames };\n\t}\n\tprint(\" ✓ publish complete\");\n\tlogger.info({ tag, status: \"ok\", packages: entries.length }, \"publish: done\");\n\treturn { status: \"ok\", packageNames };\n}\n\n// ── helpers ──────────────────────────────────────────────────────────\n\nfunction hasPackagesDir(cwd: string): boolean {\n\treturn existsSync(join(cwd, \"packages\"));\n}\n\n/** Read a `package.json`'s `name`, when it's public (`!private && name`). */\nfunction publicPackageName(pkgPath: string): string | undefined {\n\tif (!existsSync(pkgPath)) return undefined;\n\ttry {\n\t\tconst pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\")) as { name?: string; private?: boolean };\n\t\treturn !pkg.private && pkg.name ? pkg.name : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport interface PublicPackageEntry {\n\tname: string;\n\tversion: string;\n\t/** `pnpm --filter` target: `.` for a single-package repo, `./packages/<dir>` for a monorepo workspace. */\n\tdir: string;\n}\n\n/** Read a `package.json`'s `name` + `version`, when it's public (`!private && name`). */\nfunction publicPackageEntry(pkgPath: string, dir: string): PublicPackageEntry | undefined {\n\tif (!existsSync(pkgPath)) return undefined;\n\ttry {\n\t\tconst pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\")) as {\n\t\t\tname?: string;\n\t\t\tversion?: string;\n\t\t\tprivate?: boolean;\n\t\t};\n\t\treturn !pkg.private && pkg.name && pkg.version ? { name: pkg.name, version: pkg.version, dir } : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Same repo-layout detection as {@link discoverPublicPackages}, but carrying\n * version + a `pnpm --filter`-ready path — {@link runSteadyPublish}'s\n * `skipAlreadyPublished` mode needs both to check `npm view <pkg>@<version>`\n * and publish one workspace at a time.\n */\nfunction discoverPublicPackageEntries(cwd: string): readonly PublicPackageEntry[] {\n\tif (!hasPackagesDir(cwd)) {\n\t\tconst entry = publicPackageEntry(join(cwd, \"package.json\"), \".\");\n\t\treturn entry ? [entry] : [];\n\t}\n\tconst packagesDir = join(cwd, \"packages\");\n\treturn readdirSync(packagesDir, { withFileTypes: true })\n\t\t.filter((e) => e.isDirectory())\n\t\t.flatMap((e) => {\n\t\t\tconst entry = publicPackageEntry(join(packagesDir, e.name, \"package.json\"), `./packages/${e.name}`);\n\t\t\treturn entry ? [entry] : [];\n\t\t});\n}\n\n/**\n * Monorepo (`packages/` present): every public `packages/*` workspace.\n * Single package (no `packages/`): the root `package.json`, if it's public —\n * most `node-template` scaffolds are one package at the repo root.\n */\nfunction discoverPublicPackages(cwd: string): readonly string[] {\n\tif (!hasPackagesDir(cwd)) {\n\t\tconst name = publicPackageName(join(cwd, \"package.json\"));\n\t\treturn name ? [name] : [];\n\t}\n\tconst packagesDir = join(cwd, \"packages\");\n\treturn readdirSync(packagesDir, { withFileTypes: true })\n\t\t.filter((e) => e.isDirectory())\n\t\t.flatMap((e) => {\n\t\t\tconst name = publicPackageName(join(packagesDir, e.name, \"package.json\"));\n\t\t\treturn name ? [name] : [];\n\t\t});\n}\n\nasync function resolveRepoName(cwd: string, exec: NonNullable<RunPublishInput[\"exec\"]>): Promise<string> {\n\tconst result = await exec(\"git\", [\"remote\", \"get-url\", \"origin\"], { cwd });\n\tif (result.exitCode !== 0) return \"unknown\";\n\t// Matches both HTTPS (https://github.com/org/repo.git) and\n\t// SSH (git@github.com:org/repo.git) remote URL formats.\n\tconst match = /[/:]([^/:]+?)(?:\\.git)?$/.exec(result.stdout.trim());\n\treturn match?.[1] ?? \"unknown\";\n}\n\nfunction printNextSteps(print: PublishPrint, env: CliEnv, packageNames: readonly string[], repoName: string): void {\n\tprint(\"\");\n\tprint(\" → next: configure Trusted Publisher for each package on npm:\");\n\tfor (const name of packageNames) {\n\t\tprint(` https://www.npmjs.com/package/${name}/access`);\n\t}\n\tprint(` Publisher: GitHub Actions Org: theholocron Repo: ${repoName} Workflow: delivery.publish.yml`);\n\n\tif (env.get(\"NPM_TOKEN\")) {\n\t\tprint(\"\");\n\t\tprint(\" → cleanup: $NPM_TOKEN was used. Revoke it now (no API for self-revoke; UI-only):\");\n\t\tprint(\" https://www.npmjs.com/settings/~/tokens\");\n\t}\n}\n\nconst defaultExec: NonNullable<RunPublishInput[\"exec\"]> = async (cmd, args, opts) => {\n\tconst result = spawnSync(cmd, args, {\n\t\tcwd: opts.cwd,\n\t\tencoding: \"utf8\",\n\t\tstdio: [\"inherit\", \"pipe\", \"pipe\"],\n\t});\n\treturn {\n\t\texitCode: result.status ?? -1,\n\t\tstdout: result.stdout ?? \"\",\n\t\tstderr: result.stderr ?? \"\",\n\t};\n};\n\n/**\n * Fully interactive — `npm login --auth-type=web` prints a URL and waits for\n * the browser flow to complete; the operator needs to see that live, so all\n * three stdio streams are inherited (unlike `defaultExec`, which pipes\n * stdout/stderr for capture).\n */\nconst defaultLogin: NonNullable<RunPublishInput[\"login\"]> = async (cwd) => {\n\tconst result = spawnSync(\"npm\", [\"login\", \"--auth-type=web\"], { cwd, stdio: \"inherit\" });\n\treturn { exitCode: result.status ?? -1 };\n};\n","/**\n * `holocron secret set` — one-shot single-secret push.\n *\n * Complements `holocron secrets sync` (bulk vault → destinations) for\n * ad-hoc scenarios:\n * - Bootstrap secrets (e.g., NPM_TOKEN on theholocron/holocron itself\n * before the rest of the setup exists)\n * - One-off rotations that don't warrant a vault sync\n * - Setting secrets the vault doesn't track\n *\n * Value source resolution (in priority order):\n * 1. Positional `value` argument\n * 2. `--from-stdin` reads from stdin\n * 3. `--from-env <NAME>` reads from the named env var\n * 4. Implicit: env var matching the secret name (e.g., `NPM_TOKEN`)\n *\n * Errors clearly when no value can be sourced.\n */\n\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport type { LoadedConfig } from \"../config/load-config.js\";\nimport { env } from \"../env.js\";\nimport { getLogger } from \"../logger.js\";\nimport type { Secrets, SecretScope } from \"../plugin/capabilities.js\";\nimport { PluginLoader, type RuntimeContext } from \"../plugin/loader.js\";\nimport { assertPluginsResolvable } from \"../plugin/workspace.js\";\n\nexport type SecretSetPrint = (line: string) => void;\n\nexport interface RunSecretSetInput {\n\tloaded: LoadedConfig;\n\tcontext: RuntimeContext;\n\t/** Secret name (e.g., `NPM_TOKEN`). */\n\tname: string;\n\t/** Secret value. If absent, resolves via stdin / env. */\n\tvalue?: string;\n\t/** Read from stdin instead of positional or env var. */\n\tfromStdin?: boolean;\n\t/** Read from a specific env var rather than implicit-by-name. */\n\tfromEnv?: string;\n\t/** Defaults to `{ kind: 'repo' }`. */\n\tscope?: SecretScope;\n\tloader?: PluginLoader;\n\tprint?: SecretSetPrint;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n\t/** Lets tests inject a stdin reader. Defaults to reading process.stdin. */\n\treadStdin?: () => Promise<string>;\n}\n\nexport interface SecretSetReport {\n\tstatus: \"ok\" | \"fail\" | \"dry-run\";\n\tname: string;\n\tscope: SecretScope;\n\tmessage?: string;\n}\n\nexport async function runSecretSet(input: RunSecretSetInput): Promise<SecretSetReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst loader = input.loader ?? new PluginLoader(input.loaded.resolved, input.context);\n\tawait loader.load();\n\tassertPluginsResolvable(loader, \"secret set\");\n\n\tconst dryRun = input.context.dryRun ?? false;\n\tconst scope: SecretScope = input.scope ?? { kind: \"repo\" };\n\n\tif (!loader.has(\"secrets\")) {\n\t\tthrow new Error(\"`secrets` capability is not configured — add a `secrets` provider to holocron.config.json\");\n\t}\n\n\t// Resolve the value to push, surfacing a clear error when none can be sourced.\n\tconst value = await resolveValue(input);\n\tif (!value) {\n\t\tthrow new Error(\n\t\t\t`no value for secret \\`${input.name}\\` — pass it positionally, via --from-stdin, --from-env <NAME>, or set $${input.name} in the environment`\n\t\t);\n\t}\n\n\tprint(`Holocron secret set — ${input.name} (${describeScope(scope)})${dryRun ? \" (dry-run)\" : \"\"}`);\n\n\tif (dryRun) {\n\t\tconst message = `would: secrets.setSecret(${describeScope(scope)}, ${input.name}, <${value.length} chars>)`;\n\t\tprint(` … ${message}`);\n\t\treturn { status: \"dry-run\", name: input.name, scope, message };\n\t}\n\n\ttry {\n\t\tconst secrets = loader.get(\"secrets\") as Secrets;\n\t\tawait secrets.setSecret(scope, input.name, value);\n\t\tprint(` ✓ set ${input.name} via ${secrets.providerName}`);\n\t\t// `name` is a secret NAME, never the value.\n\t\tlogger.info(\n\t\t\t{ key: input.name, scope: describeScope(scope), provider: secrets.providerName, status: \"ok\" },\n\t\t\t`secret set: ${input.name}`\n\t\t);\n\t\treturn { status: \"ok\", name: input.name, scope };\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tprint(` ✗ ${message}`);\n\t\tlogger.warn({ key: input.name, scope: describeScope(scope), reason: message }, `secret set: ${input.name}`);\n\t\treturn { status: \"fail\", name: input.name, scope, message };\n\t}\n}\n\n// ── helpers ──────────────────────────────────────────────────────────\n\nasync function resolveValue(input: RunSecretSetInput): Promise<string | undefined> {\n\tif (input.value) return input.value;\n\tif (input.fromStdin) {\n\t\tconst reader = input.readStdin ?? defaultReadStdin;\n\t\tconst text = await reader();\n\t\treturn text.replace(/\\r?\\n$/, \"\"); // trim trailing newline\n\t}\n\tif (input.fromEnv) {\n\t\treturn env.get(input.fromEnv);\n\t}\n\t// Implicit: env var with the same name as the secret.\n\treturn env.get(input.name);\n}\n\nasync function defaultReadStdin(): Promise<string> {\n\tconst chunks: Buffer[] = [];\n\treturn new Promise<string>((resolve, reject) => {\n\t\tprocess.stdin.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n\t\tprocess.stdin.on(\"end\", () => resolve(Buffer.concat(chunks).toString(\"utf8\")));\n\t\tprocess.stdin.on(\"error\", reject);\n\t});\n}\n\nfunction describeScope(scope: SecretScope): string {\n\tif (scope.kind === \"repo\") return \"scope=repo\";\n\tif (scope.kind === \"environment\") return `scope=environment:${scope.name}`;\n\treturn `scope=organization:${scope.name}`;\n}\n","/**\n * `holocron secrets sync` — vault → destinations.\n *\n * Reads a named environment from the configured `vault` (1P\n * Environment / similar) as KEY=VALUE pairs, then fans those values\n * out to the configured destinations:\n *\n * - `secrets` capability (e.g., GH Actions secrets) — repo-scope\n * - `deployment` capability (e.g., Vercel env vars) — per-target\n * - local `.env` file (optional, planned for v5.1 — currently skipped\n * with a soft \"not yet\" note)\n *\n * Per-secret routing rules:\n *\n * - All keys go to `deployment` for each target the caller asks for\n * (defaults: production + preview)\n * - `secrets` (GH Actions) defaults to every key, repo-scoped — but a\n * caller can pass `githubSecretKeys` (an allowlist, from repeatable\n * `--github-secret KEY` CLI values) to restrict `secrets` to only\n * those keys, and `githubSecretScope` (same `{ kind }` shape `secret\n * set`'s own `--scope repo|env=NAME|org=NAME` parses to) to apply one\n * scope to all of them. A key not in the allowlist is skipped for\n * `secrets` entirely — still synced to `deployment` if configured.\n * Needed for a vault holding a mix of deploy-only secrets and one\n * CI-consumed, org-wide secret (holocron#781's Sentinel case: 4\n * Vercel-only keys + one org-scoped Axiom ingest token\n * `theholocron/.github`'s dispatched-check workflow also reads).\n *\n * The vault MUST implement `readEnvironment(envId)` (optional method).\n * If it doesn't, the command errors with a hint to populate the keys\n * individually via `holocron secret set` (also planned for v5.1).\n */\n\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport type { LoadedConfig } from \"../config/load-config.js\";\nimport { getLogger } from \"../logger.js\";\nimport type { Deployment, DeploymentTarget, Secrets, SecretScope, Vault } from \"../plugin/capabilities.js\";\nimport { PluginLoader, type RuntimeContext } from \"../plugin/loader.js\";\nimport { assertPluginsResolvable } from \"../plugin/workspace.js\";\nimport { withSpinner } from \"../ui/progress.js\";\nimport { style } from \"../ui/style.js\";\n\nexport type SyncPrintLine = (line: string) => void;\n\nexport type SyncRowStatus = \"ok\" | \"fail\" | \"dry-run\" | \"skip\";\n\nexport interface SyncRow {\n\tdestination: string;\n\t/** e.g., `target=production` for deployment, `scope=repo` for secrets. */\n\tscope: string;\n\tkey: string;\n\tstatus: SyncRowStatus;\n\tmessage?: string;\n}\n\nexport interface SyncReport {\n\trows: SyncRow[];\n\tsummary: { ok: number; fail: number; skip: number; dryRun: number };\n}\n\nexport interface RunSecretsSyncInput {\n\tloaded: LoadedConfig;\n\tcontext: RuntimeContext;\n\t/** Vault environment id to read. */\n\tenvironmentId: string;\n\t/** Deployment targets to sync to. Defaults to ['production', 'preview']. */\n\ttargets?: DeploymentTarget[];\n\t/** Vercel project id (or equivalent). Required if `deployment` is loaded. */\n\tprojectId?: string;\n\t/**\n\t * Allowlist restricting which vault keys reach `secrets`. Omit to push\n\t * every key (the default). See this module's own docstring.\n\t */\n\tgithubSecretKeys?: string[];\n\t/** Scope applied to every `githubSecretKeys` entry. Omit for `{ kind: \"repo\" }` (the default). */\n\tgithubSecretScope?: SecretScope;\n\tloader?: PluginLoader;\n\tprint?: SyncPrintLine;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n}\n\nexport async function runSecretsSync(input: RunSecretsSyncInput): Promise<SyncReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst loader = input.loader ?? new PluginLoader(input.loaded.resolved, input.context);\n\tawait withSpinner(\"Loading plugins…\", () => loader.load());\n\tassertPluginsResolvable(loader, \"secrets sync\");\n\n\tlogger.info(\n\t\t{ environment: input.environmentId, dryRun: (input.context.dryRun ?? false) || undefined },\n\t\t\"secrets sync: start\"\n\t);\n\n\tconst dryRun = input.context.dryRun ?? false;\n\tconst targets = input.targets ?? ([\"production\", \"preview\"] as DeploymentTarget[]);\n\n\tprint(style.header(`Holocron secrets sync — environment ${input.environmentId}${dryRun ? \" (dry-run)\" : \"\"}`));\n\tprint(style.dim(` vault: ${vaultProviderName(loader)}`));\n\tprint(\"\");\n\n\t// ── Read the vault ─────────────────────────────────────────────────\n\tconst vault = loader.get(\"vault\") as Vault;\n\tif (!vault.readEnvironment) {\n\t\tthrow new Error(\n\t\t\t`vault provider (${vault.providerName}) does not implement readEnvironment — sync needs bulk env reads`\n\t\t);\n\t}\n\tconst envVars = await withSpinner(`Reading vault environment ${input.environmentId}…`, () =>\n\t\tvault.readEnvironment!(input.environmentId)\n\t);\n\tconst keys = Object.keys(envVars).sort();\n\tprint(style.step(`read ${keys.length} keys from vault`));\n\tprint(\"\");\n\n\tconst rows: SyncRow[] = [];\n\n\t// ── Push to `secrets` (CI/Actions secrets) ─────────────────────────\n\tif (loader.has(\"secrets\")) {\n\t\tconst secrets = loader.get(\"secrets\") as Secrets;\n\t\tconst scope = input.githubSecretScope ?? { kind: \"repo\" };\n\t\tconst allowedKeys = input.githubSecretKeys ? new Set(input.githubSecretKeys) : undefined;\n\t\tprint(style.step(\"secrets\"));\n\t\tfor (const key of keys) {\n\t\t\t// No allowlist → every key (original default). With one → only\n\t\t\t// listed keys; an unlisted key is skipped for `secrets` entirely\n\t\t\t// (still reaches `deployment` above, if configured).\n\t\t\tif (allowedKeys && !allowedKeys.has(key)) continue;\n\n\t\t\trows.push(\n\t\t\t\tawait runRow(`secrets:${secrets.providerName}`, scopeLabel(scope), key, dryRun, async () => {\n\t\t\t\t\tawait secrets.setSecret(scope, key, envVars[key]!);\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatRow(rows[rows.length - 1]!));\n\t\t}\n\t}\n\n\t// ── Push to `deployment` (Vercel env vars) ─────────────────────────\n\tif (loader.has(\"deployment\")) {\n\t\tconst deploy = loader.get(\"deployment\") as Deployment;\n\t\tif (!input.projectId) {\n\t\t\tprint(style.step(\"deployment\"));\n\t\t\tconst row: SyncRow = {\n\t\t\t\tdestination: `deployment:${deploy.providerName}`,\n\t\t\t\tscope: \"no projectId\",\n\t\t\t\tkey: \"(all)\",\n\t\t\t\tstatus: \"skip\",\n\t\t\t\tmessage: \"projectId required for deployment env-var sync (pass --project-id)\",\n\t\t\t};\n\t\t\trows.push(row);\n\t\t\tprint(formatRow(row));\n\t\t} else {\n\t\t\tfor (const target of targets) {\n\t\t\t\tprint(style.step(`deployment (target=${target})`));\n\t\t\t\tfor (const key of keys) {\n\t\t\t\t\trows.push(\n\t\t\t\t\t\tawait runRow(`deployment:${deploy.providerName}`, `target=${target}`, key, dryRun, async () => {\n\t\t\t\t\t\t\tawait deploy.setEnvVar(input.projectId!, target, key, envVars[key]!);\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t\tprint(formatRow(rows[rows.length - 1]!));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (const r of rows) {\n\t\t// `key` is a secret NAME, never a value — safe to log. The logger also\n\t\t// redacts `secrets[*].value` shapes as defence in depth.\n\t\tlogger[r.status === \"fail\" ? \"warn\" : \"info\"](\n\t\t\t{\n\t\t\t\tdestination: r.destination,\n\t\t\t\tscope: r.scope,\n\t\t\t\tkey: r.key,\n\t\t\t\tstatus: r.status,\n\t\t\t\t...(r.message ? { detail: r.message } : {}),\n\t\t\t},\n\t\t\t`secrets sync: ${r.key} → ${r.destination}`\n\t\t);\n\t}\n\n\tconst summary = rows.reduce(\n\t\t(acc, r) => {\n\t\t\tif (r.status === \"ok\") acc.ok += 1;\n\t\t\telse if (r.status === \"fail\") acc.fail += 1;\n\t\t\telse if (r.status === \"skip\") acc.skip += 1;\n\t\t\telse if (r.status === \"dry-run\") acc.dryRun += 1;\n\t\t\treturn acc;\n\t\t},\n\t\t{ ok: 0, fail: 0, skip: 0, dryRun: 0 }\n\t);\n\n\tlogger[summary.fail > 0 ? \"warn\" : \"info\"]({ ...summary, keys: rows.length }, \"secrets sync: done\");\n\n\tprint(\"\");\n\tconst summaryLine = `${summary.ok} ok, ${summary.fail} fail, ${summary.skip} skipped${\n\t\tdryRun ? `, ${summary.dryRun} would-do` : \"\"\n\t}`;\n\tprint(summary.fail > 0 ? style.fail(summaryLine) : style.success(summaryLine));\n\n\treturn { rows, summary };\n}\n\n// ── helpers ──────────────────────────────────────────────────────────\n\nasync function runRow(\n\tdestination: string,\n\tscope: string,\n\tkey: string,\n\tdryRun: boolean,\n\tbody: () => Promise<void>\n): Promise<SyncRow> {\n\tif (dryRun) {\n\t\treturn { destination, scope, key, status: \"dry-run\" };\n\t}\n\ttry {\n\t\tawait body();\n\t\treturn { destination, scope, key, status: \"ok\" };\n\t} catch (err) {\n\t\treturn {\n\t\t\tdestination,\n\t\t\tscope,\n\t\t\tkey,\n\t\t\tstatus: \"fail\",\n\t\t\tmessage: err instanceof Error ? err.message : String(err),\n\t\t};\n\t}\n}\n\nfunction formatRow(row: SyncRow): string {\n\tconst detail = row.message ? style.dim(` (${row.message})`) : \"\";\n\tconst label = `${row.key}${detail}`;\n\tif (row.status === \"ok\") return ` ${style.success(label)}`;\n\tif (row.status === \"fail\") return ` ${style.fail(label)}`;\n\tif (row.status === \"dry-run\") return ` ${style.dim(`… ${label}`)}`;\n\treturn ` ${style.dim(`· ${label}`)}`;\n}\n\nfunction scopeLabel(scope: SecretScope): string {\n\tif (scope.kind === \"repo\") return \"scope=repo\";\n\tif (scope.kind === \"organization\") return `scope=organization,org=${scope.name}`;\n\treturn `scope=environment,env=${scope.name}`;\n}\n\nfunction vaultProviderName(loader: PluginLoader): string {\n\tif (!loader.has(\"vault\")) return \"<missing>\";\n\treturn (loader.get(\"vault\") as Vault).providerName;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport type { WorkspacePackage } from \"@theholocron/astromech\";\n\nimport type { ResolvedProvidersConfig } from \"../../config/config.js\";\n\n/**\n * Derived custom-properties (#677). Unlike the existing 6 GitHub\n * custom-properties fields (`lifecycle`, `open_source`, `runtime_environment`,\n * `uses_external_packages`, `monorepo`, `branch_protection_level`) — which\n * mirror what `holocron.config.ts` already states explicitly — these four are\n * *derived*: signal that isn't an explicit config field today (framework\n * choice, repo archetype, capability drift). See\n * `.notes/tech-holocron-platform.spec.md` → \"Custom-properties sync — field\n * definitions (#677)\" for the full design.\n */\n\n// \"plugin\" isn't produced by any heuristic below yet — no repo in the org\n// today is a standalone single-purpose plugin at the *repo* level (plugin\n// packages live inside `holocron`'s own `packages/holocron-plugin-*`, which\n// makes `holocron` itself \"platform\", not \"plugin\"). Kept in the union for a\n// future cross-org (`rando`, D10) repo that's nothing but one plugin.\nexport type HolocronProfile = \"library\" | \"cli\" | \"plugin\" | \"template\" | \"app\" | \"docs\" | \"platform\";\n\nexport interface PackageJsonLike {\n\tname?: string;\n\tprivate?: boolean;\n\tbin?: unknown;\n\tdependencies?: Record<string, string>;\n\tdevDependencies?: Record<string, string>;\n}\n\nexport interface DeriveProfileInput {\n\trootPackageJson: PackageJsonLike | null;\n\trepoName: string;\n\tisMonorepo: boolean;\n\t/** `packages/*` package.json contents, monorepo repos only — used to find the primary published artifact. */\n\tworkspacePackageJsons: PackageJsonLike[];\n}\n\n/**\n * Repo archetype, in priority order:\n * 1. `*-template` repo name → `template` (independent of package shape).\n * 2. Monorepo whose primary published artifact is a CLI (some workspace\n * package has `bin`) → `platform` — matches `holocron` itself: the CLI is\n * the deliverable, the plugin packages are supporting infrastructure for\n * it, not separate products.\n * 3. Monorepo with no CLI but at least one non-private workspace package →\n * `library` — matches `clients`/`configs`/`utils`/`themes`/\n * `observability`: a family of published packages, none of them a CLI.\n * Checked *before* falling into the root-package branch below, because\n * these repos' own root `package.json` is private and often carries\n * `@theholocron/astro-config` for a docs site built from the monorepo\n * root — without this check they'd wrongly resolve to `docs` off that\n * root-level signal alone, when the docs site is a secondary concern of\n * a library collection, not what the repo fundamentally is.\n * 4. Single-package repo with `package.json#bin` → `cli`.\n * 5. Docs-only site (astro/starlight present, root package private, no\n * publishable exports) → `docs`.\n * 6. Private, non-publishable, non-docs → `app`.\n * 7. Otherwise, a single publishable package → `library`.\n */\nexport function deriveProfile(input: DeriveProfileInput): HolocronProfile {\n\tif (/-template$/.test(input.repoName)) return \"template\";\n\n\tif (input.isMonorepo) {\n\t\tconst hasPublishedCli = input.workspacePackageJsons.some((pkg) => Boolean(pkg.bin));\n\t\tif (hasPublishedCli) return \"platform\";\n\n\t\tconst hasPublishedLibrary = input.workspacePackageJsons.some((pkg) => pkg.private !== true);\n\t\tif (hasPublishedLibrary) return \"library\";\n\t}\n\n\tconst pkg = input.rootPackageJson;\n\tif (pkg?.bin) return \"cli\";\n\n\tconst deps = { ...pkg?.dependencies, ...pkg?.devDependencies };\n\tconst isDocsSite = Boolean(deps[\"@theholocron/astro-config\"] || deps[\"astro\"]);\n\tif (pkg?.private && isDocsSite) return \"docs\";\n\tif (pkg?.private) return \"app\";\n\n\treturn \"library\";\n}\n\nconst KNOWN_STACK_DEPS = [\n\t\"next\",\n\t\"vite\",\n\t\"astro\",\n\t\"tsdown\",\n\t\"rollup\",\n\t\"webpack\",\n\t\"storybook\",\n\t\"vitest\",\n\t\"playwright\",\n\t\"turbo\",\n] as const;\n\n/**\n * Detected build/framework tooling — the literal \"does this repo need\n * next/vite/tsdown\" signal `holocron.config.ts` has no field for today\n * (framework choice isn't a config concept, unlike `providers`/`tasks`).\n * Curated table, not exhaustive by design — add to `KNOWN_STACK_DEPS` as new\n * frameworks show up rather than trying to detect anything on npm.\n */\nexport function deriveStack(pkg: PackageJsonLike | null): string[] {\n\tconst deps = { ...pkg?.dependencies, ...pkg?.devDependencies };\n\treturn KNOWN_STACK_DEPS.filter((name) => name in deps);\n}\n\n/** The provider capability keys actually wired in `providers: {}` — zero heuristics. */\nexport function deriveCapabilities(providers: ResolvedProvidersConfig | undefined): string[] {\n\treturn Object.keys(providers ?? {}).sort();\n}\n\n/**\n * `source` + `ci` are the minimal baseline every repo `holocron setup`\n * touches wires — every `holocron.config.ts` in this org already satisfies\n * this, so `non-compliant` here means drift (a provider manually removed\n * after setup), not an unmet aspirational policy. Deliberately not a richer\n * per-profile policy yet (e.g. \"a `library` must have `deployment`\") — that's\n * a Phase B (GitHub App) refinement once it can post *why* on a check run.\n */\nconst REQUIRED_BASELINE = [\"source\", \"ci\"] as const;\n\nexport function deriveCompliance(capabilities: readonly string[]): \"compliant\" | \"non-compliant\" {\n\treturn REQUIRED_BASELINE.every((key) => capabilities.includes(key)) ? \"compliant\" : \"non-compliant\";\n}\n\n/**\n * The Phase B refinement `deriveCompliance()`'s own doc comment names —\n * *why* a repo is non-compliant, not just that it is. `[]` when compliant.\n * Same `REQUIRED_BASELINE` `deriveCompliance()` checks against — one\n * table, not two independently-maintained baselines.\n */\nexport function missingCapabilities(capabilities: readonly string[]): string[] {\n\treturn REQUIRED_BASELINE.filter((key) => !capabilities.includes(key));\n}\n\n/**\n * Reads each workspace package's actual `package.json` content (not just\n * `readWorkspacePackages()`'s `{ slug, name, dir }` — `deriveProfile()`'s\n * `platform` detection needs `bin`, which that helper doesn't carry).\n * Missing/invalid files are skipped, matching `readWorkspacePackages()`'s\n * own soft-fail behavior.\n */\nexport async function readWorkspacePackageJsons(\n\trepoRoot: string,\n\tworkspacePackages: readonly WorkspacePackage[]\n): Promise<PackageJsonLike[]> {\n\tconst results: PackageJsonLike[] = [];\n\tfor (const { slug, dir = \"packages\" } of workspacePackages) {\n\t\ttry {\n\t\t\tconst raw = await readFile(join(repoRoot, dir, slug, \"package.json\"), \"utf8\");\n\t\t\tresults.push(JSON.parse(raw) as PackageJsonLike);\n\t\t} catch {\n\t\t\t// no package.json or invalid JSON — skip, same as readWorkspacePackages().\n\t\t}\n\t}\n\treturn results;\n}\n","export const CANONICAL_LABELS = [\n\t{ name: \"bug\", color: \"d73a4a\", description: \"Something isn't working\" },\n\t{ name: \"chore\", color: \"ededed\", description: \"Maintenance, no user-facing change\" },\n\t{ name: \"ci\", color: \"0075ca\", description: \"CI/CD pipeline changes\" },\n\t{ name: \"dependencies\", color: \"0366d6\", description: \"Dependency update\" },\n\t{ name: \"documentation\", color: \"0075ca\", description: \"Documentation only\" },\n\t{ name: \"duplicate\", color: \"cfd3d7\", description: \"Already reported\" },\n\t{ name: \"enhancement\", color: \"a2eeef\", description: \"New feature or request\" },\n\t{ name: \"good first issue\", color: \"7057ff\", description: \"Good for newcomers\" },\n\t{ name: \"help wanted\", color: \"008672\", description: \"Extra attention needed\" },\n\t{ name: \"invalid\", color: \"e4e669\", description: \"Doesn't seem right\" },\n\t{ name: \"performance\", color: \"fbca04\", description: \"Performance improvement\" },\n\t{ name: \"question\", color: \"d876e3\", description: \"Further information requested\" },\n\t{ name: \"refactor\", color: \"cfd3d7\", description: \"Code restructuring\" },\n\t{ name: \"released\", color: \"ededed\", description: \"Included in a release\" },\n\t{ name: \"test\", color: \"bfd4f2\", description: \"Test-related changes\" },\n\t{ name: \"triage\", color: \"e4e669\", description: \"Needs investigation\" },\n\t{ name: \"wontfix\", color: \"ffffff\", description: \"Won't be addressed\" },\n] as const;\n\nexport const STALE_LABELS = [\n\t\"github_actions\",\n\t\"javascript\",\n\t\"autorelease: pending\",\n\t\"autorelease: tagged\",\n\t\"released on @alpha\",\n];\n","# Configuration for sentiment-bot - https://github.com/behaviorbot/sentiment-bot\n\n# *Required* toxicity threshold between 0 and .99 with the higher numbers being the most toxic\n# Anything higher than this threshold will be marked as toxic and commented on\nsentimentBotToxicityThreshold: .7\n\n# *Required* Comment to reply with\nsentimentBotReplyComment: >\n Please be sure to review the [Code of Conduct](https://docs.theholocron.dev/reference/code-of-conduct/) and be respectful of other users.\n","/**\n * Factory that binds `source` and `tool` once and returns all header\n * constructors for auto-generated files. Prefer this over passing source\n * as a positional argument at every call site.\n *\n * @example\n * const { workflowHeader, scaffoldHeader } = createHeader({\n * source: \"packages/cli/src/templates/configs/editorconfig/create-config.ts\",\n * });\n *\n * export function createConfig(): string {\n * return `${workflowHeader()}${body}`;\n * }\n *\n * ## Which header to use\n *\n * | Function | When to use | User can edit? |\n * |-------------------|----------------------------------------------------|----------------|\n * | `workflowHeader` | Files overwritten on every setup / sync-github run | No — \"AUTO-GENERATED — do not edit\" |\n * | `scaffoldHeader` | Files written once; user takes ownership after | Yes — \"Scaffolded — edit this file freely\" |\n *\n * ## `workflowHeader` formats\n *\n * | Format | Comment style | Used for |\n * |---------------------|------------------------|-------------------------------------------------------|\n * | `\"yaml\"` (default) | `# …` lines | YAML workflows, ignore files, `.editorconfig`, labeler|\n * | `\"cjs\"` | `/* … *\\/` block | CommonJS config files (`.cjs`) |\n * | `\"shebang\"` | `#!/bin/sh` + `# …` | Shell scripts (`prepare-commit-msg`, hooks) |\n */\n\n/** Comment style produced by workflowHeader. */\nexport type WorkflowHeaderFormat = \"yaml\" | \"cjs\" | \"shebang\";\n\nexport interface CreateHeaderOptions {\n\t/** Path within theholocron/holocron that owns the file being generated. */\n\tsource: string;\n\t/** CLI command that produces the file. Defaults to \"holocron setup\". */\n\ttool?: string;\n\t/** Set true only when writing to theholocron/.github itself. */\n\tforPrimary?: boolean;\n}\n\nexport interface HeaderFunctions {\n\t/**\n\t * \"AUTO-GENERATED — do not edit\" header for files managed on every run.\n\t *\n\t * format:\n\t * \"yaml\" — `# …` comment lines (YAML, text, ignore files)\n\t * \"cjs\" — `/* … *\\/` block comment (CommonJS modules)\n\t * \"shebang\" — `#!/bin/sh` on line 1, then yaml header (shell scripts)\n\t */\n\tworkflowHeader(format?: WorkflowHeaderFormat): string;\n\t/**\n\t * \"Scaffolded — edit this file freely\" header for one-time generated files\n\t * that the user is expected to take over (e.g. codecov.yml).\n\t */\n\tscaffoldHeader(): string;\n}\n\nexport function createHeader(options: CreateHeaderOptions): HeaderFunctions {\n\tconst { source, tool = \"holocron setup\", forPrimary = false } = options;\n\n\tconst doNotEdit = forPrimary\n\t\t? `AUTO-GENERATED — do not edit in theholocron/.github directly.`\n\t\t: `AUTO-GENERATED — do not edit directly.`;\n\n\treturn {\n\t\tworkflowHeader(format: WorkflowHeaderFormat = \"yaml\"): string {\n\t\t\tif (format === \"cjs\") {\n\t\t\t\treturn [\n\t\t\t\t\t`/* ${doNotEdit}`,\n\t\t\t\t\t` * Source: theholocron/holocron · ${source}`,\n\t\t\t\t\t` * Tool: ${tool}`,\n\t\t\t\t\t` * Changes: edit source in theholocron/holocron`,\n\t\t\t\t\t` */`,\n\t\t\t\t\t``,\n\t\t\t\t].join(\"\\n\");\n\t\t\t}\n\n\t\t\tconst yamlLines = [\n\t\t\t\t`# ${doNotEdit}`,\n\t\t\t\t`# Source: theholocron/holocron · ${source}`,\n\t\t\t\t`# Tool: ${tool}`,\n\t\t\t\t`# Changes: edit source in theholocron/holocron`,\n\t\t\t\t``,\n\t\t\t].join(\"\\n\");\n\n\t\t\tif (format === \"shebang\") {\n\t\t\t\treturn `#!/bin/sh\\n\\n${yamlLines}`;\n\t\t\t}\n\n\t\t\treturn yamlLines;\n\t\t},\n\n\t\tscaffoldHeader(): string {\n\t\t\treturn [\n\t\t\t\t`# Scaffolded by holocron setup — edit this file freely.`,\n\t\t\t\t`# Source: theholocron/holocron · ${source}`,\n\t\t\t\t``,\n\t\t\t].join(\"\\n\");\n\t\t},\n\t};\n}\n",".github/*\nCHANGELOG.md\nLICENSE\n","","import { createHeader } from \"../../../utils/create-header.js\";\nimport alexignore from \"./alexignore\";\nimport alexrc from \"./alexrc.json\";\n\nconst { workflowHeader } = createHeader({\n\tsource: \"packages/cli/src/templates/configs/alexjs/create-config.ts\",\n});\n\nexport function createRcConfig(): string {\n\treturn JSON.stringify(alexrc, null, 2) + \"\\n\";\n}\n\nexport function createIgnoreConfig(): string {\n\treturn `${workflowHeader()}${alexignore}`;\n}\n","__HOLOCRON_SCRIPT__ lint commit-msg \"$1\"\n","import { createHeader } from \"../../../utils/create-header.js\";\nimport commitMsgBody from \"./commit-msg\";\n\nconst { workflowHeader } = createHeader({\n\tsource: \"packages/cli/src/templates/configs/commit-msg/create-config.ts\",\n});\n\n/**\n * `.husky/commit-msg` — lints the commit message via `holocron lint\n * commit-msg` (holocron#789), the real programmatic replacement for\n * shelling out to `commitlint --edit`. Installed by `holocron setup` when\n * hooks are enabled. Same `__HOLOCRON_SCRIPT__` substitution as `pre-push`.\n *\n * @param holocronScript - the command that invokes the CLI. Defaults to\n * `pnpm exec holocron`; the source repo passes `node packages/cli/dist/cli.mjs`.\n */\nexport function createConfig(holocronScript = \"pnpm exec holocron\"): string {\n\treturn `${workflowHeader(\"shebang\")}${commitMsgBody.replace(\"__HOLOCRON_SCRIPT__\", holocronScript)}`;\n}\n","import { createHeader } from \"../../../utils/create-header.js\";\n\nconst { workflowHeader } = createHeader({\n\tsource: \"packages/cli/src/templates/configs/devmoji/create-config.ts\",\n});\n\nexport function createConfig(): string {\n\treturn [\n\t\tworkflowHeader(\"cjs\"),\n\t\t`/* eslint-disable */`,\n\t\t`const { defineConfig } = require(\"@theholocron/devmoji-config\");`,\n\t\t`module.exports = defineConfig();`,\n\t\t``,\n\t].join(\"\\n\");\n}\n","root = true\n\n[*]\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\nindent_style = tab\nindent_size = 4\n\n[.gitattributes]\nindent_style = space\nindent_size = 2\n\n[*.{json,yml,yaml}]\nindent_style = space\nindent_size = 2\n\n[*.{md,mdx}]\ntrim_trailing_whitespace = false\n\n[.*{rc,ignore}]\nindent_style = space\nindent_size = 2\n","import { createHeader } from \"../../../utils/create-header.js\";\nimport editorconfigBody from \"./editorconfig\";\n\nconst { workflowHeader } = createHeader({\n\tsource: \"packages/cli/src/templates/configs/editorconfig/create-config.ts\",\n});\n\nexport function createConfig(): string {\n\treturn `${workflowHeader()}${editorconfigBody}`;\n}\n","","import editorconfigChecker from \"./editorconfig-checker.json\";\n\n/**\n * The generated `.editorconfig-checker.json`.\n *\n * Deliberately carries no `\"Version\"` key: editorconfig-checker treats it as a\n * hard gate and exits non-zero the moment the running binary's version differs\n * — which it does the instant a contributor's local install (Homebrew tracks\n * latest) drifts from the version super-linter bundles in CI, breaking\n * `holocron run lint` / the pre-push hook for everyone (#618). The config\n * options here (`Exclude`, `Disable`) are stable across releases, so pinning\n * buys nothing.\n */\nexport function createConfig(): string {\n\treturn JSON.stringify(editorconfigChecker, null, 2) + \"\\n\";\n}\n","# Run GitLeaks against staged changes only — a full `gitleaks git` history\n# scan re-flags every pre-existing (already-merged) finding on every commit,\n# permanently blocking the repo once any false positive lands in history.\n# CI's super-linter GITLEAKS validator is likewise scoped to changed files.\ngitleaks protect --staged --no-banner\n\n# Exit with non-zero if secrets are detected by GitLeaks\nif [ $? -ne 0 ]; then\n\techo \"Secrets detected by GitLeaks, aborting commit!\"\n\texit 1\nfi\n\n# Run lint-staged with a custom config\nnpx lint-staged --config @theholocron/lint-staged-config\n","import { createHeader } from \"../../../utils/create-header.js\";\nimport preCommitBody from \"./pre-commit\";\n\nconst { workflowHeader } = createHeader({\n\tsource: \"packages/cli/src/templates/configs/pre-commit/create-config.ts\",\n});\n\n/**\n * `.husky/pre-commit` — runs GitLeaks (scoped to staged changes) and\n * lint-staged before every commit. Installed by `holocron setup` when hooks\n * are enabled (default for `protection: \"strict\"`). `git commit --no-verify`\n * bypasses it.\n *\n * `gitleaks protect --staged` (not `gitleaks git`) is deliberate: the latter\n * scans the entire commit history on every invocation, so once any false\n * positive lands in a past commit — a fake test token, an example key in a\n * doc — every future commit is permanently blocked, regardless of what's\n * actually staged.\n */\nexport function createConfig(): string {\n\treturn `${workflowHeader(\"shebang\")}${preCommitBody}`;\n}\n","# Run the merge-gating checks locally before pushing — the same set CI runs.\n# Bypass once with: git push --no-verify\n\n# CI runners (semantic-release, super-linter auto-commit, bots) push without a\n# built dev environment — the hook has nothing to add there.\n[ -n \"$CI\" ] && exit 0\n\n__HOLOCRON_SCRIPT__ ci\n","import { createHeader } from \"../../../utils/create-header.js\";\nimport prePushBody from \"./pre-push\";\n\nconst { workflowHeader } = createHeader({\n\tsource: \"packages/cli/src/templates/configs/pre-push/create-config.ts\",\n});\n\n/**\n * `.husky/pre-push` — runs `holocron ci` (the merge-gating checks, in CI order)\n * before every push. Installed by `holocron setup` when hooks are enabled\n * (default for `protection: \"strict\"`). `git push --no-verify` bypasses it.\n *\n * @param holocronScript - the command that invokes the CLI. Defaults to\n * `pnpm exec holocron`; the source repo passes `node packages/cli/dist/cli.mjs`.\n */\nexport function createConfig(holocronScript = \"pnpm exec holocron\"): string {\n\treturn `${workflowHeader(\"shebang\")}${prePushBody.replace(\"__HOLOCRON_SCRIPT__\", holocronScript)}`;\n}\n","NAME=$(git config user.name)\nEMAIL=$(git config user.email)\n\nif [ -z \"$NAME\" ]; then\n\techo \"empty git config user.name\"\n\texit 1\nfi\n\nif [ -z \"$EMAIL\" ]; then\n\techo \"empty git config user.email\"\n\texit 1\nfi\n\ngit interpret-trailers --if-exists doNothing --trailer \\\n\t\"Signed-off-by: $NAME <$EMAIL>\" \\\n\t--in-place \"$1\"\n\n# --config <resolved shared path> (config-resolution workstream, #676) — falls\n# back to devmoji's own auto-discovery of a local devmoji.config.cjs when the\n# shared package's built dist/ isn't present (not installed, or a stale\n# install predating this file).\nDEVMOJI_CONFIG=\"node_modules/@theholocron/devmoji-config/dist/index.cjs\"\nif [ -f \"$DEVMOJI_CONFIG\" ]; then\n\tnpx devmoji --config \"$DEVMOJI_CONFIG\" -e\nelse\n\tnpx devmoji -e\nfi\n","import { createHeader } from \"../../../utils/create-header.js\";\nimport prepareCommitMsgBody from \"./prepare-commit-msg\";\n\nconst { workflowHeader } = createHeader({\n\tsource: \"packages/cli/src/templates/configs/prepare-commit-msg/create-config.ts\",\n});\n\nexport function createConfig(): string {\n\treturn `${workflowHeader(\"shebang\")}${prepareCommitMsgBody}`;\n}\n","pnpm-lock.yaml\n","---\nextends: default\n\nignore-from-file:\n - .gitignore\n - .yamlignore\n\nrules:\n comments:\n min-spaces-from-content: 1\n require-starting-space: true\n\n comments-indentation: {}\n\n document-start:\n ignore: |\n .github/*.yml\n\n indentation:\n spaces: consistent\n indent-sequences: consistent\n\n line-length: disable\n","import { createHeader } from \"../../../utils/create-header.js\";\nimport yamlignoreBody from \"./.yamlignore\";\nimport yamllintBody from \"./.yamllint.yml\";\n\nconst { workflowHeader } = createHeader({\n\tsource: \"packages/cli/src/templates/configs/yamllint/create-config.ts\",\n});\n\nexport function createConfig(): string {\n\treturn `${workflowHeader()}${yamllintBody}`;\n}\n\nexport function createIgnoreConfig(): string {\n\treturn `${workflowHeader()}${yamlignoreBody}`;\n}\n","allowRemediationCommits:\n individual: true\n","version: 2\nupdates:\n - package-ecosystem: npm\n directory: /\n schedule:\n interval: weekly\n commit-message:\n prefix: \"chore(deps)\"\n prefix-development: \"chore(deps-dev)\"\n groups:\n security-patches:\n applies-to: security-updates\n patterns:\n - \"*\"\n all-dependencies:\n update-types:\n - minor\n - patch\n\n - package-ecosystem: github-actions\n directory: /\n schedule:\n interval: weekly\n commit-message:\n prefix: \"chore(deps)\"\n groups:\n all-actions:\n patterns:\n - \"*\"\n","bug:\n - \"^fix\"\n\nchore:\n - '^chore(?!\\(deps)'\n\nci:\n - \"^ci\"\n\ndependencies:\n - '^chore\\(deps'\n\ndocumentation:\n - \"^docs\"\n\nenhancement:\n - \"^feat\"\n\nperformance:\n - \"^perf\"\n\nrefactor:\n - \"^refactor\"\n\ntest:\n - \"^test\"\n","---\nid: ADR-XXXX\ntitle: \"\"\nstatus: proposed\ndate: YYYY-MM-DD\nowners: []\nspecs: []\ndiscussion:\n github:\nsupersedes: []\nsuperseded-by: []\ntags: []\n---\n\n# [Short title of the decision]\n\n- Status: [proposed | accepted | rejected | deprecated | superseded by ADR-XXXX]\n- Date: YYYY-MM-DD\n\n## Context and Problem Statement\n\n2–3 sentences describing the situation that forced this decision.\n\n## Decision Drivers\n\n- [driver 1 — a constraint, goal, or value]\n- [driver 2]\n\n## Considered Options\n\n- [Option A]\n- [Option B]\n- [Option C — do nothing]\n\n## Decision Outcome\n\nChosen option: **[Option A]**, because [one-sentence justification].\n\n### Positive Consequences\n\n- …\n\n### Negative Consequences\n\n- …\n\n## Pros and Cons of the Options\n\n### [Option A]\n\n- Good, because [argument]\n- Bad, because [argument]\n\n### [Option B]\n\n- Good, because [argument]\n- Bad, because [argument]\n","/**\n * Canonical AI engineering workflow role prompts.\n *\n * Written to `.agents/prompts/<role>.md` by `holocron setup` when `agent` is\n * configured. Paths are gitignored and regenerated on every setup run so the\n * content always reflects the current CLI version.\n *\n * Source: docs/wiki/specifications/ai-engineering-workflow.spec.md\n */\n\nimport decisionsTemplate from \"../../templates/decisions-template.md\";\n\nexport const DECISIONS_TEMPLATE = decisionsTemplate;\n\nexport const AGENT_PROMPTS: Record<string, string> = {\n\t\"discovery.md\": `# Discovery Agent\n\nYou are performing engineering discovery.\n\nYour goal is to understand the problem and the existing system before\nproposing implementation changes.\n\nRead the relevant issue, repository code, documentation, specifications,\nand ADRs.\n\nInvestigate:\n- current behavior\n- relevant architecture\n- dependencies\n- constraints\n- existing patterns\n- affected packages/services\n- compatibility concerns\n- security concerns\n- operational concerns\n\nDo not implement anything.\nDo not assume the proposed solution is correct.\n\nProduce:\n1. Problem summary\n2. Current system behavior\n3. Relevant architecture\n4. Constraints\n5. Systems/packages likely affected\n6. Unknowns or open questions\n7. Risks\n8. Decisions that may require architectural discussion\n9. Recommended next step\n\nIf you discover a meaningful architectural choice, explicitly identify it\nrather than silently making the decision.\n`,\n\n\t\"design.md\": `# Design Agent\n\nYou are acting as a software architect.\n\nUsing the issue, discovery findings, existing architecture, specifications,\nand ADRs, propose a design for this change.\n\nDo not write implementation code.\n\nIdentify the important engineering decisions required.\n\nFor each meaningful decision:\n1. Explain the decision that must be made.\n2. Describe viable alternatives.\n3. Explain advantages and disadvantages.\n4. Identify operational and maintenance consequences.\n5. Recommend an approach and explain why.\n\nTreat existing accepted ADRs as architectural constraints.\nDo not contradict an accepted ADR without explicitly identifying the conflict.\n\nAt the end, produce:\n- Recommended design\n- Open questions\n- Decisions requiring ADRs\n- Decisions that are implementation details and do not require ADRs\n- Suggested specification scope\n\nDo not create ADRs merely because a choice exists. An ADR is warranted only\nwhen the decision is significant enough that a future engineer may reasonably\nask why one approach was selected over another.\n`,\n\n\t\"discussion.md\": `# Discussion / RFC Agent\n\nConvert the design analysis into a GitHub Discussion suitable for engineering\nreview.\n\nInclude:\n\n# Problem\n# Context\n# Constraints\n\n# Options\nFor each option:\n- description\n- advantages\n- disadvantages\n- operational consequences\n- implementation complexity\n\n# Recommended Direction\nState the recommendation clearly as a proposal, not a decision.\n\n# Open Questions\n# Decision Requested\n\nAvoid implementation-level details unless they materially affect the\narchitectural choice.\n`,\n\n\t\"adr.md\": `# ADR Author\n\nCreate an Architecture Decision Record from the accepted engineering decision.\n\nUse the accepted GitHub Discussion as the primary source of decision history.\n\nCapture the final architectural conclusion, not the full discussion.\n\nInclude:\n- Title\n- Status\n- Date\n- Context\n- Decision\n- Rationale\n- Alternatives considered\n- Consequences\n- Related issue, Discussion, and specifications\n\nClearly distinguish between the final decision, supporting rationale, and\nalternatives that were rejected.\n\nDo not introduce new architectural decisions.\n\nIf the Discussion does not contain enough information to state a decision\nconfidently, identify the missing information instead of inventing it.\n\n## Format\n\nUse MADR format. Copy the template and number sequentially:\n\n\\`\\`\\`sh\ncp docs/wiki/decisions/template.md docs/wiki/decisions/000N-short-title.md\n\\`\\`\\`\n\nSave to \\`docs/wiki/decisions/NNNN-<slug>.md\\`.\n`,\n\n\t\"spec.md\": `# Specification Agent\n\nYou are acting as a technical specification author.\n\nCreate a specification for the requested capability using:\n- the GitHub issue\n- accepted design decisions\n- accepted ADRs\n- existing system behavior\n- relevant repository documentation\n\nTreat accepted ADRs as architectural constraints.\n\nThe specification should describe WHAT the system must do, not how to implement it.\n\nInclude:\n- Objective\n- Background\n- Goals / Non-goals\n- Existing behavior\n- Required behavior\n- Interfaces\n- Data model\n- Validation\n- State transitions\n- Error handling\n- Authorization / security\n- Observability\n- Compatibility requirements\n- Edge cases\n- Testing requirements\n- Acceptance criteria\n- Related ADRs and issues\n\nThe specification should be detailed enough that another engineer or AI agent\ncould implement the feature without seeing the original planning conversation.\n\nIMPORTANT: Do not silently make new architectural decisions. If the specification\nrequires a decision that has not been established, mark it as an unresolved\ndesign question and surface it for discussion.\n\n## Process rule\n\nFile a GitHub issue BEFORE writing the spec. The spec's frontmatter \\`issue:\\`\nfield must reference it. Order: Issue → Spec → PR → Review → merge.\n`,\n\n\t\"implementation-plan.md\": `# Implementation Planner\n\nYou are acting as an implementation planner.\n\nTreat the accepted specification and ADRs as authoritative.\n\nInspect the repository and produce a concrete implementation plan for\nsatisfying the specification. Do not redesign the feature.\n\nIdentify:\n- packages/services affected\n- files likely affected\n- new files required\n- schema changes and migrations\n- API changes\n- configuration changes\n- tests required\n- observability changes\n- documentation changes\n- deployment or rollout requirements\n\nProduce an ordered implementation plan. Each step should include:\n1. Goal\n2. Files or modules affected\n3. Expected change\n4. Tests required\n5. Dependencies on earlier steps\n\nIdentify tasks that can safely be implemented in parallel.\n\nIf repository reality conflicts with the specification or ADRs, stop that\nportion of the plan and explicitly describe the conflict. Do not silently\nalter the design to work around it.\n`,\n\n\t\"implement.md\": `# Implementation Agent\n\nYou are implementing an accepted engineering specification.\n\nAuthority order:\n1. Accepted ADRs\n2. Accepted specification\n3. Approved implementation plan\n4. Existing repository conventions\n\nImplement the approved plan.\n\nDo not change product behavior described by the specification.\nDo not contradict accepted ADRs.\nDo not introduce new architectural patterns unless required by the specification.\nFollow existing repository conventions where they do not conflict with the spec.\n\nFor each implementation step:\n- make the required change\n- add or update tests\n- preserve backward compatibility where required\n- add appropriate observability\n- update relevant documentation\n\nIf you discover that repository reality makes the specification impossible or\nrequires a new architectural decision:\n\nSTOP that portion of implementation.\n\nDescribe:\n- what the specification requires\n- what the repository currently supports\n- why they conflict\n- what decision is required\n\nDo not silently invent a new design.\n`,\n\n\t\"review.md\": `# Review Agent\n\nYou are acting as an independent engineering reviewer.\n\nReview the implementation against:\n1. The GitHub issue\n2. Accepted ADRs\n3. The accepted specification\n4. The implementation plan\n5. Repository conventions\n\nDo not assume the implementation is correct simply because tests pass.\n\nEvaluate:\n\n## Specification Compliance\nIdentify every requirement in the specification and determine whether it is\nimplemented.\n\n## ADR Compliance\nIdentify any behavior or architecture that conflicts with accepted ADRs.\n\n## Correctness\nLook for logical errors, invalid state transitions, race conditions, missing\nvalidation, and incorrect assumptions.\n\n## Security\nReview authentication, authorization, data exposure, input handling, and\ntrust boundaries.\n\n## Failure Behavior\nReview errors, retries, partial failures, rollback behavior, and recovery.\n\n## Observability\nConfirm appropriate logs, metrics, traces, and diagnostic information.\n\n## Compatibility\nCheck backward compatibility and migration behavior.\n\n## Testing\nIdentify missing test cases — especially failure paths, boundary conditions,\nauthorization, state transitions, concurrency, and regression cases.\n\n## Scope\nIdentify unrelated changes or unnecessary complexity.\n\nProduce findings ordered by severity. For each finding include:\n- severity\n- location\n- violated requirement or principle\n- explanation\n- recommended correction\n\nFinally provide:\n- specification requirements fully satisfied\n- specification requirements partially satisfied\n- specification requirements missing\n- ADR violations\n- overall recommendation\n`,\n\n\t\"verify.md\": `# Verification Agent\n\nVerify this implementation against the accepted specification.\n\nTreat each acceptance criterion as independently testable.\n\nCreate a requirement matrix containing:\n- requirement\n- implementation location\n- test coverage\n- status (PASS | PARTIAL | FAIL | NOT TESTED)\n- notes\n\nDo not infer compliance merely because related code exists.\nVerify the actual behavior where possible.\nIdentify any specification language that is ambiguous or impossible to verify.\n`,\n};\n\nexport const DECISIONS_README = `# Decisions\n\nArchitectural Decision Records live here. Each file captures one architectural\ndecision, the options that were considered, and the rationale for the choice made.\n\n## Creating a new decision\n\nCopy the template and number it sequentially:\n\n\\`\\`\\`sh\ncp docs/wiki/decisions/template.md docs/wiki/decisions/000N-short-title.md\n\\`\\`\\`\n\n\\`madr\\` has no CLI — creation is manual. Frontmatter is validated in CI\nvia \\`scripts/validate-adrs.mjs\\` (runs as part of the Lint workflow).\n\n## Status values\n\n| Status | Meaning |\n| ------------ | --------------------------------------------- |\n| \\`proposed\\` | Under discussion — not yet accepted |\n| \\`accepted\\` | In effect |\n| \\`rejected\\` | Considered and declined |\n| \\`deprecated\\` | Was accepted; no longer relevant |\n| \\`superseded\\` | Replaced by a later decision (link in frontmatter) |\n\n## Index\n\n| ID | Title | Status |\n| -- | ----- | ------ |\n`;\n\nexport const STANDARDS_README = `# Standards\n\nOrg-wide engineering standards — conventions, practices, and guidelines that\napply across all repos in the org.\n\n> **Drafts** live in \\`.notes/\\` until accepted, then graduate here.\n`;\n\nexport const SPECIFICATIONS_README = `# Specifications\n\nAccepted specs for planned or in-progress features. Each spec captures what\nthe system must do — not how to implement it.\n\n> **Drafts** live in \\`.notes/*.spec.md\\` until accepted, then graduate here.\n`;\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AGENT_PROMPTS } from \"./agent-prompts-data.js\";\n\nconst AGENTS_PROMPTS_ROOT = \".agents/prompts\";\nconst PROMPTS_GITIGNORE_START = \"# managed by holocron setup — prompts\";\nconst PROMPTS_GITIGNORE_END = \"# end managed by holocron setup — prompts\";\n\nexport async function installAgentPrompts({ repoRoot }: { repoRoot: string }): Promise<string> {\n\tconst promptsDir = join(repoRoot, AGENTS_PROMPTS_ROOT);\n\tawait mkdir(promptsDir, { recursive: true });\n\n\tfor (const [filename, content] of Object.entries(AGENT_PROMPTS)) {\n\t\tawait writeFile(join(promptsDir, filename), content, \"utf8\");\n\t}\n\n\tconst gitignorePath = join(repoRoot, \".gitignore\");\n\tconst existing = await readFile(gitignorePath, \"utf8\").catch(() => \"\");\n\tconst block = [PROMPTS_GITIGNORE_START, `/${AGENTS_PROMPTS_ROOT}/`, PROMPTS_GITIGNORE_END].join(\"\\n\");\n\tlet updated: string;\n\tif (existing.includes(PROMPTS_GITIGNORE_START)) {\n\t\tconst start = existing.indexOf(PROMPTS_GITIGNORE_START);\n\t\tconst end = existing.indexOf(PROMPTS_GITIGNORE_END, start);\n\t\tconst afterBlock = end !== -1 ? existing.slice(end + PROMPTS_GITIGNORE_END.length) : \"\\n\";\n\t\tupdated = existing.slice(0, start) + block + afterBlock;\n\t} else {\n\t\tupdated = (existing.trimEnd() ? existing.trimEnd() + \"\\n\\n\" : \"\") + block + \"\\n\";\n\t}\n\tawait writeFile(gitignorePath, updated, \"utf8\");\n\n\treturn `wrote ${Object.keys(AGENT_PROMPTS).length} prompt files to ${AGENTS_PROMPTS_ROOT}/`;\n}\n","import type { Source } from \"../../plugin/capabilities.js\";\nimport { ProviderApiError } from \"../../plugin/capabilities.js\";\nimport type { SetupStepResult } from \"./run-step.js\";\n\nexport const RULESET_NAME = \"holocron-default-branch\";\n\nexport function buildClassicProtectionPayload(requiredChecks: string[] = []): Record<string, unknown> {\n\treturn {\n\t\trequired_status_checks: requiredChecks.length > 0 ? { strict: false, contexts: requiredChecks } : null,\n\t\tenforce_admins: false,\n\t\trequired_pull_request_reviews: {\n\t\t\trequired_approving_review_count: 0,\n\t\t\tdismiss_stale_reviews: false,\n\t\t\trequire_code_owner_reviews: false,\n\t\t},\n\t\trestrictions: null,\n\t\tallow_force_pushes: false,\n\t\tallow_deletions: false,\n\t};\n}\n\nexport function buildRulesetPayload(requiredChecks: string[] = []): Record<string, unknown> {\n\tconst rules: Record<string, unknown>[] = [\n\t\t{ type: \"deletion\" },\n\t\t{ type: \"non_fast_forward\" },\n\t\t{\n\t\t\ttype: \"pull_request\",\n\t\t\tparameters: {\n\t\t\t\trequired_approving_review_count: 0,\n\t\t\t\tdismiss_stale_reviews_on_push: false,\n\t\t\t\trequire_code_owner_review: false,\n\t\t\t\trequire_last_push_approval: false,\n\t\t\t\trequired_review_thread_resolution: true,\n\t\t\t\t// GitHub defaults this to `true`. It bumps the required approval\n\t\t\t\t// count to 1 for a PR with unverified / unattributed commits —\n\t\t\t\t// which, with `required_approving_review_count: 0` and a single\n\t\t\t\t// maintainer, is an unsatisfiable block (the author can't\n\t\t\t\t// self-approve). Admin bypass already covers the real risk.\n\t\t\t\trequire_extra_approval_for_unattributed_changes: false,\n\t\t\t},\n\t\t},\n\t];\n\tif (requiredChecks.length > 0) {\n\t\trules.push({\n\t\t\ttype: \"required_status_checks\",\n\t\t\tparameters: {\n\t\t\t\trequired_status_checks: requiredChecks.map((context) => ({ context })),\n\t\t\t\tstrict_required_status_checks_policy: false,\n\t\t\t},\n\t\t});\n\t}\n\treturn {\n\t\tname: RULESET_NAME,\n\t\ttarget: \"branch\",\n\t\tenforcement: \"active\",\n\t\t// Repository admins (role 4) can bypass — required for semantic-release\n\t\t// and other automation that pushes directly to the default branch.\n\t\tbypass_actors: [{ actor_id: 4, actor_type: \"RepositoryRole\", bypass_mode: \"always\" }],\n\t\tconditions: { ref_name: { include: [\"~DEFAULT_BRANCH\"], exclude: [] } },\n\t\trules,\n\t};\n}\n\n// Tries the modern Rulesets API first, falls back to classic branch protection\n// if rulesets return 403 (requires GitHub Team+ on private repos), and gracefully\n// skips if both APIs are unavailable (GitHub Free on private repos).\nexport async function upsertBranchProtection(\n\tsource: Source,\n\tdryRun: boolean,\n\trequiredChecks: string[]\n): Promise<SetupStepResult> {\n\tconst step = `upsert ruleset ${RULESET_NAME}`;\n\tif (dryRun) return { capability: \"source\", step, status: \"dry-run\" };\n\n\t// Attempt 1: modern rulesets\n\ttry {\n\t\tconst existing = await source.listRulesets();\n\t\tconst found = existing.find((r) => r.name === RULESET_NAME);\n\t\tif (found) {\n\t\t\tawait source.updateRuleset(found.id, buildRulesetPayload(requiredChecks));\n\t\t\treturn { capability: \"source\", step, status: \"ok\", message: \"updated\" };\n\t\t}\n\t\tawait source.createRuleset(buildRulesetPayload(requiredChecks));\n\t\treturn { capability: \"source\", step, status: \"ok\", message: \"created\" };\n\t} catch (err) {\n\t\tif (!(err instanceof ProviderApiError) || err.status !== 403) {\n\t\t\treturn {\n\t\t\t\tcapability: \"source\",\n\t\t\t\tstep,\n\t\t\t\tstatus: \"fail\",\n\t\t\t\tmessage: err instanceof Error ? err.message : String(err),\n\t\t\t};\n\t\t}\n\t}\n\n\t// Attempt 2: classic branch protection (free-plan fallback)\n\ttry {\n\t\tconst repo = await source.getRepo();\n\t\tawait source.protectBranch(repo.defaultBranch, buildClassicProtectionPayload(requiredChecks));\n\t\treturn { capability: \"source\", step, status: \"ok\", message: `classic protection on ${repo.defaultBranch}` };\n\t} catch (err) {\n\t\tif (err instanceof ProviderApiError && err.status === 403) {\n\t\t\treturn {\n\t\t\t\tcapability: \"source\",\n\t\t\t\tstep,\n\t\t\t\tstatus: \"skip\",\n\t\t\t\tmessage: \"branch protection unavailable on private repos without GitHub Pro/Team\",\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tcapability: \"source\",\n\t\t\tstep,\n\t\t\tstatus: \"fail\",\n\t\t\tmessage: err instanceof Error ? err.message : String(err),\n\t\t};\n\t}\n}\n","import { access, mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\nimport { DECISIONS_README, DECISIONS_TEMPLATE, SPECIFICATIONS_README, STANDARDS_README } from \"./agent-prompts-data.js\";\n\nasync function writeIfAbsent(filePath: string, content: string): Promise<boolean> {\n\ttry {\n\t\tawait access(filePath);\n\t\treturn false; // already exists — skip\n\t} catch {\n\t\tawait mkdir(dirname(filePath), { recursive: true });\n\t\tawait writeFile(filePath, content, \"utf8\");\n\t\treturn true;\n\t}\n}\n\nexport async function installEngineeringStructure({ repoRoot }: { repoRoot: string }): Promise<string> {\n\tconst results: string[] = [];\n\n\tconst writes: Array<[string, string]> = [\n\t\t[join(repoRoot, \"docs/wiki/decisions/template.md\"), DECISIONS_TEMPLATE],\n\t\t[join(repoRoot, \"docs/wiki/decisions/README.md\"), DECISIONS_README],\n\t\t[join(repoRoot, \"docs/wiki/standards/README.md\"), STANDARDS_README],\n\t\t[join(repoRoot, \"docs/wiki/specifications/README.md\"), SPECIFICATIONS_README],\n\t];\n\n\tfor (const [path, content] of writes) {\n\t\tconst wrote = await writeIfAbsent(path, content);\n\t\tif (wrote) results.push(path.replace(repoRoot + \"/\", \"\"));\n\t}\n\n\treturn results.length > 0 ? `created: ${results.join(\", \")}` : \"all files already exist — nothing to write\";\n}\n","import type { RepoSettings } from \"../../plugin/capabilities.js\";\n\nexport const BALANCED_REPO_SETTINGS: RepoSettings = {\n\tallow_squash_merge: true,\n\tallow_merge_commit: false,\n\tallow_rebase_merge: false,\n\tallow_auto_merge: true,\n\tallow_update_branch: true,\n\tdelete_branch_on_merge: true,\n\thas_issues: true,\n\thas_discussions: true,\n\thas_projects: true,\n\thas_wiki: false,\n\t// web_commit_signoff_required is intentionally omitted: GitHub rejects this\n\t// field when the organization already enforces it at org level (422). Org-level\n\t// enforcement already covers every repo — no per-repo override is needed.\n};\n","import type { LoadedConfig } from \"../../config/load-config.js\";\nimport { getLogger } from \"../../logger.js\";\nimport { ProviderApiError } from \"../../plugin/capabilities.js\";\nimport type { RuntimeContext } from \"../../plugin/loader.js\";\nimport { PluginLoader } from \"../../plugin/loader.js\";\n\nexport type SetupPrintLine = (line: string) => void;\n\nexport type SetupStatus = \"ok\" | \"fail\" | \"skip\" | \"dry-run\";\n\n/** Why a step failed with HTTP 403. */\nexport type FailReason = \"permissions\" | \"plan\";\n\nexport interface SetupStepResult {\n\tcapability: string;\n\tstep: string;\n\tstatus: SetupStatus;\n\tmessage?: string;\n\t/** Set when status === \"fail\" and the error was a 403. */\n\treason?: FailReason;\n}\n\nexport interface SetupReport {\n\tsteps: SetupStepResult[];\n\tsummary: { ok: number; fail: number; skip: number; dryRun: number };\n}\n\nexport interface RunSetupInput {\n\tloaded: LoadedConfig;\n\tcontext: RuntimeContext;\n\t/** Lets tests inject a pre-loaded loader; defaults to native dynamic import. */\n\tloader?: PluginLoader;\n\tprint?: SetupPrintLine;\n\t/** Injectable keyring backend. Tests pass `() => null` to skip real OS keychain lookups. */\n\tkeyring?: (key: string) => string | null;\n\t/**\n\t * `--hooks` / `--no-hooks` override for git-hook installation. `undefined`\n\t * defers to `config.hooks`, then to `protection: \"strict\"`.\n\t */\n\thooks?: boolean;\n}\n\nexport async function runStep(\n\tcapability: string,\n\tstep: string,\n\tdryRun: boolean,\n\tbody: () => Promise<string | void>,\n\topts: { skipCodes?: number[] } = {}\n): Promise<SetupStepResult> {\n\tconst result = await execStep(capability, step, dryRun, body, opts);\n\tconst { status, message, reason } = result;\n\tgetLogger()[status === \"fail\" ? \"warn\" : \"info\"](\n\t\t{ capability, step, status, ...(message ? { detail: message } : {}), ...(reason ? { reason } : {}) },\n\t\t`${capability}.${step}`\n\t);\n\treturn result;\n}\n\nasync function execStep(\n\tcapability: string,\n\tstep: string,\n\tdryRun: boolean,\n\tbody: () => Promise<string | void>,\n\topts: { skipCodes?: number[] } = {}\n): Promise<SetupStepResult> {\n\tif (dryRun) {\n\t\treturn { capability, step, status: \"dry-run\" };\n\t}\n\ttry {\n\t\tconst note = await body();\n\t\tconst result: SetupStepResult = { capability, step, status: \"ok\" };\n\t\tif (typeof note === \"string\") result.message = note;\n\t\treturn result;\n\t} catch (err) {\n\t\tif (err instanceof ProviderApiError) {\n\t\t\tif (err.status !== undefined && opts.skipCodes?.includes(err.status)) {\n\t\t\t\treturn { capability, step, status: \"skip\", message: err.message };\n\t\t\t}\n\t\t\tif (err.status === 403) {\n\t\t\t\tconst reason = classify403(err);\n\t\t\t\t// Plan-restriction 403s mean the feature is unavailable on the current\n\t\t\t\t// plan — not a setup failure, just a capability gap. Report as skip.\n\t\t\t\treturn { capability, step, status: reason === \"plan\" ? \"skip\" : \"fail\", message: err.message, reason };\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\tcapability,\n\t\t\tstep,\n\t\t\tstatus: \"fail\",\n\t\t\tmessage: err instanceof Error ? err.message : String(err),\n\t\t};\n\t}\n}\n\nexport function classify403(err: ProviderApiError): FailReason {\n\tconst detailText =\n\t\ttypeof err.details === \"string\"\n\t\t\t? err.details\n\t\t\t: typeof err.details === \"object\" && err.details !== null && \"message\" in err.details\n\t\t\t\t? String((err.details as { message?: unknown }).message)\n\t\t\t\t: \"\";\n\tconst text = `${err.message} ${detailText}`.toLowerCase();\n\tif (\n\t\ttext.includes(\"advanced security\") ||\n\t\ttext.includes(\"not enabled for this repository\") ||\n\t\ttext.includes(\"upgrade\") ||\n\t\ttext.includes(\"not available on\")\n\t) {\n\t\treturn \"plan\";\n\t}\n\treturn \"permissions\";\n}\n\nimport { style } from \"../../ui/style.js\";\n\nexport function formatStep(step: SetupStepResult): string {\n\tconst tag = step.reason === \"permissions\" ? \" [permissions]\" : step.reason === \"plan\" ? \" [plan restriction]\" : \"\";\n\tconst detail = step.message ? style.dim(` (${step.message})`) : \"\";\n\tconst label = `${step.step}${tag}${detail}`;\n\tif (step.status === \"ok\") return ` ${style.success(label)}`;\n\tif (step.status === \"fail\") return ` ${style.fail(label)}`;\n\tif (step.status === \"dry-run\") return ` ${style.dim(`… ${label}`)}`;\n\treturn ` ${style.dim(`· ${label}`)}`;\n}\n","import { spawnSync } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport { copyFile, mkdir, readdir, readFile, rm, stat, symlink, unlink, writeFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join, relative } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\ninterface SkillLockEntry {\n\tsource: string;\n\tsourceType: \"github\";\n\tskillPath: string;\n\tcomputedHash?: string;\n}\n\ninterface SkillsLock {\n\tversion: number;\n\tskills: Record<string, SkillLockEntry>;\n}\n\nasync function fetchExternalSkill(entry: SkillLockEntry): Promise<{ content: string; stale: boolean }> {\n\tif (entry.sourceType !== \"github\") {\n\t\t/* c8 ignore next */\n\t\tthrow new Error(`unsupported sourceType: ${entry.sourceType}`);\n\t}\n\tconst url = `https://raw.githubusercontent.com/${entry.source}/HEAD/${entry.skillPath}`;\n\tconst res = await fetch(url);\n\tif (!res.ok) throw new Error(`HTTP ${res.status} fetching ${url}`);\n\tconst content = await res.text();\n\tconst stale = !!entry.computedHash && createHash(\"sha256\").update(content).digest(\"hex\") !== entry.computedHash;\n\treturn { content, stale };\n}\n\nconst AGENTS_SKILLS_ROOT = \".agents/skills\";\n\n/** Relative path of the agent-specific symlink. undefined = unsupported agent. */\nexport const AGENT_SYMLINK_PATHS: Partial<Record<string, (name: string) => string>> = {\n\tclaude: (name) => `.claude/skills/${name}`,\n};\n\nconst GITIGNORE_BLOCK_START = \"# managed by holocron setup — skills\";\n// Safety invariant: GITIGNORE_BLOCK_START must NOT be a substring of\n// GITIGNORE_BLOCK_END. The \"# end \" prefix currently guarantees this — if\n// either string is edited, verify the invariant still holds so that\n// indexOf(GITIGNORE_BLOCK_START) cannot match inside the end marker.\nconst GITIGNORE_BLOCK_END = \"# end managed by holocron setup — skills\";\n\nexport async function installSkills({\n\tagent,\n\tskills,\n\trepoRoot,\n}: {\n\tagent: string;\n\tskills: string[];\n\trepoRoot: string;\n}): Promise<string> {\n\tconst symlinkFn = AGENT_SYMLINK_PATHS[agent];\n\tif (!symlinkFn) {\n\t\treturn `agent \"${agent}\" has no known skill install path — skipping`;\n\t}\n\n\tconst require = createRequire(pathToFileURL(join(repoRoot, \"package.json\")));\n\tlet skillsRoot: string;\n\ttry {\n\t\tskillsRoot = dirname(require.resolve(\"@theholocron/skills/package.json\"));\n\t} catch {\n\t\tconst result = spawnSync(\"pnpm\", [\"add\", \"-D\", \"@theholocron/skills\"], {\n\t\t\tcwd: repoRoot,\n\t\t\tstdio: \"inherit\",\n\t\t});\n\t\tif (result.status !== 0) {\n\t\t\tthrow new Error(\"failed to auto-install @theholocron/skills\");\n\t\t}\n\t\ttry {\n\t\t\tskillsRoot = dirname(require.resolve(\"@theholocron/skills/package.json\"));\n\t\t} catch {\n\t\t\tthrow new Error(\"failed to auto-install @theholocron/skills\");\n\t\t}\n\t}\n\n\tconst gitignorePath = join(repoRoot, \".gitignore\");\n\tconst existingContent = await readFile(gitignorePath, \"utf8\").catch(() => \"\");\n\tconst previouslyInstalled = parsePreviousSkills(existingContent, symlinkFn);\n\tconst currentSet = new Set(skills);\n\tconst stale = previouslyInstalled.filter((n) => !currentSet.has(n));\n\tfor (const name of stale) {\n\t\tawait rm(join(repoRoot, symlinkFn(name)), { force: true }).catch(() => undefined);\n\t\tawait rm(join(repoRoot, AGENTS_SKILLS_ROOT, name), { recursive: true, force: true }).catch(() => undefined);\n\t}\n\n\tconst installed: string[] = [];\n\tconst missing: string[] = [];\n\n\tfor (const name of skills) {\n\t\tconst srcDir = join(skillsRoot, \"src\", name);\n\n\t\ttry {\n\t\t\tawait stat(srcDir);\n\t\t} catch {\n\t\t\tmissing.push(name);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst agentsDir = join(repoRoot, AGENTS_SKILLS_ROOT, name);\n\t\tawait copyDirRecursive(srcDir, agentsDir);\n\n\t\tconst symlinkPath = join(repoRoot, symlinkFn(name));\n\t\tawait mkdir(dirname(symlinkPath), { recursive: true });\n\t\ttry {\n\t\t\tawait unlink(symlinkPath);\n\t\t} catch {\n\t\t\t// didn't exist — that's fine\n\t\t}\n\t\tawait symlink(relative(dirname(symlinkPath), agentsDir).replace(/\\\\/g, \"/\"), symlinkPath);\n\n\t\tinstalled.push(name);\n\t}\n\n\tconst externalFailed: string[] = [];\n\tconst externalStale: string[] = [];\n\tif (missing.length > 0) {\n\t\tlet lock: SkillsLock | null = null;\n\t\ttry {\n\t\t\tlock = JSON.parse(await readFile(join(skillsRoot, \"skills-lock.json\"), \"utf8\")) as SkillsLock;\n\t\t} catch {\n\t\t\t// No lock file or parse error — all missing remain unknown.\n\t\t}\n\t\tif (lock?.skills) {\n\t\t\tfor (const name of [...missing]) {\n\t\t\t\tconst entry = lock.skills[name];\n\t\t\t\tif (!entry) continue;\n\t\t\t\ttry {\n\t\t\t\t\tconst { content, stale: isStale } = await fetchExternalSkill(entry);\n\t\t\t\t\tconst agentsDir = join(repoRoot, AGENTS_SKILLS_ROOT, name);\n\t\t\t\t\tawait mkdir(agentsDir, { recursive: true });\n\t\t\t\t\tawait writeFile(join(agentsDir, \"SKILL.md\"), content);\n\t\t\t\t\tconst symlinkPath = join(repoRoot, symlinkFn(name));\n\t\t\t\t\tawait mkdir(dirname(symlinkPath), { recursive: true });\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait unlink(symlinkPath);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// didn't exist — that's fine\n\t\t\t\t\t}\n\t\t\t\t\tawait symlink(relative(dirname(symlinkPath), agentsDir).replace(/\\\\/g, \"/\"), symlinkPath);\n\t\t\t\t\tmissing.splice(missing.indexOf(name), 1);\n\t\t\t\t\tinstalled.push(name);\n\t\t\t\t\tif (isStale) externalStale.push(name);\n\t\t\t\t} catch {\n\t\t\t\t\tmissing.splice(missing.indexOf(name), 1);\n\t\t\t\t\texternalFailed.push(name);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (installed.length > 0 || stale.length > 0 || missing.length > 0 || externalFailed.length > 0) {\n\t\tawait updateSkillsGitignore(\n\t\t\tgitignorePath,\n\t\t\texistingContent,\n\t\t\t[...installed, ...missing, ...externalFailed],\n\t\t\tsymlinkFn\n\t\t);\n\t}\n\n\tconst parts: string[] = [`installed ${installed.length}`];\n\tif (stale.length > 0) parts.push(`pruned: ${stale.join(\", \")}`);\n\tif (externalStale.length > 0)\n\t\tparts.push(`stale: ${externalStale.join(\", \")} (run \\`holocron skills update\\` to refresh)`);\n\tif (externalFailed.length > 0) parts.push(`fetch failed: ${externalFailed.join(\", \")}`);\n\tif (missing.length > 0) parts.push(`unknown: ${missing.join(\", \")}`);\n\treturn parts.join(\"; \");\n}\n\nexport function parsePreviousSkills(gitignoreContent: string, symlinkFn: (n: string) => string): string[] {\n\tif (!gitignoreContent.includes(GITIGNORE_BLOCK_START)) return [];\n\tconst startIdx = gitignoreContent.indexOf(GITIGNORE_BLOCK_START);\n\tconst endIdx = gitignoreContent.indexOf(GITIGNORE_BLOCK_END, startIdx);\n\tconst block = endIdx !== -1 ? gitignoreContent.slice(startIdx, endIdx) : gitignoreContent.slice(startIdx);\n\tconst placeholder = \"__placeholder__\";\n\tconst symlinkPrefix = `/${symlinkFn(placeholder)}`.replace(placeholder, \"\");\n\treturn block\n\t\t.split(\"\\n\")\n\t\t.filter((line) => line.startsWith(symlinkPrefix))\n\t\t.map((line) => line.slice(symlinkPrefix.length));\n}\n\nasync function copyDirRecursive(src: string, dest: string): Promise<void> {\n\tawait mkdir(dest, { recursive: true });\n\tconst entries = await readdir(src, { withFileTypes: true });\n\tfor (const entry of entries) {\n\t\tconst srcPath = join(src, entry.name);\n\t\tconst destPath = join(dest, entry.name);\n\t\tif (entry.isDirectory()) {\n\t\t\tawait copyDirRecursive(srcPath, destPath);\n\t\t} else {\n\t\t\tawait copyFile(srcPath, destPath);\n\t\t}\n\t}\n}\n\nasync function updateSkillsGitignore(\n\tgitignorePath: string,\n\texistingContent: string,\n\tskills: string[],\n\tsymlinkFn: (name: string) => string\n): Promise<void> {\n\tconst entries = [`/${AGENTS_SKILLS_ROOT}/`, ...skills.map((n) => `/${symlinkFn(n)}`)];\n\tconst block = [GITIGNORE_BLOCK_START, ...entries, GITIGNORE_BLOCK_END].join(\"\\n\");\n\n\tlet content: string;\n\tif (existingContent.includes(GITIGNORE_BLOCK_START)) {\n\t\tconst start = existingContent.indexOf(GITIGNORE_BLOCK_START);\n\t\tconst end = existingContent.indexOf(GITIGNORE_BLOCK_END, start);\n\t\tconst afterBlock = end !== -1 ? existingContent.slice(end + GITIGNORE_BLOCK_END.length) : \"\\n\";\n\t\tcontent = existingContent.slice(0, start) + block + afterBlock;\n\t} else {\n\t\tcontent = (existingContent.trimEnd() ? existingContent.trimEnd() + \"\\n\\n\" : \"\") + block + \"\\n\";\n\t}\n\n\tawait writeFile(gitignorePath, content, \"utf8\");\n}\n","/**\n * `holocron setup` — orchestrates per-capability setup actions across\n * every plugin loaded from `holocron.config.json`.\n *\n * Per CLAUDE.md soft-skip: each step is wrapped in a try/catch and\n * failures don't abort subsequent capabilities. The summary at the end\n * reports counts so the operator can see what worked + what didn't.\n *\n * Per the Standards: when `ctx.dryRun` is true, mutating calls are\n * replaced with \"would\" log lines. Read-only probes (e.g.,\n * `vault.list`) still run so the operator sees real state.\n *\n * The orchestrator knows about specific capability methods by name\n * (e.g., `source.enableVulnerabilityAlerts`). This deliberate coupling\n * makes the \"what does setup do\" contract explicit and concrete —\n * decoupling via a per-capability `setupSteps()` method would be more\n * extensible but pushes the same knowledge into N plugins instead of\n * one central place.\n */\n\nimport { access, readFile, writeFile } from \"node:fs/promises\";\nimport { basename, join } from \"node:path\";\n\nimport { createAstromech, extractPreviewConfig, KNOWN_WORKFLOWS, readWorkspacePackages } from \"@theholocron/astromech\";\nimport type { TasksConfig } from \"@theholocron/astromech/config\";\n\nimport { AuthError, createFeatureResolver } from \"../../auth/auth-resolver.js\";\nimport { getLogger } from \"../../logger.js\";\nimport type {\n\tAuth,\n\tDeployment,\n\tDns,\n\tDnsRecordRequest,\n\tEnvironments,\n\tErrors,\n\tLogs,\n\tSecrets,\n\tSource,\n\tTooling,\n\tVault,\n\tWiki,\n\tWorkers,\n} from \"../../plugin/capabilities.js\";\nimport { PluginLoader } from \"../../plugin/loader.js\";\nimport { assertPluginsResolvable } from \"../../plugin/workspace.js\";\nimport sentimentBotConfig from \"../../templates/config.yml\";\nimport {\n\tcreateIgnoreConfig as createAlexignore,\n\tcreateRcConfig as createAlexrc,\n} from \"../../templates/configs/alexjs/index.js\";\nimport { createConfig as createCommitMsg } from \"../../templates/configs/commit-msg/index.js\";\nimport { createConfig as createDevmoji } from \"../../templates/configs/devmoji/index.js\";\nimport { createConfig as createEditorconfig } from \"../../templates/configs/editorconfig/index.js\";\nimport { createConfig as createEditorconfigChecker } from \"../../templates/configs/editorconfig-checker/index.js\";\nimport { createConfig as createPreCommit } from \"../../templates/configs/pre-commit/index.js\";\nimport { createConfig as createPrePush } from \"../../templates/configs/pre-push/index.js\";\nimport { createConfig as createPrepareCommitMsg } from \"../../templates/configs/prepare-commit-msg/index.js\";\nimport {\n\tcreateConfig as createYamllint,\n\tcreateIgnoreConfig as createYamlignore,\n} from \"../../templates/configs/yamllint/index.js\";\nimport dcoConfig from \"../../templates/dco.yml\";\nimport dependabotConfig from \"../../templates/dependabot.yml\";\nimport labelerConfig from \"../../templates/labeler.yml\";\nimport { withSpinner } from \"../../ui/progress.js\";\nimport { style } from \"../../ui/style.js\";\nimport { createHeader } from \"../../utils/create-header.js\";\nimport { installAgentPrompts } from \"./agent-prompts.js\";\nimport { upsertBranchProtection } from \"./branch-protection.js\";\nimport {\n\tderiveCapabilities,\n\tderiveCompliance,\n\tderiveProfile,\n\tderiveStack,\n\treadWorkspacePackageJsons,\n} from \"./derived-properties.js\";\nimport { installEngineeringStructure } from \"./engineering.js\";\nimport { CANONICAL_LABELS, STALE_LABELS } from \"./labels.js\";\nimport { BALANCED_REPO_SETTINGS } from \"./repo-settings.js\";\nimport type { RunSetupInput, SetupReport, SetupStepResult } from \"./run-step.js\";\nimport { formatStep, runStep } from \"./run-step.js\";\nimport { AGENT_SYMLINK_PATHS, installSkills } from \"./skills.js\";\n\nconst { workflowHeader } = createHeader({\n\tsource: \"packages/cli/src/commands/setup/run-setup.ts\",\n\ttool: \"holocron setup\",\n});\n// Thin-caller workflow content comes from astromech.thinCallers(), not this\n// file — a separate binding so its header points contributors at the actual\n// template/generation logic (packages/astromech/src/thin-callers.ts), same as\n// the workflowHeader() calls further down that write genuinely cli-owned\n// templates (labeler.yml, dependabot.yml, dco.yml, config.yml).\nconst { workflowHeader: thinCallerHeader } = createHeader({\n\tsource: \"packages/astromech/src/thin-callers.ts\",\n\ttool: \"holocron setup\",\n});\n\nexport async function runSetup(input: RunSetupInput): Promise<SetupReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = getLogger();\n\tconst loader = input.loader ?? new PluginLoader(input.loaded.resolved, input.context);\n\tawait withSpinner(\"Loading plugins…\", () => loader.load());\n\tassertPluginsResolvable(loader, \"setup\");\n\n\tconst config = input.loaded.resolved;\n\tconst dryRun = input.context.dryRun ?? false;\n\tconst steps: SetupStepResult[] = [];\n\tconst repo = config.repo;\n\tconst effectivePreset = repo?.protection;\n\n\t// Git hooks: `--hooks`/`--no-hooks` wins, then `config.hooks`, then default\n\t// on for `protection: \"strict\"`.\n\tconst hooksEnabled =\n\t\tinput.hooks ??\n\t\t(typeof config.hooks === \"boolean\"\n\t\t\t? config.hooks\n\t\t\t: typeof config.hooks === \"object\"\n\t\t\t\t? config.hooks.prePush !== false\n\t\t\t\t: effectivePreset === \"strict\");\n\n\tprint(style.header(`Holocron setup — ${config.name}${dryRun ? \" (dry-run)\" : \"\"}`));\n\tprint(style.dim(` config: ${input.loaded.filepath}`));\n\tprint(\"\");\n\n\t// ── source: security toggles + repo policy ──────────────────────────\n\tif (loader.has(\"source\")) {\n\t\tconst source = loader.get(\"source\") as Source;\n\t\tprint(style.step(\"source\"));\n\t\tconst SECURITY_SKIP_CODES: Partial<Record<string, number[]>> = {\n\t\t\tenableSecretScanning: [422],\n\t\t\tenablePrivateVulnerabilityReporting: [404],\n\t\t};\n\t\tfor (const method of [\n\t\t\t\"enableVulnerabilityAlerts\",\n\t\t\t\"enableAutomatedSecurityFixes\",\n\t\t\t\"enableSecretScanning\",\n\t\t\t\"enablePrivateVulnerabilityReporting\",\n\t\t\t\"enableDependencyGraph\",\n\t\t] as const) {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\n\t\t\t\t\t\"source\",\n\t\t\t\t\tmethod,\n\t\t\t\t\tdryRun,\n\t\t\t\t\tasync () => {\n\t\t\t\t\t\tawait source[method]();\n\t\t\t\t\t},\n\t\t\t\t\t{ skipCodes: SECURITY_SKIP_CODES[method] }\n\t\t\t\t)\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\n\t\tconst usesAdvancedCodeQL = (config.tasks ?? [])\n\t\t\t.map((e) => (typeof e === \"string\" ? e : e.name))\n\t\t\t.includes(\"security.codeScanning\");\n\t\tsteps.push(\n\t\t\tawait runStep(\n\t\t\t\t\"source\",\n\t\t\t\tusesAdvancedCodeQL ? \"disableDefaultCodeScanning\" : \"enableCodeScanning\",\n\t\t\t\tdryRun,\n\t\t\t\tasync () => {\n\t\t\t\t\tif (usesAdvancedCodeQL) {\n\t\t\t\t\t\tawait source.disableDefaultCodeScanning();\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn await source.enableCodeScanning();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t)\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\n\t\tif (effectivePreset && effectivePreset !== \"none\") {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"source\", \"updateRepoSettings\", dryRun, async () => {\n\t\t\t\t\tawait source.updateRepoSettings({\n\t\t\t\t\t\t...BALANCED_REPO_SETTINGS,\n\t\t\t\t\t\t...(repo?.defaultBranch ? { default_branch: repo.defaultBranch } : {}),\n\t\t\t\t\t});\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\n\t\t\tconst tasksConfig: TasksConfig = { tasks: config.tasks as TasksConfig[\"tasks\"] };\n\t\t\tif (config.extraRequiredChecks) tasksConfig.extraRequiredChecks = config.extraRequiredChecks;\n\t\t\tconst requiredChecks =\n\t\t\t\teffectivePreset === \"strict\"\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t\"DCO\",\n\t\t\t\t\t\t\t...createAstromech({\n\t\t\t\t\t\t\t\tcwd: input.context.repoRoot,\n\t\t\t\t\t\t\t\tconfig: tasksConfig,\n\t\t\t\t\t\t\t\tlogger,\n\t\t\t\t\t\t\t}).requiredChecks(),\n\t\t\t\t\t\t]\n\t\t\t\t\t: [];\n\t\t\tsteps.push(await upsertBranchProtection(source, dryRun, requiredChecks));\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\t}\n\n\t// ── source: workflow thin wrappers ──────────────────────────────────\n\tconst tasks = config.tasks;\n\tif (loader.has(\"source\") && tasks && tasks.length > 0) {\n\t\tconst source = loader.get(\"source\") as Source;\n\t\tprint(style.step(\"workflows\"));\n\n\t\t// astromech renders every thin caller from the manifest (lint linter set,\n\t\t// deploy paths, deploy+preview) and validates it — a bad manifest throws\n\t\t// here, aborting setup, same as before. Iterate the manifest (not the map)\n\t\t// so step reporting keeps the config's order.\n\t\tconst files = createAstromech({\n\t\t\tcwd: input.context.repoRoot,\n\t\t\tconfig: { tasks: tasks as TasksConfig[\"tasks\"] },\n\t\t\torgContext: { org: config.org, domain: config.domain },\n\t\t\tlogger,\n\t\t}).thinCallers();\n\n\t\tfor (const entry of tasks) {\n\t\t\tconst name = typeof entry === \"string\" ? entry : entry.name;\n\t\t\t// knowledge.docs / knowledge.components have no static\n\t\t\t// WORKFLOW_TEMPLATES entry (their content is always\n\t\t\t// combined-generated, astromech.ts) — not in KNOWN_WORKFLOWS, but\n\t\t\t// not \"unknown\" either.\n\t\t\tconst isCombinedContentOnly = name === \"knowledge.docs\" || name === \"knowledge.components\";\n\n\t\t\tif (!KNOWN_WORKFLOWS.has(name) && !isCombinedContentOnly) {\n\t\t\t\tsteps.push({\n\t\t\t\t\tcapability: \"source\",\n\t\t\t\t\tstep: `write workflow ${name}`,\n\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\tmessage: `unknown workflow \"${name}\" — no template available`,\n\t\t\t\t});\n\t\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// The combined-content family (delivery.deploy, knowledge.docs,\n\t\t\t// knowledge.components) all key their generated file by task name\n\t\t\t// already — no special-casing needed, unlike the old hardcoded\n\t\t\t// \"deploy.yml\" filename.\n\t\t\tconst filename = `${name}.yml`;\n\t\t\tconst content = files.get(filename);\n\t\t\tif (content === undefined) continue; // ci: false — nothing to write\n\n\t\t\tconst withPreview = content.includes(\"workflows/preview.yml@main\");\n\t\t\tconst step = withPreview ? `write workflow ${name} (with preview)` : `write workflow ${name}`;\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"source\", step, dryRun, async () => {\n\t\t\t\t\tawait source.writeWorkflowFile(filename, `${thinCallerHeader()}${content}`);\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\t}\n\n\t// ── source: labeler config ───────────────────────────────────────────\n\tif (\n\t\tloader.has(\"source\") &&\n\t\t(config.tasks ?? []).map((e) => (typeof e === \"string\" ? e : e.name)).includes(\"bookkeeping\")\n\t) {\n\t\tconst source = loader.get(\"source\") as Source;\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write .github/labeler.yml\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\".github/labeler.yml\", `${workflowHeader()}${labelerConfig}`);\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t}\n\n\t// ── source: dependabot + dco config ─────────────────────────────────\n\tif (loader.has(\"source\") && effectivePreset !== \"none\") {\n\t\tconst source = loader.get(\"source\") as Source;\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write .github/dependabot.yml\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\".github/dependabot.yml\", `${workflowHeader()}${dependabotConfig}`);\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write .github/dco.yml\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\".github/dco.yml\", `${workflowHeader()}${dcoConfig}`);\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t}\n\n\t// ── source: static config files ──────────────────────────────────────\n\tif (loader.has(\"source\")) {\n\t\tconst source = loader.get(\"source\") as Source;\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write .github/config.yml\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\".github/config.yml\", `${workflowHeader()}${sentimentBotConfig}`);\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write .alexrc.json\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\".alexrc.json\", createAlexrc());\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write .alexignore\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\".alexignore\", createAlexignore());\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write .yamllint.yml\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\".yamllint.yml\", createYamllint());\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write .yamlignore\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\".yamlignore\", createYamlignore());\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write .editorconfig\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\".editorconfig\", createEditorconfig());\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write .editorconfig-checker.json\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\".editorconfig-checker.json\", createEditorconfigChecker());\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write devmoji.config.cjs\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\"devmoji.config.cjs\", createDevmoji());\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write .husky/prepare-commit-msg\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\".husky/prepare-commit-msg\", createPrepareCommitMsg());\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write .husky/commit-msg\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\".husky/commit-msg\", createCommitMsg(config.holocronScript));\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\tif (hooksEnabled) {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"source\", \"write .husky/pre-push\", dryRun, async () => {\n\t\t\t\t\tawait source.writeRepoFile(\".husky/pre-push\", createPrePush(config.holocronScript));\n\t\t\t\t\treturn \"runs `holocron ci` before push — bypass with `git push --no-verify`\";\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"source\", \"write .husky/pre-commit\", dryRun, async () => {\n\t\t\t\t\tawait source.writeRepoFile(\".husky/pre-commit\", createPreCommit());\n\t\t\t\t\treturn \"runs GitLeaks (staged-only) + lint-staged before commit\";\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\tif (config.syncScripts !== false) {\n\t\t\t\tsteps.push(\n\t\t\t\t\tawait runStep(\"source\", \"set package.json prepare script\", dryRun, async () => {\n\t\t\t\t\t\treturn (await ensurePrepareScript(input.context.repoRoot))\n\t\t\t\t\t\t\t? \"prepare now runs husky\"\n\t\t\t\t\t\t\t: \"already runs husky\";\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\t}\n\t\t} else {\n\t\t\tsteps.push({\n\t\t\t\tcapability: \"source\",\n\t\t\t\tstep: \"write .husky/pre-push\",\n\t\t\t\tstatus: \"skip\",\n\t\t\t\tmessage: \"git hooks disabled\",\n\t\t\t});\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\tsteps.push({\n\t\t\t\tcapability: \"source\",\n\t\t\t\tstep: \"write .husky/pre-commit\",\n\t\t\t\tstatus: \"skip\",\n\t\t\t\tmessage: \"git hooks disabled\",\n\t\t\t});\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\t\t{\n\t\t\tconst configuredWorkflowNames = (config.tasks ?? []).map((e) => (typeof e === \"string\" ? e : e.name));\n\t\t\tconst hasTestWorkflow = configuredWorkflowNames.includes(\"verification.unitTests\");\n\t\t\tconst existing = await readFile(join(input.context.repoRoot, \"codecov.yml\"), \"utf8\").catch(() => null);\n\t\t\tif (!hasTestWorkflow && existing == null) {\n\t\t\t\tsteps.push({\n\t\t\t\t\tcapability: \"source\",\n\t\t\t\t\tstep: \"write codecov.yml\",\n\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\tmessage: \"no test workflow configured\",\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tsteps.push(\n\t\t\t\t\tawait runStep(\"source\", \"write codecov.yml\", dryRun, async () => {\n\t\t\t\t\t\tconst content = createAstromech({ cwd: input.context.repoRoot, logger }).codecovConfig(\n\t\t\t\t\t\t\texisting\n\t\t\t\t\t\t);\n\t\t\t\t\t\tawait source.writeRepoFile(\"codecov.yml\", content);\n\t\t\t\t\t\tconst packageCount = readWorkspacePackages(input.context.repoRoot).length;\n\t\t\t\t\t\treturn packageCount > 0 ? `${packageCount} components` : \"no components\";\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t}\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\t\t{\n\t\t\tconst astromechTurbo = createAstromech({\n\t\t\t\tcwd: input.context.repoRoot,\n\t\t\t\tconfig: { tasks: config.tasks as TasksConfig[\"tasks\"] },\n\t\t\t\tlogger,\n\t\t\t});\n\t\t\tconst content = astromechTurbo.turboConfig();\n\n\t\t\tif (content === null) {\n\t\t\t\tsteps.push({\n\t\t\t\t\tcapability: \"source\",\n\t\t\t\t\tstep: \"write turbo.json\",\n\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\tmessage: \"no fan-out-eligible tasks configured\",\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tsteps.push(\n\t\t\t\t\tawait runStep(\"source\", \"write turbo.json\", dryRun, async () => {\n\t\t\t\t\t\tawait source.writeRepoFile(\"turbo.json\", content);\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\n\t\t\t\t// #692: a root that's genuinely a directly-buildable package (not\n\t\t\t\t// just an orchestrator) silently vanishes from `turbo run <task>`\n\t\t\t\t// once turbo.json exists, unless it's an explicit workspace\n\t\t\t\t// member — fix pnpm-workspace.yaml in the same step that\n\t\t\t\t// introduces the risk.\n\t\t\t\tconst rootPkgRaw = await readFile(join(input.context.repoRoot, \"package.json\"), \"utf8\").catch(\n\t\t\t\t\t() => null\n\t\t\t\t);\n\t\t\t\tconst rootPkg = rootPkgRaw ? (JSON.parse(rootPkgRaw) as { scripts?: Record<string, string> }) : null;\n\t\t\t\tconst workspaceYaml = await readFile(join(input.context.repoRoot, \"pnpm-workspace.yaml\"), \"utf8\").catch(\n\t\t\t\t\t() => \"\"\n\t\t\t\t);\n\t\t\t\tconst rootScripts = rootPkg?.scripts ?? {};\n\t\t\t\tconst workspaceFix = astromechTurbo.ensureRootWorkspaceMember(workspaceYaml, rootScripts);\n\t\t\t\tif (workspaceFix.changed) {\n\t\t\t\t\tsteps.push(\n\t\t\t\t\t\tawait runStep(\n\t\t\t\t\t\t\t\"source\",\n\t\t\t\t\t\t\t\"fix pnpm-workspace.yaml (root workspace member, #692)\",\n\t\t\t\t\t\t\tdryRun,\n\t\t\t\t\t\t\tasync () => {\n\t\t\t\t\t\t\t\tawait source.writeRepoFile(\"pnpm-workspace.yaml\", workspaceFix.content);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// turbo.json alone is inert without turbo itself installed — see\n\t\t\t\t// ensureTurboDependency()'s own docstring for how this was found.\n\t\t\t\tif (rootPkgRaw) {\n\t\t\t\t\tconst depFix = astromechTurbo.ensureTurboDependency(rootPkgRaw, workspaceFix.content);\n\t\t\t\t\tif (depFix.changed) {\n\t\t\t\t\t\tsteps.push(\n\t\t\t\t\t\t\tawait runStep(\"source\", \"add turbo devDependency\", dryRun, async () => {\n\t\t\t\t\t\t\t\tawait source.writeRepoFile(\"package.json\", depFix.content);\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\n\t\tif (source.syncLabels) {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"source\", \"sync labels\", dryRun, async () => {\n\t\t\t\t\treturn source.syncLabels!(CANONICAL_LABELS, STALE_LABELS);\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\n\t\tconst properties: Record<string, string | string[]> = {};\n\n\t\tif (effectivePreset && effectivePreset !== \"none\")\n\t\t\tproperties[\"holocron_branch_protection_level\"] = effectivePreset;\n\n\t\tconst isMonorepo = await access(join(input.context.repoRoot, \"pnpm-workspace.yaml\"))\n\t\t\t.then(() => true)\n\t\t\t.catch(() => false);\n\t\tproperties[\"monorepo\"] = String(isMonorepo);\n\n\t\tconst manual = repo?.properties ?? {};\n\t\tif (manual.lifecycle) properties[\"lifecycle\"] = manual.lifecycle;\n\t\tif (manual.open_source !== undefined) properties[\"open_source\"] = String(manual.open_source);\n\t\tif (manual.runtime_environment) properties[\"runtime_environment\"] = manual.runtime_environment;\n\t\tif (manual.uses_external_packages !== undefined)\n\t\t\tproperties[\"uses_external_packages\"] = String(manual.uses_external_packages);\n\n\t\t// #677 — derived fields, distinct from the manual ones above: signal\n\t\t// that isn't an explicit holocron.config.ts field today (framework\n\t\t// choice, repo archetype, capability drift).\n\t\t{\n\t\t\tconst rootPackageJson = await readFile(join(input.context.repoRoot, \"package.json\"), \"utf8\")\n\t\t\t\t.then((raw) => JSON.parse(raw) as Parameters<typeof deriveStack>[0])\n\t\t\t\t.catch(() => null);\n\t\t\tconst workspacePackages = readWorkspacePackages(input.context.repoRoot);\n\t\t\tconst workspacePackageJsons = await readWorkspacePackageJsons(input.context.repoRoot, workspacePackages);\n\t\t\tproperties[\"holocron_profile\"] = deriveProfile({\n\t\t\t\trootPackageJson,\n\t\t\t\trepoName: basename(input.context.repoRoot),\n\t\t\t\tisMonorepo,\n\t\t\t\tworkspacePackageJsons,\n\t\t\t});\n\t\t\tproperties[\"holocron_stack\"] = deriveStack(rootPackageJson);\n\t\t\tconst capabilities = deriveCapabilities(config.providers);\n\t\t\tproperties[\"holocron_capabilities\"] = capabilities;\n\t\t\tproperties[\"holocron_compliance\"] = deriveCompliance(capabilities);\n\t\t}\n\n\t\tif (source.syncProperties) {\n\t\t\tsteps.push(await runStep(\"source\", \"sync properties\", dryRun, () => source.syncProperties!(properties)));\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\n\t\tconst topics = repo?.topics ?? [];\n\t\tif (topics.length > 0 && source.syncTopics) {\n\t\t\tsteps.push(await runStep(\"source\", \"sync topics\", dryRun, () => source.syncTopics!(topics)));\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\n\t\tif (config.description && source.syncDescription) {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"source\", \"sync description\", dryRun, () => source.syncDescription!(config.description!))\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\n\t\tif (config.homepage && source.syncHomepage) {\n\t\t\tsteps.push(await runStep(\"source\", \"sync homepage\", dryRun, () => source.syncHomepage!(config.homepage!)));\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\n\t\tconst teams = repo?.teams ?? [];\n\t\tif (teams.length > 0) {\n\t\t\tif (source.syncTeams) {\n\t\t\t\tsteps.push(\n\t\t\t\t\tawait runStep(\"source\", \"sync teams\", dryRun, () => source.syncTeams!(teams), { skipCodes: [422] })\n\t\t\t\t);\n\t\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\n\t\t\t\tconst repoCoord = input.context.repo ?? repo?.name ?? \"\";\n\t\t\t\tconst org = repoCoord.includes(\"/\") ? repoCoord.split(\"/\")[0]! : \"\";\n\t\t\t\tconst writeableTeams = teams\n\t\t\t\t\t.map((t) => (typeof t === \"string\" ? { slug: t, permission: \"push\" as const } : t))\n\t\t\t\t\t.filter((t) => [\"push\", \"maintain\", \"admin\"].includes(t.permission));\n\t\t\t\tif (org && writeableTeams.length > 0) {\n\t\t\t\t\tsteps.push(\n\t\t\t\t\t\tawait runStep(\"source\", \"write .github/CODEOWNERS\", dryRun, async () => {\n\t\t\t\t\t\t\tconst content = writeableTeams.map((t) => `* @${org}/${t.slug}`).join(\"\\n\") + \"\\n\";\n\t\t\t\t\t\t\tawait source.writeRepoFile(\".github/CODEOWNERS\", content);\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tsteps.push({\n\t\t\t\t\tcapability: \"source\",\n\t\t\t\t\tstep: \"sync teams\",\n\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\tmessage: \"provider does not implement syncTeams\",\n\t\t\t\t});\n\t\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── environments ────────────────────────────────────────────────────\n\tif (loader.has(\"environments\")) {\n\t\tconst envs = loader.get(\"environments\") as Environments;\n\t\tprint(style.step(\"environments\"));\n\t\tfor (const envName of [\"staging\", \"production\"]) {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"environments\", `upsert ${envName}`, dryRun, async () => {\n\t\t\t\t\tawait envs.upsertEnvironment({ name: envName });\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\t}\n\n\t// ── docs: configure GitHub Pages ────────────────────────────────────\n\tif (loader.has(\"source\") && config.docs) {\n\t\tconst source = loader.get(\"source\") as Source;\n\t\tconst resolveDeployToken = createFeatureResolver({\n\t\t\tenvName: \"HOLOCRON_DEPLOY_TOKEN\",\n\t\t\tkeyringKey: \"github.deploy\",\n\t\t});\n\t\tlet deployToken: string | undefined;\n\t\ttry {\n\t\t\tdeployToken = resolveDeployToken({ keyring: input.keyring });\n\t\t} catch (err) {\n\t\t\tif (!(err instanceof AuthError)) throw err;\n\t\t}\n\t\tprint(style.step(\"docs\"));\n\t\tif (!deployToken) {\n\t\t\tsteps.push({\n\t\t\t\tcapability: \"source\",\n\t\t\t\tstep: \"configure GitHub Pages\",\n\t\t\t\tstatus: \"skip\",\n\t\t\t\tmessage:\n\t\t\t\t\t\"no deploy token found — set HOLOCRON_DEPLOY_TOKEN or run: holocron auth set github.deploy <PAT>\",\n\t\t\t});\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t} else if (source.configurePages) {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"source\", \"configure GitHub Pages\", dryRun, async () => {\n\t\t\t\t\tawait source.configurePages!(config.docs!, deployToken);\n\t\t\t\t\tconst parts: string[] = [config.docs!.build];\n\t\t\t\t\tif (config.docs!.domain) parts.push(`domain: ${config.docs!.domain}`);\n\t\t\t\t\tif (config.docs!.https) parts.push(\"https: enforced\");\n\t\t\t\t\treturn parts.join(\", \");\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\t}\n\n\t// ── wiki: provision engineering wiki config ──────────────────────────\n\tif (loader.has(\"wiki\")) {\n\t\tconst wiki = loader.get(\"wiki\") as Wiki;\n\t\tprint(style.step(\"wiki\"));\n\t\tsteps.push(\n\t\t\tawait runStep(\"wiki\", \"provision wiki config\", dryRun, async () => {\n\t\t\t\treturn await wiki.provision({ name: config.name });\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\n\t\tconst wikiDns = wiki.dnsRecord?.();\n\t\tconst wikiProxy = wiki.proxyConfig?.();\n\t\tif (wikiDns && loader.has(\"dns\")) {\n\t\t\tconst dns = loader.get(\"dns\") as Dns;\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"dns\", `upsertRecord ${wikiDns.record.name}`, dryRun, async () => {\n\t\t\t\t\tawait dns.upsertRecord(wikiDns.zone, {\n\t\t\t\t\t\t...wikiDns.record,\n\t\t\t\t\t\tttl: 1,\n\t\t\t\t\t\t...(wikiProxy ? { proxied: true } : {}),\n\t\t\t\t\t});\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\n\t\tif (wikiProxy && wikiDns && loader.has(\"workers\")) {\n\t\t\tconst workers = loader.get(\"workers\") as Workers;\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"workers\", `upsertProxy ${wikiDns.record.name}`, dryRun, async () => {\n\t\t\t\t\tawait workers.upsertProxy(wikiDns.record.name, wikiProxy);\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\t}\n\n\t// ── deployment: ensure project + preview infrastructure ─────────────\n\tif (loader.has(\"deployment\")) {\n\t\tconst deploy = loader.get(\"deployment\") as Deployment;\n\t\tprint(style.step(\"deployment\"));\n\n\t\t// delivery.deploy, knowledge.docs, and knowledge.components all share the\n\t\t// same combined production+preview mechanism (astromech.ts) — any one of\n\t\t// them can carry the preview config that drives project/DNS provisioning.\n\t\tconst deployEntry = (config.tasks ?? [])\n\t\t\t.map((e) => (typeof e === \"string\" ? { name: e } : e))\n\t\t\t.find(\n\t\t\t\t(e) => e.name === \"delivery.deploy\" || e.name === \"knowledge.docs\" || e.name === \"knowledge.components\"\n\t\t\t);\n\t\tconst previewCfg = deployEntry?.with\n\t\t\t? extractPreviewConfig(deployEntry.with as Record<string, unknown>, {\n\t\t\t\t\torg: config.org,\n\t\t\t\t\tdomain: config.domain,\n\t\t\t\t})\n\t\t\t: null;\n\t\tconst ensureCustomDomain = async (projectId: string, hostname: string) => {\n\t\t\tif (!deploy.ensureCustomDomain) return;\n\t\t\tconst customDomainDns = { value: null as DnsRecordRequest | null };\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"deployment\", `ensureCustomDomain ${hostname}`, dryRun, async () => {\n\t\t\t\t\tcustomDomainDns.value = await deploy.ensureCustomDomain!(projectId, hostname);\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\n\t\t\tif (customDomainDns.value && loader.has(\"dns\")) {\n\t\t\t\tconst dns = loader.get(\"dns\") as Dns;\n\t\t\t\tconst dnsRecord = customDomainDns.value;\n\t\t\t\tsteps.push(\n\t\t\t\t\tawait runStep(\"dns\", `upsertRecord ${dnsRecord.record.name}`, dryRun, async () => {\n\t\t\t\t\t\tawait dns.upsertRecord(dnsRecord.zone, { ...dnsRecord.record, ttl: 1 });\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\t}\n\t\t};\n\n\t\tif (!previewCfg) {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"deployment\", `ensureProject ${config.name}`, dryRun, async () => {\n\t\t\t\t\tawait deploy.ensureProject({ name: config.name });\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\tif (deploy.domain) {\n\t\t\t\tawait ensureCustomDomain(config.name, deploy.domain);\n\t\t\t}\n\t\t}\n\n\t\tif (previewCfg) {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"deployment\", `ensureProject ${previewCfg.project}`, dryRun, async () => {\n\t\t\t\t\tawait deploy.ensureProject({ name: previewCfg.project });\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\n\t\tif (previewCfg?.domain) {\n\t\t\tawait ensureCustomDomain(previewCfg.project, previewCfg.domain);\n\t\t}\n\n\t\t// Cloudflare Pages doesn't expose its DNS challenge, so retain its\n\t\t// provider-specific apex + wildcard records. Other providers return\n\t\t// their required record from ensureCustomDomain() above.\n\t\tif (previewCfg?.domain && deploy.providerName === \"cloudflare\" && loader.has(\"dns\")) {\n\t\t\tconst dns = loader.get(\"dns\") as Dns;\n\t\t\tconst wildcardDomain = `*.${previewCfg.domain}`;\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"dns\", `upsertRecord ${previewCfg.domain}`, dryRun, async () => {\n\t\t\t\t\tawait dns.upsertRecord(previewCfg.domain!, {\n\t\t\t\t\t\ttype: \"CNAME\",\n\t\t\t\t\t\tname: previewCfg.domain!,\n\t\t\t\t\t\tcontent: `${previewCfg.project}.pages.dev`,\n\t\t\t\t\t\tttl: 1,\n\t\t\t\t\t});\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"dns\", `upsertRecord ${wildcardDomain}`, dryRun, async () => {\n\t\t\t\t\tawait dns.upsertRecord(previewCfg.domain!, {\n\t\t\t\t\t\ttype: \"CNAME\",\n\t\t\t\t\t\tname: wildcardDomain,\n\t\t\t\t\t\tcontent: `${previewCfg.project}.pages.dev`,\n\t\t\t\t\t\tttl: 1,\n\t\t\t\t\t});\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\t}\n\n\t// ── auth: ensure webhook app (optional method) ──────────────────────\n\tif (loader.has(\"auth\")) {\n\t\tconst auth = loader.get(\"auth\") as Auth;\n\t\tprint(style.step(\"auth\"));\n\t\tif (auth.ensureWebhookApp) {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"auth\", \"ensureWebhookApp\", dryRun, async () => {\n\t\t\t\t\tconst result = await auth.ensureWebhookApp!();\n\t\t\t\t\treturn `webhook ${result.alreadyExists ? \"exists\" : \"created\"}`;\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t} else {\n\t\t\tsteps.push({\n\t\t\t\tcapability: \"auth\",\n\t\t\t\tstep: \"ensureWebhookApp\",\n\t\t\t\tstatus: \"skip\",\n\t\t\t\tmessage: \"provider does not implement ensureWebhookApp\",\n\t\t\t});\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\t}\n\n\t// ── vault: bootstrap project + configs, then read-only probe ───────\n\tif (loader.has(\"vault\")) {\n\t\tconst vault = loader.get(\"vault\") as Vault;\n\t\tprint(style.step(\"vault\"));\n\n\t\tif (vault.ensureProject) {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"vault\", `ensureProject ${config.name}`, dryRun, async () => {\n\t\t\t\t\tconst result = await vault.ensureProject!(config.name);\n\t\t\t\t\treturn `project ${result.alreadyExists ? \"exists\" : \"created\"}`;\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\n\t\tif (vault.ensureEnvironment) {\n\t\t\tfor (const envName of [\"dev\", \"stg\", \"prd\"]) {\n\t\t\t\tsteps.push(\n\t\t\t\t\tawait runStep(\"vault\", `ensureEnvironment ${envName}`, dryRun, async () => {\n\t\t\t\t\t\tconst result = await vault.ensureEnvironment!(config.name, envName);\n\t\t\t\t\t\treturn `${envName} ${result.alreadyExists ? \"exists\" : \"created\"}`;\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst keys = await vault.list();\n\t\t\tsteps.push({\n\t\t\t\tcapability: \"vault\",\n\t\t\t\tstep: \"list\",\n\t\t\t\tstatus: \"ok\",\n\t\t\t\tmessage: `${keys.length} keys available`,\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tsteps.push({\n\t\t\t\tcapability: \"vault\",\n\t\t\t\tstep: \"list\",\n\t\t\t\tstatus: \"fail\",\n\t\t\t\tmessage: err instanceof Error ? err.message : String(err),\n\t\t\t});\n\t\t}\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t}\n\n\t// ── errors: provision the tracker project + push the DSN to secrets ─\n\tif (loader.has(\"errors\")) {\n\t\tconst errors = loader.get(\"errors\") as Errors;\n\t\tprint(style.step(\"errors\"));\n\n\t\tif (errors.ensureProject) {\n\t\t\tlet dsn: string | undefined;\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"errors\", `ensureProject ${config.name}`, dryRun, async () => {\n\t\t\t\t\tconst result = await errors.ensureProject!({ name: config.name });\n\t\t\t\t\tdsn = result.dsn;\n\t\t\t\t\treturn `project ${result.alreadyExists ? \"exists\" : \"created\"}`;\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\n\t\t\tif (dsn && loader.has(\"secrets\")) {\n\t\t\t\tconst secrets = loader.get(\"secrets\") as Secrets;\n\t\t\t\tconst { envKeys } = await errors.describe();\n\t\t\t\tfor (const key of envKeys) {\n\t\t\t\t\tsteps.push(\n\t\t\t\t\t\tawait runStep(\"errors\", `secrets set ${key}`, dryRun, async () => {\n\t\t\t\t\t\t\tawait secrets.setSecret({ kind: \"repo\" }, key, dsn!);\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── logs: provision the aggregation datasets ───────────────────────\n\tif (loader.has(\"logs\")) {\n\t\tconst logs = loader.get(\"logs\") as Logs;\n\t\tprint(style.step(\"logs\"));\n\n\t\tif (logs.ensureDataset) {\n\t\t\tfor (const dataset of [\"holocron-ci\", \"holocron-local\"]) {\n\t\t\t\tsteps.push(\n\t\t\t\t\tawait runStep(\"logs\", `ensureDataset ${dataset}`, dryRun, async () => {\n\t\t\t\t\t\tconst result = await logs.ensureDataset!(dataset);\n\t\t\t\t\t\treturn `${dataset} ${result.alreadyExists ? \"exists\" : \"created\"}`;\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── tooling: sync each (many cardinality) ───────────────────────────\n\tif (loader.has(\"tooling\")) {\n\t\tconst tools = loader.get(\"tooling\") as Tooling[];\n\t\tprint(style.step(\"tooling\"));\n\t\tfor (const tool of tools) {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"tooling\", `${tool.providerName}.sync`, dryRun, async () => {\n\t\t\t\t\tawait tool.sync();\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\t}\n\n\t// ── skills: install agent skills from registry ──────────────────────\n\tif (config.skills && config.skills.length > 0 && config.agent) {\n\t\tprint(style.step(\"skills\"));\n\t\tif (!(config.agent in AGENT_SYMLINK_PATHS)) {\n\t\t\tsteps.push({\n\t\t\t\tcapability: \"skills\",\n\t\t\t\tstep: \"install skills\",\n\t\t\t\tstatus: \"skip\",\n\t\t\t\tmessage: `agent \"${config.agent}\" has no known skill install path`,\n\t\t\t});\n\t\t} else {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"skills\", \"install skills\", dryRun, async () => {\n\t\t\t\t\treturn await installSkills({\n\t\t\t\t\t\tagent: config.agent!,\n\t\t\t\t\t\tskills: config.skills!,\n\t\t\t\t\t\trepoRoot: input.context.repoRoot,\n\t\t\t\t\t});\n\t\t\t\t})\n\t\t\t);\n\t\t}\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t}\n\n\t// ── prompts: write agent role prompts to .agents/prompts/ ────────────\n\tif (config.agent) {\n\t\tprint(style.step(\"prompts\"));\n\t\tsteps.push(\n\t\t\tawait runStep(\"prompts\", \"install agent prompts\", dryRun, async () => {\n\t\t\t\treturn await installAgentPrompts({ repoRoot: input.context.repoRoot });\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t}\n\n\t// ── engineering: provision docs/decisions/ and docs/engineering/ ─────\n\tif (config.docs) {\n\t\tprint(style.step(\"engineering\"));\n\t\tsteps.push(\n\t\t\tawait runStep(\"engineering\", \"provision engineering structure\", dryRun, async () => {\n\t\t\t\treturn await installEngineeringStructure({ repoRoot: input.context.repoRoot });\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t}\n\n\tconst summary = steps.reduce(\n\t\t(acc, s) => {\n\t\t\tif (s.status === \"ok\") acc.ok += 1;\n\t\t\telse if (s.status === \"fail\") acc.fail += 1;\n\t\t\telse if (s.status === \"skip\") acc.skip += 1;\n\t\t\telse if (s.status === \"dry-run\") acc.dryRun += 1;\n\t\t\treturn acc;\n\t\t},\n\t\t{ ok: 0, fail: 0, skip: 0, dryRun: 0 }\n\t);\n\n\tprint(\"\");\n\tconst summaryLine = ` ${summary.ok} ok, ${summary.fail} fail, ${summary.skip} skipped${\n\t\tdryRun ? `, ${summary.dryRun} would-do` : \"\"\n\t}`;\n\tprint(summary.fail > 0 ? style.fail(summaryLine.trim()) : style.success(summaryLine.trim()));\n\n\tconst skippedSteps = steps.filter((s) => s.status === \"skip\");\n\tif (skippedSteps.length > 0) {\n\t\tprint(\"\");\n\t\tprint(style.hint(\" Skipped:\"));\n\t\tfor (const s of skippedSteps) {\n\t\t\t/* v8 ignore next -- all skip steps set message; empty fallback is defensive */\n\t\t\tprint(style.hint(` · ${s.step}${s.message ? ` (${s.message})` : \"\"}`));\n\t\t}\n\t}\n\n\tif (steps.some((s) => s.reason === \"permissions\")) {\n\t\tprint(\"\");\n\t\tprint(style.warn(\"Some steps failed with 403 (insufficient token permissions).\"));\n\t\tprint(style.hint(\" Repo-scoped operations (rulesets, settings, workflows) require a\"));\n\t\tprint(style.hint(\" fine-grained PAT passed via --token or HOLOCRON_ADMIN_TOKEN:\"));\n\t\tprint(\"\");\n\t\tprint(style.hint(\" · Administration — read and write\"));\n\t\tprint(style.hint(\" · Code scanning alerts — read and write\"));\n\t\tprint(style.hint(\" · Contents — read and write\"));\n\t\tprint(style.hint(\" · Secret scanning alerts — read and write\"));\n\t\tprint(style.hint(\" · Workflows — read and write\"));\n\t\tprint(style.hint(\" · Metadata — read (added automatically)\"));\n\t\tprint(\"\");\n\t\tprint(style.hint(\" Org-scoped operations (teams, custom properties) require\"));\n\t\tprint(style.hint(\" HOLOCRON_ORG_TOKEN — a fine-grained PAT with resource owner set to the org:\"));\n\t\tprint(\"\");\n\t\tprint(style.hint(\" · Administration — read and write (repository permission)\"));\n\t\tprint(style.hint(\" · Members — read (organization permission)\"));\n\t\tprint(style.hint(\" · Organization custom properties — read and write (organization permission)\"));\n\t\tprint(style.hint(\" · Metadata — read (repository permission, auto-included)\"));\n\t\tprint(\"\");\n\t\tprint(style.hint(\" Create tokens at: https://github.com/settings/personal-access-tokens/new\"));\n\t\tprint(style.hint(\" Then re-run: holocron setup --token <your-admin-pat>\"));\n\t\tprint(style.hint(\" Store org token: HOLOCRON_ORG_TOKEN env var or keyring key github.org\"));\n\t}\n\n\treturn { steps, summary };\n}\n\n/**\n * Ensure `package.json#scripts.prepare` runs `husky` so git hooks register on\n * install. Merge-only: an existing `prepare` that does more than husky (e.g.\n * `turbo run build` — needed where root config files import a workspace\n * package's `dist/`, theholocron/holocron#654) is preserved and husky is\n * appended. Leaves every other script untouched. Returns `true` when it wrote\n * a change, `false` when already runs husky or there is no `package.json`.\n */\nasync function ensurePrepareScript(repoRoot: string): Promise<boolean> {\n\tconst pkgPath = join(repoRoot, \"package.json\");\n\tlet content: string;\n\ttry {\n\t\tcontent = await readFile(pkgPath, \"utf8\");\n\t} catch {\n\t\treturn false;\n\t}\n\tconst pkg = JSON.parse(content) as { scripts?: Record<string, string> };\n\tconst scripts = pkg.scripts ?? {};\n\tconst current = scripts.prepare?.trim() ?? \"\";\n\t// Already invokes husky (bare, or as a step in a chain) → nothing to do.\n\tif (/(^|[\\s&|;])husky($|[\\s&|;])/.test(current)) return false;\n\tscripts.prepare = current ? `${current} && husky` : \"husky\";\n\tpkg.scripts = scripts;\n\tawait writeFile(pkgPath, JSON.stringify(pkg, null, 2) + \"\\n\", \"utf8\");\n\treturn true;\n}\n","/**\n * `holocron skills` — install, remove, and update agent skills from @theholocron/skills.\n *\n * Unlike `holocron setup`, this command is purely local (no GitHub token\n * required). It reads `agent` and `skills` from the config and installs\n * the listed skills into `.agents/skills/<name>/` with a symlink at the\n * agent-specific path (e.g. `.claude/skills/<name>` for Claude Code).\n *\n * `holocron skills remove [name]` and `holocron skills update [name]` delegate\n * to the corresponding `npx skills` subcommands from the upstream skills CLI.\n */\n\nimport { spawnSync } from \"node:child_process\";\n\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport type { LoadedConfig } from \"../config/load-config.js\";\nimport { getLogger } from \"../logger.js\";\nimport type { RuntimeContext } from \"../plugin/loader.js\";\nimport { installSkills } from \"./setup/index.js\";\n\n// ── shared exec ──────────────────────────────────────────────────────────────\n\ntype ExecFn = (cmd: string, args: string[], opts: { cwd: string }) => { exitCode: number };\n\nconst defaultExec: ExecFn = (cmd, args, opts) => {\n\tconst result = spawnSync(cmd, args, { cwd: opts.cwd, stdio: \"inherit\" });\n\treturn { exitCode: result.status ?? -1 };\n};\n\n// ── install ──────────────────────────────────────────────────────────────────\n\nexport interface RunSkillsInput {\n\tloaded: LoadedConfig;\n\tcontext: RuntimeContext;\n\tprint?: (line: string) => void;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n}\n\nexport async function runSkillsInstall(input: RunSkillsInput): Promise<void> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst config = input.loaded.resolved;\n\n\tif (!config.agent || !config.skills?.length) {\n\t\tprint(\"Nothing to install — set `agent` and `skills` in holocron.config.ts\");\n\t\tlogger.info({ status: \"skip\", reason: \"no agent/skills configured\" }, \"skills install: done\");\n\t\treturn;\n\t}\n\n\tif (input.context.dryRun) {\n\t\tprint(`Would install ${config.skills.length} skill(s) for agent: ${config.agent}`);\n\t\tfor (const name of config.skills) {\n\t\t\tprint(` → would install: ${name}`);\n\t\t}\n\t\tlogger.info({ agent: config.agent, skills: config.skills, status: \"dry-run\" }, \"skills install: done\");\n\t\treturn;\n\t}\n\n\tprint(`Installing ${config.skills.length} skill(s) for agent: ${config.agent}`);\n\tlogger.info({ agent: config.agent, count: config.skills.length }, \"skills install: start\");\n\ttry {\n\t\tconst result = await installSkills({\n\t\t\tagent: config.agent,\n\t\t\tskills: config.skills,\n\t\t\trepoRoot: input.context.repoRoot,\n\t\t});\n\t\tprint(` → ${result}`);\n\t\tlogger.info({ agent: config.agent, skills: config.skills, status: \"ok\" }, \"skills install: done\");\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tprint(` ✗ ${message}`);\n\t\tlogger.warn({ agent: config.agent, reason: message, status: \"fail\" }, \"skills install: done\");\n\t}\n}\n\n// ── remove ───────────────────────────────────────────────────────────────────\n\nexport interface RunSkillsRemoveInput {\n\tcontext: RuntimeContext;\n\t/** Skill name(s) to remove. Omit to remove all installed skills. */\n\tnames?: string[];\n\texec?: ExecFn;\n\tlogger?: Logger;\n}\n\nexport interface SkillsRemoveReport {\n\tstatus: \"ok\" | \"fail\" | \"dry-run\";\n}\n\nexport function runSkillsRemove(input: RunSkillsRemoveInput): SkillsRemoveReport {\n\tconst { dryRun, repoRoot } = input.context;\n\tconst exec = input.exec ?? defaultExec;\n\tconst logger = input.logger ?? getLogger();\n\tconst args = [\"skills\", \"remove\", ...(input.names ?? [])];\n\n\tif (dryRun) {\n\t\tlogger.info({ argv: args }, `Would run: npx ${args.join(\" \")}`);\n\t\treturn { status: \"dry-run\" };\n\t}\n\n\tconst { exitCode } = exec(\"npx\", args, { cwd: repoRoot });\n\treturn { status: exitCode === 0 ? \"ok\" : \"fail\" };\n}\n\n// ── update ───────────────────────────────────────────────────────────────────\n\nexport interface RunSkillsUpdateInput {\n\tcontext: RuntimeContext;\n\t/** When given, update only this skill. Omit to update all. */\n\tname?: string;\n\texec?: ExecFn;\n\tlogger?: Logger;\n}\n\nexport interface SkillsUpdateReport {\n\tstatus: \"ok\" | \"fail\" | \"dry-run\";\n}\n\nexport function runSkillsUpdate(input: RunSkillsUpdateInput): SkillsUpdateReport {\n\tconst { dryRun, repoRoot } = input.context;\n\tconst exec = input.exec ?? defaultExec;\n\tconst logger = input.logger ?? getLogger();\n\tconst args = [\"skills\", \"update\", ...(input.name ? [input.name] : [])];\n\n\tif (dryRun) {\n\t\tlogger.info({ argv: args }, `Would run: npx ${args.join(\" \")}`);\n\t\treturn { status: \"dry-run\" };\n\t}\n\n\tconst { exitCode } = exec(\"npx\", args, { cwd: repoRoot });\n\treturn { status: exitCode === 0 ? \"ok\" : \"fail\" };\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport type { PackagesRegistry } from \"@theholocron/components-doc/markdown\";\nimport { generateReadme } from \"@theholocron/components-doc/markdown\";\nimport type { Logger } from \"@theholocron/observability/core\";\nimport { getClients, getConfigs, getDocs, getPlugins, getSkills, getThemes, getUtils } from \"@theholocron/registry-doc\";\n\nimport type { LoadedConfig } from \"../config/load-config.js\";\nimport { getLogger } from \"../logger.js\";\nimport type { RuntimeContext } from \"../plugin/loader.js\";\nimport { style } from \"../ui/style.js\";\n\nconst MARKER_INSTALL_START = \"<!-- holocron:installation -->\";\nconst MARKER_INSTALL_END = \"<!-- /holocron:installation -->\";\n\nconst REGISTRY_MAP: Record<string, () => PackagesRegistry> = {\n\t\"@theholocron/clients\": getClients,\n\t\"@theholocron/configs\": getConfigs,\n\t\"@theholocron/docs\": getDocs,\n\t\"@theholocron/holocron\": getPlugins,\n\t\"@theholocron/skills\": getSkills,\n\t\"@theholocron/themes\": getThemes,\n\t\"@theholocron/utils\": getUtils,\n};\n\ninterface PackageJson {\n\tname?: string;\n\thomepage?: string;\n\tprivate?: boolean;\n\tmain?: string;\n\texports?: unknown;\n\tbin?: Record<string, string> | string;\n\tpeerDependencies?: Record<string, string>;\n\tscripts?: Record<string, string>;\n\tworkspaces?: string[];\n}\n\nexport interface RunSyncReadmeInput {\n\tloaded: LoadedConfig;\n\tcontext: RuntimeContext;\n\tprint?: (line: string) => void;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n\treadFileFn?: (path: string, encoding: BufferEncoding) => Promise<string>;\n\twriteFileFn?: (path: string, content: string, encoding: BufferEncoding) => Promise<void>;\n}\n\nexport interface SyncReadmeReport {\n\tstatus: \"ok\" | \"fail\" | \"dry-run\";\n\tupdated: boolean;\n\tmessage?: string;\n}\n\nfunction generateInstallBlock(pkg: PackageJson, homepage = \"\"): string {\n\tconst { name = \"\", bin, peerDependencies = {} } = pkg;\n\tconst isCli = Boolean(bin);\n\tconst isReact = Boolean(peerDependencies[\"react\"]);\n\t// A private package with no bin and nothing importable (no `main`, no\n\t// `exports`) is a workspace root or template — not something to `pnpm\n\t// install` or `import` from.\n\tconst isConsumable = isCli || !pkg.private || Boolean(pkg.main) || pkg.exports !== undefined;\n\tconst lines: string[] = [];\n\n\tlines.push(\"## Installation\", \"\");\n\n\tif (!isConsumable) {\n\t\tlines.push(\n\t\t\t\"This repository is a workspace root — it is not published. See the\",\n\t\t\t\"packages under [`packages/`](./packages) for the tools it ships.\"\n\t\t);\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\tif (isCli) {\n\t\tlines.push(\"```bash\", `npm install --global ${name}`, \"```\");\n\t} else {\n\t\tlines.push(\"```bash\", `pnpm install ${name}`, \"```\");\n\t}\n\n\tlines.push(\"\", \"## Usage\", \"\");\n\n\tif (isCli) {\n\t\tconst commands =\n\t\t\ttypeof bin === \"string\" ? [name.split(\"/\").at(-1)!] : Object.keys(bin as Record<string, string>);\n\t\tlines.push(\"```bash\");\n\t\tfor (const cmd of commands) {\n\t\t\tlines.push(`${cmd} --help`);\n\t\t}\n\t\tlines.push(\"```\");\n\t} else if (isReact) {\n\t\tlines.push(\"```tsx\", `import {} from \"${name}\";`, \"\", \"function App() {\", ` return <></>;`, \"}\", \"```\");\n\t} else if (homepage) {\n\t\t// Exports aren't known at sync time — link the docs rather than emit a\n\t\t// meaningless empty-brace import.\n\t\tlines.push(`See the [documentation](${homepage}) for the API.`);\n\t} else {\n\t\tlines.push(\"See the package documentation for the API.\");\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\n/**\n * Replace content between `<!-- holocron:marker -->` / `<!-- /holocron:marker -->` tags.\n * Returns the updated README string, or the original if the marker pair is absent.\n */\nfunction replaceMarkerBlock(readme: string, marker: string, content: string): string {\n\tconst start = `<!-- holocron:${marker} -->`;\n\tconst end = `<!-- /holocron:${marker} -->`;\n\tconst lines = readme.split(\"\\n\");\n\tconst startIdx = lines.findIndex((l) => l.trim() === start);\n\tconst endIdx = lines.findIndex((l) => l.trim() === end);\n\tif (startIdx === -1 || endIdx === -1 || endIdx <= startIdx) return readme;\n\tlines.splice(startIdx + 1, endIdx - startIdx - 1, \"\", ...content.split(\"\\n\"), \"\");\n\treturn lines.join(\"\\n\");\n}\n\n/**\n * Apply all README updates in a single read-write cycle.\n * Returns true if the README was found (even if no changes were needed).\n */\nasync function updateReadme(\n\trepoRoot: string,\n\tinstallBlock: string,\n\tsections: Record<string, string>,\n\tdryRun: boolean,\n\treadFileFn: (path: string, encoding: BufferEncoding) => Promise<string>,\n\twriteFileFn: (path: string, content: string, encoding: BufferEncoding) => Promise<void>\n): Promise<boolean> {\n\tconst readmePath = join(repoRoot, \"README.md\");\n\tlet content: string;\n\ttry {\n\t\tcontent = await readFileFn(readmePath, \"utf8\");\n\t} catch {\n\t\treturn false;\n\t}\n\n\tlet updated = content;\n\n\t// Replace existing marker blocks for generated sections\n\tfor (const [marker, text] of Object.entries(sections)) {\n\t\tupdated = replaceMarkerBlock(updated, marker, text);\n\t}\n\n\t// Replace or insert installation block\n\tconst lines = updated.split(\"\\n\");\n\tconst startIdx = lines.findIndex((l) => l.trim() === MARKER_INSTALL_START);\n\tconst endIdx = lines.findIndex((l) => l.trim() === MARKER_INSTALL_END);\n\tconst blockLines = installBlock.split(\"\\n\");\n\n\tif (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {\n\t\tlines.splice(startIdx + 1, endIdx - startIdx - 1, \"\", ...blockLines, \"\");\n\t\tupdated = lines.join(\"\\n\");\n\t} else {\n\t\tconst descEnd = lines.findIndex((l) => l.trim() === \"<!-- /holocron:description -->\");\n\t\tconst insertAfter = descEnd !== -1 ? descEnd : lines.findIndex((l) => /^# /.test(l));\n\t\tif (insertAfter === -1) return false;\n\t\tlines.splice(insertAfter + 1, 0, \"\", MARKER_INSTALL_START, \"\", ...blockLines, \"\", MARKER_INSTALL_END);\n\t\tupdated = lines.join(\"\\n\");\n\t}\n\n\tif (!dryRun) {\n\t\tawait writeFileFn(readmePath, updated, \"utf8\");\n\t}\n\treturn true;\n}\n\nasync function updateIndexMdxDescription(\n\trepoRoot: string,\n\tdescription: string,\n\tdryRun: boolean,\n\treadFileFn: (path: string, encoding: BufferEncoding) => Promise<string>,\n\twriteFileFn: (path: string, content: string, encoding: BufferEncoding) => Promise<void>\n): Promise<void> {\n\tconst mdxPath = join(repoRoot, \"docs\", \"src\", \"content\", \"docs\", \"index.mdx\");\n\tlet content: string;\n\ttry {\n\t\tcontent = await readFileFn(mdxPath, \"utf8\");\n\t} catch {\n\t\treturn; // file doesn't exist — skip silently\n\t}\n\tconst updated = content.replace(/^(description:\\s*).*$/m, `$1${description}`);\n\tif (updated !== content && !dryRun) {\n\t\tawait writeFileFn(mdxPath, updated, \"utf8\");\n\t}\n}\n\nexport async function runSyncReadme(input: RunSyncReadmeInput): Promise<SyncReadmeReport> {\n\tconst { loaded, context, print = console.log, readFileFn = readFile, writeFileFn = writeFile } = input;\n\tconst logger = input.logger ?? getLogger();\n\n\tconst { repoRoot, dryRun = false } = context;\n\n\tconst namespaces = loaded.resolved.env?.namespaces ?? [];\n\n\tprint(style.header(`Syncing README installation block${dryRun ? \" (dry-run)\" : \"\"}…`));\n\tif (namespaces.length > 0) {\n\t\tprint(style.hint(` namespaces: ${namespaces.join(\", \")}`));\n\t}\n\n\t// Read package.json\n\tlet pkg: PackageJson;\n\ttry {\n\t\tconst raw = await readFileFn(join(repoRoot, \"package.json\"), \"utf8\");\n\t\tpkg = JSON.parse(raw) as PackageJson;\n\t} catch {\n\t\tlogger.warn({ repoRoot, reason: \"could not read package.json\" }, \"sync readme: done\");\n\t\treturn { status: \"fail\", updated: false, message: \"Could not read package.json\" };\n\t}\n\n\t// Assemble generated sections (4.3)\n\tconst description = loaded.resolved.description ?? \"\";\n\tconst homepage = loaded.resolved.homepage ?? pkg.homepage ?? \"\";\n\tconst scripts = pkg.scripts ?? {};\n\tconst packages = pkg.name ? REGISTRY_MAP[pkg.name]?.() : undefined;\n\n\tconst sections = generateReadme({ description, homepage, scripts, packages });\n\tconst markerSections: Record<string, string> = {\n\t\t...(sections.packages !== undefined && { packages: sections.packages }),\n\t\tdevelopment: sections.development,\n\t\treleases: sections.releases,\n\t};\n\n\t// Single read-write pass for all README changes\n\tconst installBlock = generateInstallBlock(pkg, homepage);\n\tconst updated = await updateReadme(repoRoot, installBlock, markerSections, dryRun, readFileFn, writeFileFn);\n\n\tif (!updated) {\n\t\tprint(style.warn(\"README.md not found or has no writable location for installation block\"));\n\t\tlogger.warn({ repoRoot, reason: \"README.md not found / no marker block\" }, \"sync readme: done\");\n\t\treturn { status: \"fail\", updated: false, message: \"README.md update failed\" };\n\t}\n\n\t// Update docs/src/content/docs/index.mdx frontmatter description (4.4)\n\tif (description) {\n\t\tawait updateIndexMdxDescription(repoRoot, description, dryRun, readFileFn, writeFileFn);\n\t}\n\n\tprint(dryRun ? style.hint(\" would update README.md\") : style.success(\" updated README.md\"));\n\tconst status = dryRun ? \"dry-run\" : \"ok\";\n\tlogger.info({ repoRoot, status, updated }, \"sync readme: done\");\n\treturn { status, updated };\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { createRestClient } from \"@theholocron/http-client\";\n\nimport type { LoadedConfig } from \"../config/load-config.js\";\nimport type { RuntimeContext } from \"../plugin/loader.js\";\nimport type { SetupStepResult } from \"./setup/index.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface WikiRepo {\n\tdisplayName: string;\n\tbasepath: string;\n\t/** Full custom domain with basepath, e.g. \"wiki.theholocron.dev/skills\". */\n\tdomain?: string;\n}\n\nexport interface RunSyncWikiInput {\n\tloaded: LoadedConfig;\n\tcontext: RuntimeContext;\n\ttoken?: string;\n\tfetch?: typeof globalThis.fetch;\n}\n\n// ---------------------------------------------------------------------------\n// Token resolution\n// ---------------------------------------------------------------------------\n\nfunction resolveToken(input: RunSyncWikiInput): string | undefined {\n\treturn (\n\t\tinput.token ??\n\t\tinput.context.cliToken ??\n\t\tprocess.env.HOLOCRON_READ_TOKEN ??\n\t\tprocess.env.GH_TOKEN ??\n\t\tprocess.env.GITHUB_TOKEN\n\t);\n}\n\n// ---------------------------------------------------------------------------\n// Config parsing helpers\n// ---------------------------------------------------------------------------\n\nfunction deriveBasepath(domain: string | undefined, repoName: string): string {\n\tif (domain) {\n\t\tconst slashIdx = domain.indexOf(\"/\");\n\t\tif (slashIdx !== -1) return domain.slice(slashIdx + 1);\n\t}\n\treturn repoName;\n}\n\nfunction toNavLabel(basepath: string): string {\n\treturn basepath\n\t\t.split(\"-\")\n\t\t.map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n\t\t.join(\" \");\n}\n\ninterface OrgRepo {\n\tname: string;\n\tfull_name: string;\n\tarchived: boolean;\n}\n\ninterface FileContents {\n\tcontent: string;\n\tencoding: string;\n}\n\nfunction extractFromJson(raw: string, repoName: string): WikiRepo | null {\n\tlet config: Record<string, unknown>;\n\ttry {\n\t\tconfig = JSON.parse(raw) as Record<string, unknown>;\n\t} catch {\n\t\treturn null;\n\t}\n\tconst providers = config.providers as Record<string, unknown> | undefined;\n\tif (!providers?.wiki) return null;\n\n\tconst wikiEntry = providers.wiki;\n\tlet domain: string | undefined;\n\n\tif (Array.isArray(wikiEntry) && wikiEntry.length === 2) {\n\t\tconst opts = wikiEntry[1] as Record<string, unknown>;\n\t\tdomain = typeof opts.domain === \"string\" ? opts.domain : undefined;\n\t}\n\n\tconst basepath = deriveBasepath(domain, repoName);\n\treturn { displayName: toNavLabel(basepath), basepath, ...(domain ? { domain } : {}) };\n}\n\nfunction extractFromTs(raw: string, repoName: string): WikiRepo | null {\n\tconst hasWikiProvider = /providers\\s*:\\s*\\{[^}]*\\bwiki\\b/s.test(raw);\n\tconst hasWikiPreset = /\\bwikiCapability\\b|\\bwiki\\s*\\(\\s*\\)/.test(raw);\n\t/* c8 ignore next */\n\tif (!hasWikiProvider && !hasWikiPreset) return null;\n\n\tconst domainMatch = raw.match(/\\bdomain\\s*:\\s*[\"']([^\"']+)[\"']/);\n\tconst domain = domainMatch?.[1];\n\n\tconst basepath = deriveBasepath(domain, repoName);\n\treturn { displayName: toNavLabel(basepath), basepath, ...(domain ? { domain } : {}) };\n}\n\n// ---------------------------------------------------------------------------\n// Discovery\n// ---------------------------------------------------------------------------\n\nexport async function discoverWikiRepos(\n\torg: string,\n\ttoken: string,\n\tfetchFn?: typeof globalThis.fetch\n): Promise<WikiRepo[]> {\n\tconst rest = createRestClient({\n\t\tbaseUrl: \"https://api.github.com\",\n\t\ttoken,\n\t\textraHeaders: {\n\t\t\taccept: \"application/vnd.github+json\",\n\t\t\t\"x-github-api-version\": \"2022-11-28\",\n\t\t},\n\t\tvendor: \"GitHub\",\n\t\tfetch: fetchFn,\n\t});\n\n\tconst allRepos: OrgRepo[] = [];\n\tlet page = 1;\n\twhile (true) {\n\t\tconst batch = await rest.request<OrgRepo[]>(`/orgs/${org}/repos`, {\n\t\t\tquery: { per_page: \"100\", page: String(page), type: \"all\" },\n\t\t});\n\t\tallRepos.push(...batch);\n\t\tif (batch.length < 100) break;\n\t\tpage++;\n\t}\n\n\tconst repos: WikiRepo[] = [];\n\n\tfor (const repo of allRepos.filter((r) => !r.archived)) {\n\t\tlet found: WikiRepo | null = null;\n\n\t\ttry {\n\t\t\tconst contents = await rest.request<FileContents>(`/repos/${repo.full_name}/contents/holocron.config.json`);\n\t\t\tif (contents.encoding === \"base64\") {\n\t\t\t\tconst raw = Buffer.from(contents.content.replace(/\\s/g, \"\"), \"base64\").toString(\"utf8\");\n\t\t\t\tfound = extractFromJson(raw, repo.name);\n\t\t\t}\n\t\t} catch {\n\t\t\t// no JSON config — try TS\n\t\t}\n\n\t\tif (!found) {\n\t\t\ttry {\n\t\t\t\tconst contents = await rest.request<FileContents>(\n\t\t\t\t\t`/repos/${repo.full_name}/contents/holocron.config.ts`\n\t\t\t\t);\n\t\t\t\tif (contents.encoding === \"base64\") {\n\t\t\t\t\tconst raw = Buffer.from(contents.content.replace(/\\s/g, \"\"), \"base64\").toString(\"utf8\");\n\t\t\t\t\tfound = extractFromTs(raw, repo.name);\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// no config found — skip\n\t\t\t}\n\t\t}\n\n\t\tif (found) repos.push(found);\n\t}\n\n\trepos.sort((a, b) => a.basepath.localeCompare(b.basepath));\n\treturn repos;\n}\n\n// ---------------------------------------------------------------------------\n// navbar-links block builder\n// ---------------------------------------------------------------------------\n\n/**\n * Builds the complete navbar-links YAML block for a given repo.\n *\n * Includes:\n * - A GitHub button linking to the repo itself (always first)\n * - A single \"Wiki\" dropdown containing minimal links to every other\n * wiki-enabled repo (excluding self), keeping the navbar uncluttered\n * regardless of how many repos are in the org.\n *\n * The block is replaced wholesale on each sync so removed/added wikis\n * stay in sync automatically.\n */\nexport function buildNavbarLinks(repos: WikiRepo[], currentBasepath: string, repoFullName: string): string {\n\tconst lines = [`navbar-links:`, ` - type: github`, ` value: https://github.com/${repoFullName}`];\n\n\tconst others = repos.filter((r) => r.basepath !== currentBasepath);\n\tif (others.length > 0) {\n\t\tlines.push(` - type: dropdown`, ` text: Other Projects`, ` icon: fa-duotone fa-book`, ` links:`);\n\t\tfor (const repo of others) {\n\t\t\tconst url = repo.domain ? `https://${repo.domain}` : `https://wiki.theholocron.dev/${repo.basepath}`;\n\t\t\tlines.push(` - href: ${url}`, ` text: ${repo.displayName}`);\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// fern/docs.yml updater\n// ---------------------------------------------------------------------------\n\n/**\n * Idempotently ensures `edit-this-page:` (inside instances) is present and\n * replaces `navbar-links:` with the provided shared block.\n *\n * Returns true when the file was modified.\n * Throws when fern/docs.yml does not exist.\n */\nexport async function mergeWikiConfig(\n\tdocsYmlPath: string,\n\tconfig: { owner: string; repoName: string; navbarBlock: string }\n): Promise<boolean> {\n\tlet content: string;\n\ttry {\n\t\tcontent = await readFile(docsYmlPath, \"utf8\");\n\t} catch {\n\t\tthrow new Error(`fern/docs.yml not found at ${docsYmlPath}`);\n\t}\n\n\tlet updated = content;\n\n\t// 1. Ensure edit-this-page: is nested inside the instances block entry.\n\tif (!updated.includes(\"edit-this-page:\")) {\n\t\tconst editBlock = [\n\t\t\t` edit-this-page:`,\n\t\t\t` github:`,\n\t\t\t` owner: ${config.owner}`,\n\t\t\t` repo: ${config.repoName}`,\n\t\t\t` branch: main`,\n\t\t].join(\"\\n\");\n\n\t\tif (/^ {4}multi-source: true$/m.test(updated)) {\n\t\t\tupdated = updated.replace(/^( {4}multi-source: true)$/m, `$1\\n${editBlock}`);\n\t\t} else if (/^ {4}custom-domain: .+$/m.test(updated)) {\n\t\t\tupdated = updated.replace(/^( {4}custom-domain: .+)$/m, `$1\\n${editBlock}`);\n\t\t} else {\n\t\t\t// Fallback: insert after the \" - url:\" list item line\n\t\t\tupdated = updated.replace(/^( {2}- url: .+)$/m, `$1\\n${editBlock}`);\n\t\t}\n\t}\n\n\t// 2. Replace navbar-links: wholesale so removed/added wikis stay in sync.\n\tconst navbarRe = /^navbar-links:(?:\\n[ \\t][^\\n]*)*/m;\n\tif (navbarRe.test(updated)) {\n\t\tupdated = updated.replace(navbarRe, config.navbarBlock);\n\t} else if (/^colors:/m.test(updated)) {\n\t\tupdated = updated.replace(/^(colors:)/m, `${config.navbarBlock}\\n\\n$1`);\n\t} else {\n\t\tupdated = updated.trimEnd() + \"\\n\\n\" + config.navbarBlock + \"\\n\";\n\t}\n\n\tif (updated !== content) {\n\t\tawait writeFile(docsYmlPath, updated, \"utf8\");\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n// ---------------------------------------------------------------------------\n// Validate\n// ---------------------------------------------------------------------------\n\n/**\n * Checks that fern/docs.yml has the required wiki header fields.\n * Returns a list of missing field names; empty means valid.\n */\nexport async function validateWikiConfig(docsYmlPath: string): Promise<string[]> {\n\tlet content: string;\n\ttry {\n\t\tcontent = await readFile(docsYmlPath, \"utf8\");\n\t} catch {\n\t\treturn [\"fern/docs.yml not found\"];\n\t}\n\n\tconst missing: string[] = [];\n\tif (!content.includes(\"edit-this-page:\")) missing.push(\"edit-this-page\");\n\tif (!content.includes(\"navbar-links:\")) missing.push(\"navbar-links\");\n\treturn missing;\n}\n\n// ---------------------------------------------------------------------------\n// runSyncWiki\n// ---------------------------------------------------------------------------\n\nexport async function runSyncWiki(input: RunSyncWikiInput): Promise<SetupStepResult> {\n\tconst config = input.loaded.resolved;\n\tconst dryRun = input.context.dryRun ?? false;\n\n\tif (!config.providers.wiki) {\n\t\treturn { capability: \"local\", step: \"sync wiki\", status: \"skip\", message: \"no wiki provider configured\" };\n\t}\n\n\tconst rawRepo = input.context.repo ?? config.repo?.name;\n\tif (!rawRepo) {\n\t\treturn { capability: \"local\", step: \"sync wiki\", status: \"skip\", message: \"no repo configured\" };\n\t}\n\n\tconst [owner, repoName] = rawRepo.split(\"/\") as [string, string | undefined];\n\tif (!owner || !repoName) {\n\t\treturn {\n\t\t\tcapability: \"local\",\n\t\t\tstep: \"sync wiki\",\n\t\t\tstatus: \"skip\",\n\t\t\tmessage: \"repo must be owner/name format\",\n\t\t};\n\t}\n\n\tconst org = config.org ?? owner;\n\n\tconst token = resolveToken(input);\n\tif (!token) {\n\t\treturn {\n\t\t\tcapability: \"local\",\n\t\t\tstep: \"sync wiki\",\n\t\t\tstatus: \"skip\",\n\t\t\tmessage: \"no GitHub token available (set HOLOCRON_READ_TOKEN or GH_TOKEN)\",\n\t\t};\n\t}\n\n\tif (dryRun) {\n\t\treturn { capability: \"local\", step: \"sync wiki\", status: \"dry-run\" };\n\t}\n\n\tconst docsYmlPath = join(input.context.repoRoot, \"fern\", \"docs.yml\");\n\n\ttry {\n\t\tconst repos = await discoverWikiRepos(org, token, input.fetch);\n\n\t\t// Derive the current repo's basepath from its own wiki config so we\n\t\t// can exclude it from the nav links it renders for itself.\n\t\t// config.providers.wiki is already resolved to { tuple: { options } } form.\n\t\tconst wikiOpts = (config.providers.wiki as unknown as { tuple?: { options?: Record<string, unknown> } })?.tuple\n\t\t\t?.options;\n\t\tconst domain = typeof wikiOpts?.domain === \"string\" ? wikiOpts.domain : undefined;\n\t\tconst currentBasepath = deriveBasepath(domain, repoName);\n\n\t\tconst navbarBlock = buildNavbarLinks(repos, currentBasepath, rawRepo);\n\n\t\tconst changed = await mergeWikiConfig(docsYmlPath, { owner, repoName, navbarBlock });\n\t\treturn {\n\t\t\tcapability: \"local\",\n\t\t\tstep: \"sync wiki\",\n\t\t\tstatus: \"ok\",\n\t\t\tmessage: changed ? `updated (${repos.length} wiki repos discovered)` : \"already up to date\",\n\t\t};\n\t} catch (err) {\n\t\treturn {\n\t\t\tcapability: \"local\",\n\t\t\tstep: \"sync wiki\",\n\t\t\tstatus: \"fail\",\n\t\t\tmessage: err instanceof Error ? err.message : /* c8 ignore next */ String(err),\n\t\t};\n\t}\n}\n","import { access, mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { basename, join } from \"node:path\";\n\nimport { createAstromech, KNOWN_WORKFLOWS, readWorkspacePackages } from \"@theholocron/astromech\";\nimport type { TasksConfig } from \"@theholocron/astromech/config\";\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport type { LoadedConfig } from \"../config/load-config.js\";\nimport { getLogger } from \"../logger.js\";\nimport type { Source } from \"../plugin/capabilities.js\";\nimport { PluginLoader, type RuntimeContext } from \"../plugin/loader.js\";\nimport { createHeader } from \"../utils/create-header.js\";\nimport type { SetupPrintLine, SetupReport, SetupStepResult } from \"./setup/index.js\";\nimport {\n\tCANONICAL_LABELS,\n\tderiveCapabilities,\n\tderiveCompliance,\n\tderiveProfile,\n\tderiveStack,\n\treadWorkspacePackageJsons,\n\tSTALE_LABELS,\n} from \"./setup/index.js\";\n\n// The only content this file ever prefixes with workflowHeader() is thin-caller\n// workflow content from astromech.thinCallers() — sync.ts just writes it. The\n// actual template/generation logic a contributor would edit lives there.\nconst { workflowHeader } = createHeader({\n\tsource: \"packages/astromech/src/thin-callers.ts\",\n\ttool: \"holocron sync\",\n});\nimport { runSyncReadme } from \"./sync-readme.js\";\nimport { runSyncWiki } from \"./sync-wiki.js\";\n\nexport const SYNC_STEPS = [\n\t\"labels\",\n\t\"properties\",\n\t\"teams\",\n\t\"topics\",\n\t\"keywords\",\n\t\"description\",\n\t\"homepage\",\n\t\"readme\",\n\t\"workflows\",\n\t\"scripts\",\n\t\"turbo\",\n\t\"wiki\",\n] as const;\nexport type SyncStep = (typeof SYNC_STEPS)[number];\n\n// Steps that write to the local filesystem only — no provider token needed.\nconst LOCAL_STEPS = new Set<SyncStep>([\n\t\"keywords\",\n\t\"description\",\n\t\"homepage\",\n\t\"readme\",\n\t\"workflows\",\n\t\"scripts\",\n\t\"turbo\",\n\t\"wiki\",\n]);\n\nexport interface RunSyncInput {\n\tloaded: LoadedConfig;\n\tcontext: RuntimeContext;\n\tsteps?: string[];\n\tloader?: PluginLoader;\n\tprint?: SetupPrintLine;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n}\n\nexport async function runSync(input: RunSyncInput): Promise<SetupReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst loader = input.loader ?? new PluginLoader(input.loaded.resolved, input.context);\n\n\tconst config = input.loaded.resolved;\n\tconst dryRun = input.context.dryRun ?? false;\n\tconst requestedSteps = input.steps;\n\tconst steps: SetupStepResult[] = [];\n\n\tlogger.info({ config: config.name, steps: requestedSteps ?? \"all\", dryRun: dryRun || undefined }, \"sync: start\");\n\n\t// `load()` soft-skips any plugin it can't load (missing token, package\n\t// not installed). Remote steps then push a `skip` result when\n\t// `source` is absent; local steps (keywords, description, readme…)\n\t// write to disk regardless.\n\tawait loader.load();\n\tfor (const failure of loader.loadFailures()) {\n\t\tlogger.warn(\n\t\t\t{ capability: failure.key, provider: failure.provider, reason: failure.error.message },\n\t\t\t`sync: plugin ${failure.provider} unavailable`\n\t\t);\n\t}\n\n\tprint(`Holocron sync — ${config.name}${dryRun ? \" (dry-run)\" : \"\"}`);\n\tprint(` config: ${input.loaded.filepath}`);\n\tprint(\"\");\n\n\tif (loader.has(\"source\")) {\n\t\tconst source = loader.get(\"source\") as Source;\n\t\tprint(\" → source\");\n\n\t\tfor (const stepName of SYNC_STEPS) {\n\t\t\tif (requestedSteps !== undefined && !requestedSteps.includes(stepName)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// Local steps are handled below, outside this block.\n\t\t\tif (LOCAL_STEPS.has(stepName)) continue;\n\n\t\t\tif (stepName === \"labels\") {\n\t\t\t\tif (source.syncLabels) {\n\t\t\t\t\tsteps.push(\n\t\t\t\t\t\tawait runSyncStep(\"source\", \"sync labels\", dryRun, () =>\n\t\t\t\t\t\t\tsource.syncLabels!(CANONICAL_LABELS, STALE_LABELS)\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t} else {\n\t\t\t\t\tsteps.push({\n\t\t\t\t\t\tcapability: \"source\",\n\t\t\t\t\t\tstep: \"sync labels\",\n\t\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\t\tmessage: \"provider does not implement syncLabels\",\n\t\t\t\t\t});\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (stepName === \"properties\") {\n\t\t\t\tif (source.syncProperties) {\n\t\t\t\t\tconst repo = config.repo;\n\t\t\t\t\tconst properties: Record<string, string | string[]> = {};\n\t\t\t\t\tconst effectivePreset = repo?.protection;\n\t\t\t\t\tif (effectivePreset && effectivePreset !== \"none\")\n\t\t\t\t\t\tproperties[\"holocron_branch_protection_level\"] = effectivePreset;\n\t\t\t\t\tconst isMonorepo = await access(join(input.context.repoRoot, \"pnpm-workspace.yaml\"))\n\t\t\t\t\t\t.then(() => true)\n\t\t\t\t\t\t.catch(() => false);\n\t\t\t\t\tproperties[\"monorepo\"] = String(isMonorepo);\n\t\t\t\t\tconst manual = repo?.properties ?? {};\n\t\t\t\t\tif (manual.lifecycle) properties[\"lifecycle\"] = manual.lifecycle;\n\t\t\t\t\tif (manual.open_source !== undefined) properties[\"open_source\"] = String(manual.open_source);\n\t\t\t\t\tif (manual.runtime_environment) properties[\"runtime_environment\"] = manual.runtime_environment;\n\t\t\t\t\tif (manual.uses_external_packages !== undefined)\n\t\t\t\t\t\tproperties[\"uses_external_packages\"] = String(manual.uses_external_packages);\n\n\t\t\t\t\t// #677 — derived fields, distinct from the manual ones above: signal\n\t\t\t\t\t// that isn't an explicit holocron.config.ts field today (framework\n\t\t\t\t\t// choice, repo archetype, capability drift).\n\t\t\t\t\t{\n\t\t\t\t\t\tconst rootPackageJson = await readFile(join(input.context.repoRoot, \"package.json\"), \"utf8\")\n\t\t\t\t\t\t\t.then((raw) => JSON.parse(raw) as Parameters<typeof deriveStack>[0])\n\t\t\t\t\t\t\t.catch(() => null);\n\t\t\t\t\t\tconst workspacePackages = readWorkspacePackages(input.context.repoRoot);\n\t\t\t\t\t\tconst workspacePackageJsons = await readWorkspacePackageJsons(\n\t\t\t\t\t\t\tinput.context.repoRoot,\n\t\t\t\t\t\t\tworkspacePackages\n\t\t\t\t\t\t);\n\t\t\t\t\t\tproperties[\"holocron_profile\"] = deriveProfile({\n\t\t\t\t\t\t\trootPackageJson,\n\t\t\t\t\t\t\trepoName: basename(input.context.repoRoot),\n\t\t\t\t\t\t\tisMonorepo,\n\t\t\t\t\t\t\tworkspacePackageJsons,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tproperties[\"holocron_stack\"] = deriveStack(rootPackageJson);\n\t\t\t\t\t\tconst capabilities = deriveCapabilities(config.providers);\n\t\t\t\t\t\tproperties[\"holocron_capabilities\"] = capabilities;\n\t\t\t\t\t\tproperties[\"holocron_compliance\"] = deriveCompliance(capabilities);\n\t\t\t\t\t}\n\n\t\t\t\t\tsteps.push(\n\t\t\t\t\t\tawait runSyncStep(\"source\", \"sync properties\", dryRun, () => source.syncProperties!(properties))\n\t\t\t\t\t);\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t} else {\n\t\t\t\t\tsteps.push({\n\t\t\t\t\t\tcapability: \"source\",\n\t\t\t\t\t\tstep: \"sync properties\",\n\t\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\t\tmessage: \"provider does not implement syncProperties\",\n\t\t\t\t\t});\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (stepName === \"teams\") {\n\t\t\t\tconst teams = config.repo?.teams ?? [];\n\t\t\t\tif (teams.length === 0) {\n\t\t\t\t\tsteps.push({\n\t\t\t\t\t\tcapability: \"source\",\n\t\t\t\t\t\tstep: \"sync teams\",\n\t\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\t\tmessage: \"no teams configured\",\n\t\t\t\t\t});\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t} else if (source.syncTeams) {\n\t\t\t\t\tsteps.push(await runSyncStep(\"source\", \"sync teams\", dryRun, () => source.syncTeams!(teams)));\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\n\t\t\t\t\tconst repoCoord = input.context.repo ?? config.repo?.name ?? \"\";\n\t\t\t\t\tconst org = repoCoord.includes(\"/\") ? repoCoord.split(\"/\")[0]! : \"\";\n\t\t\t\t\tconst writeableTeams = teams\n\t\t\t\t\t\t.map((t) => (typeof t === \"string\" ? { slug: t, permission: \"push\" as const } : t))\n\t\t\t\t\t\t.filter((t) => [\"push\", \"maintain\", \"admin\"].includes(t.permission));\n\t\t\t\t\tif (org && writeableTeams.length > 0) {\n\t\t\t\t\t\tsteps.push(\n\t\t\t\t\t\t\tawait runSyncStep(\"source\", \"write .github/CODEOWNERS\", dryRun, async () => {\n\t\t\t\t\t\t\t\tconst content = writeableTeams.map((t) => `* @${org}/${t.slug}`).join(\"\\n\") + \"\\n\";\n\t\t\t\t\t\t\t\tawait source.writeRepoFile(\".github/CODEOWNERS\", content);\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t);\n\t\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tsteps.push({\n\t\t\t\t\t\tcapability: \"source\",\n\t\t\t\t\t\tstep: \"sync teams\",\n\t\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\t\tmessage: \"provider does not implement syncTeams\",\n\t\t\t\t\t});\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (stepName === \"topics\") {\n\t\t\t\tconst topics = config.repo?.topics ?? [];\n\t\t\t\tif (topics.length === 0) {\n\t\t\t\t\tsteps.push({\n\t\t\t\t\t\tcapability: \"source\",\n\t\t\t\t\t\tstep: \"sync topics\",\n\t\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\t\tmessage: \"no topics configured\",\n\t\t\t\t\t});\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t} else if (source.syncTopics) {\n\t\t\t\t\tsteps.push(await runSyncStep(\"source\", \"sync topics\", dryRun, () => source.syncTopics!(topics)));\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t} else {\n\t\t\t\t\tsteps.push({\n\t\t\t\t\t\tcapability: \"source\",\n\t\t\t\t\t\tstep: \"sync topics\",\n\t\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\t\tmessage: \"provider does not implement syncTopics\",\n\t\t\t\t\t});\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Report unknown step names\n\t\tif (requestedSteps) {\n\t\t\tfor (const name of requestedSteps) {\n\t\t\t\tif (!(SYNC_STEPS as ReadonlyArray<string>).includes(name)) {\n\t\t\t\t\tsteps.push({\n\t\t\t\t\t\tcapability: \"source\",\n\t\t\t\t\t\tstep: `sync ${name}`,\n\t\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\t\tmessage: `unknown step \"${name}\"`,\n\t\t\t\t\t});\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── local-only steps (no provider token required) ──────────────────\n\t// keywords, description, homepage, readme, and workflows write to local\n\t// files and optionally push to GitHub when source is loaded. They run\n\t// outside the `if (loader.has(\"source\"))` block so they work without a token.\n\n\tfor (const stepName of [\n\t\t\"keywords\",\n\t\t\"description\",\n\t\t\"homepage\",\n\t\t\"readme\",\n\t\t\"workflows\",\n\t\t\"scripts\",\n\t\t\"turbo\",\n\t\t\"wiki\",\n\t] as const) {\n\t\tif (requestedSteps !== undefined && !requestedSteps.includes(stepName)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (stepName === \"keywords\") {\n\t\t\tconst topics = config.repo?.topics ?? [];\n\t\t\tif (topics.length === 0) {\n\t\t\t\tsteps.push({\n\t\t\t\t\tcapability: \"local\",\n\t\t\t\t\tstep: \"sync keywords\",\n\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\tmessage: \"no topics configured\",\n\t\t\t\t});\n\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t} else {\n\t\t\t\tsteps.push(\n\t\t\t\t\tawait runSyncStep(\"local\", \"sync keywords\", dryRun, async () => {\n\t\t\t\t\t\tconst wrote = await writePackageJsonField(input.context.repoRoot, \"keywords\", topics);\n\t\t\t\t\t\treturn wrote\n\t\t\t\t\t\t\t? `${topics.length} keywords written`\n\t\t\t\t\t\t\t: `${topics.length} topics (no package.json)`;\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t}\n\t\t}\n\n\t\tif (stepName === \"description\") {\n\t\t\tconst description = config.description;\n\t\t\tif (!description) {\n\t\t\t\tsteps.push({\n\t\t\t\t\tcapability: \"local\",\n\t\t\t\t\tstep: \"sync description\",\n\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\tmessage: \"no description configured\",\n\t\t\t\t});\n\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t} else {\n\t\t\t\tconst source = loader.has(\"source\") ? (loader.get(\"source\") as Source) : null;\n\t\t\t\tsteps.push(\n\t\t\t\t\tawait runSyncStep(\"local\", \"sync description\", dryRun, async () => {\n\t\t\t\t\t\tconst pkgWrote = await writePackageJsonField(\n\t\t\t\t\t\t\tinput.context.repoRoot,\n\t\t\t\t\t\t\t\"description\",\n\t\t\t\t\t\t\tdescription\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst readmeWrote = await updateReadmeDescription(input.context.repoRoot, description);\n\t\t\t\t\t\tif (source?.syncDescription) {\n\t\t\t\t\t\t\tawait source.syncDescription(description);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst parts: string[] = [];\n\t\t\t\t\t\tif (pkgWrote) parts.push(\"package.json\");\n\t\t\t\t\t\tif (readmeWrote) parts.push(\"README.md\");\n\t\t\t\t\t\tif (source?.syncDescription) parts.push(\"GitHub\");\n\t\t\t\t\t\treturn parts.length > 0 ? parts.join(\", \") + \" updated\" : \"description synced\";\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t}\n\t\t}\n\n\t\tif (stepName === \"homepage\") {\n\t\t\tconst homepage = config.homepage;\n\t\t\tif (!homepage) {\n\t\t\t\tsteps.push({\n\t\t\t\t\tcapability: \"local\",\n\t\t\t\t\tstep: \"sync homepage\",\n\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\tmessage: \"no homepage configured\",\n\t\t\t\t});\n\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t} else {\n\t\t\t\tconst source = loader.has(\"source\") ? (loader.get(\"source\") as Source) : null;\n\t\t\t\tsteps.push(\n\t\t\t\t\tawait runSyncStep(\"local\", \"sync homepage\", dryRun, async () => {\n\t\t\t\t\t\tconst pkgWrote = await writePackageJsonField(input.context.repoRoot, \"homepage\", homepage);\n\t\t\t\t\t\tif (source?.syncHomepage) {\n\t\t\t\t\t\t\tawait source.syncHomepage(homepage);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst parts: string[] = [];\n\t\t\t\t\t\tif (pkgWrote) parts.push(\"package.json\");\n\t\t\t\t\t\tif (source?.syncHomepage) parts.push(\"GitHub\");\n\t\t\t\t\t\treturn parts.length > 0 ? parts.join(\", \") + \" updated\" : \"homepage synced\";\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t}\n\t\t}\n\n\t\tif (stepName === \"readme\") {\n\t\t\tconst report = await runSyncReadme({ loaded: input.loaded, context: input.context, print: () => {} });\n\t\t\tsteps.push({\n\t\t\t\tcapability: \"local\",\n\t\t\t\tstep: \"sync readme\",\n\t\t\t\tstatus: report.status === \"ok\" ? \"ok\" : report.status === \"dry-run\" ? \"dry-run\" : \"skip\",\n\t\t\t\t...(report.message ? { message: report.message } : {}),\n\t\t\t});\n\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t}\n\n\t\tif (stepName === \"workflows\") {\n\t\t\tconst taskEntries = config.tasks ?? [];\n\t\t\tif (taskEntries.length === 0) {\n\t\t\t\tsteps.push({\n\t\t\t\t\tcapability: \"local\",\n\t\t\t\t\tstep: \"sync workflows\",\n\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\tmessage: \"no tasks configured\",\n\t\t\t\t});\n\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t} else {\n\t\t\t\t// astromech renders every thin caller from the manifest (lint linter\n\t\t\t\t// set, deploy paths, deploy+preview). Iterate the manifest (not the\n\t\t\t\t// map) so step reporting keeps the config's order.\n\t\t\t\tconst files = createAstromech({\n\t\t\t\t\tcwd: input.context.repoRoot,\n\t\t\t\t\tconfig: { tasks: config.tasks as TasksConfig[\"tasks\"] },\n\t\t\t\t\torgContext: { org: config.org, domain: config.domain },\n\t\t\t\t\tlogger,\n\t\t\t\t}).thinCallers();\n\n\t\t\t\tfor (const entry of taskEntries) {\n\t\t\t\t\tconst name = typeof entry === \"string\" ? entry : entry.name;\n\t\t\t\t\t// knowledge.docs / knowledge.components have no static\n\t\t\t\t\t// WORKFLOW_TEMPLATES entry (their content is always\n\t\t\t\t\t// combined-generated, astromech.ts) — not in KNOWN_WORKFLOWS,\n\t\t\t\t\t// but not \"unknown\" either.\n\t\t\t\t\tconst isCombinedContentOnly = name === \"knowledge.docs\" || name === \"knowledge.components\";\n\n\t\t\t\t\tif (!KNOWN_WORKFLOWS.has(name) && !isCombinedContentOnly) {\n\t\t\t\t\t\tsteps.push({\n\t\t\t\t\t\t\tcapability: \"local\",\n\t\t\t\t\t\t\tstep: `sync workflow ${name}`,\n\t\t\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\t\t\tmessage: `unknown workflow \"${name}\" — no template available`,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\t// The combined-content family (delivery.deploy, knowledge.docs,\n\t\t\t\t\t// knowledge.components) all key their generated file by task\n\t\t\t\t\t// name already — no special-casing needed.\n\t\t\t\t\tconst filename = `${name}.yml`;\n\t\t\t\t\tconst content = files.get(filename);\n\t\t\t\t\tif (content === undefined) continue; // ci: false — nothing to write\n\n\t\t\t\t\tconst withPreview = content.includes(\"workflows/preview.yml@main\");\n\t\t\t\t\tconst step = `sync workflow ${name}${withPreview ? \" (with preview)\" : \"\"}`;\n\t\t\t\t\tsteps.push(\n\t\t\t\t\t\tawait runSyncStep(\"local\", step, dryRun, async () => {\n\t\t\t\t\t\t\tawait writeWorkflowFile(input.context.repoRoot, filename, `${workflowHeader()}${content}`);\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (stepName === \"scripts\") {\n\t\t\tif (config.syncScripts === false) {\n\t\t\t\tsteps.push({\n\t\t\t\t\tcapability: \"local\",\n\t\t\t\t\tstep: \"sync scripts\",\n\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\tmessage: \"syncScripts: false\",\n\t\t\t\t});\n\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t} else {\n\t\t\t\tconst tasksConfig: TasksConfig = { tasks: config.tasks as TasksConfig[\"tasks\"] };\n\t\t\t\tif (config.holocronScript !== undefined) tasksConfig.holocronScript = config.holocronScript;\n\t\t\t\tconst astromechScripts = createAstromech({\n\t\t\t\t\tcwd: input.context.repoRoot,\n\t\t\t\t\tconfig: tasksConfig,\n\t\t\t\t\tlogger,\n\t\t\t\t});\n\t\t\t\tconst desired = astromechScripts.packageScripts();\n\t\t\t\t// #747: which of `desired`'s keys turbo.json would fan out — the\n\t\t\t\t// only ones an existing direct-tool root script is ever protected\n\t\t\t\t// for. See mergePackageJsonScripts()'s own docstring.\n\t\t\t\tconst turboContent = astromechScripts.turboConfig();\n\t\t\t\tconst turboEligible = new Set<string>(\n\t\t\t\t\tturboContent\n\t\t\t\t\t\t? Object.keys((JSON.parse(turboContent) as { tasks: Record<string, unknown> }).tasks)\n\t\t\t\t\t\t: []\n\t\t\t\t);\n\n\t\t\t\tsteps.push(\n\t\t\t\t\tawait runSyncStep(\"local\", \"sync scripts\", dryRun, async () => {\n\t\t\t\t\t\tconst changed = await mergePackageJsonScripts(input.context.repoRoot, desired, turboEligible);\n\t\t\t\t\t\tif (changed === null) return \"no package.json\";\n\t\t\t\t\t\tif (changed.length === 0) return `${Object.keys(desired).length} scripts already current`;\n\t\t\t\t\t\treturn `${changed.join(\", \")} set`;\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t}\n\t\t}\n\n\t\tif (stepName === \"turbo\") {\n\t\t\tconst astromechTurbo = createAstromech({\n\t\t\t\tcwd: input.context.repoRoot,\n\t\t\t\tconfig: { tasks: config.tasks as TasksConfig[\"tasks\"] },\n\t\t\t\tlogger,\n\t\t\t});\n\t\t\tconst content = astromechTurbo.turboConfig();\n\n\t\t\tif (content === null) {\n\t\t\t\tsteps.push({\n\t\t\t\t\tcapability: \"local\",\n\t\t\t\t\tstep: \"sync turbo.json\",\n\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\tmessage: \"no fan-out-eligible tasks configured\",\n\t\t\t\t});\n\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t} else {\n\t\t\t\tsteps.push(\n\t\t\t\t\tawait runSyncStep(\"local\", \"sync turbo.json\", dryRun, async () => {\n\t\t\t\t\t\tawait writeFile(join(input.context.repoRoot, \"turbo.json\"), content, \"utf8\");\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\n\t\t\t\t// #692: fix pnpm-workspace.yaml in the same step that introduces\n\t\t\t\t// the risk — see run-setup.ts's identical wiring for the full\n\t\t\t\t// explanation.\n\t\t\t\tconst rootPkgRaw = await readFile(join(input.context.repoRoot, \"package.json\"), \"utf8\").catch(\n\t\t\t\t\t() => null\n\t\t\t\t);\n\t\t\t\tconst rootPkg = rootPkgRaw ? (JSON.parse(rootPkgRaw) as { scripts?: Record<string, string> }) : null;\n\t\t\t\tconst workspaceYaml = await readFile(join(input.context.repoRoot, \"pnpm-workspace.yaml\"), \"utf8\").catch(\n\t\t\t\t\t() => \"\"\n\t\t\t\t);\n\t\t\t\tconst rootScripts = rootPkg?.scripts ?? {};\n\t\t\t\tconst workspaceFix = astromechTurbo.ensureRootWorkspaceMember(workspaceYaml, rootScripts);\n\t\t\t\tif (workspaceFix.changed) {\n\t\t\t\t\tsteps.push(\n\t\t\t\t\t\tawait runSyncStep(\n\t\t\t\t\t\t\t\"local\",\n\t\t\t\t\t\t\t\"fix pnpm-workspace.yaml (root workspace member, #692)\",\n\t\t\t\t\t\t\tdryRun,\n\t\t\t\t\t\t\tasync () => {\n\t\t\t\t\t\t\t\tawait writeFile(\n\t\t\t\t\t\t\t\t\tjoin(input.context.repoRoot, \"pnpm-workspace.yaml\"),\n\t\t\t\t\t\t\t\t\tworkspaceFix.content,\n\t\t\t\t\t\t\t\t\t\"utf8\"\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t}\n\n\t\t\t\t// turbo.json alone is inert without turbo itself installed —\n\t\t\t\t// see ensureTurboDependency()'s own docstring for how this was\n\t\t\t\t// found (a global-version fallback that silently broke on an\n\t\t\t\t// unrelated turbo install).\n\t\t\t\tif (rootPkgRaw) {\n\t\t\t\t\tconst depFix = astromechTurbo.ensureTurboDependency(rootPkgRaw, workspaceFix.content);\n\t\t\t\t\tif (depFix.changed) {\n\t\t\t\t\t\tsteps.push(\n\t\t\t\t\t\t\tawait runSyncStep(\"local\", \"add turbo devDependency\", dryRun, async () => {\n\t\t\t\t\t\t\t\tawait writeFile(join(input.context.repoRoot, \"package.json\"), depFix.content, \"utf8\");\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t);\n\t\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (stepName === \"wiki\") {\n\t\t\tconst result = await runSyncWiki({ loaded: input.loaded, context: input.context });\n\t\t\tsteps.push(result);\n\t\t\tprint(formatSyncStep(result));\n\t\t}\n\t}\n\n\tfor (const s of steps) {\n\t\tlogger[s.status === \"fail\" ? \"warn\" : \"info\"](\n\t\t\t{ capability: s.capability, step: s.step, status: s.status, ...(s.message ? { detail: s.message } : {}) },\n\t\t\t`sync: ${s.step}`\n\t\t);\n\t}\n\n\tconst summary = steps.reduce(\n\t\t(acc, s) => {\n\t\t\tif (s.status === \"ok\") acc.ok += 1;\n\t\t\telse if (s.status === \"fail\") acc.fail += 1;\n\t\t\telse if (s.status === \"skip\") acc.skip += 1;\n\t\t\telse if (s.status === \"dry-run\") acc.dryRun += 1;\n\t\t\treturn acc;\n\t\t},\n\t\t{ ok: 0, fail: 0, skip: 0, dryRun: 0 }\n\t);\n\n\tlogger[summary.fail > 0 ? \"warn\" : \"info\"]({ ...summary }, \"sync: done\");\n\n\tprint(\"\");\n\tprint(\n\t\t` ${summary.ok} ok, ${summary.fail} fail, ${summary.skip} skipped${\n\t\t\tdryRun ? `, ${summary.dryRun} would-do` : \"\"\n\t\t}`\n\t);\n\n\treturn { steps, summary };\n}\n\nasync function runSyncStep(\n\tcapability: string,\n\tstep: string,\n\tdryRun: boolean,\n\tbody: () => Promise<string | void>\n): Promise<SetupStepResult> {\n\tif (dryRun) {\n\t\treturn { capability, step, status: \"dry-run\" };\n\t}\n\ttry {\n\t\tconst note = await body();\n\t\tconst result: SetupStepResult = { capability, step, status: \"ok\" };\n\t\tif (typeof note === \"string\") result.message = note;\n\t\treturn result;\n\t} catch (err) {\n\t\treturn {\n\t\t\tcapability,\n\t\t\tstep,\n\t\t\tstatus: \"fail\",\n\t\t\tmessage: err instanceof Error ? err.message : String(err),\n\t\t};\n\t}\n}\n\nfunction formatSyncStep(step: SetupStepResult): string {\n\tconst icon = step.status === \"ok\" ? \"✓\" : step.status === \"fail\" ? \"✗\" : step.status === \"dry-run\" ? \"…\" : \"·\";\n\tconst detail = step.message ? ` (${step.message})` : \"\";\n\treturn ` ${icon} ${step.step}${detail}`;\n}\n\nasync function writePackageJsonField(repoRoot: string, field: string, value: unknown): Promise<boolean> {\n\tconst pkgPath = join(repoRoot, \"package.json\");\n\tlet content: string;\n\ttry {\n\t\tcontent = await readFile(pkgPath, \"utf8\");\n\t} catch {\n\t\treturn false;\n\t}\n\tconst pkg = JSON.parse(content) as Record<string, unknown>;\n\tpkg[field] = value;\n\tawait writeFile(pkgPath, JSON.stringify(pkg, null, 2) + \"\\n\", \"utf8\");\n\treturn true;\n}\n\n/**\n * Merge `desired` script entries into `package.json#scripts` — sets only the\n * listed keys, never touches the rest. Returns the sorted list of keys that\n * drifted (empty when all current), or `null` when there is no `package.json`.\n *\n * `turboEligible` (#747): task names `turbo.json` fans out — the same set\n * {@link EnsureRootWorkspaceMemberResult} above already keys off. For those\n * only, an *existing* script that isn't the generated `holocron run <task>\n * --` wrapper is left untouched: root may genuinely be a directly-buildable\n * package (not an orchestrator) with its own real command (`tsc --noEmit`,\n * `vitest run`, …) for that task. Overwriting it would silently discard the\n * real command and, once `turbo.json` exists and root is a real workspace\n * member (#692), reintroduce infinite recursion — `turbo run <task>` →\n * root's own `<task>` script → the wrapper → `holocron run <task>` sees\n * `turbo.json` still defines the task → `turbo run <task>` again, forever.\n * Every other key (non-turbo tasks, `holocron`, `prepare`, …) has no\n * legitimate direct-command alternative and stays fully generator-owned.\n */\nasync function mergePackageJsonScripts(\n\trepoRoot: string,\n\tdesired: Record<string, string>,\n\tturboEligible: ReadonlySet<string>\n): Promise<string[] | null> {\n\tconst pkgPath = join(repoRoot, \"package.json\");\n\tlet content: string;\n\ttry {\n\t\tcontent = await readFile(pkgPath, \"utf8\");\n\t} catch {\n\t\treturn null;\n\t}\n\tconst pkg = JSON.parse(content) as Record<string, unknown>;\n\tconst scripts = (pkg.scripts ?? {}) as Record<string, string>;\n\tconst changed: string[] = [];\n\tfor (const [name, command] of Object.entries(desired)) {\n\t\tconst existing = scripts[name];\n\t\tif (turboEligible.has(name) && existing !== undefined && !isGeneratedRunWrapper(existing, name)) continue;\n\t\tif (existing !== command) {\n\t\t\tscripts[name] = command;\n\t\t\tchanged.push(name);\n\t\t}\n\t}\n\tif (changed.length === 0) return [];\n\tpkg.scripts = scripts;\n\tawait writeFile(pkgPath, JSON.stringify(pkg, null, 2) + \"\\n\", \"utf8\");\n\treturn changed.sort();\n}\n\n/**\n * Matches the exact shape `packageScripts()` generates for `taskName` —\n * `<bin> run <taskName> --`, `<bin>` normally `holocron` but substitutable\n * (`holocronScript`, itself allowed to be multi-word, e.g. `\"node\npackages/cli/dist/cli.mjs\"` — see its own test). Checking the *suffix*\n * rather than the whole string means an old wrapper survives a\n * `holocronScript` rename intact — it's still recognized as a wrapper (safe\n * to update to the new one), not mistaken for a real command.\n */\nfunction isGeneratedRunWrapper(command: string, taskName: string): boolean {\n\treturn command.endsWith(` run ${taskName} --`);\n}\n\nconst README_DESC_START = \"<!-- holocron:description -->\";\nconst README_DESC_END = \"<!-- /holocron:description -->\";\n\nasync function updateReadmeDescription(repoRoot: string, description: string): Promise<boolean> {\n\tconst readmePath = join(repoRoot, \"README.md\");\n\tlet content: string;\n\ttry {\n\t\tcontent = await readFile(readmePath, \"utf8\");\n\t} catch {\n\t\treturn false;\n\t}\n\tconst lines = content.split(\"\\n\");\n\n\tconst startIdx = lines.findIndex((l) => l.trim() === README_DESC_START);\n\tconst endIdx = lines.findIndex((l) => l.trim() === README_DESC_END);\n\tif (startIdx !== -1) {\n\t\tif (endIdx === -1 || endIdx <= startIdx) return false;\n\t\tlines.splice(startIdx + 1, endIdx - startIdx - 1, description);\n\t\tawait writeFile(readmePath, lines.join(\"\\n\"), \"utf8\");\n\t\treturn true;\n\t}\n\n\tconst h1Index = lines.findIndex((l) => /^# /.test(l));\n\tif (h1Index === -1) return false;\n\n\tlines.splice(h1Index + 1, 0, \"\", README_DESC_START, description, README_DESC_END);\n\tawait writeFile(readmePath, lines.join(\"\\n\"), \"utf8\");\n\treturn true;\n}\n\nasync function writeWorkflowFile(repoRoot: string, filename: string, content: string): Promise<void> {\n\tconst dir = join(repoRoot, \".github\", \"workflows\");\n\tawait mkdir(dir, { recursive: true });\n\tawait writeFile(join(dir, filename), content, \"utf8\");\n}\n","/**\n * Holocron-specific credential resolution for the telemetry sinks — the env\n * chain plus Holocron's own shipped fallbacks. This is **CLI policy**, not part\n * of the portable adapter set: `sentry-sink.ts` / `posthog-sink.ts` take a\n * resolved DSN / key and never read the environment. When the adapters move to\n * `@theholocron/observability` (#635) this module stays here.\n *\n * errors: HOLOCRON_SENTRY_DSN → SENTRY_DSN → FALLBACK_DSN\n * analytics: HOLOCRON_POSTHOG_PROJECT_TOKEN → POSTHOG_PROJECT_TOKEN → FALLBACK_POSTHOG_PROJECT_TOKEN\n * host: HOLOCRON_POSTHOG_HOST → POSTHOG_HOST → DEFAULT_POSTHOG_HOST\n *\n * The `SENTRY_DSN` / `POSTHOG_PROJECT_TOKEN` fallbacks are the vendor-native\n * names a consumer repo sets to route CLI telemetry to its own project. The\n * built-in fallbacks are ingest-only keys — publishable by design, same risk\n * model as ADR-0007 / ADR-0008.\n */\n\nimport { env } from \"../env.js\";\n\n/** Holocron's own Sentry project — the fallback when no env var points elsewhere. */\nconst FALLBACK_DSN = \"https://95cbb72ad5636c94e119a5405ee8f55f@o4508238154104832.ingest.us.sentry.io/4511810950791168\";\n\n/** Holocron's own PostHog project write key — ingest-only. */\nconst FALLBACK_POSTHOG_PROJECT_TOKEN = \"phc_AC4vFCvYzwnzmG7Vg5nEc3PZKZztoPyfKp4Lb9BbXcLK\"; // gitleaks:allow\n\nconst DEFAULT_POSTHOG_HOST = \"https://us.i.posthog.com\";\n\n/** Resolve the Sentry DSN. `\"\"` → error telemetry disabled. */\nexport function resolveDsn(): string {\n\treturn env.get(\"HOLOCRON_SENTRY_DSN\") ?? env.get(\"SENTRY_DSN\") ?? FALLBACK_DSN;\n}\n\n/** Resolve the PostHog project key. `\"\"` → usage analytics disabled. */\nexport function resolvePostHogKey(): string {\n\treturn (\n\t\tenv.get(\"HOLOCRON_POSTHOG_PROJECT_TOKEN\") ?? env.get(\"POSTHOG_PROJECT_TOKEN\") ?? FALLBACK_POSTHOG_PROJECT_TOKEN\n\t);\n}\n\n/** Resolve the PostHog ingest host. */\nexport function resolvePostHogHost(): string {\n\treturn env.get(\"HOLOCRON_POSTHOG_HOST\") ?? env.get(\"POSTHOG_HOST\") ?? DEFAULT_POSTHOG_HOST;\n}\n","/**\n * CLI self-telemetry orchestration — errors (Sentry), usage analytics (PostHog).\n *\n * This module holds *no* vendor SDK import. Each concern sits behind an\n * interface from `@theholocron/observability` ({@link ErrorSink} /\n * {@link AnalyticsSink}); the `SentrySink` / `PostHogSink` adapters there are\n * the only `@sentry/node` / `posthog-node` call sites, and a `Noop*Sink` is\n * installed when telemetry is off. Same seam the package's `Logger` uses for\n * Pino.\n *\n * Activation is env-var + shipped-fallback, resolved here (`telemetry/resolve.ts`)\n * and passed to the sink — the adapters read no environment. The single kill\n * switch is `HOLOCRON_TELEMETRY=false` (legacy alias `NO_HOLOCRON_TELEMETRY`);\n * see ADR-0007 / ADR-0008.\n */\n\nimport { createHash } from \"node:crypto\";\nimport { hostname, userInfo } from \"node:os\";\n\nimport { PostHogSink } from \"@theholocron/observability/analytics\";\nimport {\n\ttype AnalyticsSink,\n\ttype CommandSpan,\n\ttype ErrorSink,\n\tNoopAnalyticsSink,\n\tNoopErrorSink,\n\tredactObject,\n} from \"@theholocron/observability/core\";\nimport { SentrySink } from \"@theholocron/observability/errors\";\n\nimport type { TelemetryConfig } from \"./config/config.js\";\nimport { env } from \"./env.js\";\nimport { getRunId } from \"./logger.js\";\nimport { resolveDsn, resolvePostHogHost, resolvePostHogKey } from \"./telemetry/resolve.js\";\n\n// ── sinks ────────────────────────────────────────────────────────────────────\n\nlet errors: ErrorSink = new NoopErrorSink();\nlet analytics: AnalyticsSink = new NoopAnalyticsSink();\n\n// ── gate ─────────────────────────────────────────────────────────────────────\n\n/**\n * The shared opt-out. `HOLOCRON_TELEMETRY=false` (going-forward) or\n * `NO_HOLOCRON_TELEMETRY` (any truthy value, back-compat) disables all sinks.\n */\nfunction isEnabled(): boolean {\n\treturn env.get(\"HOLOCRON_TELEMETRY\") !== \"false\" && !env.get(\"NO_HOLOCRON_TELEMETRY\");\n}\n\n// ── identity ─────────────────────────────────────────────────────────────────\n\nlet commandStartedAt = 0;\nlet currentCommand = \"unknown\";\nlet lastErrorType: string | undefined;\nlet currentSpan: CommandSpan | undefined;\n\n/**\n * Anonymous, stable per-machine id — `sha256(hostname + username)` truncated\n * (ADR-0008). One-way: no raw hostname or username is ever transmitted.\n */\nfunction machineId(): string {\n\ttry {\n\t\treturn createHash(\"sha256\").update(`${hostname()} ${userInfo().username}`).digest(\"hex\").slice(0, 32);\n\t} catch {\n\t\treturn \"unknown\";\n\t}\n}\n\n/** Properties every analytics event carries — pivot key to the Axiom trace. */\nfunction baseProps(): Record<string, unknown> {\n\tconst runId = getRunId();\n\treturn {\n\t\tcommand: currentCommand,\n\t\tci: Boolean(env.get(\"CI\")),\n\t\t...(runId ? { runId } : {}),\n\t};\n}\n\n// ── lifecycle ────────────────────────────────────────────────────────────────\n\nexport function init(version: string): void {\n\tconst dsn = resolveDsn();\n\tif (isEnabled() && dsn !== \"\") {\n\t\terrors = new SentrySink();\n\t\terrors.init({\n\t\t\tdsn,\n\t\t\trelease: `holocron@${version}`,\n\t\t\tenvironment: env.get(\"CI\") ? \"ci\" : \"local\",\n\t\t\ttags: { os: process.platform, node: process.version, ci: String(Boolean(env.get(\"CI\"))) },\n\t\t});\n\t}\n\tconst posthogKey = resolvePostHogKey();\n\tif (isEnabled() && posthogKey !== \"\") {\n\t\tanalytics = new PostHogSink({ key: posthogKey, host: resolvePostHogHost() });\n\t\tanalytics.identify(machineId(), {\n\t\t\tci: Boolean(env.get(\"CI\")),\n\t\t\tos: process.platform,\n\t\t\tnode: process.version,\n\t\t\tcli: version,\n\t\t\t...(env.get(\"HOLOCRON_ORG\") ? { org: env.get(\"HOLOCRON_ORG\") } : {}),\n\t\t});\n\t}\n}\n\n/**\n * Apply the `telemetry` config block — the committed override layer, run once\n * per command *after* config loads (so it lands after {@link init}). Env still\n * wins: this only ever *narrows* what `init` turned on, never re-enables.\n *\n * - `enabled: false` → swap both sinks to no-ops for the rest of the run.\n * - `analytics: \"none\"` → drop usage analytics only; error reporting stays.\n *\n * A live sink is drained best-effort before it is dropped so an in-flight\n * Sentry session / PostHog queue still leaves the process cleanly.\n */\nexport function applyConfig(cfg: TelemetryConfig | undefined): void {\n\tif (!cfg) return;\n\n\t// Best-effort drain — never let a rejected close() surface as an unhandled\n\t// rejection from this sync path.\n\tconst drain = (p: Promise<unknown>): void => {\n\t\tp.catch(() => {});\n\t};\n\n\tif (cfg.enabled === false) {\n\t\tdrain(errors.flush());\n\t\tdrain(analytics.shutdown());\n\t\terrors = new NoopErrorSink();\n\t\tanalytics = new NoopAnalyticsSink();\n\t\treturn;\n\t}\n\n\tif (cfg.analytics === \"none\") {\n\t\tdrain(analytics.shutdown());\n\t\tanalytics = new NoopAnalyticsSink();\n\t}\n}\n\n/** Capture a PostHog event. Every `properties` object runs through the scrubber. */\nexport function event(name: string, properties: Record<string, unknown> = {}): void {\n\tanalytics.capture(machineId(), name, redactObject({ ...baseProps(), ...properties }));\n}\n\nexport function startCommand(name: string): (ok: boolean) => void {\n\tcurrentCommand = name;\n\tcommandStartedAt = Date.now();\n\tlastErrorType = undefined;\n\tcurrentSpan = errors.startSpan(name);\n\n\tevent(\"command_started\", { dry_run: process.argv.includes(\"--dry-run\") });\n\n\treturn (ok: boolean) => {\n\t\tcurrentSpan?.setStatus(ok);\n\t\tcurrentSpan?.end();\n\t\tevent(ok ? \"command_completed\" : \"command_failed\", {\n\t\t\tstatus: ok ? \"ok\" : \"fail\",\n\t\t\tduration_ms: Date.now() - commandStartedAt,\n\t\t\t...(ok || !lastErrorType ? {} : { error_type: lastErrorType }),\n\t\t});\n\t};\n}\n\nexport function captureException(err: unknown): void {\n\tlastErrorType = err instanceof Error ? err.constructor.name : \"Error\";\n\terrors.captureException(err);\n}\n\nexport function endSession(): void {\n\terrors.endSession();\n}\n\nexport async function flush(): Promise<void> {\n\tawait errors.flush();\n\tawait analytics.shutdown();\n\terrors = new NoopErrorSink();\n\tanalytics = new NoopAnalyticsSink();\n}\n\n// ── test hook ────────────────────────────────────────────────────────────────\n\n/** Drop the sinks + command state back to their no-op defaults. */\nexport function resetTelemetry(): void {\n\terrors = new NoopErrorSink();\n\tanalytics = new NoopAnalyticsSink();\n\tcommandStartedAt = 0;\n\tcurrentCommand = \"unknown\";\n\tlastErrorType = undefined;\n\tcurrentSpan = undefined;\n}\n","import { createHash } from \"node:crypto\";\nimport { mkdirSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\n\nimport { reusableTemplates } from \"@theholocron/astromech\";\nimport { createGitHubClient } from \"@theholocron/github-client\";\nimport { ProviderApiError } from \"@theholocron/http-client\";\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport { getLogger } from \"../logger.js\";\nimport { event as telemetryEvent } from \"../telemetry.js\";\n\nconst DEFAULT_REPO = \"theholocron/.github\";\n\nexport type SyncGithubStatus = \"ok\" | \"fail\" | \"dry-run\";\n\nexport interface RunSyncGithubInput {\n\t/** GitHub personal access token with repo write access. */\n\ttoken: string;\n\t/** Target org/repo. Defaults to \"theholocron/.github\". */\n\trepo?: string;\n\t/**\n\t * Push files to this branch instead of the default branch.\n\t * If the branch doesn't exist it is created from the default branch HEAD.\n\t * Combine with `createPr: true` to open a PR after the push.\n\t */\n\tbranch?: string;\n\t/** After pushing to `branch`, open a PR to the default branch. No-op if `branch` is unset. */\n\tcreatePr?: boolean;\n\t/** Commit message for the sync commit. */\n\tmessage?: string;\n\tdryRun?: boolean;\n\t/**\n\t * Write generated files to this local directory instead of pushing to the GitHub API.\n\t * Useful for local validation (e.g. actionlint) before a real sync run.\n\t * When set, no API calls are made and token is not required.\n\t */\n\toutputDir?: string;\n\tprint?: (line: string) => void;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n\t/** Injectable for testing. */\n\tfetch?: typeof globalThis.fetch;\n}\n\nexport interface SyncGithubReport {\n\tstatus: SyncGithubStatus;\n\tcreated: number;\n\tupdated: number;\n\tunchanged: number;\n\t/** URL of the opened PR, when createPr is true and changes were made. */\n\tprUrl?: string;\n\tmessage?: string;\n}\n\ntype FileBatch = Array<{ path: string; content: string }>;\n\n/**\n * The file set `sync-github` pushes to `theholocron/.github` — the reusable\n * `workflow_call` implementations, composite actions and starter-workflow\n * metadata, generated by `@theholocron/astromech`. Secondary repos get nothing:\n * their thin callers are managed by `holocron sync --steps workflows`, which\n * executes the resolved config (regex parsing here can't resolve preset spreads\n * like `...tasks` from `nodeDocs()` — see issue #464).\n */\nfunction buildBatch(repo: string): FileBatch {\n\tif (repo !== DEFAULT_REPO) return [];\n\treturn [...reusableTemplates()].map(([path, content]) => ({ path, content }));\n}\n\n/** Git blob SHA: sha1(\"blob {len}\\0{content}\") — used to detect unchanged files. */\nexport function gitBlobSha(content: string): string {\n\tconst buf = Buffer.from(content, \"utf8\");\n\treturn createHash(\"sha1\").update(`blob ${buf.length}\\0`).update(buf).digest(\"hex\");\n}\n\nexport async function runSyncGithub(input: RunSyncGithubInput): Promise<SyncGithubReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst repo = input.repo ?? DEFAULT_REPO;\n\tconst { token, dryRun = false, branch, createPr = false } = input;\n\tconst message = input.message ?? `chore: sync from theholocron/holocron`;\n\n\tconst client = createGitHubClient({ token, fetch: input.fetch });\n\n\tprint(`holocron sync-github${dryRun ? \" (dry-run)\" : \"\"}`);\n\tprint(` repo: ${repo}`);\n\tif (branch) print(` branch: ${branch}`);\n\tprint(\"\");\n\n\tlogger.info({ repo, branch, createPr: createPr || undefined, dryRun: dryRun || undefined }, \"sync-github: start\");\n\n\t/** Single exit point — one structured line per invocation, whatever the path. */\n\tconst done = (r: SyncGithubReport): SyncGithubReport => {\n\t\tlogger[r.status === \"fail\" ? \"warn\" : \"info\"](\n\t\t\t{\n\t\t\t\trepo,\n\t\t\t\tstatus: r.status,\n\t\t\t\tcreated: r.created,\n\t\t\t\tupdated: r.updated,\n\t\t\t\tunchanged: r.unchanged,\n\t\t\t\t...(r.message ? { reason: r.message } : {}),\n\t\t\t\t...(r.prUrl ? { pr: r.prUrl } : {}),\n\t\t\t},\n\t\t\t\"sync-github: done\"\n\t\t);\n\t\ttelemetryEvent(\"sync_github_run\", {\n\t\t\trepo,\n\t\t\tstatus: r.status,\n\t\t\t...(branch ? { branch } : {}),\n\t\t\trepos_targeted: 1,\n\t\t\tfiles_changed: r.created + r.updated,\n\t\t\tpr_opened: Boolean(r.prUrl),\n\t\t});\n\t\treturn r;\n\t};\n\n\t// ── output-dir: write all files to disk without any API calls ───────────\n\tif (input.outputDir) {\n\t\tconst batch = buildBatch(repo);\n\t\tfor (const file of batch) {\n\t\t\tconst dest = join(input.outputDir, file.path);\n\t\t\tmkdirSync(dirname(dest), { recursive: true });\n\t\t\twriteFileSync(dest, file.content, \"utf8\");\n\t\t}\n\t\tprint(` ${batch.length} files written to ${input.outputDir}`);\n\t\treturn done({ status: \"ok\", created: batch.length, updated: 0, unchanged: 0 });\n\t}\n\n\t// ── 1. Resolve target branch ─────────────────────────────────────────────\n\tlet targetBranch = branch;\n\tlet defaultBranch: string | undefined;\n\tif (!targetBranch || createPr) {\n\t\ttry {\n\t\t\tconst repoData = await client.repos.getRepo(repo);\n\t\t\tdefaultBranch = repoData.default_branch;\n\t\t\tif (!targetBranch) targetBranch = defaultBranch;\n\t\t} catch {\n\t\t\tconst msg = \"failed to fetch repo metadata\";\n\t\t\tprint(` ✗ ${msg}`);\n\t\t\treturn done({ status: \"fail\", created: 0, updated: 0, unchanged: 0, message: msg });\n\t\t}\n\t}\n\n\t// ── 2. Get HEAD commit → base tree ───────────────────────────────────────\n\tconst baseBranch = createPr && defaultBranch ? defaultBranch : targetBranch!;\n\tlet headSha: string;\n\tlet baseTreeSha: string;\n\tlet existingBlobs: Map<string, string>;\n\ttry {\n\t\tconst ref = await client.git.getRef(repo, baseBranch);\n\t\theadSha = ref.object.sha;\n\t\tconst commit = await client.git.getCommit(repo, headSha);\n\t\tbaseTreeSha = commit.tree.sha;\n\t\tconst treeData = await client.git.getTree(repo, baseTreeSha, true);\n\t\texistingBlobs = new Map(treeData.tree.filter((i) => i.type === \"blob\").map((i) => [i.path, i.sha]));\n\t} catch (err) {\n\t\tconst msg = err instanceof Error ? err.message : `Branch ${baseBranch} not found`;\n\t\tprint(` ✗ ${msg}`);\n\t\treturn done({ status: \"fail\", created: 0, updated: 0, unchanged: 0, message: msg });\n\t}\n\n\t// ── 3. Build file batch ─────────────────────────────────────────────────\n\t// Secondary-repo thin callers are managed by `holocron sync --steps workflows`.\n\tconst batch = buildBatch(repo);\n\n\t// ── 5. Detect changes ────────────────────────────────────────────────────\n\tlet created = 0;\n\tlet updated = 0;\n\tlet unchanged = 0;\n\tconst changedFiles: Array<{ path: string; content: string }> = [];\n\n\tfor (const file of batch) {\n\t\tconst localSha = gitBlobSha(file.content);\n\t\tconst existingSha = existingBlobs.get(file.path);\n\n\t\tif (existingSha === localSha) {\n\t\t\tprint(` · unchanged ${file.path}`);\n\t\t\tunchanged++;\n\t\t} else if (existingSha) {\n\t\t\tprint(` ${dryRun ? \"~\" : \"✓\"} updated ${file.path}`);\n\t\t\tlogger.debug({ file: file.path, change: \"updated\" }, \"sync-github: file\");\n\t\t\tupdated++;\n\t\t\tif (!dryRun) changedFiles.push(file);\n\t\t} else {\n\t\t\tprint(` ${dryRun ? \"~\" : \"✓\"} created ${file.path}`);\n\t\t\tlogger.debug({ file: file.path, change: \"created\" }, \"sync-github: file\");\n\t\t\tcreated++;\n\t\t\tif (!dryRun) changedFiles.push(file);\n\t\t}\n\t}\n\n\tprint(\"\");\n\tprint(` ${created} created, ${updated} updated, ${unchanged} unchanged`);\n\n\tif (dryRun || changedFiles.length === 0) {\n\t\treturn done({ status: dryRun ? \"dry-run\" : \"ok\", created, updated, unchanged });\n\t}\n\n\t// ── 6. Create blobs for changed files ────────────────────────────────────\n\tconst treeEntries: Array<{ path: string; mode: string; type: string; sha: string }> = [];\n\tfor (const file of changedFiles) {\n\t\ttry {\n\t\t\tconst blob = await client.git.createBlob(repo, file.content);\n\t\t\ttreeEntries.push({ path: file.path, mode: \"100644\", type: \"blob\", sha: blob.sha });\n\t\t} catch (err) {\n\t\t\tconst msg = `failed to create blob for ${file.path}: ${err instanceof Error ? err.message : String(err)}`;\n\t\t\tprint(` ✗ ${msg}`);\n\t\t\treturn done({ status: \"fail\", created, updated, unchanged, message: msg });\n\t\t}\n\t}\n\n\t// ── 7. Create tree ───────────────────────────────────────────────────────\n\tlet newTreeSha: string;\n\ttry {\n\t\tconst newTree = await client.git.createTree(repo, treeEntries, baseTreeSha);\n\t\tnewTreeSha = newTree.sha;\n\t} catch (err) {\n\t\tconst msg = `failed to create tree: ${err instanceof Error ? err.message : String(err)}`;\n\t\tprint(` ✗ ${msg}`);\n\t\treturn done({ status: \"fail\", created, updated, unchanged, message: msg });\n\t}\n\n\t// ── 8. Create commit ─────────────────────────────────────────────────────\n\tlet newCommitSha: string;\n\ttry {\n\t\tconst newCommit = await client.git.createCommit(repo, message, newTreeSha, [headSha]);\n\t\tnewCommitSha = newCommit.sha;\n\t} catch (err) {\n\t\tconst msg = `failed to create commit: ${err instanceof Error ? err.message : String(err)}`;\n\t\tprint(` ✗ ${msg}`);\n\t\treturn done({ status: \"fail\", created, updated, unchanged, message: msg });\n\t}\n\n\t// ── 9. Update (or create) branch ref ────────────────────────────────────\n\ttry {\n\t\tif (createPr && branch) {\n\t\t\ttry {\n\t\t\t\tawait client.git.createRef(repo, `refs/heads/${branch}`, newCommitSha);\n\t\t\t} catch (err) {\n\t\t\t\tif (!(err instanceof ProviderApiError) || err.status !== 422) throw err;\n\t\t\t\t// Branch already exists from a previous partial run — force-update it.\n\t\t\t\tawait client.git.updateRef(repo, `heads/${branch}`, newCommitSha, true);\n\t\t\t}\n\t\t} else {\n\t\t\tawait client.git.updateRef(repo, `heads/${targetBranch!}`, newCommitSha);\n\t\t}\n\t} catch (err) {\n\t\tconst msg = `failed to update ref: ${err instanceof Error ? err.message : String(err)}`;\n\t\tprint(` ✗ ${msg}`);\n\t\treturn done({ status: \"fail\", created, updated, unchanged, message: msg });\n\t}\n\n\t// ── 10. Open PR if requested ─────────────────────────────────────────────\n\tlet prUrl: string | undefined;\n\tif (branch && createPr && !dryRun) {\n\t\ttry {\n\t\t\tconst pr = await client.git.createPull(repo, {\n\t\t\t\ttitle: message.split(\"\\n\")[0]!,\n\t\t\t\thead: branch,\n\t\t\t\tbase: \"main\",\n\t\t\t\tbody: \"Auto-generated by `holocron sync-github`. Review and merge to apply template updates.\",\n\t\t\t});\n\t\t\tprUrl = pr.html_url;\n\t\t\tprint(` → PR opened: ${prUrl}`);\n\t\t} catch (err) {\n\t\t\tconst alreadyExists =\n\t\t\t\terr instanceof ProviderApiError && err.status === 422 && String(err.details).includes(\"already exists\");\n\t\t\tif (alreadyExists) {\n\t\t\t\tprint(` → PR already open for ${branch} — branch updated, ready to merge`);\n\t\t\t} else {\n\t\t\t\tprint(` ⚠ PR creation failed: ${err instanceof Error ? err.message : String(err)}`);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn done({ status: \"ok\", created, updated, unchanged, prUrl });\n}\n","/**\n * `holocron upgrade deps` — bring a repo's `@theholocron/*` dependency pins and\n * its `holocron.config.ts` up to the current major.\n *\n * Two concerns:\n *\n * 1. **Catalog pins.** Every `@theholocron/*` entry in `pnpm-workspace.yaml`\n * (`catalog:` and every named `catalogs.*`) is bumped to the latest published\n * version, preserving the range prefix (`^` / `~`). Never downgrades.\n * 2. **`holocron.config.ts` migration.** `@theholocron/holocron-config@8`\n * dropped the 7.x preset shape (`const { repo, workflows, providers } =\n * node()` + `repo.requiredChecks` + `workflows:`) for a composed-preset\n * (`const preset = node()` + `...preset` + `tasks:` + `extraRequiredChecks:`).\n * This applies the mechanical transforms and flags anything that needs a\n * human eye.\n *\n * After running, `pnpm install && holocron ci`.\n */\n\nimport { readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport { getLogger } from \"../logger.js\";\n\n// ── npm registry ─────────────────────────────────────────────────────────────\n\nexport type FetchLatest = (pkg: string) => Promise<string | null>;\n\nconst FETCH_TIMEOUT_MS = 4000;\n\n/** Resolve a package's `latest` dist-tag from the npm registry. */\nexport const fetchLatestFromNpm: FetchLatest = async (pkg) => {\n\ttry {\n\t\tconst res = await fetch(`https://registry.npmjs.org/${encodeURIComponent(pkg)}`, {\n\t\t\tsignal: AbortSignal.timeout(FETCH_TIMEOUT_MS),\n\t\t\theaders: { accept: \"application/vnd.npm.install-v1+json\" },\n\t\t});\n\t\tif (!res.ok) return null;\n\t\tconst data = (await res.json()) as { \"dist-tags\"?: Record<string, string> };\n\t\treturn data[\"dist-tags\"]?.[\"latest\"] ?? null;\n\t} catch {\n\t\treturn null;\n\t}\n};\n\n// ── semver (just enough) ─────────────────────────────────────────────────────\n\n/** `a > b` for `x.y.z` release versions (prerelease tags are ignored). */\nexport function gt(a: string, b: string): boolean {\n\tconst pa = a.split(\".\").map((n) => parseInt(n, 10));\n\tconst pb = b.split(\".\").map((n) => parseInt(n, 10));\n\tfor (let i = 0; i < 3; i++) {\n\t\tconst x = pa[i] ?? 0;\n\t\tconst y = pb[i] ?? 0;\n\t\tif (x !== y) return x > y;\n\t}\n\treturn false;\n}\n\n// ── 1. catalog pins ──────────────────────────────────────────────────────────\n\nconst CATALOG_LINE = /^(\\s*['\"]?)(@theholocron\\/[a-z0-9-]+)(['\"]?\\s*:\\s*['\"]?)([~^]?)(\\d+\\.\\d+\\.\\d+[\\w.-]*)(['\"]?\\s*)$/;\n\nexport interface CatalogBump {\n\tpkg: string;\n\tfrom: string;\n\tto: string;\n}\n\n/**\n * Rewrite every `@theholocron/*` pin in a `pnpm-workspace.yaml` to `latest`,\n * keeping the range prefix. `latest` is looked up once per package.\n */\nexport async function bumpCatalogs(\n\tcontent: string,\n\tfetchLatest: FetchLatest\n): Promise<{ content: string; bumps: CatalogBump[] }> {\n\tconst lines = content.split(\"\\n\");\n\tconst wanted = new Set<string>();\n\tfor (const line of lines) {\n\t\tconst m = CATALOG_LINE.exec(line);\n\t\tif (m) wanted.add(m[2]!);\n\t}\n\n\tconst latest = new Map<string, string | null>();\n\tawait Promise.all(\n\t\t[...wanted].map(async (pkg) => {\n\t\t\tlatest.set(pkg, await fetchLatest(pkg));\n\t\t})\n\t);\n\n\tconst bumps: CatalogBump[] = [];\n\tconst out = lines.map((line) => {\n\t\tconst m = CATALOG_LINE.exec(line);\n\t\tif (!m) return line;\n\t\tconst [, pre, pkg, mid, prefix, current, post] = m;\n\t\tconst next = latest.get(pkg!);\n\t\tif (!next || next === current || !gt(next, current!)) return line;\n\t\tbumps.push({ pkg: pkg!, from: current!, to: next });\n\t\treturn `${pre}${pkg}${mid}${prefix}${next}${post}`;\n\t});\n\n\treturn { content: out.join(\"\\n\"), bumps };\n}\n\n// ── 2. holocron.config.ts migration (7.x → 8.x) ──────────────────────────────\n\nexport interface ConfigMigration {\n\tcontent: string;\n\tchanged: boolean;\n\ttransforms: string[];\n\twarnings: string[];\n}\n\n/** True if the file still uses the 7.x preset shape. */\nexport function isLegacyConfig(content: string): boolean {\n\t// Only the 7.x markers count: a `workflows:` key, a `...repo.requiredChecks`\n\t// spread, or a preset destructure that pulls `workflows`. A config already on\n\t// `compose()` + `tasks:` + `extraRequiredChecks:` that merely destructures\n\t// `{ repo, providers }` is valid 8.x — touching it strands `...tasks` /\n\t// `...extraRequiredChecks` on the removed binding.\n\treturn (\n\t\t/\\.\\.\\.repo\\.requiredChecks/.test(content) ||\n\t\t/^\\s*workflows\\s*:/m.test(content) ||\n\t\t/const\\s*\\{[^}]*\\bworkflows\\b[^}]*\\}\\s*=\\s*(compose\\(|[a-zA-Z]+\\()/.test(content)\n\t);\n}\n\n/**\n * Apply the mechanical 7.x → 8.x transforms to a `holocron.config.ts`. Best\n * effort — the result should always be reviewed and run through `holocron ci`.\n */\nexport function migrateConfig(content: string): ConfigMigration {\n\tconst transforms: string[] = [];\n\tconst warnings: string[] = [];\n\tlet s = content;\n\n\tif (!isLegacyConfig(s)) {\n\t\treturn { content, changed: false, transforms, warnings };\n\t}\n\n\t// `const { repo, workflows, ... } = <preset>;` → `const preset = <preset>;`\n\tlet destructured: string[] = [];\n\ts = s.replace(\n\t\t/const\\s*\\{([^}]*)\\}\\s*=\\s*((?:compose\\([\\s\\S]*?\\)|[a-zA-Z]+\\([\\s\\S]*?\\)))\\s*;/,\n\t\t(_m, names: string, expr: string) => {\n\t\t\tdestructured = names\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((n) => n.trim().split(\":\")[0]!.trim())\n\t\t\t\t.filter(Boolean);\n\t\t\ttransforms.push(\"destructured preset → `const preset = …`\");\n\t\t\treturn `const preset = ${expr.trim()};`;\n\t\t}\n\t);\n\n\t// Any binding that was destructured and is still spread bare (`...tasks`,\n\t// `...extraRequiredChecks`, …) now has to come off `preset`.\n\tfor (const name of destructured) {\n\t\tif (name === \"repo\" || name === \"providers\" || name === \"workflows\") continue; // handled explicitly below\n\t\tconst bare = new RegExp(`\\\\.\\\\.\\\\.${name}\\\\b(?!\\\\.)`, \"g\");\n\t\tif (bare.test(s)) {\n\t\t\ts = s.replace(bare, `...preset.${name}`);\n\t\t\ttransforms.push(`\\`...${name}\\` → \\`...preset.${name}\\``);\n\t\t}\n\t}\n\n\t// Inject `...preset,` as the first key of defineConfig({ … })\n\tif (/const preset =/.test(s) && !/\\.\\.\\.preset\\b/.test(s)) {\n\t\ts = s.replace(/(defineConfig\\(\\{\\s*\\n)/, `$1\\t...preset,\\n`);\n\t\ttransforms.push(\"spread `...preset` into defineConfig()\");\n\t}\n\n\t// Drop the top-level destructure pass-throughs — `...preset` covers them.\n\ts = s.replace(/^\\torg,\\n/m, \"\");\n\ts = s.replace(/^\\tdomain,\\n/m, \"\");\n\ts = s.replace(/^\\tdocs,\\n/m, \"\");\n\n\t// Spread renames\n\tif (/\\.\\.\\.repo\\.properties/.test(s)) {\n\t\ts = s.replace(/\\.\\.\\.repo\\.properties/g, \"...preset.repo?.properties\");\n\t\ttransforms.push(\"`...repo.properties` → `...preset.repo?.properties`\");\n\t}\n\tif (/([{[,]\\s*)\\.\\.\\.repo\\b(?!\\.)/.test(s)) {\n\t\ts = s.replace(/([{[,]\\s*)\\.\\.\\.repo\\b(?!\\.)/g, \"$1...preset.repo\");\n\t\ttransforms.push(\"`...repo` → `...preset.repo`\");\n\t}\n\tif (/\\.\\.\\.providers\\b/.test(s)) {\n\t\ts = s.replace(/\\.\\.\\.providers\\b/g, \"...preset.providers\");\n\t\ttransforms.push(\"`...providers` → `...preset.providers`\");\n\t}\n\n\t// `repo.requiredChecks` is gone — the derived checks come from `tasks`.\n\t// Pull the custom entries out to a top-level `extraRequiredChecks`.\n\tconst rc = /(\\n\\s*)requiredChecks\\s*:\\s*\\[\\s*\\n?\\s*\\.\\.\\.repo\\.requiredChecks\\s*,?\\s*([\\s\\S]*?)\\n\\s*\\]\\s*,/.exec(s);\n\tif (rc) {\n\t\tconst custom = rc[2]!.trim().replace(/,\\s*$/, \"\");\n\t\ts = s.replace(rc[0], \"\");\n\t\tif (custom) {\n\t\t\tconst block = `\\textraRequiredChecks: [\\n\\t\\t${custom\n\t\t\t\t.split(\"\\n\")\n\t\t\t\t.map((l) => l.trim())\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.join(\"\\n\\t\\t\")}\\n\\t],\\n`;\n\t\t\ts = s.replace(/(defineConfig\\(\\{\\s*\\n(?:\\t\\.\\.\\.preset,\\n)?)/, `$1${block}`);\n\t\t\ttransforms.push(\"`repo.requiredChecks` custom entries → top-level `extraRequiredChecks`\");\n\t\t\twarnings.push(\"check the moved `extraRequiredChecks` — the preset already contributes lint/test/typecheck\");\n\t\t} else {\n\t\t\ts = s.replace(/,(\\s*)\\.\\.\\.repo\\.requiredChecks/g, \"$1\");\n\t\t\ttransforms.push(\"dropped `...repo.requiredChecks`\");\n\t\t}\n\t}\n\n\t// `workflows:` → `tasks:` (`...workflows` → `...preset.tasks`)\n\tif (/^\\s*workflows\\s*:/m.test(s)) {\n\t\ts = s.replace(/(\\n\\s*)workflows(\\s*:\\s*\\[)/, \"$1tasks$2\");\n\t\ts = s.replace(/\\.\\.\\.workflows\\b/g, \"...preset.tasks\");\n\t\ttransforms.push(\"`workflows:` → `tasks:` (`...workflows` → `...preset.tasks`)\");\n\t\twarnings.push(\n\t\t\t\"review the `tasks` array — a bare workflow name that should gate merges now needs `{ name, required: true }`\"\n\t\t);\n\t}\n\n\treturn { content: s, changed: s !== content, transforms, warnings };\n}\n\n// ── public API ───────────────────────────────────────────────────────────────\n\nexport interface RunUpgradeDepsInput {\n\t/** Repo root. Defaults to `process.cwd()`. */\n\tcwd?: string;\n\t/** Print what would change without writing. */\n\tdryRun?: boolean;\n\t/** Skip the `holocron.config.ts` migration (pins only). */\n\tpinsOnly?: boolean;\n\tprint?: (line: string) => void;\n\tlogger?: Logger;\n\treadFile?: (path: string) => string;\n\twriteFile?: (path: string, content: string) => void;\n\tfetchLatest?: FetchLatest;\n}\n\nexport type UpgradeDepsStatus = \"ok\" | \"fail\" | \"dry-run\";\n\nexport interface UpgradeDepsReport {\n\tstatus: UpgradeDepsStatus;\n\tbumps: readonly CatalogBump[];\n\tconfigMigrated: boolean;\n\tconfigWarnings: readonly string[];\n\tmessage?: string;\n}\n\nexport async function runUpgradeDeps(input: RunUpgradeDepsInput = {}): Promise<UpgradeDepsReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst cwd = input.cwd ?? process.cwd();\n\tconst dryRun = input.dryRun ?? false;\n\tconst pinsOnly = input.pinsOnly ?? false;\n\tconst _readFile = input.readFile ?? ((p: string) => readFileSync(p, \"utf8\"));\n\tconst _writeFile = input.writeFile ?? ((p: string, c: string) => writeFileSync(p, c));\n\tconst fetchLatest = input.fetchLatest ?? fetchLatestFromNpm;\n\n\tlogger.info({ dryRun: dryRun || undefined, pinsOnly: pinsOnly || undefined }, \"upgrade deps: start\");\n\tprint(`Upgrading @theholocron/* dependencies${dryRun ? \" (dry-run)\" : \"\"}…`);\n\n\t// ── 1. catalog pins ──\n\tconst wsPath = join(cwd, \"pnpm-workspace.yaml\");\n\tlet bumps: CatalogBump[] = [];\n\ttry {\n\t\tconst ws = _readFile(wsPath);\n\t\tconst result = await bumpCatalogs(ws, fetchLatest);\n\t\tbumps = result.bumps;\n\t\tif (bumps.length > 0) {\n\t\t\tif (!dryRun) _writeFile(wsPath, result.content);\n\t\t\tprint(\"\");\n\t\t\tprint(` pnpm-workspace.yaml — ${bumps.length} pin${bumps.length === 1 ? \"\" : \"s\"}`);\n\t\t\tfor (const b of bumps) print(` ${dryRun ? \"~\" : \"✓\"} ${b.pkg} ${b.from} → ${b.to}`);\n\t\t} else {\n\t\t\tprint(\" · pnpm-workspace.yaml — @theholocron/* pins already current\");\n\t\t}\n\t} catch {\n\t\tprint(\" · no pnpm-workspace.yaml — skipping catalog pins\");\n\t}\n\n\t// ── 2. holocron.config.ts migration ──\n\tlet configMigrated = false;\n\tlet configWarnings: string[] = [];\n\tif (!pinsOnly) {\n\t\tfor (const name of [\"holocron.config.ts\", \"holocron.config.js\"]) {\n\t\t\tlet cfg: string;\n\t\t\ttry {\n\t\t\t\tcfg = _readFile(join(cwd, name));\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst m = migrateConfig(cfg);\n\t\t\tif (!m.changed) {\n\t\t\t\tprint(` · ${name} — already on the current preset API`);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!dryRun) _writeFile(join(cwd, name), m.content);\n\t\t\tconfigMigrated = true;\n\t\t\tconfigWarnings = m.warnings;\n\t\t\tprint(\"\");\n\t\t\tprint(` ${name} — ${dryRun ? \"would migrate\" : \"migrated\"} to the 8.x preset API`);\n\t\t\tfor (const t of m.transforms) print(` ${dryRun ? \"~\" : \"✓\"} ${t}`);\n\t\t\tfor (const w of m.warnings) print(` ⚠ ${w}`);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tprint(\"\");\n\tif (bumps.length === 0 && !configMigrated) {\n\t\tprint(\"Nothing to do — already up to date.\");\n\t} else {\n\t\tprint(`Next: ${dryRun ? \"run without --dry-run, then \" : \"\"}\\`pnpm install && holocron ci\\``);\n\t\tif (configMigrated) print(\" review holocron.config.ts before committing.\");\n\t}\n\n\tconst status: UpgradeDepsStatus = dryRun ? \"dry-run\" : \"ok\";\n\tlogger.info({ bumps: bumps.length, configMigrated, warnings: configWarnings.length, status }, \"upgrade deps: done\");\n\treturn { status, bumps, configMigrated, configWarnings };\n}\n","import { readdirSync, readFileSync, statSync, writeFileSync } from \"node:fs\";\nimport { basename, join } from \"node:path\";\n\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport { getLogger } from \"../logger.js\";\n\n// Directories to skip when walking the repo tree\nconst SKIP_DIRS = new Set([\"node_modules\", \".git\", \"dist\", \"coverage\", \"build\", \".turbo\", \".next\", \"out\"]);\n\n// ── per-file-type patch functions ─────────────────────────────────────────────\n// Each returns the new file content, or null if nothing in that file changed.\n\nfunction patchPackageJson(content: string, from: number, to: number): string | null {\n\tlet pkg: Record<string, unknown>;\n\ttry {\n\t\tpkg = JSON.parse(content) as Record<string, unknown>;\n\t} catch {\n\t\treturn null;\n\t}\n\n\tlet changed = false;\n\n\tconst engines = pkg.engines as Record<string, string> | undefined;\n\tif (engines?.node && /^>=\\d+(?:\\.0\\.0)?$/.test(engines.node)) {\n\t\tconst major = parseInt(engines.node.match(/\\d+/)![0]!, 10);\n\t\tif (major === from) {\n\t\t\tengines.node = `>=${to}.0.0`;\n\t\t\tchanged = true;\n\t\t}\n\t}\n\n\tfor (const field of [\"devDependencies\", \"dependencies\"] as const) {\n\t\tconst deps = pkg[field] as Record<string, string> | undefined;\n\t\tif (!deps?.[\"@types/node\"]) continue;\n\t\t// Only update exact semver ranges; leave catalog: pins alone\n\t\tif (deps[\"@types/node\"] === `^${from}.0.0`) {\n\t\t\tdeps[\"@types/node\"] = `^${to}.0.0`;\n\t\t\tchanged = true;\n\t\t}\n\t}\n\n\treturn changed ? JSON.stringify(pkg, null, 2) + \"\\n\" : null;\n}\n\nfunction patchYaml(content: string, from: number, to: number): string | null {\n\t// node-version: 20 / node-version: '20' / node-version: \"20\"\n\tconst updated = content.replace(/node-version:\\s+['\"]?(\\d+)['\"]?/g, (match, ver) =>\n\t\tver === String(from) ? match.replace(String(from), String(to)) : match\n\t);\n\treturn updated !== content ? updated : null;\n}\n\nfunction patchPinFile(content: string, from: number, to: number): string | null {\n\t// .nvmrc / .node-version — \"20\" or \"20.x.y\" on the first line\n\tconst trimmed = content.trim();\n\tif (trimmed === String(from) || trimmed.startsWith(`${from}.`)) {\n\t\treturn `${to}\\n`;\n\t}\n\treturn null;\n}\n\nfunction patchDockerfile(content: string, from: number, to: number): string | null {\n\t// FROM node:20 / FROM node:20-alpine / FROM node:20.11.0\n\tconst updated = content.replace(/^(FROM\\s+node:)(\\d+)/gm, (match, prefix, ver) =>\n\t\tver === String(from) ? `${prefix}${to}` : match\n\t);\n\treturn updated !== content ? updated : null;\n}\n\nfunction patchToolVersions(content: string, from: number, to: number): string | null {\n\t// nodejs 20 / nodejs 20.11.0\n\tconst updated = content.replace(/^(nodejs\\s+)(\\d+)/gm, (match, prefix, ver) =>\n\t\tver === String(from) ? `${prefix}${to}` : match\n\t);\n\treturn updated !== content ? updated : null;\n}\n\ninterface Pattern {\n\tmatches: (filename: string) => boolean;\n\tpatch: (content: string, from: number, to: number) => string | null;\n}\n\nconst PATTERNS: Pattern[] = [\n\t{ matches: (n) => n === \"package.json\", patch: patchPackageJson },\n\t{ matches: (n) => n.endsWith(\".yml\") || n.endsWith(\".yaml\"), patch: patchYaml },\n\t{ matches: (n) => n === \".nvmrc\" || n === \".node-version\", patch: patchPinFile },\n\t{ matches: (n) => n === \"Dockerfile\" || n.startsWith(\"Dockerfile.\"), patch: patchDockerfile },\n\t{ matches: (n) => n === \".tool-versions\", patch: patchToolVersions },\n];\n\n// ── auto-detect current major from the repo ───────────────────────────────────\n\nfunction detectFrom(cwd: string, _readFile: (p: string) => string): number | null {\n\tfor (const name of [\".nvmrc\", \".node-version\"]) {\n\t\ttry {\n\t\t\tconst major = parseInt(_readFile(join(cwd, name)).trim(), 10);\n\t\t\tif (!isNaN(major)) return major;\n\t\t} catch {\n\t\t\t/* absent */\n\t\t}\n\t}\n\ttry {\n\t\tconst pkg = JSON.parse(_readFile(join(cwd, \"package.json\"))) as Record<string, unknown>;\n\t\tconst node = (pkg.engines as Record<string, string> | undefined)?.node;\n\t\tif (node) {\n\t\t\tconst m = node.match(/(\\d+)/);\n\t\t\tif (m) return parseInt(m[1]!, 10);\n\t\t}\n\t} catch {\n\t\t/* absent */\n\t}\n\treturn null;\n}\n\n// ── default file walker ───────────────────────────────────────────────────────\n\nfunction defaultWalkFiles(dir: string): string[] {\n\tconst results: string[] = [];\n\n\tfunction walk(current: string): void {\n\t\tlet entries: string[];\n\t\ttry {\n\t\t\tentries = readdirSync(current);\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\t\tfor (const entry of entries) {\n\t\t\tif (SKIP_DIRS.has(entry)) continue;\n\t\t\tconst abs = join(current, entry);\n\t\t\ttry {\n\t\t\t\tif (statSync(abs).isDirectory()) walk(abs);\n\t\t\t\telse results.push(abs);\n\t\t\t} catch {\n\t\t\t\t/* skip unreadable */\n\t\t\t}\n\t\t}\n\t}\n\n\twalk(dir);\n\treturn results;\n}\n\n// ── public API ────────────────────────────────────────────────────────────────\n\nexport interface RunUpgradeNodeInput {\n\t/** Target Node.js major version (e.g., 22). */\n\tto: number;\n\t/** Source major version. Auto-detected from .nvmrc / engines.node when omitted. */\n\tfrom?: number;\n\t/** Working directory (repo root). Defaults to process.cwd(). */\n\tcwd?: string;\n\t/** Print what would change without writing anything. */\n\tdryRun?: boolean;\n\t/**\n\t * Extra file paths (relative to cwd) to scan in addition to the normal\n\t * walk. Use for non-conventional locations not covered by the pattern\n\t * registry (e.g., custom Dockerfiles, .tool-versions in a subdirectory).\n\t * Sourced from `upgrade.node.extra` in holocron.config.json.\n\t */\n\textra?: string[];\n\tprint?: (line: string) => void;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n\t/** Injectable for testing. */\n\treadFile?: (path: string) => string;\n\twriteFile?: (path: string, content: string) => void;\n\twalkFiles?: (dir: string) => string[];\n}\n\nexport type UpgradeNodeStatus = \"ok\" | \"fail\" | \"dry-run\";\n\nexport interface UpgradeNodeReport {\n\tstatus: UpgradeNodeStatus;\n\tupdated: readonly string[];\n\tmessage?: string;\n}\n\nexport async function runUpgradeNode(input: RunUpgradeNodeInput): Promise<UpgradeNodeReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst cwd = input.cwd ?? process.cwd();\n\tconst { to, dryRun = false, extra = [] } = input;\n\tconst _readFile = input.readFile ?? ((p: string) => readFileSync(p, \"utf8\"));\n\tconst _writeFile = input.writeFile ?? ((p: string, c: string) => writeFileSync(p, c));\n\tconst _walkFiles = input.walkFiles ?? defaultWalkFiles;\n\n\tconst from = input.from ?? detectFrom(cwd, _readFile);\n\tif (from === null) {\n\t\tconst message = \"could not detect current Node version — pass --from <major>\";\n\t\tlogger.warn({ to, reason: message }, \"upgrade node: done\");\n\t\treturn { status: \"fail\", updated: [], message };\n\t}\n\n\tlogger.info({ from, to, dryRun: dryRun || undefined }, \"upgrade node: start\");\n\n\tif (from === to) {\n\t\tprint(`Already at Node.js ${to} — nothing to do.`);\n\t\tlogger.info({ from, to, updated: 0, status: \"ok\" }, \"upgrade node: done\");\n\t\treturn { status: \"ok\", updated: [] };\n\t}\n\n\tprint(`Upgrading Node.js ${from} → ${to}${dryRun ? \" (dry-run)\" : \"\"}…`);\n\n\tconst updated: string[] = [];\n\tconst scanned = [..._walkFiles(cwd), ...extra.map((p) => join(cwd, p))];\n\n\tfor (const abs of scanned) {\n\t\tconst name = basename(abs);\n\t\tconst pattern = PATTERNS.find((p) => p.matches(name));\n\t\tif (!pattern) continue;\n\n\t\tlet content: string;\n\t\ttry {\n\t\t\tcontent = _readFile(abs);\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst patched = pattern.patch(content, from, to);\n\t\tif (patched === null) continue;\n\n\t\tconst rel = abs.startsWith(cwd + \"/\") ? abs.slice(cwd.length + 1) : abs;\n\t\tif (!dryRun) _writeFile(abs, patched);\n\t\tprint(` ${dryRun ? \"~\" : \"✓\"} ${rel}`);\n\t\tlogger.debug({ file: rel, from, to }, \"upgrade node: patched\");\n\t\tupdated.push(rel);\n\t}\n\n\tif (updated.length === 0) {\n\t\tprint(` · no files contained Node.js ${from} pins`);\n\t}\n\n\tconst status = dryRun ? \"dry-run\" : \"ok\";\n\tlogger.info({ from, to, updated: updated.length, status }, \"upgrade node: done\");\n\treturn { status, updated };\n}\n","/**\n * Lints one commit message string against an already-loaded commitlint\n * config. The genuinely environment-independent half of commit-message\n * linting (holocron#789) — *obtaining* a `QualifiedConfig` differs by\n * caller (Sentinel isolates itself from any ambient config since it runs\n * standalone, away from a real repo checkout; `lintCommitMsgFile` below\n * just lets cosmiconfig discover the invoking repo's own\n * `commitlint.config.*`, matching `commitlint --edit`'s own contract) —\n * but linting one message against a loaded config is identical either way.\n *\n * Real `@commitlint/lint` — the same programmatic API `@commitlint/cli`\n * itself uses internally — never a reimplementation of commitlint's rules.\n */\n\nimport lint from \"@commitlint/lint\";\nimport type { LintOptions, ParserPreset, QualifiedConfig } from \"@commitlint/types\";\n\nexport interface CommitMessageViolation {\n\t/** Rule name, e.g. `\"subject-empty\"`. */\n\trule: string;\n\t/** commitlint's own message for the failure, e.g. `\"subject may not be empty\"`. */\n\tmessage: string;\n}\n\n/** `parserPreset.parserOpts`, if the loaded config sets one — same lookup `@commitlint/cli`'s own `selectParserOpts()` does. */\nfunction selectParserOpts(parserPreset: ParserPreset | undefined): ParserPreset[\"parserOpts\"] {\n\treturn parserPreset?.parserOpts;\n}\n\nexport async function lintCommitMessage(message: string, loaded: QualifiedConfig): Promise<CommitMessageViolation[]> {\n\tconst opts: LintOptions = {\n\t\t// `@theholocron/commitlint-config` sets no parserPreset of its own\n\t\t// (relies on commitlint's built-in default parser) or a non-empty\n\t\t// `ignores` today beyond the one dependabot-bump matcher it does set —\n\t\t// both `?? {}`/`?? []` are real fallbacks for a config that could set\n\t\t// either, not dead code, even though this org's own shared config\n\t\t// never exercises the \"unset\" side for `ignores` and never exercises\n\t\t// the \"set\" side for `parserPreset`.\n\t\t/* istanbul ignore next -- see comment above */\n\t\tparserOpts: selectParserOpts(loaded.parserPreset) ?? {},\n\t\tplugins: loaded.plugins,\n\t\t/* istanbul ignore next -- see comment above */\n\t\tignores: loaded.ignores ?? [],\n\t\tdefaultIgnores: loaded.defaultIgnores !== false,\n\t};\n\n\tconst outcome = await lint(message, loaded.rules, opts);\n\tif (outcome.valid) return [];\n\treturn outcome.errors.map((error) => ({ rule: error.name, message: error.message }));\n}\n","/**\n * `holocron lint commit-msg <file>` — a real programmatic replacement for\n * shelling out to `commitlint --edit \"$1\"` from `.husky/commit-msg`\n * (holocron#789). Matches that CLI's own contract exactly: `file` is a\n * path to the commit message being written (the arg git's `commit-msg`\n * hook passes as `$1`), no `--config` override needed — `@commitlint/load`\n * runs from `cwd` with no seed, so cosmiconfig's own normal upward search\n * discovers the invoking repo's real `commitlint.config.*` file, exactly\n * as `commitlint --edit` (no `--config` flag) already does today. Unlike\n * Sentinel's `loadIsolatedConfig()`, no isolation is needed here — this\n * runs inside a real repo checkout with a real `node_modules`, not\n * standalone on a server.\n */\n\nimport { readFile } from \"node:fs/promises\";\n\nimport load from \"@commitlint/load\";\n\nimport { type CommitMessageViolation, lintCommitMessage } from \"./lint-message.js\";\n\nexport interface LintCommitMsgFileResult {\n\tvalid: boolean;\n\tviolations: CommitMessageViolation[];\n}\n\nexport async function lintCommitMsgFile(filePath: string, cwd = process.cwd()): Promise<LintCommitMsgFileResult> {\n\tconst message = await readFile(filePath, \"utf8\");\n\tconst loaded = await load({}, { cwd });\n\tconst violations = await lintCommitMessage(message, loaded);\n\treturn { valid: violations.length === 0, violations };\n}\n","/**\n * `holocron.config.{ts,js,mjs,cjs,json}` loader.\n *\n * File discovery + module loading (typed configs via `tsx`, no build\n * step) is delegated to `@theholocron/datapad`. This module keeps the\n * holocron-specific parts: filling `name` / `repo.name` defaults and\n * running the config through `resolveConfig`.\n *\n * Probe order is TS-first (`.ts` → `.js` → `.mjs` → `.cjs` → `.json`) —\n * see ADR-0010 / issue #75 / #81.\n */\n\nimport { execFile } from \"node:child_process\";\nimport { readFile } from \"node:fs/promises\";\nimport { basename, dirname, join } from \"node:path\";\nimport { promisify } from \"node:util\";\n\nimport { loadTasksConfig } from \"@theholocron/astromech/config\";\nimport { ConfigFileError, loadConfigFile } from \"@theholocron/datapad\";\n\nconst execFileAsync = promisify(execFile);\n\nimport type { HolocronConfig, ResolvedHolocronConfig } from \"./config.js\";\nimport { resolveConfig } from \"./config.js\";\n\nexport { ConfigFileError } from \"@theholocron/datapad\";\n\nexport interface LoadedConfig {\n\tresolved: ResolvedHolocronConfig;\n\t/** Absolute path to the file the config was read from. */\n\tfilepath: string;\n}\n\n/**\n * Read + parse + resolve `holocron.config.*` from the given directory.\n * Throws {@link ConfigFileError} when nothing is found or a file cannot\n * be loaded, or `ConfigError` when the config is invalid.\n */\nexport async function loadConfig(cwd: string): Promise<LoadedConfig> {\n\tconst found = await loadConfigFile<HolocronConfig>({ cwd, name: \"holocron\" });\n\tif (!found) {\n\t\tthrow new ConfigFileError(\n\t\t\t`no holocron.config.{ts,js,mjs,cjs,json} found in ${cwd}. Create one — see the README for the schema.`\n\t\t);\n\t}\n\tconst withDefaults = await deriveDefaults(dirname(found.filepath), found.config);\n\treturn { resolved: resolveConfig(withDefaults), filepath: found.filepath };\n}\n\nasync function deriveDefaults(configDir: string, raw: HolocronConfig): Promise<HolocronConfig> {\n\tconst result = { ...raw };\n\tif (!result.name) {\n\t\tresult.name = (await readPackageJsonName(configDir)) ?? basename(configDir);\n\t}\n\tif (result.repo && !result.repo.name) {\n\t\tconst repoName = await readGitRemote(configDir);\n\t\tif (repoName) result.repo = { ...result.repo, name: repoName };\n\t}\n\n\t// Layer in the task manifest. `holocron.config`'s `tasks` key is one input;\n\t// a dedicated `astromech.config.{ts,js,mjs,json}` is merged on top (it wins\n\t// on scalars, task arrays concatenate). Doing it here keeps `holocron setup`\n\t// / `sync` / `doctor` on the same manifest that `holocron run` / `holocron\n\t// ci` resolve directly via `loadTasksConfig`.\n\tconst manifest = await loadTasksConfig(configDir);\n\tif (manifest.tasks) result.tasks = manifest.tasks;\n\tif (manifest.syncScripts !== undefined) result.syncScripts = manifest.syncScripts;\n\tif (manifest.holocronScript !== undefined) result.holocronScript = manifest.holocronScript;\n\tif (manifest.hooks !== undefined) result.hooks = manifest.hooks;\n\tif (manifest.extraRequiredChecks) {\n\t\tresult.extraRequiredChecks = [...(result.extraRequiredChecks ?? []), ...manifest.extraRequiredChecks];\n\t}\n\n\treturn result;\n}\n\nasync function readPackageJsonName(dir: string): Promise<string | undefined> {\n\ttry {\n\t\tconst content = await readFile(join(dir, \"package.json\"), \"utf8\");\n\t\tconst pkg = JSON.parse(content) as { name?: string };\n\t\treturn typeof pkg.name === \"string\" ? pkg.name.replace(/^@[^/]+\\//, \"\") : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nasync function readGitRemote(dir: string): Promise<string | undefined> {\n\ttry {\n\t\tconst { stdout } = await execFileAsync(\"git\", [\"remote\", \"get-url\", \"origin\"], { cwd: dir });\n\t\treturn parseGitRemoteUrl(stdout.trim());\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction parseGitRemoteUrl(url: string): string | undefined {\n\tconst httpsMatch = url.match(/github\\.com\\/([^/]+\\/[^/]+?)(?:\\.git)?$/);\n\tif (httpsMatch) return httpsMatch[1]!;\n\tconst sshMatch = url.match(/github\\.com:([^/]+\\/[^/]+?)(?:\\.git)?$/);\n\tif (sshMatch) return sshMatch[1]!;\n\treturn undefined;\n}\n","/**\n * The interactive fallback — replaces every \"run --help to see commands\"\n * dead end with a prompt. Three layers, all driven by {@link COMMAND_REGISTRY}:\n *\n * 1. `holocron` with no command → searchable picker over every command\n * 2. a parent command with no sub → `select()` over that group's commands\n * 3. a leaf command missing a → `input()` / `select()` per positional\n * required positional\n *\n * Layers 1–2 are driven from `cli.ts`'s `$0` handlers via {@link launchMenu}:\n * pick a command, prompt for its required positionals, then **spawn a fresh\n * `holocron <command> …` child process** (`stdio: \"inherit\"`) rather than\n * re-entering yargs' own parse pipeline — see the spec's \"spawn vs re-parse\"\n * section (theholocron/holocron#438) for why. Layer 3 is driven directly from\n * each leaf command's own handler in `cli.ts`, calling\n * {@link promptForPositionals} for just that one command — no spawn needed,\n * the handler already has everything else it needs.\n *\n * Every prompt is preceded by a `process.stdin.isTTY` check. A non-TTY run\n * (CI, a script, a pipe) throws {@link NonInteractiveError} instead of\n * hanging on `@inquirer/prompts` (which otherwise throws its own\n * `ExitPromptError` the moment stdin closes) — `cli.ts`'s `USER_FACING_ERRORS`\n * catch prints its message cleanly, restoring the old demandCommand-style\n * hard failure for non-interactive callers.\n */\n\nimport { spawn } from \"node:child_process\";\n\nimport { input, select } from \"@inquirer/prompts\";\nimport search from \"@inquirer/search\";\n\nimport { listStoredProviders } from \"./auth/keyring.js\";\n\n/** Raised when a prompt is needed but stdin isn't a TTY — see the module doc. */\nexport class NonInteractiveError extends Error {\n\toverride name = \"NonInteractiveError\";\n}\n\nexport interface PositionalPrompt {\n\t/** The yargs positional's camelCased argv key (e.g. `\"newVersion\"`). */\n\tkey: string;\n\t/**\n\t * The literal token in the command string, when it differs from `key`\n\t * (yargs positionals are kebab-case there — `<new-version>` — but\n\t * camelCased in argv). Shown in the non-interactive fallback message.\n\t * Defaults to `key`.\n\t */\n\tcliArg?: string;\n\t/** Label shown to the user. */\n\tmessage: string;\n\ttype: \"input\" | \"select\";\n\t/**\n\t * Required when `type === \"select\"`. A plain list for a fixed set, or a\n\t * thunk for a set resolved at prompt time (e.g. `auth unset`'s provider\n\t * choices are whatever currently has a stored token — there's no fixed\n\t * provider list, providers are open-ended plugin packages).\n\t */\n\tchoices?: string[] | (() => string[]);\n\t/** Optional `input()` validation — e.g. numeric positionals. */\n\tvalidate?: (value: string) => boolean | string;\n}\n\nexport interface CommandEntry {\n\t/** Full command name as typed at the CLI, e.g. `\"auth set\"`. */\n\tname: string;\n\t/** One-liner, matches the yargs registration's description. */\n\tdescription: string;\n\t/** Required positionals only, in order. Empty when the command needs none. */\n\tpositionals: PositionalPrompt[];\n\t/** Parent command, for Layer 2 grouping: `\"auth\" | \"skills\" | \"upgrade\"`. */\n\tgroup?: string;\n}\n\nconst numeric = (value: string): boolean | string => (/^\\d+$/.test(value) ? true : \"enter a number\");\n\n/**\n * The full command surface, hand-maintained in parallel with `cli.ts`'s\n * yargs registrations (this module does not introspect yargs at runtime).\n * `run <task>` is deliberately excluded — it's CI/scripting-oriented, and an\n * interactive prompt in front of it would work against that. `lint\n * commit-msg <file>` is excluded for the same reason: it's invoked\n * exclusively from `.husky/commit-msg \"$1\"`, never typed by a human.\n */\nexport const COMMAND_REGISTRY: CommandEntry[] = [\n\t{ name: \"version\", description: \"Print the CLI version\", positionals: [] },\n\t{\n\t\tname: \"clone\",\n\t\tdescription: \"Clone all repos in a GitHub org as siblings under a single directory\",\n\t\tpositionals: [],\n\t},\n\t{ name: \"doctor\", description: \"Load the config and run a smoke check against every provider\", positionals: [] },\n\t{ name: \"setup\", description: \"Apply infra setup actions across every configured capability\", positionals: [] },\n\t{\n\t\tname: \"secret set\",\n\t\tdescription: \"Set a single secret via the configured `secrets` capability\",\n\t\tpositionals: [{ key: \"name\", message: \"Secret name:\", type: \"input\" }],\n\t},\n\t{\n\t\tname: \"secrets sync\",\n\t\tdescription: \"Read a vault environment + fan KEY=VALUEs out to secrets + deployment env vars\",\n\t\tpositionals: [{ key: \"environmentId\", message: \"Vault environment id:\", type: \"input\" }],\n\t},\n\t{\n\t\tname: \"deploy\",\n\t\tdescription: \"Trigger a deployment via the configured `deployment` capability\",\n\t\tpositionals: [{ key: \"branch\", message: \"Branch to deploy:\", type: \"input\" }],\n\t},\n\t{\n\t\tname: \"cleanup-preview\",\n\t\tdescription: \"List and delete Cloudflare Pages preview deployments for a GitHub PR\",\n\t\tpositionals: [{ key: \"pr\", message: \"PR number:\", type: \"input\", validate: numeric }],\n\t},\n\t{\n\t\tname: \"bump-versions\",\n\t\tdescription: \"Bump all non-private package versions in lockstep (semantic-release prepareCmd)\",\n\t\tpositionals: [{ key: \"newVersion\", cliArg: \"new-version\", message: \"New version:\", type: \"input\" }],\n\t},\n\t{\n\t\tname: \"publish\",\n\t\tdescription: \"Publish @theholocron/* packages to npm\",\n\t\tpositionals: [],\n\t},\n\t{\n\t\tname: \"sync\",\n\t\tdescription:\n\t\t\t\"Sync state from config to the provider and local files (labels, properties, teams, topics, keywords, description, homepage, readme, workflows, scripts, wiki)\",\n\t\tpositionals: [],\n\t},\n\t{ name: \"ci\", description: \"Run the merge-gating checks locally, in CI order — 'will CI pass?'\", positionals: [] },\n\t{\n\t\tname: \"sync-github\",\n\t\tdescription: \"Sync workflow templates and composite actions to theholocron/.github\",\n\t\tpositionals: [],\n\t},\n\t{\n\t\tname: \"sync-readme\",\n\t\tdescription: \"Sync the Installation + Usage block in README.md from package.json\",\n\t\tpositionals: [],\n\t},\n\t{ name: \"config show\", description: \"Print the resolved holocron config\", positionals: [] },\n\t{\n\t\tname: \"new\",\n\t\tdescription: \"Scaffold a new repo from a GitHub template (e.g. cli, react, nextjs, node, monorepo, base)\",\n\t\tpositionals: [],\n\t},\n\t{\n\t\tname: \"plugin create\",\n\t\tdescription: \"Scaffold a new @theholocron/holocron-plugin-<slug> package\",\n\t\tpositionals: [\n\t\t\t{ key: \"slug\", message: \"Package slug (kebab-case):\", type: \"input\" },\n\t\t\t{ key: \"vendor\", message: \"Vendor display name (PascalCase):\", type: \"input\" },\n\t\t],\n\t},\n\t{\n\t\tname: \"skills install\",\n\t\tdescription: \"Copy skills from @theholocron/skills into .agents/ with agent symlinks\",\n\t\tpositionals: [],\n\t\tgroup: \"skills\",\n\t},\n\t{\n\t\tname: \"skills remove\",\n\t\tdescription: \"Remove installed skills via npx skills remove\",\n\t\tpositionals: [],\n\t\tgroup: \"skills\",\n\t},\n\t{\n\t\tname: \"skills update\",\n\t\tdescription: \"Update installed skills to their latest upstream versions via npx skills update\",\n\t\tpositionals: [],\n\t\tgroup: \"skills\",\n\t},\n\t{\n\t\tname: \"upgrade node\",\n\t\tdescription: \"Scan the repo and update every Node.js version pin to a new major\",\n\t\tpositionals: [{ key: \"to\", message: \"Target Node.js major version:\", type: \"input\", validate: numeric }],\n\t\tgroup: \"upgrade\",\n\t},\n\t{\n\t\tname: \"upgrade deps\",\n\t\tdescription: \"Bump every @theholocron/* pin to latest and migrate holocron.config.ts to the current preset API\",\n\t\tpositionals: [],\n\t\tgroup: \"upgrade\",\n\t},\n\t{\n\t\tname: \"auth set\",\n\t\tdescription: \"Verify + store a bootstrap token for a provider\",\n\t\tpositionals: [{ key: \"provider\", message: \"Provider name:\", type: \"input\" }],\n\t\tgroup: \"auth\",\n\t},\n\t{\n\t\tname: \"auth unset\",\n\t\tdescription: \"Remove a stored bootstrap token\",\n\t\tpositionals: [{ key: \"provider\", message: \"Provider:\", type: \"select\", choices: listStoredProviders }],\n\t\tgroup: \"auth\",\n\t},\n\t{\n\t\tname: \"auth check\",\n\t\tdescription: \"Re-verify a stored bootstrap token\",\n\t\tpositionals: [{ key: \"provider\", message: \"Provider:\", type: \"select\", choices: listStoredProviders }],\n\t\tgroup: \"auth\",\n\t},\n\t{\n\t\tname: \"auth list\",\n\t\tdescription: \"List every provider with a stored bootstrap token\",\n\t\tpositionals: [],\n\t\tgroup: \"auth\",\n\t},\n];\n\n/** Look up a {@link CommandEntry} by its full name — for Layer 3 call sites in `cli.ts`. */\nexport function getEntry(name: string): CommandEntry {\n\tconst entry = COMMAND_REGISTRY.find((e) => e.name === name);\n\tif (!entry) throw new Error(`interactive-menu: no COMMAND_REGISTRY entry named \"${name}\"`);\n\treturn entry;\n}\n\n/**\n * Searchable autocomplete over `entries` — the Layer 1 top-level picker, and\n * (passed a `group`-filtered subset) the Layer 2 parent-command picker.\n * `select()` would work too at these list sizes, but `search()` degrades\n * gracefully as the surface grows and costs nothing when it doesn't.\n */\nexport async function pickCommand(\n\tentries: CommandEntry[],\n\tmessage = \"What would you like to do?\"\n): Promise<CommandEntry> {\n\tconst byName = new Map(entries.map((e) => [e.name, e]));\n\tconst picked = await search<string>({\n\t\tmessage,\n\t\tsource: (term) => searchChoices(entries, term),\n\t});\n\t// `source` only ever returns names drawn from `entries`, so this is always defined.\n\treturn byName.get(picked)!;\n}\n\n/**\n * `@inquirer/search`'s `source` callback, factored out as a plain function —\n * unit-testable directly instead of only through a mocked `search()` call.\n * Empty/undefined `term` (nothing typed yet) returns every entry.\n */\nexport function searchChoices(\n\tentries: CommandEntry[],\n\tterm: string | undefined\n): Array<{ name: string; value: string; description: string }> {\n\tconst pool = !term ? entries : entries.filter((e) => matches(e, term));\n\treturn pool.map((e) => ({ name: e.name, value: e.name, description: e.description }));\n}\n\nfunction matches(entry: CommandEntry, term: string): boolean {\n\tconst needle = term.toLowerCase();\n\treturn entry.name.toLowerCase().includes(needle) || entry.description.toLowerCase().includes(needle);\n}\n\n/**\n * For each of `entry.positionals` not already present in `argv`, prompts for\n * it (`input()` or `select()`, per the positional's `type`) and returns the\n * resolved values in positional order — ready to append to a spawned child's\n * argv, or to use directly in the current handler (Layer 3).\n *\n * Throws {@link NonInteractiveError} the first time it would need to prompt\n * on a non-TTY stdin, and again if a `select` positional's choices resolve\n * empty (nothing to pick from — e.g. `auth unset` with no stored tokens).\n */\nexport async function promptForPositionals(entry: CommandEntry, argv: Record<string, unknown>): Promise<string[]> {\n\tconst out: string[] = [];\n\tfor (const positional of entry.positionals) {\n\t\tconst existing = argv[positional.key];\n\t\tif (existing !== undefined && existing !== \"\") {\n\t\t\tout.push(String(existing));\n\t\t\tcontinue;\n\t\t}\n\t\tif (!process.stdin.isTTY) {\n\t\t\tthrow new NonInteractiveError(\n\t\t\t\t`\\`${entry.name}\\` needs \"${positional.key}\" — pass it directly: holocron ${entry.name} <${positional.cliArg ?? positional.key}>`\n\t\t\t);\n\t\t}\n\t\tif (positional.type === \"select\") {\n\t\t\tconst choices =\n\t\t\t\ttypeof positional.choices === \"function\" ? positional.choices() : (positional.choices ?? []);\n\t\t\tif (choices.length === 0) {\n\t\t\t\tthrow new NonInteractiveError(\n\t\t\t\t\t`\\`${entry.name}\\`: no ${positional.key} to choose from — nothing stored yet`\n\t\t\t\t);\n\t\t\t}\n\t\t\tout.push(await select({ message: positional.message, choices: choices.map((c) => ({ value: c })) }));\n\t\t} else {\n\t\t\tout.push(\n\t\t\t\tawait input({\n\t\t\t\t\tmessage: positional.message,\n\t\t\t\t\t...(positional.validate ? { validate: positional.validate } : {}),\n\t\t\t\t})\n\t\t\t);\n\t\t}\n\t}\n\treturn out;\n}\n\n/**\n * `--token` (repeatable), `--org`, `--cwd`, `--dry-run` — the global flags a\n * menu-launched child should inherit from the parent invocation. Everything\n * else (command-specific options) was never captured by the top-level `$0`\n * handler in the first place, so there's nothing else to forward.\n */\nexport function forwardedFlags(argv: Record<string, unknown>): string[] {\n\tconst out: string[] = [];\n\tconst tokens = argv.token as string[] | undefined;\n\tfor (const t of tokens ?? []) out.push(\"--token\", t);\n\tif (typeof argv.org === \"string\") out.push(\"--org\", argv.org);\n\tif (typeof argv.cwd === \"string\") out.push(\"--cwd\", argv.cwd);\n\tif (argv.dryRun === true) out.push(\"--dry-run\");\n\treturn out;\n}\n\n/** `entry.name` split into tokens, resolved positionals appended, then forwarded flags. */\nexport function buildChildArgv(\n\tentry: CommandEntry,\n\tpositionals: string[],\n\tparentArgv: Record<string, unknown>\n): string[] {\n\treturn [...entry.name.split(\" \"), ...positionals, ...forwardedFlags(parentArgv)];\n}\n\n/** Spawn `holocron <...args>` inheriting stdio; resolve with its exit code. */\nfunction spawnChild(args: string[]): Promise<number> {\n\treturn new Promise((resolve) => {\n\t\tconst child = spawn(process.execPath, [process.argv[1]!, ...args], { stdio: \"inherit\" });\n\t\tchild.on(\"exit\", (code) => resolve(code ?? 0));\n\t\tchild.on(\"error\", () => resolve(1));\n\t});\n}\n\n/**\n * Layers 1 and 2: pick a command from `entries`, prompt for its required\n * positionals, spawn it as a fresh `holocron` invocation, and set\n * `process.exitCode` from the child — the caller (a `$0` handler in\n * `cli.ts`) returns normally afterward so the parent's own telemetry\n * flush / update-notifier tail still runs. The parent's own\n * `command_completed` event fires with command name \"unknown\" (the\n * middleware ran before any command was picked) — left as-is rather than\n * suppressed; it's a real, useful signal (\"the menu got used\").\n */\nexport async function launchMenu(\n\tentries: CommandEntry[],\n\tparentArgv: Record<string, unknown>,\n\tpickMessage?: string,\n\tnonInteractiveMessage = \"Run `holocron --help` to see available commands.\"\n): Promise<void> {\n\tif (!process.stdin.isTTY) {\n\t\tthrow new NonInteractiveError(nonInteractiveMessage);\n\t}\n\tconst picked = await pickCommand(entries, pickMessage);\n\tconst positionals = await promptForPositionals(picked, {});\n\tconst childArgv = buildChildArgv(picked, positionals, parentArgv);\n\tprocess.exitCode = await spawnChild(childArgv);\n}\n","import { mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport chalk from \"chalk\";\n\nimport { env } from \"./env.js\";\n\nconst PACKAGE_NAME = \"@theholocron/cli\";\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000;\nconst FETCH_TIMEOUT_MS = 3000;\n\ninterface CacheEntry {\n\tlatestVersion: string;\n\tcheckedAt: number;\n}\n\nfunction getCacheDir(): string {\n\treturn env.get(\"HOLOCRON_CACHE_DIR\") ?? join(homedir(), \".cache\", \"holocron\");\n}\n\nfunction getCachePath(): string {\n\treturn join(getCacheDir(), \"update-check.json\");\n}\n\nfunction readCache(): CacheEntry | null {\n\ttry {\n\t\treturn JSON.parse(readFileSync(getCachePath(), \"utf8\")) as CacheEntry;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction writeCache(entry: CacheEntry): void {\n\ttry {\n\t\tmkdirSync(getCacheDir(), { recursive: true });\n\t\twriteFileSync(getCachePath(), JSON.stringify(entry));\n\t} catch {\n\t\t// silently ignore — update check is best-effort\n\t}\n}\n\nasync function fetchLatestVersion(channel: string): Promise<string | null> {\n\ttry {\n\t\tconst res = await fetch(`https://registry.npmjs.org/${encodeURIComponent(PACKAGE_NAME)}`, {\n\t\t\tsignal: AbortSignal.timeout(FETCH_TIMEOUT_MS),\n\t\t});\n\t\tif (!res.ok) return null;\n\t\tconst data = (await res.json()) as { \"dist-tags\": Record<string, string> };\n\t\treturn data[\"dist-tags\"][channel] ?? data[\"dist-tags\"][\"latest\"] ?? null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction getChannel(version: string): string {\n\tconst match = /^[^-]+-([a-zA-Z]+)/.exec(version);\n\treturn match?.[1] ?? \"latest\";\n}\n\nexport function isUpdateAvailable(current: string, latest: string): boolean {\n\tconst normalize = (v: string) => v.replace(/^v/, \"\");\n\tconst c = normalize(current);\n\tconst l = normalize(latest);\n\tif (c === l) return false;\n\n\tconst splitPre = (v: string): [string, string] => {\n\t\tconst idx = v.indexOf(\"-\");\n\t\treturn idx === -1 ? [v, \"\"] : [v.slice(0, idx), v.slice(idx + 1)];\n\t};\n\n\tconst [cRelease, cPre] = splitPre(c);\n\tconst [lRelease, lPre] = splitPre(l);\n\n\tconst parseRelease = (r: string) => r.split(\".\").map(Number);\n\tconst cParts = parseRelease(cRelease);\n\tconst lParts = parseRelease(lRelease);\n\n\tfor (let i = 0; i < Math.max(cParts.length, lParts.length); i++) {\n\t\tconst cv = cParts[i] ?? 0;\n\t\tconst lv = lParts[i] ?? 0;\n\t\tif (lv > cv) return true;\n\t\tif (lv < cv) return false;\n\t}\n\n\t// Release parts equal — compare prerelease\n\tif (!lPre && cPre) return true; // stable > prerelease\n\tif (lPre && !cPre) return false; // prerelease < stable\n\n\t// Both prerelease — compare segment by segment\n\tconst cPreParts = cPre.split(\".\");\n\tconst lPreParts = lPre.split(\".\");\n\tfor (let i = 0; i < Math.max(cPreParts.length, lPreParts.length); i++) {\n\t\tconst cv = cPreParts[i] ?? \"\";\n\t\tconst lv = lPreParts[i] ?? \"\";\n\t\tconst cvNum = Number(cv);\n\t\tconst lvNum = Number(lv);\n\t\tif (!isNaN(cvNum) && !isNaN(lvNum)) {\n\t\t\tif (lvNum > cvNum) return true;\n\t\t\tif (lvNum < cvNum) return false;\n\t\t} else {\n\t\t\tif (lv > cv) return true;\n\t\t\tif (lv < cv) return false;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nfunction formatNotice(current: string, latest: string): string {\n\tconst installCmd = `npm install -g ${PACKAGE_NAME}`;\n\t// Measure raw strings before applying chalk so we avoid control-char regexes.\n\tconst raw1 = `Update available: ${current} → ${latest}`;\n\tconst raw2 = `Run ${installCmd} to update`;\n\tconst width = Math.max(raw1.length, raw2.length) + 4;\n\tconst bar = chalk.yellow(\"─\".repeat(width));\n\tconst border = chalk.yellow(\"│\");\n\tconst pad = (raw: string, styled: string) => `${border} ${styled}${\" \".repeat(width - 2 - raw.length)} ${border}`;\n\treturn [\n\t\t\"\",\n\t\tchalk.yellow(`╭${bar}╮`),\n\t\tpad(raw1, `Update available: ${chalk.dim(current)} → ${chalk.green(latest)}`),\n\t\tpad(raw2, `Run ${chalk.cyan(installCmd)} to update`),\n\t\tchalk.yellow(`╰${bar}╯`),\n\t\t\"\",\n\t].join(\"\\n\");\n}\n\nexport async function checkForUpdates(currentVersion: string): Promise<(() => void) | null> {\n\tif (env.get(\"CI\") || env.get(\"NO_UPDATE_NOTIFIER\")) return null;\n\n\tconst channel = getChannel(currentVersion);\n\tconst cache = readCache();\n\tconst now = Date.now();\n\n\tlet latestVersion: string | null = null;\n\n\tif (cache && now - cache.checkedAt < CACHE_TTL_MS) {\n\t\tlatestVersion = cache.latestVersion;\n\t} else {\n\t\tlatestVersion = await fetchLatestVersion(channel);\n\t\tif (latestVersion) writeCache({ latestVersion, checkedAt: now });\n\t}\n\n\tif (!latestVersion || !isUpdateAvailable(currentVersion, latestVersion)) return null;\n\n\treturn () => {\n\t\tprocess.stderr.write(formatNotice(currentVersion, latestVersion as string) + \"\\n\");\n\t};\n}\n","import { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nimport { input, select } from \"@inquirer/prompts\";\nimport { createAstromech } from \"@theholocron/astromech\";\nimport { loadTasksConfig } from \"@theholocron/astromech/config\";\nimport type { LogLevel } from \"@theholocron/observability/core\";\nimport yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\n\nimport { AuthError, createFeatureResolver } from \"./auth/auth-resolver.js\";\nimport { type ParsedTokenArgs, parseTokenArgs, TokenParseError } from \"./auth/token-args.js\";\nimport { runAuthCheck, runAuthList, runAuthSet, runAuthUnset } from \"./commands/auth.js\";\nimport { runCleanupPreview } from \"./commands/cleanup-preview.js\";\nimport { runClone } from \"./commands/clone.js\";\nimport { commandsInContext } from \"./commands/contexts.js\";\nimport { runDeploy, runDeployFromFiles } from \"./commands/deploy.js\";\nimport { runDoctor } from \"./commands/doctor.js\";\nimport { NewError, parseTopics, runNew, validateRepoName } from \"./commands/new.js\";\nimport { runNpmBumpVersions } from \"./commands/npm-bump-versions.js\";\nimport { PluginCreateError, resolvePluginCreateInputs, runPluginCreate } from \"./commands/plugin-create/index.js\";\nimport { runPublish, runSteadyPublish, runSyncTrust } from \"./commands/publish.js\";\nimport { runSecretSet } from \"./commands/secret-set.js\";\nimport { runSecretsSync } from \"./commands/secrets-sync.js\";\nimport { runSetup } from \"./commands/setup/index.js\";\nimport { runSkillsInstall, runSkillsRemove, runSkillsUpdate } from \"./commands/skills.js\";\nimport { runSync } from \"./commands/sync.js\";\nimport { runSyncGithub } from \"./commands/sync-github.js\";\nimport { runSyncReadme } from \"./commands/sync-readme.js\";\nimport { runUpgradeDeps } from \"./commands/upgrade-deps.js\";\nimport { runUpgradeNode } from \"./commands/upgrade-node.js\";\nimport { lintCommitMsgFile } from \"./commit-lint/lint-commit-msg-file.js\";\nimport type { TelemetryConfig } from \"./config/config.js\";\nimport { loadConfig } from \"./config/load-config.js\";\nimport { env } from \"./env.js\";\nimport { COMMAND_REGISTRY, getEntry, launchMenu, promptForPositionals } from \"./interactive-menu.js\";\nimport { buildCliLogger, type BuildCliLoggerOpts, getLogger, getRunId } from \"./logger.js\";\nimport { CARDINALITY } from \"./plugin/capabilities.js\";\nimport { applyConfig, captureException, endSession, flush, init, startCommand } from \"./telemetry.js\";\nimport { checkForUpdates } from \"./update-notifier.js\";\n\nconst resolveCloneToken = createFeatureResolver({ envName: \"HOLOCRON_READ_TOKEN\", keyringKey: \"github.read\" });\nconst resolveSyncToken = createFeatureResolver({ envName: \"HOLOCRON_SYNC_TOKEN\", keyringKey: \"github.sync\" });\n\n/**\n * Error class names whose `.message` is a complete, actionable sentence —\n * the top-level catch prints it and suppresses the stack trace.\n */\nconst USER_FACING_ERRORS = new Set([\"WorkspaceContextError\", \"ConfigFileError\", \"NonInteractiveError\"]);\n\nconst { version: CLI_VERSION } = JSON.parse(readFileSync(new URL(\"../package.json\", import.meta.url), \"utf-8\")) as {\n\tversion: string;\n};\n\n/** Whether to print the correlation id at command end (`--debug` / `--verbose`). */\nlet printRunId = false;\n\n/**\n * Resolves the active org in priority order:\n * 1. `--org` CLI flag\n * 2. `HOLOCRON_ORG` env var\n * 3. `org` from `holocron.config.ts`\n */\nfunction resolveOrg(argv: { org?: string }, config: { org?: string }): string | undefined {\n\treturn argv.org ?? env.get(\"HOLOCRON_ORG\") ?? config.org;\n}\n\n/**\n * `buildCliLogger` options derived from a loaded `holocron.config` — the\n * level, the Axiom dataset, and the resolved org for a keyring-backed\n * Axiom token. Used by every handler that has already called `loadConfig`.\n */\nfunction cliLoggerOpts(\n\targv: { org?: string; verbose?: boolean; quiet?: boolean },\n\tresolved: { org?: string; log?: { level?: LogLevel; axiom?: { dataset?: string } } }\n): BuildCliLoggerOpts {\n\treturn {\n\t\tconfigLevel: resolved.log?.level,\n\t\tconfigAxiomDataset: resolved.log?.axiom?.dataset,\n\t\torg: resolveOrg(argv, resolved),\n\t};\n}\n\n/**\n * Fold a loaded `holocron.config` into the running process: reconfigure the\n * logger from `log:`, then apply the `telemetry:` override layer. Every handler\n * that has called `loadConfig` runs this, so a repo's `telemetry.enabled: false`\n * (or `analytics: \"none\"`) is honoured for that command. Env still wins —\n * `applyConfig` only narrows what `init` already turned on.\n */\nfunction applyResolvedConfig(\n\targv: { org?: string; verbose?: boolean; quiet?: boolean },\n\tresolved: {\n\t\torg?: string;\n\t\tlog?: { level?: LogLevel; axiom?: { dataset?: string } };\n\t\ttelemetry?: TelemetryConfig;\n\t}\n): void {\n\tbuildCliLogger(argv, cliLoggerOpts(argv, resolved));\n\tapplyConfig(resolved.telemetry);\n}\n\n/** Parses --token values and returns the context spread, or null on parse error (exits with code 1). */\nfunction tokenContext(rawTokens: string[] | undefined): ParsedTokenArgs | null {\n\tif (!rawTokens?.length) return {};\n\ttry {\n\t\treturn parseTokenArgs(rawTokens);\n\t} catch (err) {\n\t\tif (err instanceof TokenParseError) {\n\t\t\tgetLogger().error(`--token: ${err.message}`);\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn null;\n\t\t}\n\t\tthrow err;\n\t}\n}\n\ninit(CLI_VERSION);\nconst updateCheckPromise = checkForUpdates(CLI_VERSION);\n\nlet finishCommand: (ok: boolean) => void = () => {};\n/** Set by `.fail()` once it has printed an error, so the outer catch doesn't repeat it. */\nlet errorReported = false;\n\ntry {\n\tawait yargs(hideBin(process.argv))\n\t\t.scriptName(\"\")\n\t\t.usage(\"holocron <command> [options]\")\n\t\t// Keep everything after `--` in `argv['--']` instead of folding it into\n\t\t// `argv._`. `holocron run <task> [job] -- <args>` forwards `<args>` to the\n\t\t// underlying tool (`lhci autorun --config=…`, `turbo run build -- …`); the\n\t\t// telemetry command name reads `argv._` and must not pick these up.\n\t\t.parserConfiguration({ \"populate--\": true })\n\t\t// ── global options (apply to every subcommand) ──────────────────────\n\t\t.option(\"dry-run\", {\n\t\t\ttype: \"boolean\",\n\t\t\tdefault: false,\n\t\t\tdescribe:\n\t\t\t\t\"Print what would be mutated without calling capability mutators. \" +\n\t\t\t\t\"Commands branch on this; read-only commands ignore it.\",\n\t\t})\n\t\t.option(\"token\", {\n\t\t\ttype: \"string\",\n\t\t\tarray: true,\n\t\t\tdescribe:\n\t\t\t\t\"Vendor token override for plugins. \" +\n\t\t\t\t\"Bare form: --token <value> (fallback for all plugins, single-plugin commands). \" +\n\t\t\t\t\"Keyed form: --token vendor=value (targets a specific provider; repeat for each). \" +\n\t\t\t\t\"Example: --token github=ghp_xxx --token vercel=v_yyy\",\n\t\t})\n\t\t.option(\"org\", {\n\t\t\ttype: \"string\",\n\t\t\tdescribe:\n\t\t\t\t\"Active org name for namespaced keyring lookup. \" +\n\t\t\t\t\"Overrides HOLOCRON_ORG env var and the `org` field in holocron.config.ts. \" +\n\t\t\t\t\"Example: --org theholocron\",\n\t\t})\n\t\t.option(\"cwd\", {\n\t\t\ttype: \"string\",\n\t\t\tdefault: process.cwd(),\n\t\t\tdescribe: \"Directory to search for holocron.config.json\",\n\t\t})\n\t\t.option(\"verbose\", {\n\t\t\ttype: \"boolean\",\n\t\t\tdefault: false,\n\t\t\tdescribe: \"Set the log level to debug — full structured operational output.\",\n\t\t})\n\t\t.option(\"debug\", {\n\t\t\ttype: \"boolean\",\n\t\t\tdefault: false,\n\t\t\tdescribe: \"Print the run ID at command end for Axiom lookup. Does not change the log level.\",\n\t\t})\n\t\t.option(\"quiet\", {\n\t\t\ttype: \"boolean\",\n\t\t\tdefault: false,\n\t\t\tdescribe: \"Set the log level to error — suppress info and warn.\",\n\t\t})\n\t\t.middleware((argv) => {\n\t\t\tconst name = (argv._ as string[]).slice(0, 2).join(\" \") || \"unknown\";\n\t\t\tprintRunId = Boolean(argv.debug || argv.verbose);\n\t\t\t// Establish the root logger first (command name + flags + env) so its\n\t\t\t// `runId` is available to tag telemetry events. Handlers that load a\n\t\t\t// config call `buildCliLogger(argv, { configLevel })` again to fold in\n\t\t\t// the lowest-priority level + Axiom-dataset sources.\n\t\t\tbuildCliLogger(argv, { command: name, org: argv.org });\n\t\t\tfinishCommand = startCommand(name);\n\t\t})\n\t\t// ── commands ────────────────────────────────────────────────────────\n\t\t.command(\n\t\t\t\"version\",\n\t\t\t\"Print the CLI version\",\n\t\t\t() => {},\n\t\t\t() => {\n\t\t\t\tconsole.log(`holocron ${CLI_VERSION}`);\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"clone\",\n\t\t\t\"Clone all repos in a GitHub org as siblings under a single directory\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.option(\"org\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdemandOption: true,\n\t\t\t\t\t\tdescribe: \"GitHub org to clone (e.g., theholocron)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"dir\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Parent directory to clone into (default: ~/Code/<org>)\",\n\t\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tconst tokens = tokenContext(argv.token);\n\t\t\t\tif (!tokens) return;\n\t\t\t\tlet token: string;\n\t\t\t\ttry {\n\t\t\t\t\ttoken = resolveCloneToken({ cliToken: tokens.cliTokens?.[\"github\"] ?? tokens.cliToken });\n\t\t\t\t} catch (err) {\n\t\t\t\t\tgetLogger().error(`clone: ${err instanceof AuthError ? err.message : String(err)}`);\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst report = await runClone({\n\t\t\t\t\torg: argv.org,\n\t\t\t\t\ttoken,\n\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t...(argv.dir ? { dir: argv.dir } : {}),\n\t\t\t\t});\n\t\t\t\tif (report.status === \"fail\") process.exitCode = 1;\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"doctor\",\n\t\t\t\"Load the config and run a smoke check against every provider\",\n\t\t\t(y) =>\n\t\t\t\ty.option(\"repo\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescribe: 'Repo coords (\"owner/name\"). Defaults to plugin-specific resolution.',\n\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tconst tokens = tokenContext(argv.token);\n\t\t\t\tif (!tokens) return;\n\t\t\t\tconst loaded = await loadConfig(argv.cwd);\n\t\t\t\tapplyResolvedConfig(argv, loaded.resolved);\n\t\t\t\tconst report = await runDoctor({\n\t\t\t\t\tloaded,\n\t\t\t\t\tcontext: {\n\t\t\t\t\t\trepoRoot: argv.cwd,\n\t\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t\t...(argv.repo ? { repo: argv.repo } : {}),\n\t\t\t\t\t\t...tokens,\n\t\t\t\t\t\torg: resolveOrg(argv, loaded.resolved),\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tif (report.summary.fail > 0) {\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"setup\",\n\t\t\t\"Apply infra setup actions across every configured capability\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.option(\"repo\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: 'Repo coords (\"owner/name\"). Defaults to plugin-specific resolution.',\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"hooks\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"Install git hooks (.husky/pre-push → holocron ci). Default: on for protection:'strict'. --no-hooks to skip.\",\n\t\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tconst tokens = tokenContext(argv.token);\n\t\t\t\tif (!tokens) return;\n\t\t\t\tconst loaded = await loadConfig(argv.cwd);\n\t\t\t\tapplyResolvedConfig(argv, loaded.resolved);\n\t\t\t\tconst report = await runSetup({\n\t\t\t\t\tloaded,\n\t\t\t\t\tcontext: {\n\t\t\t\t\t\trepoRoot: argv.cwd,\n\t\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t\t...(argv.repo ? { repo: argv.repo } : {}),\n\t\t\t\t\t\t...tokens,\n\t\t\t\t\t\torg: resolveOrg(argv, loaded.resolved),\n\t\t\t\t\t},\n\t\t\t\t\t...(argv.hooks !== undefined ? { hooks: argv.hooks as boolean } : {}),\n\t\t\t\t});\n\t\t\t\tif (report.summary.fail > 0) {\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"skills\",\n\t\t\t\"Manage agent skills from the @theholocron/skills registry\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.command(\n\t\t\t\t\t\t\"install\",\n\t\t\t\t\t\t\"Copy skills from @theholocron/skills into .agents/ with agent symlinks\",\n\t\t\t\t\t\t() => {},\n\t\t\t\t\t\tasync (argv) => {\n\t\t\t\t\t\t\tconst loaded = await loadConfig(argv.cwd);\n\t\t\t\t\t\t\tawait runSkillsInstall({ loaded, context: { repoRoot: argv.cwd, dryRun: argv.dryRun } });\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\t\t\t\t\t.command(\n\t\t\t\t\t\t\"remove [names..]\",\n\t\t\t\t\t\t\"Remove installed skills via npx skills remove\",\n\t\t\t\t\t\t(yy) =>\n\t\t\t\t\t\t\tyy.positional(\"names\", {\n\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\tarray: true,\n\t\t\t\t\t\t\t\tdescribe: \"Skill name(s) to remove (omit to remove all installed skills)\",\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t(argv) => {\n\t\t\t\t\t\t\tconst report = runSkillsRemove({\n\t\t\t\t\t\t\t\tcontext: { repoRoot: argv.cwd, dryRun: argv.dryRun },\n\t\t\t\t\t\t\t\t...(argv.names?.length ? { names: argv.names as string[] } : {}),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (report.status === \"fail\") process.exitCode = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\t\t\t\t\t.command(\n\t\t\t\t\t\t\"update [name]\",\n\t\t\t\t\t\t\"Update installed skills to their latest upstream versions via npx skills update\",\n\t\t\t\t\t\t(yy) =>\n\t\t\t\t\t\t\tyy.positional(\"name\", {\n\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\tdescribe: \"Skill name to update (omit to update all installed skills)\",\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t(argv) => {\n\t\t\t\t\t\t\tconst report = runSkillsUpdate({\n\t\t\t\t\t\t\t\tcontext: { repoRoot: argv.cwd, dryRun: argv.dryRun },\n\t\t\t\t\t\t\t\t...(argv.name ? { name: argv.name as string } : {}),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (report.status === \"fail\") process.exitCode = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\t\t\t\t\t.command(\n\t\t\t\t\t\t\"$0\",\n\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t() => {},\n\t\t\t\t\t\tasync (argv) => {\n\t\t\t\t\t\t\tawait launchMenu(\n\t\t\t\t\t\t\t\tCOMMAND_REGISTRY.filter((e) => e.group === \"skills\"),\n\t\t\t\t\t\t\t\targv,\n\t\t\t\t\t\t\t\t\"skills — choose a subcommand:\",\n\t\t\t\t\t\t\t\t\"Run `holocron skills --help` to see available skills subcommands.\"\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t),\n\t\t\t() => {}\n\t\t)\n\t\t.command(\n\t\t\t\"secret set [name] [value]\",\n\t\t\t\"Set a single secret via the configured `secrets` capability\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.positional(\"name\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Secret name (e.g., NPM_TOKEN)\",\n\t\t\t\t\t})\n\t\t\t\t\t.positional(\"value\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"Secret value (positional). If omitted, sources from --from-stdin, --from-env, or env var matching <name>.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"from-stdin\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdefault: false,\n\t\t\t\t\t\tdescribe: \"Read the secret value from stdin\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"from-env\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Read the secret value from the named env var (otherwise: env var matching <name>)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"scope\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdefault: \"repo\",\n\t\t\t\t\t\tdescribe: 'Scope: \"repo\" (default), \"env=<name>\", or \"org=<name>\"',\n\t\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tconst tokens = tokenContext(argv.token);\n\t\t\t\tif (!tokens) return;\n\t\t\t\tconst [name] = await promptForPositionals(getEntry(\"secret set\"), argv as Record<string, unknown>);\n\t\t\t\tconst scopeArg = argv.scope as string;\n\t\t\t\tconst scope = parseScope(scopeArg);\n\t\t\t\tconst loaded = await loadConfig(argv.cwd);\n\t\t\t\tapplyResolvedConfig(argv, loaded.resolved);\n\t\t\t\tconst report = await runSecretSet({\n\t\t\t\t\tloaded,\n\t\t\t\t\tcontext: {\n\t\t\t\t\t\trepoRoot: argv.cwd,\n\t\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t\t...tokens,\n\t\t\t\t\t\torg: resolveOrg(argv, loaded.resolved),\n\t\t\t\t\t},\n\t\t\t\t\tname: name!,\n\t\t\t\t\t...(argv.value ? { value: argv.value as string } : {}),\n\t\t\t\t\t...(argv.fromStdin ? { fromStdin: true } : {}),\n\t\t\t\t\t...(argv.fromEnv ? { fromEnv: argv.fromEnv as string } : {}),\n\t\t\t\t\tscope,\n\t\t\t\t});\n\t\t\t\tif (report.status === \"fail\") {\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"secrets sync [environmentId]\",\n\t\t\t\"Read a vault environment + fan KEY=VALUEs out to secrets + deployment env vars\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.positional(\"environmentId\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Vault environment id to read (1P Environment id, etc.)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"project-id\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Deployment project id (e.g., Vercel prj_*). Required when deployment is loaded.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"target\", {\n\t\t\t\t\t\ttype: \"array\",\n\t\t\t\t\t\tdefault: [\"production\", \"preview\"] as Array<\"development\" | \"preview\" | \"production\">,\n\t\t\t\t\t\tdescribe: \"Deployment targets to sync to. Defaults to production + preview.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"github-secret\", {\n\t\t\t\t\t\ttype: \"array\",\n\t\t\t\t\t\tdescribe: \"Vault key(s) to push to GH Actions secrets (repeatable). Omit to push every key.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"github-secret-scope\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdefault: \"repo\",\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t'Scope applied to every --github-secret key: \"repo\" (default), \"env=<name>\", or \"org=<name>\".',\n\t\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tconst tokens = tokenContext(argv.token);\n\t\t\t\tif (!tokens) return;\n\t\t\t\tconst githubSecretScope = parseScope(argv.githubSecretScope as string);\n\t\t\t\tconst [environmentId] = await promptForPositionals(\n\t\t\t\t\tgetEntry(\"secrets sync\"),\n\t\t\t\t\targv as Record<string, unknown>\n\t\t\t\t);\n\t\t\t\tconst loaded = await loadConfig(argv.cwd);\n\t\t\t\tapplyResolvedConfig(argv, loaded.resolved);\n\t\t\t\tconst report = await runSecretsSync({\n\t\t\t\t\tloaded,\n\t\t\t\t\tcontext: {\n\t\t\t\t\t\trepoRoot: argv.cwd,\n\t\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t\t...tokens,\n\t\t\t\t\t\torg: resolveOrg(argv, loaded.resolved),\n\t\t\t\t\t},\n\t\t\t\t\tenvironmentId: environmentId!,\n\t\t\t\t\t...(argv.projectId ? { projectId: argv.projectId } : {}),\n\t\t\t\t\t...(argv.githubSecret?.length ? { githubSecretKeys: argv.githubSecret as string[] } : {}),\n\t\t\t\t\tgithubSecretScope,\n\t\t\t\t\ttargets: argv.target as Array<\"development\" | \"preview\" | \"production\">,\n\t\t\t\t});\n\t\t\t\tif (report.summary.fail > 0) {\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"deploy [branch]\",\n\t\t\t\"Trigger a deployment via the configured `deployment` capability\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.positional(\"branch\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Git branch to deploy (omit when using --files)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"project-id\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdemandOption: true,\n\t\t\t\t\t\tdescribe: \"Deployment project id (e.g., Vercel prj_*)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"target\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tchoices: [\"production\", \"staging\"] as const,\n\t\t\t\t\t\tdescribe: \"Named environment to deploy into. Omit for a branch preview.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"files\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"Deploy from a local directory of source files instead of a Git branch — calls deployFunction(), no linked repo required. Conflicts with `branch`.\",\n\t\t\t\t\t})\n\t\t\t\t\t.conflicts(\"files\", \"branch\"),\n\t\t\tasync (argv) => {\n\t\t\t\tconst tokens = tokenContext(argv.token);\n\t\t\t\tif (!tokens) return;\n\t\t\t\tconst loaded = await loadConfig(argv.cwd);\n\t\t\t\tapplyResolvedConfig(argv, loaded.resolved);\n\t\t\t\tconst context = {\n\t\t\t\t\trepoRoot: argv.cwd,\n\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t...tokens,\n\t\t\t\t\torg: resolveOrg(argv, loaded.resolved),\n\t\t\t\t};\n\n\t\t\t\tif (argv.files) {\n\t\t\t\t\tconst report = await runDeployFromFiles({\n\t\t\t\t\t\tloaded,\n\t\t\t\t\t\tcontext,\n\t\t\t\t\t\tprojectId: argv.projectId as string,\n\t\t\t\t\t\tdir: argv.files as string,\n\t\t\t\t\t\t...(argv.target ? { target: argv.target as \"production\" | \"staging\" } : {}),\n\t\t\t\t\t});\n\t\t\t\t\tif (report.status === \"fail\") {\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst [branch] = await promptForPositionals(getEntry(\"deploy\"), argv as Record<string, unknown>);\n\t\t\t\tconst report = await runDeploy({\n\t\t\t\t\tloaded,\n\t\t\t\t\tcontext,\n\t\t\t\t\tprojectId: argv.projectId as string,\n\t\t\t\t\tbranch: branch!,\n\t\t\t\t\t...(argv.target ? { target: argv.target as \"production\" | \"staging\" } : {}),\n\t\t\t\t});\n\t\t\t\tif (report.status === \"fail\") {\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"cleanup-preview [pr]\",\n\t\t\t\"List and delete Cloudflare Pages preview deployments for a GitHub PR\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.positional(\"pr\", {\n\t\t\t\t\t\ttype: \"number\",\n\t\t\t\t\t\tdescribe: \"PR number to clean up\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"project\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdemandOption: true,\n\t\t\t\t\t\tdescribe: \"Cloudflare Pages project name (e.g. theholocron-preview)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"repo\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"GitHub repo as owner/name — defaults to the repo in holocron.config\",\n\t\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tconst tokens = tokenContext(argv.token);\n\t\t\t\tif (!tokens) return;\n\t\t\t\tconst [pr] = await promptForPositionals(getEntry(\"cleanup-preview\"), argv as Record<string, unknown>);\n\t\t\t\tconst loaded = await loadConfig(argv.cwd);\n\t\t\t\tapplyResolvedConfig(argv, loaded.resolved);\n\t\t\t\tconst report = await runCleanupPreview({\n\t\t\t\t\tloaded,\n\t\t\t\t\tcontext: {\n\t\t\t\t\t\trepoRoot: argv.cwd,\n\t\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t\t...tokens,\n\t\t\t\t\t\torg: resolveOrg(argv, loaded.resolved),\n\t\t\t\t\t},\n\t\t\t\t\tprNumber: Number(pr),\n\t\t\t\t\tproject: argv.project as string,\n\t\t\t\t\t...(argv.repo ? { repo: argv.repo as string } : {}),\n\t\t\t\t});\n\t\t\t\tif (report.status === \"fail\") {\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"bump-versions [new-version]\",\n\t\t\t\"Bump all non-private package versions in lockstep (semantic-release prepareCmd)\",\n\t\t\t(y) =>\n\t\t\t\ty.positional(\"new-version\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescribe: \"Version to set (e.g., 4.2.0 or 2.0.0-alpha.1)\",\n\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tconst [newVersion] = await promptForPositionals(\n\t\t\t\t\tgetEntry(\"bump-versions\"),\n\t\t\t\t\targv as Record<string, unknown>\n\t\t\t\t);\n\t\t\t\tconst report = await runNpmBumpVersions({\n\t\t\t\t\tversion: newVersion!,\n\t\t\t\t\tcwd: argv.cwd,\n\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t});\n\t\t\t\tif (report.status === \"fail\") {\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"publish\",\n\t\t\t\"Publish @theholocron/* packages to npm\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.option(\"initial\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdefault: false,\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"One-shot bootstrap publish for trusted-publishing-eligible packages (npm needs the \" +\n\t\t\t\t\t\t\t\"package to exist before Trusted Publishing can be configured for it). Skips the \" +\n\t\t\t\t\t\t\t\"steady-state OIDC path below — use only for a package's very first publish.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"tag\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"npm distribution tag. Defaults to alpha for --initial, latest for a steady-state publish.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"otp\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"One-time password from your authenticator (required if npm needs 2FA for writes)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"sync-trust\", {\n\t\t\t\t\t\ttype: \"array\",\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"Migrate npm Trusted Publisher config to a new workflow filename across every public \" +\n\t\t\t\t\t\t\t\"package: --sync-trust <old-file> <new-file>. See issue #689 — npm requires fresh \" +\n\t\t\t\t\t\t\t\"interactive 2FA per package; re-run after approving the printed authUrl if it stops early.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"repo\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"owner/repo for Trusted Publisher config (--sync-trust). Defaults to theholocron/holocron.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"provenance\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdefault: true,\n\t\t\t\t\t\tdescribe: \"Publish with --provenance (steady-state only). Default on — free under CI/OIDC.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"skip-already-published\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdefault: false,\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"Steady-state only: check `npm view <pkg>@<version>` before publishing each package and \" +\n\t\t\t\t\t\t\t\"skip it if that exact version already exists, instead of one bulk publish. For repos \" +\n\t\t\t\t\t\t\t\"that ship many independently-versioned packages where a release doesn't bump every one.\",\n\t\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tif (argv.syncTrust) {\n\t\t\t\t\tconst [oldFile, newFile] = argv.syncTrust as [string?, string?];\n\t\t\t\t\tif (!oldFile || !newFile) {\n\t\t\t\t\t\tgetLogger().error(\"publish --sync-trust requires exactly two values: <old-file> <new-file>\");\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst report = await runSyncTrust({\n\t\t\t\t\t\tcwd: argv.cwd,\n\t\t\t\t\t\toldFile,\n\t\t\t\t\t\tnewFile,\n\t\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t\t...(argv.repo ? { repo: argv.repo as string } : {}),\n\t\t\t\t\t});\n\t\t\t\t\tif (report.status === \"fail\") {\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (argv.initial) {\n\t\t\t\t\tconst report = await runPublish({\n\t\t\t\t\t\tcwd: argv.cwd,\n\t\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t\t...(argv.tag ? { tag: argv.tag as string } : {}),\n\t\t\t\t\t\t...(argv.otp ? { otp: argv.otp as string } : {}),\n\t\t\t\t\t});\n\t\t\t\t\tif (report.status === \"fail\") {\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst report = await runSteadyPublish({\n\t\t\t\t\tcwd: argv.cwd,\n\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\tprovenance: argv.provenance as boolean,\n\t\t\t\t\tskipAlreadyPublished: argv.skipAlreadyPublished as boolean,\n\t\t\t\t\t...(argv.tag ? { tag: argv.tag as string } : {}),\n\t\t\t\t\t...(argv.otp ? { otp: argv.otp as string } : {}),\n\t\t\t\t});\n\t\t\t\tif (report.status === \"fail\") {\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"sync [steps..]\",\n\t\t\t\"Sync state from config to the provider and local files (labels, properties, teams, topics, keywords, description, homepage, readme, workflows, scripts, wiki)\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.positional(\"steps\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tarray: true,\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"Steps to run: labels, properties, teams, topics, keywords, description, homepage, readme, workflows, scripts, wiki (default: all)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"repo\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: 'Repo coords (\"owner/name\"). Defaults to plugin-specific resolution.',\n\t\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tconst tokens = tokenContext(argv.token);\n\t\t\t\tif (!tokens) return;\n\t\t\t\tconst loaded = await loadConfig(argv.cwd);\n\t\t\t\tapplyResolvedConfig(argv, loaded.resolved);\n\t\t\t\tconst report = await runSync({\n\t\t\t\t\tloaded,\n\t\t\t\t\tcontext: {\n\t\t\t\t\t\trepoRoot: argv.cwd,\n\t\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t\t...(argv.repo ? { repo: argv.repo } : {}),\n\t\t\t\t\t\t...tokens,\n\t\t\t\t\t\torg: resolveOrg(argv, loaded.resolved),\n\t\t\t\t\t},\n\t\t\t\t\t...(argv.steps && argv.steps.length > 0 ? { steps: argv.steps as string[] } : {}),\n\t\t\t\t});\n\t\t\t\tif (report.summary.fail > 0) {\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"run <task> [job] [passthrough..]\",\n\t\t\t\"Run a task locally (test, typecheck, lint, build, audit) — figures out turbo / the tool / the package manager\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.positional(\"task\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdemandOption: true,\n\t\t\t\t\t\tdescribe: \"Task name (test, typecheck, lint, build, audit). See `holocron run --help`.\",\n\t\t\t\t\t})\n\t\t\t\t\t.positional(\"job\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"Sub-job within the task (e.g. `holocron run audit performance`). Omit to run every job. Only `audit` has jobs today.\",\n\t\t\t\t\t})\n\t\t\t\t\t.positional(\"passthrough\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tarray: true,\n\t\t\t\t\t\tdescribe: \"Args forwarded to the tool — put them after `--`.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"required\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdefault: false,\n\t\t\t\t\t\tdescribe: \"Fail (exit 1) if this repo has no such task, instead of skipping.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"filter\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"turbo --filter=<pkg> passthrough (monorepo).\",\n\t\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tconst { logger } = buildCliLogger(argv, { command: \"run\" });\n\t\t\t\t// The task manifest drives `lint`'s linter set; other tasks are\n\t\t\t\t// filesystem-driven and ignore it. Missing / unparseable config → undefined.\n\t\t\t\tconst config = await loadTasksConfig(argv.cwd as string).catch(() => undefined);\n\t\t\t\tconst astromech = createAstromech({ cwd: argv.cwd, logger, config });\n\t\t\t\tconst report = astromech.run(argv.task as string, {\n\t\t\t\t\t...(argv.job !== undefined ? { job: argv.job as string } : {}),\n\t\t\t\t\tpassthrough: [\n\t\t\t\t\t\t...((argv.passthrough as string[] | undefined) ?? []),\n\t\t\t\t\t\t...((argv[\"--\"] as string[] | undefined) ?? []),\n\t\t\t\t\t],\n\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\trequired: argv.required,\n\t\t\t\t\t...(argv.filter ? { filter: argv.filter as string } : {}),\n\t\t\t\t});\n\t\t\t\tif (report.status === \"fail\" || report.status === \"unknown\") process.exitCode = 1;\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"ci\",\n\t\t\t\"Run the merge-gating checks locally, in CI order — 'will CI pass?'\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.option(\"all\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdefault: false,\n\t\t\t\t\t\tdescribe: \"Run every `ci: true` task, not just the required ones.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"filter\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"turbo --filter=<pkg> passthrough (monorepo).\",\n\t\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tconst { logger } = buildCliLogger(argv, { command: \"ci\" });\n\t\t\t\tconst config = await loadTasksConfig(argv.cwd as string).catch(() => undefined);\n\t\t\t\tconst astromech = createAstromech({ cwd: argv.cwd, logger, config });\n\t\t\t\tconst report = astromech.ci({\n\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\tscope: argv.all ? \"all\" : \"required\",\n\t\t\t\t\t...(argv.filter ? { filter: argv.filter as string } : {}),\n\t\t\t\t});\n\t\t\t\tif (report.status === \"fail\") process.exitCode = 1;\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"lint\",\n\t\t\t\"Lint content locally against the org's shared rules\",\n\t\t\t(y) =>\n\t\t\t\ty.command(\n\t\t\t\t\t\"commit-msg <file>\",\n\t\t\t\t\t\"Lint a commit message file — matches `commitlint --edit`'s own contract, for use from .husky/commit-msg\",\n\t\t\t\t\t(yy) =>\n\t\t\t\t\t\tyy.positional(\"file\", {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdemandOption: true,\n\t\t\t\t\t\t\tdescribe: \"Path to the commit message file (git's commit-msg hook passes this as $1).\",\n\t\t\t\t\t\t}),\n\t\t\t\t\tasync (argv) => {\n\t\t\t\t\t\tconst result = await lintCommitMsgFile(argv.file as string, argv.cwd as string);\n\t\t\t\t\t\tif (!result.valid) {\n\t\t\t\t\t\t\tfor (const violation of result.violations) {\n\t\t\t\t\t\t\t\tconsole.error(`✖ ${violation.rule}: ${violation.message}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t),\n\t\t\t() => {}\n\t\t)\n\t\t.command(\n\t\t\t\"sync-github\",\n\t\t\t\"Sync workflow templates and composite actions to theholocron/.github\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.option(\"repo\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdefault: \"theholocron/.github\",\n\t\t\t\t\t\tdescribe: \"Target org/repo (default: theholocron/.github)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"branch\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"Push to this branch instead of the default branch (enables PR-based workflow for protected repos)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"pr\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdefault: false,\n\t\t\t\t\t\tdescribe: \"Open a PR after pushing to --branch (no-op without --branch)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"message\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Commit message (default: chore: sync from theholocron/holocron)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"output-dir\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Write generated files to this local directory instead of pushing (for validation)\",\n\t\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tconst outputDir = argv[\"output-dir\"] as string | undefined;\n\t\t\t\tconst parsed = tokenContext(argv.token);\n\t\t\t\tif (!parsed) return;\n\t\t\t\tlet token: string;\n\t\t\t\tif (outputDir) {\n\t\t\t\t\ttoken = \"no-token-needed\";\n\t\t\t\t} else {\n\t\t\t\t\ttry {\n\t\t\t\t\t\ttoken = resolveSyncToken({ cliToken: parsed.cliTokens?.[\"github\"] ?? parsed.cliToken });\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tgetLogger().error(`sync-github: ${err instanceof AuthError ? err.message : String(err)}`);\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst report = await runSyncGithub({\n\t\t\t\t\ttoken,\n\t\t\t\t\trepo: argv.repo,\n\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t...(argv.branch ? { branch: argv.branch } : {}),\n\t\t\t\t\t...(argv.pr ? { createPr: true } : {}),\n\t\t\t\t\t...(argv.message ? { message: argv.message } : {}),\n\t\t\t\t\t...(outputDir ? { outputDir } : {}),\n\t\t\t\t});\n\t\t\t\tif (report.status === \"fail\") {\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"sync-readme\",\n\t\t\t\"Sync the Installation + Usage block in README.md from package.json\",\n\t\t\t(y) =>\n\t\t\t\ty.option(\"dry-run\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdescribe: \"Print what would change without writing\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tconst loaded = await loadConfig(argv.cwd);\n\t\t\t\tapplyResolvedConfig(argv, loaded.resolved);\n\t\t\t\tconst report = await runSyncReadme({\n\t\t\t\t\tloaded,\n\t\t\t\t\tcontext: { repoRoot: argv.cwd, dryRun: argv.dryRun },\n\t\t\t\t});\n\t\t\t\tif (report.status === \"fail\") process.exitCode = 1;\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"config show\",\n\t\t\t\"Print the resolved holocron config\",\n\t\t\t() => {},\n\t\t\tasync (argv) => {\n\t\t\t\tconst loaded = await loadConfig(argv.cwd);\n\t\t\t\tconsole.log(JSON.stringify(loaded.resolved, null, 2));\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"new [type] [name]\",\n\t\t\t\"Scaffold a new repo from a GitHub template (e.g. cli, react, nextjs, node, monorepo, base)\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.positional(\"type\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"Template type — maps to theholocron/<type>-template \" +\n\t\t\t\t\t\t\t\"(e.g. cli, react, nextjs, node, monorepo, base)\",\n\t\t\t\t\t})\n\t\t\t\t\t.positional(\"name\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"New repo name (kebab-case, e.g. my-tool)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"description\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Short description — replaces <description> placeholders in the template\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"homepage\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Homepage URL — replaces <homepage> placeholders and appears in holocron.config.ts\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"vault\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Vault provider: none, doppler, 1password, infisical\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"deployment\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Deployment provider: none, vercel\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"agent\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"AI agent: claude, none\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"runtime-environment\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Runtime environment: node, browser, universal, none\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"topics\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Comma-separated repo topics (e.g. typescript,nodejs)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"protection\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Branch protection level: strict, balanced, minimal\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"open-source\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdescribe: \"Whether the repo is open source (default: true)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"uses-external-packages\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdescribe: \"Whether the repo calls external APIs or services (default: true)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"skills\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Comma-separated agent skill names (e.g. git-safety,pr-workflow)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"is-template\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdescribe: \"Mark the new repo as a GitHub template repository\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"org\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdefault: \"theholocron\",\n\t\t\t\t\t\tdescribe: \"GitHub org that owns the template and will own the new repo\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"verify\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdefault: true,\n\t\t\t\t\t\tdescribe: \"Run pnpm install + holocron setup after bootstrapping (--no-verify skips)\",\n\t\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst tokens = tokenContext(argv.token);\n\t\t\t\t\tif (!tokens) return;\n\t\t\t\t\tconst adminToken = tokens.cliTokens?.[\"github\"] ?? tokens.cliToken;\n\n\t\t\t\t\tlet type = argv.type as string | undefined;\n\t\t\t\t\tlet name = argv.name as string | undefined;\n\t\t\t\t\tlet description = argv.description as string | undefined;\n\t\t\t\t\tlet homepage = argv.homepage as string | undefined;\n\t\t\t\t\tlet vaultProvider = argv.vault as string | undefined;\n\t\t\t\t\tlet vaultProject: string | undefined;\n\t\t\t\t\tlet vaultConfig: string | undefined;\n\t\t\t\t\tlet deploymentProvider = argv.deployment as string | undefined;\n\t\t\t\t\tlet agent = argv.agent as string | undefined;\n\t\t\t\t\tlet runtimeEnvironment = argv.runtimeEnvironment as string | undefined;\n\t\t\t\t\tlet topics: string[] = parseTopics(argv.topics as string | undefined);\n\t\t\t\t\tlet protection = argv.protection as string | undefined;\n\t\t\t\t\tlet openSource = argv.openSource as boolean | undefined;\n\t\t\t\t\tlet usesExternalPackages = argv.usesExternalPackages as boolean | undefined;\n\t\t\t\t\tlet skills: string[] = parseTopics(argv.skills as string | undefined);\n\t\t\t\t\tconst isTemplate = argv.isTemplate as boolean | undefined;\n\n\t\t\t\t\t// Interactive wizard — skip any field already supplied as a CLI arg\n\t\t\t\t\tif (!type) {\n\t\t\t\t\t\ttype = await select({\n\t\t\t\t\t\t\tmessage: \"Template type:\",\n\t\t\t\t\t\t\tchoices: [\n\t\t\t\t\t\t\t\t{ name: \"node — Node.js library or tool\", value: \"node\" },\n\t\t\t\t\t\t\t\t{ name: \"cli — CLI application (inquirer, chalk, yargs)\", value: \"cli\" },\n\t\t\t\t\t\t\t\t{ name: \"monorepo — Turbo monorepo\", value: \"monorepo\" },\n\t\t\t\t\t\t\t\t{ name: \"react — React component library\", value: \"react\" },\n\t\t\t\t\t\t\t\t{ name: \"nextjs — Next.js application\", value: \"nextjs\" },\n\t\t\t\t\t\t\t\t{ name: \"base — Minimal repo (no package.json)\", value: \"base\" },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!name) {\n\t\t\t\t\t\tname = await input({\n\t\t\t\t\t\t\tmessage: \"Repo name (kebab-case):\",\n\t\t\t\t\t\t\tvalidate: validateRepoName,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tname = name.trim();\n\t\t\t\t\t}\n\n\t\t\t\t\tif (description === undefined) {\n\t\t\t\t\t\tdescription = await input({ message: \"Short description:\" });\n\t\t\t\t\t}\n\n\t\t\t\t\tif (homepage === undefined) {\n\t\t\t\t\t\tconst raw = await input({ message: \"Homepage URL (optional, Enter to skip):\" });\n\t\t\t\t\t\thomepage = raw.trim() || undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!runtimeEnvironment) {\n\t\t\t\t\t\truntimeEnvironment = await select({\n\t\t\t\t\t\t\tmessage: \"Runtime environment:\",\n\t\t\t\t\t\t\tchoices: [\n\t\t\t\t\t\t\t\t{ name: \"node — Node.js process\", value: \"node\" },\n\t\t\t\t\t\t\t\t{ name: \"browser — Browser only\", value: \"browser\" },\n\t\t\t\t\t\t\t\t{ name: \"universal — Node.js + browser\", value: \"universal\" },\n\t\t\t\t\t\t\t\t{ name: \"none — No runtime (docs, config, etc.)\", value: \"none\" },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tdefault: type === \"base\" ? \"none\" : \"node\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!vaultProvider) {\n\t\t\t\t\t\tvaultProvider = await select({\n\t\t\t\t\t\t\tmessage: \"Vault provider:\",\n\t\t\t\t\t\t\tchoices: [\n\t\t\t\t\t\t\t\t{ name: \"None\", value: \"none\" },\n\t\t\t\t\t\t\t\t{ name: \"Doppler\", value: \"doppler\" },\n\t\t\t\t\t\t\t\t{ name: \"1Password\", value: \"1password\" },\n\t\t\t\t\t\t\t\t{ name: \"Infisical\", value: \"infisical\" },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (vaultProvider === \"doppler\") {\n\t\t\t\t\t\tvaultProject = await input({ message: \"Doppler project name:\", default: name });\n\t\t\t\t\t\tvaultConfig = await input({ message: \"Doppler config:\", default: \"dev\" });\n\t\t\t\t\t} else if (vaultProvider === \"1password\" || vaultProvider === \"infisical\") {\n\t\t\t\t\t\tvaultProject = await input({\n\t\t\t\t\t\t\tmessage: `${vaultProvider === \"1password\" ? \"1Password vault\" : \"Infisical project\"} name:`,\n\t\t\t\t\t\t\tdefault: name,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!deploymentProvider) {\n\t\t\t\t\t\tdeploymentProvider = await select({\n\t\t\t\t\t\t\tmessage: \"Deployment provider:\",\n\t\t\t\t\t\t\tchoices: [\n\t\t\t\t\t\t\t\t{ name: \"None\", value: \"none\" },\n\t\t\t\t\t\t\t\t{ name: \"Vercel\", value: \"vercel\" },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!agent) {\n\t\t\t\t\t\tagent = await select({\n\t\t\t\t\t\t\tmessage: \"AI agent:\",\n\t\t\t\t\t\t\tchoices: [\n\t\t\t\t\t\t\t\t{ name: \"Claude\", value: \"claude\" },\n\t\t\t\t\t\t\t\t{ name: \"None\", value: \"none\" },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (topics.length === 0) {\n\t\t\t\t\t\tconst raw = await input({ message: \"Topics (comma-separated, optional):\" });\n\t\t\t\t\t\ttopics = parseTopics(raw);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!protection) {\n\t\t\t\t\t\tprotection = await select({\n\t\t\t\t\t\t\tmessage: \"Branch protection:\",\n\t\t\t\t\t\t\tchoices: [\n\t\t\t\t\t\t\t\t{ name: \"strict — required reviews + passing checks\", value: \"strict\" },\n\t\t\t\t\t\t\t\t{ name: \"balanced — required reviews, flexible checks\", value: \"balanced\" },\n\t\t\t\t\t\t\t\t{ name: \"minimal — branch protection only\", value: \"minimal\" },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (openSource === undefined) {\n\t\t\t\t\t\tconst ans = await select({\n\t\t\t\t\t\t\tmessage: \"Open source?\",\n\t\t\t\t\t\t\tchoices: [\n\t\t\t\t\t\t\t\t{ name: \"Yes\", value: \"yes\" },\n\t\t\t\t\t\t\t\t{ name: \"No\", value: \"no\" },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\t\t\t\t\t\topenSource = ans === \"yes\";\n\t\t\t\t\t}\n\n\t\t\t\t\tif (usesExternalPackages === undefined) {\n\t\t\t\t\t\tconst ans = await select({\n\t\t\t\t\t\t\tmessage: \"Uses external APIs or services?\",\n\t\t\t\t\t\t\tchoices: [\n\t\t\t\t\t\t\t\t{ name: \"Yes\", value: \"yes\" },\n\t\t\t\t\t\t\t\t{ name: \"No\", value: \"no\" },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\t\t\t\t\t\tusesExternalPackages = ans === \"yes\";\n\t\t\t\t\t}\n\n\t\t\t\t\tif (skills.length === 0) {\n\t\t\t\t\t\tconst raw = await input({ message: \"Agent skills (comma-separated, optional):\" });\n\t\t\t\t\t\tskills = parseTopics(raw);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!type) {\n\t\t\t\t\t\tgetLogger().error(\"new: template type is required\");\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (!name) {\n\t\t\t\t\t\tgetLogger().error(\"new: repo name is required\");\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst report = await runNew({\n\t\t\t\t\t\ttype,\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tdescription: description || undefined,\n\t\t\t\t\t\thomepage,\n\t\t\t\t\t\tvaultProvider: (vaultProvider as \"doppler\" | \"1password\" | \"infisical\" | \"none\") ?? \"none\",\n\t\t\t\t\t\tvaultProject,\n\t\t\t\t\t\tvaultConfig,\n\t\t\t\t\t\tdeploymentProvider: (deploymentProvider as \"vercel\" | \"none\") ?? \"none\",\n\t\t\t\t\t\tagent: (agent as \"claude\" | \"none\") ?? \"claude\",\n\t\t\t\t\t\truntimeEnvironment: (runtimeEnvironment as \"node\" | \"browser\" | \"universal\" | \"none\") ?? \"node\",\n\t\t\t\t\t\tprotection: protection ?? \"strict\",\n\t\t\t\t\t\topenSource: openSource ?? true,\n\t\t\t\t\t\tusesExternalPackages: usesExternalPackages ?? true,\n\t\t\t\t\t\ttopics,\n\t\t\t\t\t\tskills,\n\t\t\t\t\t\tisTemplate,\n\t\t\t\t\t\torg: argv.org,\n\t\t\t\t\t\ttoken: adminToken,\n\t\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t\tnoVerify: !argv.verify,\n\t\t\t\t\t\tcwd: argv.cwd,\n\t\t\t\t\t});\n\t\t\t\t\tif (report.status === \"fail\") process.exitCode = 1;\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (err instanceof NewError) {\n\t\t\t\t\t\tgetLogger().error(`new: ${err.message}`);\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthrow err;\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"plugin create [slug] [vendor]\",\n\t\t\t\"Scaffold a new @theholocron/holocron-plugin-<slug> package\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.positional(\"slug\", { type: \"string\", describe: \"Package slug (kebab-case)\" })\n\t\t\t\t\t.positional(\"vendor\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Vendor display name (PascalCase)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"capability\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"Capability key: source|ci|secrets|environments|issues|deployment|storage|auth|vault|dns|tooling|notifications|analytics|errors|logs|wiki|workers\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"token-env\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Holocron env var name (defaults to HOLOCRON_<VENDOR>_TOKEN)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"vendor-env\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Vendor-native env var name\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"base-url\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"REST base URL\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"verify\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdefault: true,\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"Run post-scaffold pnpm install + typecheck + lint + test (default true; --no-verify skips)\",\n\t\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst [slug, vendor] = await promptForPositionals(\n\t\t\t\t\t\tgetEntry(\"plugin create\"),\n\t\t\t\t\t\targv as Record<string, unknown>\n\t\t\t\t\t);\n\t\t\t\t\tconst { capability, vendorEnv, baseUrl } = await resolvePluginCreateInputs(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcapability: argv.capability as string | undefined,\n\t\t\t\t\t\t\tvendorEnv: argv.vendorEnv as string | undefined,\n\t\t\t\t\t\t\tbaseUrl: argv.baseUrl as string | undefined,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tselectCapability: () =>\n\t\t\t\t\t\t\t\tselect({\n\t\t\t\t\t\t\t\t\tmessage: \"Capability:\",\n\t\t\t\t\t\t\t\t\tchoices: Object.keys(CARDINALITY).map((k) => ({ name: k, value: k })),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tinputVendorEnv: () =>\n\t\t\t\t\t\t\t\tinput({\n\t\t\t\t\t\t\t\t\tmessage: `Vendor-native env var for the ${vendor} token (e.g. MYVENDOR_API_KEY):`,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tinputBaseUrl: () =>\n\t\t\t\t\t\t\t\tinput({\n\t\t\t\t\t\t\t\t\tmessage: `REST base URL for the ${vendor} API (e.g. https://api.myvendor.com):`,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\n\t\t\t\t\tconst report = runPluginCreate({\n\t\t\t\t\t\tslug: slug!,\n\t\t\t\t\t\tvendorName: vendor!,\n\t\t\t\t\t\tcapability,\n\t\t\t\t\t\tvendorEnv,\n\t\t\t\t\t\tbaseUrl,\n\t\t\t\t\t\t...(argv.tokenEnv ? { tokenEnv: argv.tokenEnv as string } : {}),\n\t\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t\t// Yargs: `--no-verify` flips `argv.verify` to false. We pass\n\t\t\t\t\t\t// the inverse to preserve the internal `noVerify` naming.\n\t\t\t\t\t\tnoVerify: !argv.verify,\n\t\t\t\t\t\tcwd: argv.cwd,\n\t\t\t\t\t});\n\t\t\t\t\tif (report.status === \"fail\") process.exitCode = 1;\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (err instanceof PluginCreateError) {\n\t\t\t\t\t\tgetLogger().error(`plugin create: ${err.message}`);\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthrow err;\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"upgrade\",\n\t\t\t\"Upgrade toolchain version pins across the repo\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.command(\n\t\t\t\t\t\t\"node [to]\",\n\t\t\t\t\t\t\"Scan the repo and update every Node.js version pin to a new major\",\n\t\t\t\t\t\t(yy) =>\n\t\t\t\t\t\t\tyy\n\t\t\t\t\t\t\t\t.positional(\"to\", {\n\t\t\t\t\t\t\t\t\ttype: \"number\",\n\t\t\t\t\t\t\t\t\tdescribe: \"Target Node.js major version (e.g., 22)\",\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.option(\"from\", {\n\t\t\t\t\t\t\t\t\ttype: \"number\",\n\t\t\t\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\t\t\t\"Current major version to replace. Auto-detected from .nvmrc / engines.node when omitted.\",\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\tasync (argv) => {\n\t\t\t\t\t\t\tconst [to] = await promptForPositionals(\n\t\t\t\t\t\t\t\tgetEntry(\"upgrade node\"),\n\t\t\t\t\t\t\t\targv as Record<string, unknown>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t// Read upgrade.node.extra from holocron.config.json if present.\n\t\t\t\t\t\t\t// We read the raw file directly rather than through loadConfig because\n\t\t\t\t\t\t\t// the upgrade config is not part of the plugin schema.\n\t\t\t\t\t\t\tlet extra: string[] = [];\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst raw = readFileSync(join(argv.cwd, \"holocron.config.json\"), \"utf8\");\n\t\t\t\t\t\t\t\tconst cfg = JSON.parse(raw) as { upgrade?: { node?: { extra?: unknown } } };\n\t\t\t\t\t\t\t\tconst extraRaw = cfg.upgrade?.node?.extra;\n\t\t\t\t\t\t\t\tif (Array.isArray(extraRaw)) {\n\t\t\t\t\t\t\t\t\textra = extraRaw as string[];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t/* no config or no upgrade section — fine */\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst report = await runUpgradeNode({\n\t\t\t\t\t\t\t\tto: Number(to),\n\t\t\t\t\t\t\t\t...(argv.from != null ? { from: argv.from as number } : {}),\n\t\t\t\t\t\t\t\tcwd: argv.cwd,\n\t\t\t\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t\t\t\textra,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (report.status === \"fail\") {\n\t\t\t\t\t\t\t\tif (report.message) getLogger().error(`upgrade node: ${report.message}`);\n\t\t\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\t\t\t\t\t.command(\n\t\t\t\t\t\t\"deps\",\n\t\t\t\t\t\t\"Bump every @theholocron/* pin to latest and migrate holocron.config.ts to the current preset API\",\n\t\t\t\t\t\t(yy) =>\n\t\t\t\t\t\t\tyy.option(\"pins-only\", {\n\t\t\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\t\t\tdefault: false,\n\t\t\t\t\t\t\t\tdescribe: \"Only bump the catalog pins — skip the holocron.config.ts migration\",\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\tasync (argv) => {\n\t\t\t\t\t\t\tconst report = await runUpgradeDeps({\n\t\t\t\t\t\t\t\tcwd: argv.cwd,\n\t\t\t\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t\t\t\tpinsOnly: argv.pinsOnly as boolean,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (report.status === \"fail\") {\n\t\t\t\t\t\t\t\tif (report.message) getLogger().error(`upgrade deps: ${report.message}`);\n\t\t\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\t\t\t\t\t.command(\n\t\t\t\t\t\t\"$0\",\n\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t() => {},\n\t\t\t\t\t\tasync (argv) => {\n\t\t\t\t\t\t\tawait launchMenu(\n\t\t\t\t\t\t\t\tCOMMAND_REGISTRY.filter((e) => e.group === \"upgrade\"),\n\t\t\t\t\t\t\t\targv,\n\t\t\t\t\t\t\t\t\"upgrade — choose a subcommand:\",\n\t\t\t\t\t\t\t\t\"Run `holocron upgrade --help` to see available upgrade subcommands.\"\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t),\n\t\t\t() => {}\n\t\t)\n\t\t.command(\n\t\t\t\"auth <subcommand>\",\n\t\t\t\"Manage bootstrap credentials in the OS keyring\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.command(\n\t\t\t\t\t\t\"set [provider] [value]\",\n\t\t\t\t\t\t\"Verify + store a bootstrap token for a provider\",\n\t\t\t\t\t\t(yy) => yy.positional(\"provider\", { type: \"string\" }).positional(\"value\", { type: \"string\" }),\n\t\t\t\t\t\tasync (argv) => {\n\t\t\t\t\t\t\tconst [provider] = await promptForPositionals(\n\t\t\t\t\t\t\t\tgetEntry(\"auth set\"),\n\t\t\t\t\t\t\t\targv as Record<string, unknown>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tconst result = await runAuthSet({\n\t\t\t\t\t\t\t\tprovider: provider!,\n\t\t\t\t\t\t\t\t...(argv.value ? { positional: argv.value as string } : {}),\n\t\t\t\t\t\t\t\t...(argv.org ? { org: argv.org as string } : {}),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (result.status === \"fail\") process.exitCode = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\t\t\t\t\t.command(\n\t\t\t\t\t\t\"unset [provider]\",\n\t\t\t\t\t\t\"Remove a stored bootstrap token\",\n\t\t\t\t\t\t(yy) => yy.positional(\"provider\", { type: \"string\" }),\n\t\t\t\t\t\tasync (argv) => {\n\t\t\t\t\t\t\tconst [provider] = await promptForPositionals(\n\t\t\t\t\t\t\t\tgetEntry(\"auth unset\"),\n\t\t\t\t\t\t\t\targv as Record<string, unknown>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\trunAuthUnset({ provider: provider! });\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\t\t\t\t\t.command(\n\t\t\t\t\t\t\"check [provider]\",\n\t\t\t\t\t\t\"Re-verify a stored bootstrap token\",\n\t\t\t\t\t\t(yy) => yy.positional(\"provider\", { type: \"string\" }),\n\t\t\t\t\t\tasync (argv) => {\n\t\t\t\t\t\t\tconst [provider] = await promptForPositionals(\n\t\t\t\t\t\t\t\tgetEntry(\"auth check\"),\n\t\t\t\t\t\t\t\targv as Record<string, unknown>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tconst result = await runAuthCheck({\n\t\t\t\t\t\t\t\tprovider: provider!,\n\t\t\t\t\t\t\t\t...(argv.org ? { org: argv.org as string } : {}),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (result.status === \"fail\") process.exitCode = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\t\t\t\t\t.command(\n\t\t\t\t\t\t\"list\",\n\t\t\t\t\t\t\"List every provider with a stored bootstrap token\",\n\t\t\t\t\t\t() => {},\n\t\t\t\t\t\tasync () => {\n\t\t\t\t\t\t\tawait runAuthList();\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\t\t\t\t\t.command(\n\t\t\t\t\t\t\"$0\",\n\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t() => {},\n\t\t\t\t\t\tasync (argv) => {\n\t\t\t\t\t\t\tawait launchMenu(\n\t\t\t\t\t\t\t\tCOMMAND_REGISTRY.filter((e) => e.group === \"auth\"),\n\t\t\t\t\t\t\t\targv,\n\t\t\t\t\t\t\t\t\"auth — choose a subcommand:\",\n\t\t\t\t\t\t\t\t\"Run `holocron auth --help` to see available auth subcommands.\"\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t),\n\t\t\t() => {}\n\t\t)\n\t\t.command(\n\t\t\t\"$0\",\n\t\t\tfalse,\n\t\t\t() => {},\n\t\t\tasync (argv) => {\n\t\t\t\tawait launchMenu(\n\t\t\t\t\tCOMMAND_REGISTRY.filter((e) => !e.group),\n\t\t\t\t\targv\n\t\t\t\t);\n\t\t\t}\n\t\t)\n\t\t.strict()\n\t\t.help()\n\t\t.epilogue(\n\t\t\t\"Execution contexts:\\n\" +\n\t\t\t\t` global works from a bare 'npm i -g': ${commandsInContext(\"global\").join(\", \")}\\n` +\n\t\t\t\t` repo-aware needs ./holocron.config in cwd: ${commandsInContext(\"repo-aware\").join(\", \")}\\n` +\n\t\t\t\t` workspace also needs the plugin packages: ${commandsInContext(\"workspace\").join(\", \")}\\n` +\n\t\t\t\t\" https://theholocron.github.io/holocron/execution-contexts\"\n\t\t)\n\t\t.fail((msg, err) => {\n\t\t\t// A user-facing error (a `workspace` command with no resolvable\n\t\t\t// plugins, a missing `holocron.config`) — its message is the whole\n\t\t\t// story. Print that: no usage dump, no stack trace.\n\t\t\tif (err instanceof Error && USER_FACING_ERRORS.has(err.name)) {\n\t\t\t\tcaptureException(err);\n\t\t\t\tgetLogger().error(err.message);\n\t\t\t\terrorReported = true;\n\t\t\t\tprocess.exitCode = 1;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Anything else a handler threw: hand back to the outer catch so\n\t\t\t// telemetry + the generic path own it.\n\t\t\tif (err) throw err;\n\t\t\t// A yargs validation failure (unknown command, missing positional):\n\t\t\t// keep yargs' own message.\n\t\t\tgetLogger().error(msg);\n\t\t\terrorReported = true;\n\t\t\tprocess.exitCode = 1;\n\t\t})\n\t\t.parse();\n} catch (err) {\n\tcaptureException(err);\n\t// User-facing errors carry a self-contained message — print it instead of\n\t// letting a raw stack trace escape (unless `.fail()` already did).\n\tif (!errorReported && err instanceof Error && USER_FACING_ERRORS.has(err.name)) {\n\t\tgetLogger().error(err.message);\n\t}\n\tif (!process.exitCode) process.exitCode = 1;\n}\n\nfinishCommand(!process.exitCode);\nendSession();\n// `--debug` / `--verbose`: surface the correlation id for Axiom lookup. This is\n// user-facing reference output (print semantics); cli.ts has no `print` injection.\nconst rid = getRunId();\nif (printRunId && rid) console.log(`Run ID: ${rid}`);\nconst notify = await updateCheckPromise;\nnotify?.();\nawait flush();\n\n/**\n * Parse `--scope` strings: `repo` | `env=NAME` | `org=NAME`.\n */\nfunction parseScope(\n\ts: string\n): { kind: \"repo\" } | { kind: \"environment\"; name: string } | { kind: \"organization\"; name: string } {\n\tif (s === \"repo\") return { kind: \"repo\" };\n\tif (s.startsWith(\"env=\")) return { kind: \"environment\", name: s.slice(\"env=\".length) };\n\tif (s.startsWith(\"org=\")) return { kind: \"organization\", name: s.slice(\"org=\".length) };\n\tthrow new Error(`invalid --scope \"${s}\" — expected \"repo\", \"env=<name>\", or \"org=<name>\"`);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.mjs","names":["getKeyringToken","defaultImporter","SKIP_DIRS","defaultWalkFiles","SKIP_DIRS","defaultWalkFiles","preflight","defaultExec","deriveDefaults","render","render","render","render","render","render","render","render","render","render","render","render","render","render","render","render","render","renderPackageJson","renderTsconfigJson","renderVitestConfig","renderEslintConfig","renderTsdownConfig","renderReadme","renderAuth","renderRest","renderVerifyToken","renderPluginIndex","renderCapability","renderHelpers","renderAuthTest","renderRestTest","renderVerifyTokenTest","renderCapabilityTest","renderIndexTest","renderValidateScript","deriveDefaults","defaultExec","printNextSteps","defaultExec","alexrc","createIgnoreConfig","workflowHeader","alexignore","createConfig","workflowHeader","commitMsgBody","createConfig","workflowHeader","createConfig","workflowHeader","editorconfigBody","createConfig","editorconfigChecker","createConfig","workflowHeader","preCommitBody","createConfig","workflowHeader","prePushBody","createConfig","workflowHeader","prepareCommitMsgBody","workflowHeader","yamllintBody","yamlignoreBody","decisionsTemplate","ProviderApiError","ProviderApiError","workflowHeader","labelerConfig","dependabotConfig","dcoConfig","sentimentBotConfig","createAlexrc","createAlexignore","createYamllint","createYamlignore","createEditorconfig","createEditorconfigChecker","createDevmoji","createPrepareCommitMsg","createCommitMsg","createPrePush","createPreCommit","FETCH_TIMEOUT_MS"],"sources":["../src/env.ts","../src/auth/keyring.ts","../src/auth/auth-resolver.ts","../src/auth/token-args.ts","../src/plugin/capabilities.ts","../src/config/config.ts","../src/logger.ts","../src/plugin/loader.ts","../src/plugin/workspace.ts","../src/ui/progress.ts","../src/ui/style.ts","../src/commands/auth.ts","../src/commands/cleanup-preview.ts","../src/commands/clone.ts","../src/commands/contexts.ts","../src/commands/deploy.ts","../src/commands/doctor.ts","../src/commands/new.ts","../src/commands/npm-bump-versions.ts","../src/commands/plugin-create/template-inputs.ts","../src/commands/plugin-create/templates/auth.ts","../src/commands/plugin-create/templates/auth-test.ts","../src/commands/plugin-create/templates/capability.ts","../src/commands/plugin-create/templates/capability-test.ts","../src/commands/plugin-create/templates/eslint-config.ts","../src/commands/plugin-create/templates/helpers.ts","../src/commands/plugin-create/templates/index-test.ts","../src/commands/plugin-create/templates/package-json.ts","../src/commands/plugin-create/templates/plugin-index.ts","../src/commands/plugin-create/templates/readme.ts","../src/commands/plugin-create/templates/rest.ts","../src/commands/plugin-create/templates/rest-test.ts","../src/commands/plugin-create/templates/tsconfig-json.ts","../src/commands/plugin-create/templates/tsdown-config.ts","../src/commands/plugin-create/templates/validate-script.ts","../src/commands/plugin-create/templates/verify-token.ts","../src/commands/plugin-create/templates/verify-token-test.ts","../src/commands/plugin-create/templates/vitest-config.ts","../src/commands/plugin-create/index.ts","../src/commands/publish.ts","../src/commands/secret-set.ts","../src/commands/secrets-sync.ts","../src/commands/setup/derived-properties.ts","../src/commands/setup/labels.ts","../src/templates/config.yml","../src/utils/create-header.ts","../src/templates/configs/alexjs/alexignore","../src/templates/configs/alexjs/alexrc.json","../src/templates/configs/alexjs/create-config.ts","../src/templates/configs/commit-msg/commit-msg","../src/templates/configs/commit-msg/create-config.ts","../src/templates/configs/devmoji/create-config.ts","../src/templates/configs/editorconfig/editorconfig","../src/templates/configs/editorconfig/create-config.ts","../src/templates/configs/editorconfig-checker/editorconfig-checker.json","../src/templates/configs/editorconfig-checker/create-config.ts","../src/templates/configs/pre-commit/pre-commit","../src/templates/configs/pre-commit/create-config.ts","../src/templates/configs/pre-push/pre-push","../src/templates/configs/pre-push/create-config.ts","../src/templates/configs/prepare-commit-msg/prepare-commit-msg","../src/templates/configs/prepare-commit-msg/create-config.ts","../src/templates/configs/yamllint/.yamlignore","../src/templates/configs/yamllint/.yamllint.yml","../src/templates/configs/yamllint/create-config.ts","../src/templates/dco.yml","../src/templates/dependabot.yml","../src/templates/labeler.yml","../src/templates/decisions-template.md","../src/commands/setup/agent-prompts-data.ts","../src/commands/setup/agent-prompts.ts","../src/commands/setup/branch-protection.ts","../src/commands/setup/engineering.ts","../src/commands/setup/repo-settings.ts","../src/commands/setup/run-step.ts","../src/commands/setup/skills.ts","../src/commands/setup/run-setup.ts","../src/commands/skills.ts","../src/commands/sync-readme.ts","../src/commands/sync-wiki.ts","../src/commands/sync.ts","../src/telemetry/resolve.ts","../src/telemetry.ts","../src/commands/sync-github.ts","../src/commands/upgrade-deps.ts","../src/commands/upgrade-node.ts","../src/commit-lint/lint-message.ts","../src/commit-lint/lint-commit-msg-file.ts","../src/config/load-config.ts","../src/interactive-menu.ts","../src/update-notifier.ts","../src/cli.ts"],"sourcesContent":["import { createEnvLookup } from \"@theholocron/env-utils\";\n\nexport type { EnvLookup as CliEnv } from \"@theholocron/env-utils\";\n\n/** Singleton env for simple global lookups throughout the CLI. */\nexport const env = createEnvLookup();\n\n/**\n * Create an injectable env for commands that accept a fake env in tests.\n * Pass `input.env` when available, falls back to `process.env`.\n */\nexport function makeEnv(source?: Record<string, string | undefined>) {\n\treturn createEnvLookup(source);\n}\n","/**\n * Keyring-backed bootstrap credential store.\n *\n * Every holocron plugin's bootstrap token (the one it needs before it\n * can talk to its vendor's API) can be stored in the OS keyring under\n * a single reverse-DNS service scope. Managed via `holocron auth`\n * subcommands; consulted at position 4 in every plugin's auth\n * precedence chain (after --token / HOLOCRON_<X>_TOKEN / <native>_TOKEN).\n *\n * See `docs/wiki/specifications/tech-auth-bootstrap.spec.md` for the design rationale.\n *\n * Failure model: keyring access is best-effort. Platforms without a\n * supported credential store (some Linux CI images, sandboxed\n * environments) will throw from the underlying library. Every export\n * here catches and returns a null/empty result rather than propagating\n * — the plugin's precedence chain then falls through to\n * env-var-only paths, which is exactly how CI is meant to work.\n */\n\nimport { Entry, findCredentials } from \"@napi-rs/keyring\";\n\nconst SERVICE = \"com.theholocron.cli\";\n\n/**\n * Store or overwrite a bootstrap token for a provider. Returns true on\n * success, false when the underlying keyring is unsupported or errored.\n */\nexport function setToken(provider: string, token: string): boolean {\n\ttry {\n\t\tnew Entry(SERVICE, provider).setPassword(token);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Read the bootstrap token for a provider. Returns `null` for both\n * \"not stored\" and \"keyring unavailable\" — callers can treat them the\n * same way (fall through to env-var precedence).\n */\nexport function getToken(provider: string): string | null {\n\ttry {\n\t\treturn new Entry(SERVICE, provider).getPassword();\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Delete a stored token. Returns true when a token was removed, false\n * when there was nothing to delete or the keyring is unavailable.\n * Distinguishing the two cases isn't worth the surface area — the\n * command output makes the situation clear either way.\n */\nexport function deleteToken(provider: string): boolean {\n\ttry {\n\t\treturn new Entry(SERVICE, provider).deletePassword();\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * List provider slugs with a stored token in this service scope.\n * Uses the library's `findCredentials(service)` — supported on all\n * platforms the underlying credential store supports.\n */\nexport function listStoredProviders(): string[] {\n\ttry {\n\t\treturn findCredentials(SERVICE).map((c) => c.account);\n\t} catch {\n\t\treturn [];\n\t}\n}\n","// Re-exported from @theholocron/http — the canonical home for HTTP primitives.\n// createResolveToken is wrapped here to inject the keyring backend so plugins\n// don't need to pass it explicitly.\nimport {\n\tAuthError,\n\tcreateResolveToken as _createResolveToken,\n\ttype ResolveTokenConfig as _ResolveTokenConfig,\n\ttype ResolveTokenInput,\n} from \"@theholocron/http-client\";\n\nimport { makeEnv } from \"../env.js\";\nimport { getToken as getKeyringToken } from \"./keyring.js\";\n\nexport { AuthError, type ResolveTokenInput };\n\nexport type ResolveTokenConfig = Omit<_ResolveTokenConfig, \"getKeyringToken\">;\n\n/** Wraps `createResolveToken` from `@theholocron/http` and injects the\n * system keyring so plugins stay at a one-liner call site. */\nexport function createResolveToken(config: ResolveTokenConfig): (input?: ResolveTokenInput) => string {\n\treturn _createResolveToken({ ...config, getKeyringToken });\n}\n\nexport interface FeatureResolverConfig {\n\t/** Env var name for this feature, e.g. `\"HOLOCRON_ISSUES_TOKEN\"`. */\n\tenvName: string;\n\t/** Keyring account key, e.g. `\"github.issues\"`. */\n\tkeyringKey: string;\n}\n\n/**\n * Build a strict, single-feature token resolver.\n *\n * Resolution chain: `--token flag → envName env var → keyring(keyringKey)`.\n * No broad-token fallback — if the feature-specific token is absent the\n * operation fails with a message naming the exact env var to set.\n */\nexport function createFeatureResolver(config: FeatureResolverConfig): (input?: ResolveTokenInput) => string {\n\treturn function resolveFeatureToken(input: ResolveTokenInput = {}): string {\n\t\tconst env = makeEnv(input.env);\n\t\tconst keyring = input.keyring ?? getKeyringToken;\n\t\tconst token = input.cliToken || env.get(config.envName) || keyring(config.keyringKey);\n\t\tif (!token) {\n\t\t\tthrow new AuthError(\n\t\t\t\t`no GitHub token found for this operation. Pass --token <PAT>, ` +\n\t\t\t\t\t`set ${config.envName}, or run: holocron auth set ${config.keyringKey} <PAT>`\n\t\t\t);\n\t\t}\n\t\treturn token;\n\t};\n}\n","export class TokenParseError extends Error {\n\toverride name = \"TokenParseError\";\n}\n\nexport interface ParsedTokenArgs {\n\t/** Set when a bare (unkeyed) --token value was passed. Used as fallback for all plugins. */\n\tcliToken?: string;\n\t/** Set when one or more vendor=value pairs were passed. */\n\tcliTokens?: Record<string, string>;\n}\n\n/**\n * Converts raw --token CLI values into a typed result.\n *\n * Bare form: --token ghp_xxx → { cliToken: \"ghp_xxx\" }\n * Keyed form: --token github=ghp_xxx → { cliTokens: { github: \"ghp_xxx\" } }\n * Mixed: --token github=ghp_xxx --token v_yyy\n * → { cliToken: \"v_yyy\", cliTokens: { github: \"ghp_xxx\" } }\n *\n * Values may contain \"=\" (e.g. base64 strings) — only the first \"=\" is treated as a separator.\n */\nexport function parseTokenArgs(tokens: string[]): ParsedTokenArgs {\n\tif (tokens.length === 0) return {};\n\n\tconst cliTokens: Record<string, string> = {};\n\tconst bare: string[] = [];\n\n\tfor (const raw of tokens) {\n\t\tconst eqIdx = raw.indexOf(\"=\");\n\n\t\tif (eqIdx === -1) {\n\t\t\tbare.push(raw);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst vendor = raw.slice(0, eqIdx);\n\t\tconst value = raw.slice(eqIdx + 1);\n\n\t\tif (vendor.trim() === \"\") {\n\t\t\tthrow new TokenParseError(`invalid --token value \"${raw}\": vendor name must not be empty`);\n\t\t}\n\t\tif (/\\s/.test(vendor)) {\n\t\t\tthrow new TokenParseError(`invalid --token value \"${raw}\": vendor name must not contain whitespace`);\n\t\t}\n\t\tif (value === \"\") {\n\t\t\tthrow new TokenParseError(`invalid --token value \"${raw}\": token value must not be empty`);\n\t\t}\n\n\t\tcliTokens[vendor] = value;\n\t}\n\n\tif (bare.length > 1) {\n\t\tthrow new TokenParseError(\n\t\t\t`only one bare --token value is allowed; got ${bare.length.toString()} — use vendor=value form for multiple tokens`\n\t\t);\n\t}\n\n\tconst result: ParsedTokenArgs = {};\n\tif (bare.length === 1) result.cliToken = bare[0];\n\tif (Object.keys(cliTokens).length > 0) result.cliTokens = cliTokens;\n\treturn result;\n}\n","/**\n * Capability interfaces — the contracts that providers implement.\n *\n * Each capability has a stable key (`'source'`, `'ci'`, …) and a\n * cardinality (`'single'` = one provider; `'many'` = several active\n * at once). The cardinality is part of the type contract via\n * `CardinalityFor<K>` so config resolution + command code can branch\n * statically.\n *\n * See `docs/wiki/specifications/tech-architecture.spec.md` for the design narrative\n * (issue: #74).\n */\n\nexport type CapabilityKey =\n\t| \"source\"\n\t| \"ci\"\n\t| \"secrets\"\n\t| \"environments\"\n\t| \"issues\"\n\t| \"deployment\"\n\t| \"storage\"\n\t| \"auth\"\n\t| \"vault\"\n\t| \"dns\"\n\t| \"tooling\"\n\t| \"notifications\"\n\t| \"analytics\"\n\t| \"errors\"\n\t| \"logs\"\n\t| \"wiki\"\n\t| \"workers\";\n\nexport type Cardinality = \"single\" | \"many\";\n\nexport const CARDINALITY = {\n\tsource: \"single\",\n\tci: \"single\",\n\tsecrets: \"single\",\n\tenvironments: \"single\",\n\tissues: \"single\",\n\tdeployment: \"single\",\n\tstorage: \"single\",\n\tauth: \"single\",\n\tvault: \"single\",\n\tdns: \"single\",\n\ttooling: \"many\",\n\tnotifications: \"many\",\n\tanalytics: \"many\",\n\terrors: \"single\",\n\tlogs: \"single\",\n\twiki: \"single\",\n\tworkers: \"single\",\n} as const satisfies Record<CapabilityKey, Cardinality>;\n\n/**\n * No capabilities are strictly required — repos without secrets (e.g. org\n * community health repos) legitimately omit vault. Plugins validate their\n * own requirements at call time.\n */\nexport const REQUIRED_CAPABILITIES: readonly CapabilityKey[] = [] as const;\n\n// ───────────────────────────────────────────────────────────────────────\n// Common shapes\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface ProviderIdentity {\n\treadonly key: CapabilityKey;\n\treadonly providerName: string;\n}\n\nexport { ProviderApiError } from \"@theholocron/http-client\";\n\n// ───────────────────────────────────────────────────────────────────────\n// source — repos, branches, PRs, rulesets, settings, workflow files\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface Ruleset {\n\tid: number;\n\tname: string;\n\tenforcement: \"active\" | \"evaluate\" | \"disabled\";\n\ttarget?: string;\n}\n\nexport interface RepoSettings {\n\tallow_squash_merge?: boolean;\n\tallow_merge_commit?: boolean;\n\tallow_rebase_merge?: boolean;\n\tallow_auto_merge?: boolean;\n\t/** Always suggest updating PR branches when the base branch has new commits. */\n\tallow_update_branch?: boolean;\n\tdelete_branch_on_merge?: boolean;\n\tdefault_branch?: string;\n\thas_issues?: boolean;\n\thas_discussions?: boolean;\n\thas_projects?: boolean;\n\thas_wiki?: boolean;\n}\n\nexport interface RepoRef {\n\towner: string;\n\tname: string;\n\tdefaultBranch: string;\n}\n\nexport interface LabelDef {\n\treadonly name: string;\n\treadonly color: string;\n\treadonly description: string;\n}\n\nexport type TeamPermission = \"pull\" | \"triage\" | \"push\" | \"maintain\" | \"admin\";\n\n/** Shorthand `\"slug\"` defaults to `push` permission. */\nexport type TeamEntry = string | { slug: string; permission: TeamPermission };\n\nexport interface Source extends ProviderIdentity {\n\treadonly key: \"source\";\n\n\t/** Auth sanity-check. Throws ProviderApiError on auth failure. */\n\twhoami(): Promise<{ login: string }>;\n\n\tgetRepo(): Promise<RepoRef>;\n\n\t// Rulesets / branch protection\n\tlistRulesets(): Promise<Ruleset[]>;\n\tcreateRuleset(payload: Record<string, unknown>): Promise<Ruleset>;\n\tupdateRuleset(id: number, payload: Record<string, unknown>): Promise<Ruleset>;\n\n\t// Repo settings\n\tupdateRepoSettings(settings: RepoSettings): Promise<void>;\n\n\t/**\n\t * Classic branch protection — fallback for private repos on free plans\n\t * where the Rulesets API (requires Team+) returns 403.\n\t */\n\tprotectBranch(branch: string, payload: Record<string, unknown>): Promise<void>;\n\n\t// Security toggles (idempotent; flip-or-noop)\n\tenableVulnerabilityAlerts(): Promise<void>;\n\tenableAutomatedSecurityFixes(): Promise<void>;\n\tenableSecretScanning(): Promise<void>;\n\tenablePrivateVulnerabilityReporting(): Promise<void>;\n\t/**\n\t * Enables the dependency graph and automatic dependency snapshot\n\t * submission. Also enables secret-scanning validity checks and\n\t * non-provider pattern detection — these require GitHub Advanced\n\t * Security at the org level; the call is accepted but may be a no-op\n\t * until that is configured.\n\t */\n\tenableDependencyGraph(): Promise<void>;\n\n\t/**\n\t * Enables CodeQL default setup with the extended query suite and\n\t * `threat_model: all` (scans both remote and local exploit paths).\n\t * Triggers a new analysis run; returns the run id.\n\t */\n\tenableCodeScanning(): Promise<string>;\n\n\t/**\n\t * Disables CodeQL default setup. Required when the repo uses an advanced\n\t * CodeQL workflow instead — GitHub rejects SARIF from advanced workflows\n\t * while default setup is active.\n\t */\n\tdisableDefaultCodeScanning(): Promise<void>;\n\n\t// Workflow files — local YAML files in `.github/workflows/` (or\n\t// equivalent). These are conceptually repo content; providers may\n\t// throw `NotImplementedError` if the underlying VCS has no notion\n\t// of declarative CI files.\n\tlistWorkflowFiles(): Promise<string[]>;\n\treadWorkflowFile(name: string): Promise<string | null>;\n\twriteWorkflowFile(name: string, contents: string): Promise<void>;\n\tremoveWorkflowFile(name: string): Promise<void>;\n\n\t/**\n\t * Write an arbitrary file relative to the repo root. Used for\n\t * provisioning config files that live outside `.github/workflows/`\n\t * (e.g. `.github/dependabot.yml`).\n\t */\n\twriteRepoFile(path: string, contents: string): Promise<void>;\n\n\t/**\n\t * Idempotently sync repo labels to a canonical set. Creates missing\n\t * labels, patches color/description drift, deletes stale labels.\n\t * Optional — providers that have no label concept omit this.\n\t */\n\tsyncLabels?(canonical: ReadonlyArray<LabelDef>, stale: ReadonlyArray<string>): Promise<string>;\n\n\t/**\n\t * Set org-level custom property values on the repo. `string[]` for\n\t * `multi_select` properties, plain `string` for everything else.\n\t * Optional — providers that don't support custom properties omit this.\n\t */\n\tsyncProperties?(values: Record<string, string | string[]>): Promise<string>;\n\n\t/**\n\t * Replace the repo's topic set with the supplied list.\n\t * Optional — providers that don't support topics omit this.\n\t */\n\tsyncTopics?(topics: string[]): Promise<string>;\n\n\t/**\n\t * Sync GitHub team repository access. String shorthand defaults to `push`.\n\t * Optional — providers without a team concept omit this.\n\t */\n\tsyncTeams?(teams: TeamEntry[]): Promise<string>;\n\n\t/**\n\t * Set the repository description.\n\t * Optional — providers that don't support setting descriptions omit this.\n\t */\n\tsyncDescription?(description: string): Promise<string>;\n\n\t/**\n\t * Set the repository homepage URL (the \"Website\" field on the repo landing page).\n\t * Optional — providers that don't support setting a homepage omit this.\n\t */\n\tsyncHomepage?(homepage: string): Promise<string>;\n\n\t/**\n\t * Fetch a pull request by number. The `repo` override lets callers look up\n\t * a PR in a different repo than the one the plugin is scoped to — useful\n\t * when the cleanup command targets another repo's PR (e.g. docs PR from\n\t * the holocron repo context).\n\t * Optional — providers without a PR concept omit this.\n\t */\n\tgetPullRequest?(number: number, repo?: string): Promise<PullRequest>;\n\n\t/**\n\t * Enable or update GitHub Pages for the repository.\n\t * Idempotent: POST to create, PUT to update existing settings.\n\t * Requires HOLOCRON_DEPLOY_TOKEN (pages:write + repo scope) — passed\n\t * explicitly because it is a different PAT from the main admin token.\n\t * Optional — providers without a Pages concept omit this.\n\t */\n\tconfigurePages?(config: PagesConfig, token: string): Promise<void>;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// Pages\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface PagesConfig {\n\t/** GitHub Pages build source. */\n\tbuild: \"workflow\" | \"branch\";\n\t/**\n\t * Custom domain / CNAME (e.g. \"docs.theholocron.dev\").\n\t * When set and `homepage` is absent in holocron.config, setup derives\n\t * homepage as `https://{domain}/`.\n\t */\n\tdomain?: string;\n\t/** Enforce HTTPS. Only effective once the custom domain is DNS-verified. */\n\thttps?: boolean;\n}\n\nexport interface PullRequest {\n\tnumber: number;\n\ttitle: string;\n\t/** \"open\" | \"closed\" — GitHub marks merged PRs as \"closed\". */\n\tstate: \"open\" | \"closed\";\n\t/** True when the PR was merged (as opposed to closed without merging). */\n\tmerged: boolean;\n\t/** The head branch name (e.g. \"fix/my-change\"). */\n\tbranch: string;\n\turl: string;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// ci — workflow runs (history + status only)\n// ───────────────────────────────────────────────────────────────────────\n\nexport type CiRunStatus = \"queued\" | \"in_progress\" | \"completed\" | \"cancelled\" | \"failure\" | \"success\" | \"skipped\";\n\nexport interface CiRun {\n\tid: string | number;\n\tworkflowName: string;\n\tbranch: string;\n\tsha: string;\n\tstatus: CiRunStatus;\n\turl: string;\n\tstartedAt: string;\n\tcompletedAt?: string;\n}\n\nexport interface CiRunFilter {\n\tbranch?: string;\n\tstatus?: CiRunStatus;\n\tlimit?: number;\n}\n\nexport interface Ci extends ProviderIdentity {\n\treadonly key: \"ci\";\n\tlistRuns(filter?: CiRunFilter): Promise<CiRun[]>;\n\tgetRun(id: string | number): Promise<CiRun>;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// secrets — CI/platform secrets sync destination (multi-scope)\n// ───────────────────────────────────────────────────────────────────────\n\nexport type SecretScope =\n\t{ kind: \"repo\" } | { kind: \"environment\"; name: string } | { kind: \"organization\"; name: string };\n\nexport interface Secrets extends ProviderIdentity {\n\treadonly key: \"secrets\";\n\n\t/** List secret NAMES (not values) at the given scope. */\n\tlistSecrets(scope: SecretScope): Promise<string[]>;\n\n\t/** Idempotent upsert. Adapter handles encryption. */\n\tsetSecret(scope: SecretScope, name: string, value: string): Promise<void>;\n\n\tdeleteSecret(scope: SecretScope, name: string): Promise<void>;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// environments — named deployment environments\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface EnvironmentReviewer {\n\ttype: \"User\" | \"Team\";\n\t/** Numeric id — GitHub's reviewer API silently ignores login strings. */\n\tid: number;\n}\n\nexport interface Environment {\n\tname: string;\n\treviewers?: EnvironmentReviewer[];\n\twaitTimer?: number;\n\tpreventSelfReview?: boolean;\n}\n\nexport interface Environments extends ProviderIdentity {\n\treadonly key: \"environments\";\n\tlistEnvironments(): Promise<Environment[]>;\n\tupsertEnvironment(env: Environment): Promise<void>;\n\tdeleteEnvironment(name: string): Promise<void>;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// issues — tracker\n// ───────────────────────────────────────────────────────────────────────\n\nexport type LifecycleSlot = \"inProgress\" | \"inReview\" | \"done\";\n\nexport type StatusCategory = \"open\" | \"in-progress\" | \"in-review\" | \"done\" | \"other\";\n\nexport interface TrackerUser {\n\tid: string;\n\tdisplayName: string;\n\temailAddress?: string;\n}\n\nexport interface Issue {\n\t/** Human-readable key — \"#42\" for GitHub, \"RANDO-42\" for Jira. */\n\tkey: string;\n\t/** Internal opaque id. */\n\tid: string;\n\tsummary: string;\n\tbody?: string;\n\tstatus: string;\n\tstatusCategory: StatusCategory;\n\tassignee: TrackerUser | null;\n\tupdated: string;\n\turl?: string;\n}\n\nexport interface IssueSearchFilter {\n\t/** Restrict to issues assigned to a specific id, or 'currentUser'. */\n\tassignee?: string | \"currentUser\";\n\t/** Exclude issues in the `done` category. */\n\topenOnly?: boolean;\n\t/** Max number of issues to return. Adapters apply a sensible default. */\n\tlimit?: number;\n}\n\nexport interface LifecycleResult {\n\t/** False when no API write happened (already at target state). */\n\ttransitioned: boolean;\n\t/** Status name the issue is in after this call. */\n\tstatus: string;\n\t/** Adapter-specific note (e.g., \"label set\" / \"closed (completed)\"). */\n\tvia?: string;\n}\n\nexport interface TrackerDoctorReport {\n\t/** \"Authenticated as ...\" subject for the spinner. */\n\tauthedAs: string;\n\t/** Free-form \"Project: RANDO\" / \"Repo: rando-id/rando\" identifier. */\n\tprojectLabel: string;\n\t/** Status values the adapter exposes. */\n\tstatuses: Array<{ name: string; category: StatusCategory }>;\n\t/**\n\t * Per-lifecycle-slot readiness check. `resolved` indicates whether\n\t * the configured value actually maps to something the tracker\n\t * recognizes; the `note` is the rendered explanation.\n\t */\n\tlifecycle: Array<{\n\t\tslot: LifecycleSlot;\n\t\tvalue: string | null;\n\t\tresolved: boolean;\n\t\tnote: string;\n\t}>;\n}\n\nexport interface Issues extends ProviderIdentity {\n\treadonly key: \"issues\";\n\n\t/** Currently-authenticated user. */\n\tgetMyself(): Promise<TrackerUser>;\n\n\tsearch(filter: IssueSearchFilter): Promise<Issue[]>;\n\tget(key: string): Promise<Issue>;\n\n\tcreate(input: {\n\t\tsummary: string;\n\t\tbody?: string;\n\t\tlabels?: string[];\n\t\t/** Numeric id or exact title (case-insensitive). */\n\t\tmilestone?: string;\n\t}): Promise<{ key: string }>;\n\n\t/** Idempotent — `transitioned: false` if the issue is already at the target. */\n\ttransition(key: string, slot: LifecycleSlot): Promise<LifecycleResult>;\n\n\tcomment(key: string, body: string): Promise<void>;\n\n\tdoctor(): Promise<TrackerDoctorReport>;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// deployment — preview/prod deploy targets\n// ───────────────────────────────────────────────────────────────────────\n\n/** Env-var scope on the deploy platform. */\nexport type DeploymentTarget = \"development\" | \"preview\" | \"production\";\n\n/**\n * Named deployment trigger target — `undefined` means a branch\n * preview (no named environment).\n */\nexport type DeploymentTrigger = \"production\" | \"staging\";\n\nexport interface DeploymentProject {\n\tid: string;\n\tname: string;\n\tframework?: string;\n\t/** True when the project is linked to a Git provider. */\n\tgitLinked?: boolean;\n\trootDirectory?: string | null;\n}\n\nexport interface DeploymentProjectSettings {\n\tpreviewDeploymentsDisabled?: boolean;\n\t/** Vercel-specific: whether the GitHub integration creates deployments\n\t * for every push (false → only on-demand triggers). */\n\tgitProviderCreateDeployments?: boolean;\n}\n\nexport interface DeploymentRecord {\n\tid: string;\n\turl: string;\n\t/** Branch this deployment was made from (null if not git-sourced). */\n\tbranch: string | null;\n\t/** Named environment if one was targeted; undefined for branch previews. */\n\ttarget?: DeploymentTrigger;\n\tstatus: \"queued\" | \"building\" | \"ready\" | \"error\" | \"cancelled\";\n\tcreatedAt?: string;\n}\n\n/** Config for `Deployment.deployFunction()` — source files, not a Git ref. */\nexport interface DeployFunctionConfig {\n\t/**\n\t * Files to deploy, keyed by path relative to the project root (e.g.\n\t * `\"api/webhook.js\"`, `\"package.json\"`). Content is plain text — the\n\t * provider handles any wire-format encoding.\n\t */\n\tfiles: Record<string, string>;\n\t/**\n\t * Named deployment target. Omit for a preview deployment — same\n\t * semantics as `triggerDeployment`'s `target`.\n\t */\n\ttarget?: DeploymentTrigger;\n}\n\nexport interface DeployFunctionResult {\n\tdeploymentId: string;\n\turl: string;\n}\n\nexport interface Deployment extends ProviderIdentity {\n\treadonly key: \"deployment\";\n\t/**\n\t * Custom domain declared in the deployment provider's configuration.\n\t * `holocron setup` attaches it to the configured project and hands any\n\t * returned verification record to the `dns` capability.\n\t */\n\treadonly domain?: string;\n\n\tlistProjects(): Promise<DeploymentProject[]>;\n\t/** Create if missing, otherwise return existing. Idempotent. */\n\tensureProject(input: {\n\t\tname: string;\n\t\tframework?: string;\n\t\t/** \"owner/repo\" — passed when linking to a Git provider. */\n\t\trepo?: string;\n\t\trootDirectory?: string;\n\t}): Promise<DeploymentProject>;\n\n\tupdateProjectSettings(projectId: string, settings: DeploymentProjectSettings): Promise<DeploymentProject>;\n\n\t// Env vars on the deploy platform (Vercel-style: per-target).\n\tlistEnvVars(projectId: string, target: DeploymentTarget): Promise<string[]>;\n\tsetEnvVar(projectId: string, target: DeploymentTarget, name: string, value: string): Promise<void>;\n\n\t/**\n\t * Kick off a deployment of the given branch. Omit `target` for a\n\t * branch preview; pass `'production'` / `'staging'` to deploy into\n\t * a named environment.\n\t */\n\ttriggerDeployment(input: {\n\t\tprojectId: string;\n\t\tbranch: string;\n\t\ttarget?: DeploymentTrigger;\n\t}): Promise<DeploymentRecord>;\n\n\tgetDeployment(deploymentId: string): Promise<DeploymentRecord>;\n\n\t/**\n\t * Deploy (or update) a project directly from source files, bypassing\n\t * Git entirely — the non-git counterpart to `triggerDeployment`, for a\n\t * consumer with no repo to link (a webhook receiver shipped as an npm\n\t * package, for instance, rather than deployed from its own Git\n\t * history). `projectId` may be a project name for providers that\n\t * accept either. Optional — providers without a files-based deploy API\n\t * omit this (e.g. Cloudflare Pages, git-source only today).\n\t */\n\tdeployFunction?(projectId: string, config: DeployFunctionConfig): Promise<DeployFunctionResult>;\n\n\t/**\n\t * List preview deployments for a specific branch alias (e.g. \"repo-pr-42\").\n\t * Optional — providers that don't support listing by branch omit this.\n\t */\n\tlistPreviewDeployments?(projectId: string, branch: string): Promise<DeploymentRecord[]>;\n\n\t/**\n\t * Delete specific preview deployments by id. Returns the count deleted.\n\t * Optional — providers that don't support deletion omit this.\n\t */\n\tdeletePreviewDeployments?(projectId: string, deploymentIds: string[]): Promise<number>;\n\n\t/**\n\t * Add a custom domain (or wildcard) to the project. Idempotent — no-op\n\t * when the domain is already present. Optional: providers without a\n\t * custom domain API omit this.\n\t *\n\t * Returns the DNS record needed to finish verification — `null` when\n\t * the domain is already verified, or when the provider's API doesn't\n\t * surface DNS-challenge details at all (e.g. Cloudflare Pages, whose\n\t * custom-domain flow doesn't expose the same per-request verification\n\t * handshake Vercel's does). Callers hand a non-null result straight\n\t * to `dns.upsertRecord(result.zone, result.record)` — the exact\n\t * pattern `setup` already uses for `Wiki.dnsRecord()`.\n\t */\n\tensureCustomDomain?(projectId: string, hostname: string): Promise<DnsRecordRequest | null>;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// storage — DB / object / file store\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface StorageBranch {\n\tid: string;\n\tname: string;\n\t/** Parent branch id; null for the root/main branch. */\n\tparentId: string | null;\n\tcreatedAt: string;\n}\n\nexport interface ConnectionStringOptions {\n\t/** Use the pooled (PgBouncer) URL when available. Defaults to false. */\n\tpooled?: boolean;\n}\n\nexport interface Storage extends ProviderIdentity {\n\treadonly key: \"storage\";\n\n\t/**\n\t * Connection string for the given scope. Scope is provider-specific:\n\t *\n\t * - branch-based providers (Neon, PlanetScale): scope = branch\n\t * name or id\n\t * - flat providers (single Postgres instance): scope is ignored\n\t *\n\t * Callers (or the orchestrator) decide how a deploy target maps to\n\t * a scope; the storage plugin doesn't own that mapping.\n\t */\n\tgetConnectionString(scope: string, options?: ConnectionStringOptions): Promise<string>;\n\n\t// Branch operations (optional — flat providers can omit).\n\tlistBranches?(): Promise<StorageBranch[]>;\n\tcreateBranch?(input: { name: string; from?: string }): Promise<StorageBranch>;\n\tdestroyBranch?(branch: string): Promise<void>;\n\t/** Restore one branch to match another (e.g., reset preview → main). */\n\tresetBranch?(input: { branch: string; from: string }): Promise<void>;\n\n\t/**\n\t * Provider-specific feature toggle. For Postgres providers this is\n\t * `CREATE EXTENSION IF NOT EXISTS ...` per branch.\n\t */\n\tenableExtension?(input: { branch: string; extension: string }): Promise<void>;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// auth — identity provider\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface AuthDescription {\n\tprovider: string;\n\t/** Env-var names the app needs at runtime (CLERK_PUBLISHABLE_KEY, etc.). */\n\tenvKeys: string[];\n}\n\nexport interface AuthIdentity {\n\tprovider: string;\n\t/** Provider-specific health signal (user count, role, account name, etc.). */\n\tdetails?: Record<string, unknown>;\n}\n\nexport interface AuthUser {\n\tid: string;\n\temail: string;\n}\n\nexport interface CreateAuthUserInput {\n\temail: string;\n\tpassword: string;\n\tfirstName?: string;\n\tlastName?: string;\n}\n\nexport interface WebhookDashboardInfo {\n\turl: string;\n}\n\nexport interface Auth extends ProviderIdentity {\n\treadonly key: \"auth\";\n\n\t/** Env-var keys the runtime app needs. */\n\tdescribe(): Promise<AuthDescription>;\n\n\t/** Reachability probe — proves the configured key works. */\n\twhoami(): Promise<AuthIdentity>;\n\n\t// Optional capabilities — providers implement what they support.\n\n\t/** Idempotent webhook backend provisioning (Clerk: Svix app). */\n\tensureWebhookApp?(): Promise<{ alreadyExists: boolean }>;\n\n\t/** Deep-link to the provider's webhook config dashboard. */\n\tgetWebhookDashboardUrl?(): Promise<WebhookDashboardInfo>;\n\n\t/** Seed a user (test fixtures, admin bootstrap). */\n\tcreateUser?(input: CreateAuthUserInput): Promise<AuthUser>;\n\n\t/** Wire the auth provider's webhook into the project's repo. */\n\tsyncWebhook?(input: { repo: string; secretRef: string }): Promise<void>;\n}\n\n// ── Normalized webhook events (cross-provider sync) ──────────────────\n//\n// Plugins implementing `auth` may also expose a `parseWebhook` utility\n// (NOT a capability method — exported alongside the plugin's\n// createPlugin) that translates the vendor's webhook payload into one\n// of these normalized event shapes. Your app's webhook handler then\n// reads the normalized event and is vendor-agnostic:\n//\n// import { parseWebhook } from '@theholocron/holocron-plugin-clerk'\n// import type { AuthEvent } from '@theholocron/cli'\n//\n// app.post('/webhooks/clerk', async (req) => {\n// const event: AuthEvent = await parseWebhook({\n// body: req.body,\n// headers: req.headers,\n// signingSecret: process.env.CLERK_WEBHOOK_SECRET!,\n// })\n// await db.users.upsert(event.user)\n// })\n//\n// Swap clerk for another auth plugin → change one import line; the\n// handler logic stays the same.\n\nexport type AuthEventType = \"user.created\" | \"user.updated\" | \"user.deleted\";\n\nexport interface NormalizedAuthUser {\n\tid: string;\n\temail: string;\n\tfirstName?: string | null;\n\tlastName?: string | null;\n\t/** Provider-native fields preserved verbatim for consumers that need them. */\n\traw?: Record<string, unknown>;\n}\n\nexport interface AuthEvent {\n\ttype: AuthEventType;\n\tuser: NormalizedAuthUser;\n\t/** ISO timestamp of when the event occurred. */\n\toccurredAt: string;\n}\n\nexport interface ParseWebhookInput {\n\t/** Raw request body (string or Buffer). */\n\tbody: string | Buffer;\n\t/** Incoming HTTP headers — needed for signature verification. */\n\theaders: Record<string, string | string[] | undefined>;\n\t/** The signing secret the auth provider issued for this webhook endpoint. */\n\tsigningSecret: string;\n}\n\nexport class WebhookVerificationError extends Error {\n\toverride name = \"WebhookVerificationError\";\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// vault — REQUIRED source-of-truth for secrets\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface EnsureResult {\n\t/** True when the resource already existed (idempotent no-op). */\n\talreadyExists: boolean;\n}\n\nexport interface Vault extends ProviderIdentity {\n\treadonly key: \"vault\";\n\n\t/**\n\t * Read a secret by reference. The reference format is\n\t * provider-specific (1P: \"op://Vault/Item/field\"; HashiCorp Vault:\n\t * \"kv/path#field\"; etc.). Adapters validate the reference shape.\n\t */\n\tread(reference: string): Promise<string>;\n\n\t/** Write or update a secret. */\n\twrite(reference: string, value: string): Promise<void>;\n\n\t/** List secret keys available to the project. */\n\tlist(): Promise<string[]>;\n\n\t/**\n\t * Optional environment notion within the vault (e.g., 1P\n\t * Environments — named KEY=VALUE bundles). Adapters without\n\t * environments return [].\n\t */\n\tenvironments?(): Promise<string[]>;\n\n\t/**\n\t * Optional bulk read of an environment's KEY=VALUE pairs. Powers\n\t * the `holocron secrets sync` flow where the orchestrator pulls a\n\t * whole environment from the vault then fans the values out to\n\t * destinations (CI secrets, deployment env vars, local .env).\n\t */\n\treadEnvironment?(environmentId: string): Promise<Record<string, string>>;\n\n\t/**\n\t * Optional — create the top-level project container in the vault\n\t * if it does not exist. Idempotent: `alreadyExists: true` when the\n\t * project was already there. Providers whose data model has no\n\t * project notion (or that gate this behind a paid tier) omit this.\n\t */\n\tensureProject?(name: string): Promise<EnsureResult>;\n\n\t/**\n\t * Optional — create a named environment/config inside a project\n\t * (e.g., Doppler config `dev` / `stg` / `prd`). Idempotent.\n\t * Providers whose data model has a single flat namespace omit this.\n\t */\n\tensureEnvironment?(project: string, name: string): Promise<EnsureResult>;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// dns — DNS record management\n// ───────────────────────────────────────────────────────────────────────\n\nexport type DnsRecordType = \"A\" | \"AAAA\" | \"CNAME\" | \"TXT\" | \"MX\" | \"NS\" | \"SRV\" | \"CAA\";\n\nexport interface DnsRecord {\n\tid?: string;\n\ttype: DnsRecordType;\n\tname: string;\n\tcontent: string;\n\tttl?: number;\n\tpriority?: number;\n\tproxied?: boolean;\n}\n\n/**\n * A DNS record a capability wants created, plus which zone it belongs\n * to — the shape `Wiki.dnsRecord()` and `Deployment.ensureCustomDomain()`\n * both hand off to `Dns.upsertRecord()`. Not tied to either capability;\n * any provider that needs \"here's a record, go create it\" returns this.\n */\nexport interface DnsRecordRequest {\n\t/** Zone apex passed as the first argument to `dns.upsertRecord`. */\n\tzone: string;\n\trecord: DnsRecord;\n}\n\nexport interface Dns extends ProviderIdentity {\n\treadonly key: \"dns\";\n\tlistRecords(domain: string): Promise<DnsRecord[]>;\n\tupsertRecord(domain: string, record: DnsRecord): Promise<DnsRecord>;\n\tdeleteRecord(domain: string, id: string): Promise<void>;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// errors — error tracking / crash reporting\n// logs — structured log aggregation\n//\n// Both are self-contained: they activate at runtime from env vars alone\n// (`HOLOCRON_SENTRY_DSN`, `HOLOCRON_AXIOM_TOKEN` + `HOLOCRON_AXIOM_DATASET`)\n// with no provider entry in `holocron.config`. The provider entry only\n// enables `holocron setup` provisioning and `holocron doctor` checks.\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface Errors extends ProviderIdentity {\n\treadonly key: \"errors\";\n\t/** Returns the env var names the app reads at runtime for this provider. */\n\tdescribe(): Promise<{ provider: string; envKeys: string[] }>;\n\twhoami?(): Promise<{ org: string }>;\n\tensureProject?(input: { name: string; platform?: string }): Promise<{ dsn: string; alreadyExists: boolean }>;\n}\n\nexport interface Logs extends ProviderIdentity {\n\treadonly key: \"logs\";\n\t/** Returns the env var names the app reads at runtime for this provider. */\n\tdescribe(): Promise<{ provider: string; envKeys: string[] }>;\n\t/** Verify the token by fetching the target dataset's info. */\n\twhoami?(): Promise<{ ok: boolean; dataset: string }>;\n\t/** Create the aggregation dataset if it does not already exist. Idempotent. */\n\tensureDataset?(name: string): Promise<{ alreadyExists: boolean }>;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// Multi-provider capabilities — many can be active at once\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface ToolingDoctorReport {\n\tok: boolean;\n\tmessage: string;\n}\n\nexport interface Tooling extends ProviderIdentity {\n\treadonly key: \"tooling\";\n\n\t/** Sync the tool's authoritative state from the repo. */\n\tsync(): Promise<void>;\n\n\tdoctor(): Promise<ToolingDoctorReport>;\n}\n\nexport interface Notifications extends ProviderIdentity {\n\treadonly key: \"notifications\";\n\n\t/**\n\t * Send a message. `channel` is provider-specific (Slack channel id,\n\t * Discord webhook url-name, etc.); adapters resolve from config.\n\t */\n\tsend(channel: string, message: string): Promise<void>;\n}\n\nexport interface Analytics extends ProviderIdentity {\n\treadonly key: \"analytics\";\n\t/** Returns the env var names the app reads at runtime for this provider. */\n\tdescribe(): Promise<{ provider: string; envKeys: string[] }>;\n\twhoami?(): Promise<{ org: string }>;\n\tensureProject?(name: string): Promise<{ token: string; alreadyExists: boolean }>;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// wiki — engineering knowledge publishing platform\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface WikiProvisionOpts {\n\t/** Project display name used in the wiki title (e.g. \"Holocron\"). */\n\tname?: string;\n}\n\n/**\n * Reverse-proxy configuration returned by `Wiki.proxyConfig()`.\n * Used by `setup` to deploy a Worker that forwards traffic to the wiki\n * provider's ingress with the required headers injected.\n */\nexport interface WikiProxyConfig {\n\t/** Proxy target URL (e.g. \"https://app.buildwithfern.com\"). */\n\ttarget: string;\n\t/** Headers injected on every proxied request. */\n\theaders: Record<string, string>;\n}\n\n/**\n * Engineering wiki provider.\n *\n * A swappable provider for publishing the `docs/decisions/` and\n * `docs/engineering/` surfaces as a browsable, access-controlled site.\n * Local-only providers (fern, mintlify) write config files; remote\n * providers (github) make API calls.\n */\nexport interface Wiki extends ProviderIdentity {\n\treadonly key: \"wiki\";\n\t/** Provision the wiki — write config files or call the provider API. */\n\tprovision(opts?: WikiProvisionOpts): Promise<string>;\n\t/**\n\t * DNS record needed for the custom domain, when one is configured.\n\t * Returns null when no custom domain is set.\n\t * Called by `setup` to provision the CNAME via the `dns` capability.\n\t */\n\tdnsRecord?(): DnsRecordRequest | null;\n\t/**\n\t * Reverse-proxy config when the wiki provider requires a Worker-level\n\t * proxy in addition to the CNAME. Returns null when no proxy is needed.\n\t * Called by `setup` to deploy the proxy via the `workers` capability.\n\t */\n\tproxyConfig?(): WikiProxyConfig | null;\n}\n\n/** Config for `Workers.deployScript()` — an arbitrary Worker, not a generated reverse-proxy. */\nexport interface DeployScriptConfig {\n\t/** The full Worker script source — a single ES module (`export default { fetch(...) {...} }`). */\n\tcode: string;\n\t/**\n\t * Secret bindings — `env.<name>` in the deployed Worker. Values are\n\t * write-only; the provider never echoes them back, here or anywhere else.\n\t */\n\tsecrets?: Record<string, string>;\n\t/**\n\t * Route pattern(s) this Worker should serve (e.g.\n\t * `\"sentinel.theholocron.dev/*\"`). Omit for a Worker reached only via\n\t * its `*.workers.dev` URL.\n\t */\n\troutes?: string[];\n}\n\nexport interface DeployScriptResult {\n\t/** The deployed script's name at the provider. */\n\tscriptName: string;\n}\n\n/**\n * Edge Worker management capability.\n *\n * Deploys and manages Worker scripts. `upsertProxy` is the existing,\n * narrower case `setup` uses to wire wiki custom-domain reverse-proxies;\n * `deployScript` is the general case — any Worker, any code, its own\n * secrets — for a consumer that isn't a reverse-proxy (a webhook\n * receiver, for instance).\n */\nexport interface Workers extends ProviderIdentity {\n\treadonly key: \"workers\";\n\t/**\n\t * Deploy (or update) a reverse-proxy Worker for `hostname`.\n\t * Forwards all `hostname/*` requests to `config.target`, injecting\n\t * `config.headers` on each request.\n\t */\n\tupsertProxy(hostname: string, config: WikiProxyConfig): Promise<void>;\n\t/** Deploy (or update) an arbitrary Worker script, optionally with secrets and routes. */\n\tdeployScript(name: string, config: DeployScriptConfig): Promise<DeployScriptResult>;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// Capability map (key → implementation type) + cardinality helpers\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface CapabilityImpls {\n\tsource: Source;\n\tci: Ci;\n\tsecrets: Secrets;\n\tenvironments: Environments;\n\tissues: Issues;\n\tdeployment: Deployment;\n\tstorage: Storage;\n\tauth: Auth;\n\tvault: Vault;\n\tdns: Dns;\n\ttooling: Tooling;\n\tnotifications: Notifications;\n\tanalytics: Analytics;\n\terrors: Errors;\n\tlogs: Logs;\n\twiki: Wiki;\n\tworkers: Workers;\n}\n\nexport type CardinalityFor<K extends CapabilityKey> = (typeof CARDINALITY)[K];\n\n/** Resolved runtime shape: single → one impl; many → array. */\nexport type ResolvedCapability<K extends CapabilityKey> =\n\tCardinalityFor<K> extends \"many\" ? CapabilityImpls[K][] : CapabilityImpls[K];\n\nexport function isMulti<K extends CapabilityKey>(key: K): CardinalityFor<K> extends \"many\" ? true : false {\n\treturn (CARDINALITY[key] === \"many\") as CardinalityFor<K> extends \"many\" ? true : false;\n}\n","/**\n * `holocron.config.json` schema, parser, and provider resolution.\n *\n * ESLint-style entry forms:\n *\n * \"source\": \"github\" ← single, short\n * \"deployment\": [\"vercel\", { team: \"rando\" }] ← single, with options\n * \"notifications\": [\"slack\", \"discord\"] ← multi, short\n * \"notifications\": [\n * [\"slack\", { channel: \"#ops\" }],\n * [\"discord\", { webhook: \"env:HOOK\" }]\n * ] ← multi, with options\n *\n * Discriminator: an array entry is a `[provider, options]` tuple when\n * the length is 2 AND element[1] is a non-array, non-null object.\n * Otherwise it's a multi-provider list (string[] or tuple[]).\n *\n * Validation rules:\n * - `vault` is REQUIRED (every project has secrets somewhere)\n * - Entries for `'many'` capabilities are normalized to an array of\n * normalized tuples; entries for `'single'` capabilities are\n * normalized to one tuple\n * - Tokens / secret values never appear in config — providers read\n * them from env (or pull from `vault` at runtime)\n */\n\nimport type { LogLevel } from \"@theholocron/observability/core\";\n\nimport {\n\ttype CapabilityKey,\n\tCARDINALITY,\n\ttype PagesConfig,\n\tREQUIRED_CAPABILITIES,\n\ttype TeamEntry,\n\ttype TeamPermission,\n} from \"../plugin/capabilities.js\";\n\n/** Structured-logging config. The Axiom **token** never lives here — only in\n * env vars or the OS keyring — but the non-secret dataset name may. */\nexport interface LogConfig {\n\t/**\n\t * Default log level. The lowest-priority level source: `--verbose` /\n\t * `--quiet` and `HOLOCRON_LOG_LEVEL` both outrank it.\n\t */\n\tlevel?: LogLevel;\n\t/**\n\t * Axiom log-shipping. Set `axiom.dataset` to opt local runs into Axiom\n\t * without exporting `HOLOCRON_AXIOM_DATASET` — the CLI then pairs it with\n\t * the token from `HOLOCRON_AXIOM_TOKEN` / `AXIOM_TOKEN` or the OS keyring\n\t * (`holocron auth set axiom[.<org>] <TOKEN>`). Env vars still win. In CI,\n\t * prefer the `HOLOCRON_AXIOM_DATASET` variable.\n\t */\n\taxiom?: {\n\t\t/** Target Axiom dataset, e.g. `\"holocron-local\"`. */\n\t\tdataset?: string;\n\t};\n}\n\n/**\n * CLI self-telemetry config — the committed, reviewable override layer over the\n * env-var + shipped-fallback activation (ADR-0007 / ADR-0008). No secret lives\n * here; the Sentry DSN and PostHog key come from env vars or ship as fallbacks.\n *\n * Precedence: `HOLOCRON_TELEMETRY=false` (env) → `telemetry.enabled` (this) →\n * default on. `enabled` never *re-enables* what the env var turned off.\n */\nexport interface TelemetryConfig {\n\t/**\n\t * Repo-level opt-out — the committed peer of `HOLOCRON_TELEMETRY=false`.\n\t * `false` installs the no-op sinks for the whole run. Default on.\n\t */\n\tenabled?: boolean;\n\t/**\n\t * Usage-analytics provider. `\"none\"` disables PostHog usage analytics while\n\t * leaving error reporting (Sentry) untouched. Default `\"posthog\"`.\n\t */\n\tanalytics?: \"posthog\" | \"none\";\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// Raw config (what users write in holocron.config.json)\n// ───────────────────────────────────────────────────────────────────────\n\nexport type ProviderOptions = Record<string, unknown>;\n\n/**\n * The shape a capability config package's default export must satisfy.\n * Config packages let teams share a pre-bundled provider + options across\n * repos (Level 1 of the shareable-configs story, issue #75).\n *\n * @example\n * // @acme/holocron-vault/index.ts\n * import type { CapabilityConfigPackage } from '@theholocron/cli'\n * export default {\n * provider: '1password',\n * options: { vault: 'acme-app' },\n * } satisfies CapabilityConfigPackage\n */\nexport interface CapabilityConfigPackage {\n\tprovider: string;\n\toptions?: ProviderOptions;\n}\n\nexport type SingleEntry = string | [provider: string, options: ProviderOptions];\n\nexport type MultiEntry = Array<string | [provider: string, options: ProviderOptions]>;\n\nexport type RawProviderEntry = SingleEntry | MultiEntry;\n\nexport type RawProvidersConfig = Partial<Record<CapabilityKey, RawProviderEntry>>;\n\nexport type RepoProtection = \"balanced\" | \"strict\" | \"none\";\n\nexport type { PagesConfig, TeamEntry, TeamPermission };\n\n/**\n * Raw `docs` config as written by the user. `build` is optional so the\n * field can be declared without committing to a build type yet; setup\n * will error if `docs` is present but `build` is absent.\n */\nexport interface DocsConfig {\n\t/**\n\t * GitHub Pages build source.\n\t * \"workflow\" → GitHub Actions (PUT { build_type: \"workflow\" })\n\t * \"branch\" → classic gh-pages branch (PUT { build_type: \"legacy\", source: { branch: \"gh-pages\", path: \"/\" } })\n\t * When absent, Pages is not managed by `holocron setup`.\n\t */\n\tbuild?: \"workflow\" | \"branch\";\n\t/**\n\t * Custom domain / CNAME (e.g. \"docs.theholocron.dev\").\n\t * When set and `homepage` is not explicitly provided, setup derives\n\t * `homepage` as `https://{domain}/` for package.json and the repo website field.\n\t */\n\tdomain?: string;\n\t/** Enforce HTTPS. Only effective once the custom domain is DNS-verified. */\n\thttps?: boolean;\n}\n\nexport interface RepoProperties {\n\tlifecycle?: \"active\" | \"experimental\" | \"deprecated\";\n\topen_source?: boolean;\n\truntime_environment?: \"node\" | \"browser\" | \"universal\" | \"none\";\n\tuses_external_packages?: boolean;\n}\n\nexport interface RepoConfig {\n\t/** \"owner/name\" — the GitHub repository coordinate. Derived from the git remote when absent. */\n\tname?: string;\n\t/**\n\t * GitHub's repo-level default branch (`HEAD`) — what a fresh clone checks\n\t * out, what `gh pr create`/the compare UI target by default, and what\n\t * Sentinel's `validateConfig()` reads (D6: the App only ever reads config\n\t * from the repo's default branch, never a PR ref, as a security boundary\n\t * — never widen that to read PR branches instead of fixing this field).\n\t * Synced by `holocron setup`. Omit to leave GitHub's current setting\n\t * untouched — most repos never need this. Exists for a repo using a\n\t * `main`/`alpha` prerelease-channel split (CLAUDE.md's Releases section)\n\t * where active development happens on a non-`main` branch: set this to\n\t * that branch so Sentinel validates against what's actually being\n\t * developed, then change it back once that branch merges to `main` for a\n\t * stable cut and stops being the active branch.\n\t */\n\tdefaultBranch?: string;\n\t/**\n\t * Branch protection preset applied by `holocron setup`. When omitted,\n\t * no protection is applied and no `branch_protection_level` property is set.\n\t * Required-status-check contexts for `\"strict\"` are derived from the task\n\t * manifest — `{ required: true }` tasks + top-level `extraRequiredChecks`\n\t * (see `astromech.requiredChecks()`).\n\t */\n\tprotection?: RepoProtection;\n\t/**\n\t * GitHub teams granted repository access. Synced by `holocron setup`, which\n\t * also writes `.github/CODEOWNERS` for teams with write-or-higher permission.\n\t * String shorthand defaults to `push` (Write).\n\t */\n\tteams?: TeamEntry[];\n\t/** GitHub topics set on the repository. */\n\ttopics?: string[];\n\t/** GitHub custom properties synced to the org dashboard. */\n\tproperties?: RepoProperties;\n}\n\nexport interface AppConfig {\n\tname: string;\n\tpath: string;\n\tkind?: string;\n}\n\nexport interface DoctorConfig {\n\tchecks?: string[];\n}\n\nexport interface EnvConfig {\n\t/**\n\t * Namespace prefixes used by this project's env vars.\n\t * Listed from least- to most-specific (cascade model — last wins).\n\t * Tooling reads this to generate `.env.example`, validate required\n\t * vars, and produce documentation.\n\t *\n\t * @example\n\t * // Project-only prefix\n\t * namespaces: [\"CLI_TEMPLATE\"]\n\t *\n\t * // Org-wide defaults + project-specific overrides\n\t * namespaces: [\"HOLOCRON\", \"MY_CLI\"]\n\t */\n\tnamespaces?: string[];\n}\n\n/**\n * A single Chromatic project entry in a monorepo `run-chromatic` config.\n * Each entry produces one matrix job in CI, publishing to a separate Chromatic project.\n *\n * The `tokenName` maps to a repository secret named `CHROMATIC_PROJECT_TOKEN_<TOKENNAME>`.\n * Additional fields correspond to chromaui/action inputs and are passed through directly.\n *\n * @see https://www.chromatic.com/docs/monorepos/\n */\nexport interface ChromaticProjectConfig {\n\t/**\n\t * Secret suffix. The CI job reads `CHROMATIC_PROJECT_TOKEN_<tokenName>`.\n\t * Must be uppercase (e.g. `\"WEB\"`, `\"UI\"`).\n\t */\n\ttokenName: string;\n\t/**\n\t * Path to run the Chromatic build from, relative to the repo root.\n\t * Typically the package directory (e.g. `\"apps/web\"`, `\"packages/ui\"`).\n\t */\n\tworkingDir: string;\n\t/**\n\t * Script name to build Storybook. Defaults to `\"build:storybook\"`.\n\t * Must accept `--output-dir` pass-through (use `turbo run … --` at root).\n\t */\n\tbuildScript?: string;\n\t/**\n\t * Path to the Storybook folder relative to `workingDir`, for TurboSnap.\n\t * Tells Chromatic where to find `.storybook/` when the Storybook config\n\t * is in a subdirectory. Corresponds to `--storybook-base-dir`.\n\t */\n\tstorybookBaseDir?: string;\n\t/**\n\t * Glob patterns of files/dirs that should NOT trigger a TurboSnap bailout\n\t * when changed. Useful for ignoring non-UI changes in a monorepo\n\t * (e.g. `\"./packages/!(ui)/**\"` to focus TurboSnap on the UI package).\n\t * Corresponds to `--untraced`. Accepts a single glob string or array.\n\t */\n\tuntraced?: string | string[];\n\t/**\n\t * Glob patterns matching story files to snapshot. When set, only matching\n\t * stories are captured. Corresponds to `--only-story-files`.\n\t * Cannot be combined with `onlyStoryNames`.\n\t */\n\tonlyStoryFiles?: string;\n\t/**\n\t * Exit with code 0 even when visual changes are detected.\n\t * Useful during initial setup before baselines are approved.\n\t * Corresponds to `--exit-zero-on-changes`.\n\t */\n\texitZeroOnChanges?: boolean;\n}\n\n/**\n * A single Storybook app in a deploy workflow config.\n * `name` becomes the sandbox sub-path (`_site/sandbox/<name>/`).\n * `path` is the working directory relative to the repo root; defaults to `\".\"` (repo root) when omitted.\n */\nexport interface StorybookDeployProject {\n\tname?: string;\n\tpath?: string;\n}\n\n/**\n * Typed `with:` inputs for reusable workflows.\n *\n * `run-chromatic` accepts either a plain boolean (single-project) or a\n * `ChromaticProjectConfig[]` object (multi-project monorepo).\n *\n * `docs` / `storybook` are high-level deploy shorthand that `holocron setup`\n * translates to `type` / `storybook-projects` before writing the thin caller.\n * They also drive automatic `paths:` derivation so you never need to write\n * `paths:` manually for deploy entries.\n */\nexport type WorkflowWithConfig = Record<string, unknown> & {\n\t\"run-chromatic\"?: boolean | { projects: ChromaticProjectConfig[] };\n\t/**\n\t * Docs deployment shorthand. `true` uses the org-standard `docs/` directory;\n\t * `{ path: \"custom\" }` uses a custom directory. Both derive a `paths:` entry automatically.\n\t */\n\tdocs?: true | { path: string };\n\t/** Storybook apps to deploy alongside docs. Each entry's `path` is appended to `paths:`. */\n\tstorybook?: StorybookDeployProject[];\n};\n\n/**\n * A `tasks` manifest entry in object form. A bare string entry is shorthand\n * for `{ name, ci: true, local: true }`.\n */\nexport interface TaskEntryConfig {\n\tname: string;\n\twith?: WorkflowWithConfig;\n\tpaths?: string[];\n\tlinters?: string[];\n\t/** Emit a `.github/workflows/<name>.yml` thin caller + include in `holocron ci`. Default `true`. */\n\tci?: boolean;\n\t/** Write a `package.json` script + let `holocron run <name>` resolve the task. Default `true`. */\n\tlocal?: boolean;\n\t/** The task's CI check context is a required status check + part of `holocron ci`'s default run. */\n\trequired?: boolean;\n}\n\nexport interface HolocronConfig {\n\t/** Project name. Derived from package.json when absent. */\n\tname?: string;\n\tdescription?: string;\n\t/** Project homepage URL. Synced to package.json#homepage and the GitHub repo's website field by `holocron sync`. */\n\thomepage?: string;\n\t/**\n\t * Active org name for namespaced keyring lookup. When set, token resolution\n\t * tries `<service>.<org>` before the unnamespaced `<service>` fallback, so\n\t * a single machine can hold credentials for multiple GitHub orgs without\n\t * collision. Overridden by `--org` CLI flag or `HOLOCRON_ORG` env var.\n\t */\n\torg?: string;\n\t/**\n\t * Org canonical domain (e.g. `\"theholocron.dev\"`). Subdomains are derived\n\t * from this — `preview: true` on a deploy workflow resolves the preview base\n\t * domain as `preview.<domain>`, giving URLs like `<repo>-pr-<n>.<domain>`.\n\t */\n\tdomain?: string;\n\t/**\n\t * Repository identity and metadata. When set, `PluginLoader` injects\n\t * `repo.name` into every plugin's `RuntimeContext.repo` so plugins that\n\t * need a repo (github, etc.) don't require `--repo` on every invocation.\n\t * `--repo` on the command line still overrides.\n\t */\n\trepo?: RepoConfig;\n\t/**\n\t * The task manifest — what this repo runs. Each entry is a task name\n\t * (backed by a reusable workflow in `theholocron/.github`), or the object\n\t * form to pass `with:` inputs. `@theholocron/astromech` reads this as the\n\t * single source for `holocron run` / `holocron ci` / the generated CI\n\t * workflows / `package.json` scripts.\n\t *\n\t * Supported values (intent-facing vocabulary — epic #672, D3):\n\t * \"verification.unitTests\" | \"verification.typeSafety\" | \"verification.performance\" |\n\t * \"sourceQuality.staticAnalysis\" | \"sourceQuality.formatting\" |\n\t * \"sourceQuality.structuredDataValidation\" | \"sourceQuality.deadCodeAnalysis\" |\n\t * \"security.secretDetection\" | \"security.codeScanning\" |\n\t * \"delivery.build\" | \"delivery.publish\" | \"delivery.deploy\" | \"delivery.bundleSize\" |\n\t * \"platform.repoSync\" | \"platform.commitStandards\" | \"platform.repoValidation\" |\n\t * \"knowledge.wiki\" | \"knowledge.docs\" | \"knowledge.components\" |\n\t * \"review\" | \"tag\" | \"stale\" | \"greetings\" | \"dependencies\" | \"bookkeeping\"\n\t *\n\t * `holocron setup` writes `.github/workflows/<name>.yml` for each entry,\n\t * calling the corresponding reusable workflow in `theholocron/.github`.\n\t * Files are overwritten on each run — they are generated artifacts.\n\t *\n\t * ### delivery.deploy / knowledge.docs / knowledge.components\n\t * `delivery.deploy` uses `docs` and/or `storybook` in `with:` — setup\n\t * derives `paths:` automatically. `docs: true` uses the org-standard\n\t * `docs/` directory; `docs: { path: \"custom\" }` overrides it.\n\t * `knowledge.docs` / `knowledge.components` are the same underlying\n\t * mechanism, each dedicated to exactly one type — they imply the\n\t * corresponding shorthand, so a repo using them never has to spell out\n\t * `docs: true` / `storybook: […]` itself.\n\t *\n\t * ```ts\n\t * // Docs only (standard layout)\n\t * { name: \"delivery.deploy\", with: { docs: true } }\n\t * // …or equivalently, the dedicated task:\n\t * \"knowledge.docs\"\n\t *\n\t * // Docs + monorepo storybooks\n\t * {\n\t * name: \"delivery.deploy\",\n\t * with: {\n\t * docs: true,\n\t * storybook: [\n\t * { name: \"web\", path: \"apps/web\" },\n\t * { name: \"ui\", path: \"packages/ui\" },\n\t * ],\n\t * },\n\t * }\n\t *\n\t * // Non-standard docs location\n\t * { name: \"delivery.deploy\", with: { docs: { path: \"packages/site\" } } }\n\t * ```\n\t *\n\t * ### run-chromatic\n\t * For a single-project repo, use `\"run-chromatic\": true` with a\n\t * `CHROMATIC_PROJECT_TOKEN` repository secret.\n\t *\n\t * For monorepos with multiple Storybooks, use the object form:\n\t * ```ts\n\t * \"run-chromatic\": {\n\t * projects: [\n\t * { tokenName: \"WEB\", workingDir: \"apps/web\" },\n\t * { tokenName: \"UI\", workingDir: \"packages/ui\" },\n\t * ]\n\t * }\n\t * ```\n\t * Each `tokenName` maps to a repository secret named\n\t * `CHROMATIC_PROJECT_TOKEN_<TOKENNAME>`. `holocron setup` expands this\n\t * to the flat `run-chromatic: true` + `chromatic-projects: <json>` inputs\n\t * that the reusable workflow accepts.\n\t *\n\t * @example\n\t * [\"sourceQuality.staticAnalysis\", { \"name\": \"delivery.publish\", \"with\": { \"run-build\": false } }]\n\t * { \"name\": \"delivery.deploy\", \"with\": { \"docs\": true } }\n\t */\n\ttasks?: Array<string | TaskEntryConfig>;\n\t/**\n\t * Opt out of `holocron sync`'s `package.json` script writes. Default `true`.\n\t */\n\tsyncScripts?: boolean;\n\t/**\n\t * The command the synced `\"holocron\"` `package.json` script runs. Default\n\t * `\"holocron\"` (the installed bin). This repo overrides it to run its own\n\t * build (`\"node packages/cli/dist/cli.mjs\"`).\n\t */\n\tholocronScript?: string;\n\t/**\n\t * Required status-check contexts not backed by a `required` task (codecov\n\t * gates, the bundle-build check, …). `holocron setup` appends these to the\n\t * task-derived list from `astromech.requiredChecks()`.\n\t */\n\textraRequiredChecks?: string[];\n\t/**\n\t * Git hooks `holocron setup` installs. `true` / `{ prePush: true }` writes\n\t * `.husky/pre-push` (runs `holocron ci` before every push); `false` /\n\t * `{ prePush: false }` opts out. Omitted → on for `protection: \"strict\"`,\n\t * off otherwise. `--hooks` / `--no-hooks` on `holocron setup` override.\n\t */\n\thooks?: boolean | { prePush?: boolean };\n\tproviders: RawProvidersConfig;\n\tapps?: AppConfig[];\n\tdoctor?: DoctorConfig;\n\t/**\n\t * Agent runtime that determines where skills are installed by `holocron setup`.\n\t * Skills are installed to `.agents/skills/<name>/` (canonical) with a\n\t * relative symlink at the agent-specific path:\n\t * - `\"claude\"` → `.claude/skills/<name>` → `../../.agents/skills/<name>`\n\t * - `\"codex\"` | `\"gemini\"` → logged as unsupported; skipped gracefully.\n\t */\n\tagent?: \"claude\" | \"codex\" | \"gemini\";\n\t/**\n\t * Skill names from `@theholocron/skills` to install during `holocron setup`.\n\t * Installed paths are gitignored and managed by setup — do not commit them.\n\t *\n\t * @example\n\t * [\"git-safety\", \"pr-workflow\", \"commit-standards\"]\n\t */\n\tskills?: string[];\n\t/**\n\t * GitHub Pages configuration. When present, `holocron setup` calls the\n\t * Pages API using `HOLOCRON_DEPLOY_TOKEN` (requires `pages:write` + `repo` scope).\n\t * When absent, Pages is left as-is.\n\t *\n\t * @example\n\t * { build: \"workflow\", domain: \"docs.theholocron.dev\", https: true }\n\t */\n\tdocs?: DocsConfig;\n\t/**\n\t * Environment variable namespace configuration.\n\t * Declares the prefix(es) this project uses for its env vars so that\n\t * tooling can generate `.env.example`, validate required vars, and\n\t * produce accurate documentation without hard-coding prefix strings.\n\t *\n\t * @example\n\t * { namespaces: [\"HOLOCRON\", \"MY_CLI\"] }\n\t */\n\tenv?: EnvConfig;\n\t/**\n\t * Structured-logging config. Only the level belongs here — Axiom\n\t * credentials come from env vars, never a committed file.\n\t *\n\t * @example\n\t * { level: \"debug\" }\n\t */\n\tlog?: LogConfig;\n\t/**\n\t * CLI self-telemetry override layer. Env var (`HOLOCRON_TELEMETRY=false`)\n\t * still wins; this is the committed way to opt a repo out or drop usage\n\t * analytics while keeping error reporting.\n\t *\n\t * @example\n\t * { enabled: false }\n\t * { analytics: \"none\" }\n\t */\n\ttelemetry?: TelemetryConfig;\n\t/**\n\t * ESLint bundle option overrides that Sentinel's centralized static-\n\t * analysis check (holocron#849) can't otherwise see. Bucket 1 checks\n\t * never read a PR's own committed files for config — this is the\n\t * declared source of truth Sentinel reads instead, so its check stays\n\t * in sync with what each package's own `eslint.config.ts` already\n\t * enforces locally and in CI.\n\t */\n\teslint?: EslintConfig;\n}\n\n/**\n * Repo-root-relative directories treated as browser-targeted for eslint's\n * node-builtins compatibility checks — mirrors\n * `@theholocron/eslint-config`'s `library({ browserPackages })` option.\n * Only needed for a package whose own `eslint.config.ts` already declares\n * `browserPackages` (a deliberate outlier, not the norm — see that\n * package's own config file for why).\n *\n * @example\n * { browserPackages: [\"packages/github-client/src/app-auth\"] }\n */\nexport interface EslintConfig {\n\tbrowserPackages?: string[];\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// Resolved config (what the runtime sees after parsing)\n// ───────────────────────────────────────────────────────────────────────\n\nexport interface ResolvedTuple {\n\tprovider: string;\n\t/** Resolved package name (`@theholocron/holocron-plugin-<provider>` for short refs). */\n\tpackageName: string;\n\toptions: ProviderOptions;\n}\n\nexport type ResolvedProviderEntry =\n\t{ cardinality: \"single\"; tuple: ResolvedTuple } | { cardinality: \"many\"; tuples: ResolvedTuple[] };\n\nexport type ResolvedProvidersConfig = Partial<Record<CapabilityKey, ResolvedProviderEntry>>;\n\nexport interface ResolvedHolocronConfig {\n\tname: string;\n\tdescription?: string;\n\thomepage?: string;\n\torg?: string;\n\tdomain?: string;\n\trepo?: RepoConfig;\n\ttasks?: Array<string | TaskEntryConfig>;\n\tsyncScripts?: boolean;\n\tholocronScript?: string;\n\textraRequiredChecks?: string[];\n\thooks?: boolean | { prePush?: boolean };\n\tproviders: ResolvedProvidersConfig;\n\tapps: AppConfig[];\n\tdoctor: DoctorConfig;\n\tagent?: \"claude\" | \"codex\" | \"gemini\";\n\tskills?: string[];\n\t/** Resolved Pages config. `build` is guaranteed present when this field exists. */\n\tdocs?: PagesConfig;\n\tenv?: EnvConfig;\n\tlog?: LogConfig;\n\ttelemetry?: TelemetryConfig;\n\teslint?: EslintConfig;\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// Errors\n// ───────────────────────────────────────────────────────────────────────\n\nexport class ConfigError extends Error {\n\toverride name = \"ConfigError\";\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// Helpers\n// ───────────────────────────────────────────────────────────────────────\n\nconst PLUGIN_PREFIX = \"@theholocron/holocron-plugin-\";\nconst COMMUNITY_PREFIX = \"holocron-plugin-\";\n\n/**\n * Resolve `\"github\"` → `\"@theholocron/holocron-plugin-github\"`.\n * Fully-qualified names (scoped or not) are honored verbatim, which\n * is how third-party plugins published outside the org work.\n */\nexport function resolvePluginPackage(provider: string): string {\n\tif (!provider) throw new ConfigError(\"provider name is empty\");\n\tif (provider.startsWith(\"@\")) return provider;\n\tif (provider.startsWith(COMMUNITY_PREFIX)) return provider;\n\tif (provider.includes(\"/\")) return provider;\n\treturn PLUGIN_PREFIX + provider;\n}\n\n/** A bare `[provider, options]` tuple, with both elements present? */\nfunction isOptionsTuple(value: unknown): value is [string, ProviderOptions] {\n\tif (!Array.isArray(value)) return false;\n\tif (value.length !== 2) return false;\n\tif (typeof value[0] !== \"string\") return false;\n\tconst opt = value[1];\n\treturn typeof opt === \"object\" && opt !== null && !Array.isArray(opt);\n}\n\nfunction normalizeEntry(entry: string | [string, ProviderOptions]): ResolvedTuple {\n\tif (typeof entry === \"string\") {\n\t\treturn { provider: entry, packageName: resolvePluginPackage(entry), options: {} };\n\t}\n\tconst [provider, options] = entry;\n\treturn { provider, packageName: resolvePluginPackage(provider), options };\n}\n\n// ───────────────────────────────────────────────────────────────────────\n// Parse / resolve\n// ───────────────────────────────────────────────────────────────────────\n\nexport function resolveEntry(key: CapabilityKey, raw: RawProviderEntry): ResolvedProviderEntry {\n\tconst cardinality = CARDINALITY[key];\n\n\t// Single short form: \"github\"\n\tif (typeof raw === \"string\") {\n\t\tif (cardinality === \"many\") {\n\t\t\tthrow new ConfigError(`\\`${key}\\` accepts multiple providers; wrap a single one in an array: [\"${raw}\"]`);\n\t\t}\n\t\treturn { cardinality: \"single\", tuple: normalizeEntry(raw) };\n\t}\n\n\tif (!Array.isArray(raw)) {\n\t\tthrow new ConfigError(`\\`${key}\\` entry must be a string or array, got ${typeof raw}`);\n\t}\n\n\t// Single options tuple: [\"vercel\", { team: \"rando\" }]\n\tif (isOptionsTuple(raw)) {\n\t\tif (cardinality === \"many\") {\n\t\t\t// Same shape, but cardinality forces multi — promote to one-element list\n\t\t\treturn { cardinality: \"many\", tuples: [normalizeEntry(raw)] };\n\t\t}\n\t\treturn { cardinality: \"single\", tuple: normalizeEntry(raw) };\n\t}\n\n\t// Multi list — array of strings, tuples, or a mix\n\tif (cardinality === \"single\") {\n\t\tthrow new ConfigError(\n\t\t\t`\\`${key}\\` accepts exactly one provider; got a multi-provider list with ${raw.length} entries`\n\t\t);\n\t}\n\n\tconst tuples = raw.map((entry, idx) => {\n\t\tif (typeof entry === \"string\") return normalizeEntry(entry);\n\t\tif (isOptionsTuple(entry)) return normalizeEntry(entry);\n\t\tthrow new ConfigError(`\\`${key}[${idx}]\\` must be a provider string or [provider, options] tuple`);\n\t});\n\n\treturn { cardinality: \"many\", tuples };\n}\n\nexport function resolveConfig(raw: HolocronConfig): ResolvedHolocronConfig {\n\tif (!raw.name) {\n\t\tthrow new ConfigError(\"`name` is required\");\n\t}\n\tif (!raw.providers || typeof raw.providers !== \"object\") {\n\t\tthrow new ConfigError(\"`providers` block is required\");\n\t}\n\n\tconst providers: ResolvedProvidersConfig = {};\n\tfor (const [key, entry] of Object.entries(raw.providers)) {\n\t\tif (entry === undefined) continue;\n\t\tproviders[key as CapabilityKey] = resolveEntry(key as CapabilityKey, entry as RawProviderEntry);\n\t}\n\n\tfor (const required of REQUIRED_CAPABILITIES) {\n\t\tif (!providers[required]) {\n\t\t\tthrow new ConfigError(`required capability \\`${required}\\` is missing from providers`);\n\t\t}\n\t}\n\n\t// Validate docs and narrow build to required\n\tlet docs: PagesConfig | undefined;\n\tif (raw.docs !== undefined) {\n\t\tif (!raw.docs.build) {\n\t\t\tthrow new ConfigError(\"`docs.build` is required when `docs` is set\");\n\t\t}\n\t\tdocs = raw.docs as PagesConfig;\n\t}\n\n\t// Derive homepage from docs.domain when not explicitly set\n\tconst homepage = raw.homepage ?? (docs?.domain ? `https://${docs.domain}/` : undefined);\n\n\treturn {\n\t\tname: raw.name,\n\t\tdescription: raw.description,\n\t\thomepage,\n\t\torg: raw.org,\n\t\tdomain: raw.domain,\n\t\trepo: raw.repo,\n\t\ttasks: raw.tasks,\n\t\tsyncScripts: raw.syncScripts,\n\t\tholocronScript: raw.holocronScript,\n\t\textraRequiredChecks: raw.extraRequiredChecks,\n\t\thooks: raw.hooks,\n\t\tproviders,\n\t\tapps: raw.apps ?? [],\n\t\tdoctor: raw.doctor ?? {},\n\t\tagent: raw.agent,\n\t\tskills: raw.skills,\n\t\tdocs,\n\t\tenv: raw.env,\n\t\tlog: raw.log,\n\t\ttelemetry: raw.telemetry,\n\t\teslint: raw.eslint,\n\t};\n}\n","/**\n * CLI-side wiring for `@theholocron/observability/logger`.\n *\n * `logger` is the operational-output channel — internal state, debug\n * traces, errors, structured context that routes to Axiom. It runs in\n * parallel to `print` (user-facing UX output) and does not replace it.\n */\n\nimport type { Logger, LogLevel } from \"@theholocron/observability/core\";\nimport type { AxiomTransportConfig } from \"@theholocron/observability/logger\";\nimport { createLogger, parseLogLevel, resolveAxiomFromEnv } from \"@theholocron/observability/logger\";\n\nimport { getToken } from \"./auth/keyring.js\";\nimport { env } from \"./env.js\";\n\n/**\n * Resolve the explicit level to hand to `createLogger`, in priority order:\n *\n * 1. `--verbose` → `\"debug\"` 2. `--quiet` → `\"error\"`\n * 3. `HOLOCRON_LOG_LEVEL` env var\n * 4. `holocron.config` `log.level` (`configLevel`)\n *\n * Returns `undefined` when nothing applies — `createLogger` then defaults\n * to `\"info\"`. Resolving the full chain here (rather than passing\n * `configLevel` straight through) keeps config below the env var.\n */\nexport function resolveLogLevel(\n\targv: { verbose?: boolean; quiet?: boolean },\n\tconfigLevel?: LogLevel\n): LogLevel | undefined {\n\tif (argv.verbose) return \"debug\";\n\tif (argv.quiet) return \"error\";\n\treturn parseLogLevel(env.get(\"HOLOCRON_LOG_LEVEL\")) ?? configLevel;\n}\n\nlet root: { logger: Logger; runId: string } | undefined;\nlet rootLevel: LogLevel | undefined;\nlet rootCommand: string | undefined;\nlet rootAxiomKey: string | undefined;\n\nexport interface BuildCliLoggerOpts {\n\t/** Active command name — bound on the root as `command` for every line. */\n\tcommand?: string;\n\t/** `holocron.config` `log.level`, from a handler that has loaded a config. */\n\tconfigLevel?: LogLevel;\n\t/**\n\t * `holocron.config` `log.axiom.dataset` — the non-secret Axiom dataset\n\t * name. Paired with a keyring token when the env vars are absent.\n\t */\n\tconfigAxiomDataset?: string;\n\t/**\n\t * Resolved org (`--org` → `HOLOCRON_ORG` → config `org`) for the\n\t * namespaced keyring lookup (`axiom.<org>` before bare `axiom`).\n\t */\n\torg?: string;\n}\n\n/**\n * Resolve Axiom credentials for the CLI. Env vars win — same contract as\n * `@theholocron/observability`'s `resolveAxiomFromEnv`. Failing that, the CLI-only\n * bridge pairs the OS-keyring token (`axiom.<org>` then bare `axiom`) with a\n * dataset from `HOLOCRON_AXIOM_DATASET` / `AXIOM_DATASET` or\n * `holocron.config` `log.axiom.dataset`. Returns `undefined` unless both a\n * token and a dataset are found.\n */\nfunction resolveCliAxiom(opts: BuildCliLoggerOpts): AxiomTransportConfig | undefined {\n\tconst fromEnv = resolveAxiomFromEnv();\n\tif (fromEnv) return fromEnv;\n\n\tconst dataset = env.get(\"HOLOCRON_AXIOM_DATASET\") || env.get(\"AXIOM_DATASET\") || opts.configAxiomDataset;\n\tif (!dataset) return undefined;\n\n\tconst org = opts.org ?? env.get(\"HOLOCRON_ORG\");\n\tconst token = (org ? getToken(`axiom.${org}`) : null) ?? getToken(\"axiom\");\n\treturn token ? { dataset, token } : undefined;\n}\n\n/**\n * The process-wide root logger. Built once (from `cli.ts`'s middleware,\n * with the command name + flags + env). Rebuilt at most once more when a\n * command's handler supplies `holocron.config` context the flag/env-only\n * first pass could not have known — `log.level` (unless `--verbose` /\n * `--quiet` already fixed it) or `log.axiom.dataset` + the resolved org\n * for a keyring-backed Axiom transport. That rebuild generates a fresh\n * `runId`, which is harmless: nothing logs between the middleware and the\n * handler.\n */\nexport function buildCliLogger(\n\targv: { verbose?: boolean; quiet?: boolean },\n\topts: BuildCliLoggerOpts = {}\n): { logger: Logger; runId: string } {\n\tconst { command, configLevel } = opts;\n\tif (command) rootCommand = command;\n\tconst level = resolveLogLevel(argv, configLevel);\n\tconst axiom = resolveCliAxiom(opts);\n\tconst axiomKey = axiom?.dataset;\n\tconst rebuildForConfig = configLevel !== undefined && level !== rootLevel && !argv.verbose && !argv.quiet;\n\tconst rebuildForAxiom = axiomKey !== undefined && axiomKey !== rootAxiomKey;\n\tif (!root || rebuildForConfig || rebuildForAxiom) {\n\t\tconst built = createLogger({ ...(level ? { level } : {}), ...(axiom ? { axiom } : {}) });\n\t\troot = {\n\t\t\tlogger: rootCommand ? built.logger.child({ command: rootCommand }) : built.logger,\n\t\t\trunId: built.runId,\n\t\t};\n\t\trootLevel = level;\n\t\trootAxiomKey = axiomKey;\n\t}\n\treturn root;\n}\n\n/** Lazily-memoized `Logger` for module-level call sites with no `argv` in scope. */\nexport function getLogger(): Logger {\n\treturn (root ??= createLogger()).logger;\n}\n\n/** The current root logger's correlation id, if a root has been built. */\nexport function getRunId(): string | undefined {\n\treturn root?.runId;\n}\n\n/** Test hook — drop the memoized root so the next call rebuilds it. */\nexport function resetCliLogger(): void {\n\troot = undefined;\n\trootLevel = undefined;\n\trootCommand = undefined;\n\trootAxiomKey = undefined;\n}\n","/**\n * `PluginLoader` — loads provider plugins per the resolved config and\n * builds a typed capability registry the runtime can query.\n *\n * Flow:\n * 1. Walk `config.providers[*]` from `resolveConfig()`\n * 2. For each entry, dynamic-import the resolved package name\n * (`@theholocron/holocron-plugin-<provider>` by default)\n * 3. Call the package's exported `createPlugin(options)` to get a\n * plugin object whose `capabilities` map holds factories\n * 4. Invoke the matching capability factory and stash the impl in\n * the registry — single-cardinality entries hold one impl,\n * many-cardinality entries hold an array\n *\n * A package may instead export a capability config (see\n * `CapabilityConfigPackage` in config.ts). The loader detects the shape\n * at import time and re-resolves to the underlying plugin, merging the\n * preset options with any per-project overrides from the config file\n * (project options win, mirroring ESLint's `extends` precedence).\n *\n * Loader keeps NO knowledge of vendor tokens. Each plugin reads its\n * own env vars (`HOLOCRON_ADMIN_TOKEN`, `HOLOCRON_VERCEL_TOKEN`, etc.)\n * inside its `createPlugin`. That keeps the loader vendor-agnostic\n * and the auth story per-plugin explicit.\n *\n * `importer` is injectable so tests don't need real network or\n * sibling packages installed.\n */\n\nimport { createRequire } from \"node:module\";\nimport { pathToFileURL } from \"node:url\";\n\nimport type { CapabilityConfigPackage, ResolvedHolocronConfig, ResolvedTuple } from \"../config/config.js\";\nimport { resolvePluginPackage } from \"../config/config.js\";\nimport type { CapabilityKey, CardinalityFor, ResolvedCapability } from \"./capabilities.js\";\nimport { CARDINALITY } from \"./capabilities.js\";\n\n/**\n * Per-invocation context every plugin receives, on top of its own\n * config-time options. Kept intentionally narrow.\n */\nexport interface RuntimeContext {\n\t/** \"owner/name\" — the repo this invocation is operating on. */\n\trepo?: string;\n\t/** Absolute path to the working repo root. */\n\trepoRoot: string;\n\t/**\n\t * When true, commands print what they WOULD mutate instead of\n\t * actually calling capability mutators. Set by the global\n\t * `--dry-run` flag. Capabilities themselves are unaware — the check\n\t * lives at the command layer.\n\t */\n\tdryRun?: boolean;\n\t/**\n\t * Token passed via bare `--token <value>`. Used as fallback for all\n\t * plugins when no matching entry exists in `cliTokens`.\n\t */\n\tcliToken?: string;\n\t/**\n\t * Per-provider tokens from `--token vendor=value` pairs. The loader\n\t * routes each entry to the matching plugin (by `tuple.provider`) as\n\t * its `cliToken`, falling back to `cliToken` for unmatched providers.\n\t * Plugins never receive this map — they always see a single `cliToken`.\n\t */\n\tcliTokens?: Record<string, string>;\n\t/**\n\t * Active org name for namespaced keyring lookup. Resolved from\n\t * `--org` flag → `HOLOCRON_ORG` env var → `org` in config, then\n\t * injected here so plugins receive it via their options\n\t * (which extend `ResolveTokenInput`) without any per-plugin change.\n\t */\n\torg?: string;\n}\n\n/**\n * The shape every plugin's default-or-named export must satisfy:\n * `createPlugin(opts)` returns an object with capability factories.\n */\nexport interface LoadedPlugin {\n\tname: string;\n\tcapabilities: Partial<{\n\t\t[K in CapabilityKey]: () => unknown;\n\t}>;\n}\n\nexport interface PluginModule {\n\tcreatePlugin: (opts: Record<string, unknown>) => LoadedPlugin;\n}\n\n/** Returns `unknown` — the loader type-narrows inside `loadOne`. */\nexport type PluginImporter = (packageName: string) => Promise<unknown>;\n\nexport class LoaderError extends Error {\n\toverride name = \"LoaderError\";\n}\n\n/** A provider that could not be loaded — missing token, bad package, unimplemented capability. */\nexport interface PluginLoadFailure {\n\tkey: CapabilityKey;\n\tprovider: string;\n\tpackageName: string;\n\terror: Error;\n}\n\nexport class PluginLoader {\n\tprivate readonly registry = new Map<CapabilityKey, unknown>();\n\tprivate readonly failures: PluginLoadFailure[] = [];\n\n\tconstructor(\n\t\tprivate readonly config: ResolvedHolocronConfig,\n\t\tprivate readonly context: RuntimeContext,\n\t\tprivate readonly importer: PluginImporter = defaultImporter\n\t) {}\n\n\t/**\n\t * Imports every configured plugin and builds the capability registry.\n\t *\n\t * Never throws for a single plugin's failure — a missing vendor token,\n\t * an uninstalled package, or an unimplemented capability records a\n\t * {@link PluginLoadFailure} and the load continues. This is the\n\t * \"soft-skip over hard-fail\" contract: a command that needs a\n\t * capability learns it is absent via `has()` / `get()` (which\n\t * re-surfaces the original error), and orchestrators report the skip\n\t * in their summary. Inspect {@link loadFailures} for the full list.\n\t */\n\tasync load(): Promise<void> {\n\t\tconst entries = Object.entries(this.config.providers) as Array<\n\t\t\t[CapabilityKey, ResolvedHolocronConfig[\"providers\"][CapabilityKey]]\n\t\t>;\n\n\t\tfor (const [key, entry] of entries) {\n\t\t\tif (!entry) continue;\n\t\t\tif (entry.cardinality === \"single\") {\n\t\t\t\ttry {\n\t\t\t\t\tthis.registry.set(key, await this.loadOne(key, entry.tuple));\n\t\t\t\t} catch (err) {\n\t\t\t\t\tthis.recordFailure(key, entry.tuple, err);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst impls: unknown[] = [];\n\t\t\t\tfor (const tuple of entry.tuples) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\timpls.push(await this.loadOne(key, tuple));\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tthis.recordFailure(key, tuple, err);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (impls.length > 0) this.registry.set(key, impls);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate recordFailure(key: CapabilityKey, tuple: ResolvedTuple, err: unknown): void {\n\t\tthis.failures.push({\n\t\t\tkey,\n\t\t\tprovider: tuple.provider,\n\t\t\tpackageName: tuple.packageName,\n\t\t\terror: err instanceof Error ? err : new Error(String(err)),\n\t\t});\n\t}\n\n\t/** Providers that failed to load during {@link load}. Empty on a clean load. */\n\tloadFailures(): readonly PluginLoadFailure[] {\n\t\treturn this.failures;\n\t}\n\n\t/**\n\t * Type-safe lookup. Single-cardinality keys return one impl;\n\t * many-cardinality keys return an array. `ResolvedCapability<K>`\n\t * encodes the split via the `CARDINALITY` map.\n\t */\n\tget<K extends CapabilityKey>(key: K): ResolvedCapability<K> {\n\t\tconst impl = this.registry.get(key);\n\t\tif (impl === undefined) {\n\t\t\t// If the plugin was configured but failed to load, re-surface the\n\t\t\t// original error (e.g. `AuthError: no Vercel token found`) rather\n\t\t\t// than a generic \"not loaded\" — single-capability commands then\n\t\t\t// give the operator an actionable message.\n\t\t\tconst failure = this.failures.find((f) => f.key === key);\n\t\t\tif (failure) throw failure.error;\n\t\t\tthrow new LoaderError(`capability \\`${key}\\` is not loaded — is it declared in holocron.config.json?`);\n\t\t}\n\t\treturn impl as ResolvedCapability<K>;\n\t}\n\n\t/** Whether a capability has been loaded. */\n\thas<K extends CapabilityKey>(key: K): boolean {\n\t\treturn this.registry.has(key);\n\t}\n\n\t/** All capability keys currently loaded. Useful for the doctor command. */\n\tloadedKeys(): CapabilityKey[] {\n\t\treturn Array.from(this.registry.keys());\n\t}\n\n\t/** Internal — invoke a plugin's capability factory and return the impl. */\n\tprivate async loadOne(key: CapabilityKey, tuple: ResolvedTuple): Promise<unknown> {\n\t\tconst mod = await this.importer(tuple.packageName).catch((err: unknown) => {\n\t\t\tthrow new LoaderError(\n\t\t\t\t`failed to import \\`${tuple.packageName}\\` for capability \\`${key}\\`: ${\n\t\t\t\t\terr instanceof Error ? err.message : String(err)\n\t\t\t\t}`\n\t\t\t);\n\t\t});\n\n\t\t// Plugin package: exports createPlugin(opts) → { capabilities }\n\t\tif (isPluginModule(mod)) {\n\t\t\t// Resolve the effective token for this specific plugin.\n\t\t\t// cliTokens[provider] wins over the bare cliToken fallback.\n\t\t\tconst effectiveToken = this.context.cliTokens?.[tuple.provider] ?? this.context.cliToken;\n\n\t\t\t// Precedence (later wins): project-level defaults from config →\n\t\t\t// runtime context (CLI flags: --repo, --token) → per-plugin\n\t\t\t// resolved token → tuple options (per-plugin overrides in config).\n\t\t\t// cliTokens is explicitly cleared so the map never reaches plugins.\n\t\t\tconst plugin = mod.createPlugin({\n\t\t\t\t...this.projectDefaults(),\n\t\t\t\t...this.context,\n\t\t\t\t...(effectiveToken !== undefined ? { cliToken: effectiveToken } : {}),\n\t\t\t\tcliTokens: undefined,\n\t\t\t\t...tuple.options,\n\t\t\t});\n\t\t\tconst factory = plugin.capabilities[key];\n\t\t\tif (typeof factory !== \"function\") {\n\t\t\t\tthrow new LoaderError(`\\`${tuple.packageName}\\` does not implement the \\`${key}\\` capability`);\n\t\t\t}\n\t\t\treturn factory();\n\t\t}\n\n\t\t// Capability config package: default export is { provider, options? }.\n\t\t// Re-resolve to the underlying plugin; preset options are the base,\n\t\t// per-project tuple options override them (ESLint extends precedence).\n\t\tif (isCapabilityConfigModule(mod)) {\n\t\t\tconst cap = (mod as { default: CapabilityConfigPackage }).default;\n\t\t\treturn this.loadOne(key, {\n\t\t\t\tprovider: cap.provider,\n\t\t\t\tpackageName: resolvePluginPackage(cap.provider),\n\t\t\t\toptions: { ...cap.options, ...tuple.options },\n\t\t\t});\n\t\t}\n\n\t\tthrow new LoaderError(\n\t\t\t`\\`${tuple.packageName}\\` does not export \\`createPlugin(options)\\` or a capability config ({ provider, options? })`\n\t\t);\n\t}\n\n\t/**\n\t * Project-level defaults that get merged into every plugin's options\n\t * unless overridden by the CLI context or per-plugin tuple options.\n\t * See `docs/wiki/specifications/tech-setup-and-config.spec.md` §Design.\n\t */\n\tprivate projectDefaults(): Partial<RuntimeContext> {\n\t\tconst defaults: Partial<RuntimeContext> = {};\n\t\tif (this.config.repo?.name) defaults.repo = this.config.repo.name;\n\t\treturn defaults;\n\t}\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────\n\n/** Default importer — resolves from cwd first so the global CLI finds project plugins. */\nconst defaultImporter: PluginImporter = async (pkg) => {\n\ttry {\n\t\tconst localRequire = createRequire(process.cwd() + \"/\");\n\t\tconst resolved = localRequire.resolve(pkg);\n\t\treturn import(pathToFileURL(resolved).href);\n\t} catch {\n\t\treturn import(pkg);\n\t}\n};\n\nfunction isPluginModule(mod: unknown): mod is PluginModule {\n\treturn typeof (mod as PluginModule).createPlugin === \"function\";\n}\n\nfunction isCapabilityConfigModule(mod: unknown): mod is { default: CapabilityConfigPackage } {\n\tconst def = (mod as { default?: unknown }).default;\n\treturn typeof (def as CapabilityConfigPackage)?.provider === \"string\";\n}\n\n/** Convenience re-export so callers can compute counts without importing CARDINALITY directly. */\nexport function cardinalityOf<K extends CapabilityKey>(key: K): CardinalityFor<K> {\n\treturn CARDINALITY[key];\n}\n","/**\n * The `workspace`-context guard.\n *\n * A `workspace` command (`sync`, `setup`, `doctor`, …) needs the\n * configured providers' `@theholocron/holocron-plugin-*` packages to\n * resolve. From a bare `npm i -g @theholocron/cli` they don't, and the\n * {@link PluginLoader} — which soft-skips every failure — leaves the\n * command with an empty registry and a stack of `Cannot find package`\n * errors.\n *\n * {@link assertPluginsResolvable} turns that specific situation (every\n * provider failed, and every failure is a module-resolution failure)\n * into one actionable {@link WorkspaceContextError} the CLI prints\n * instead of a stack trace. Any other mix — some plugins loaded, or a\n * failure that's an auth/token error rather than a missing package —\n * is left alone for the command's own soft-skip reporting.\n *\n * Spec: `docs/wiki/specifications/tech-cli-execution-contexts.spec.md`\n * (theholocron/holocron#576).\n */\n\nimport { LoaderError, type PluginLoader } from \"./loader.js\";\n\n/**\n * Raised when a `workspace` command runs somewhere its provider plugins\n * cannot be resolved — the \"you're on a global install\" case. Carries the\n * unresolved package names so the message can be specific.\n */\nexport class WorkspaceContextError extends Error {\n\toverride name = \"WorkspaceContextError\";\n\treadonly command: string;\n\treadonly packages: readonly string[];\n\n\tconstructor(command: string, packages: readonly string[]) {\n\t\tconst [first, ...rest] = packages;\n\t\tconst subject =\n\t\t\trest.length > 0\n\t\t\t\t? `${first} (and ${rest.length} other${rest.length === 1 ? \"\" : \"s\"})`\n\t\t\t\t: (first ?? \"its plugins\");\n\t\tsuper(\n\t\t\t`\\`${command}\\` needs ${subject}, but no plugin package resolves here.\\n` +\n\t\t\t\t`Run it from a repo that has the \\`@theholocron/holocron-plugin-*\\` packages as devDependencies, ` +\n\t\t\t\t`or \\`pnpm exec holocron ${command}\\`. A global install can't resolve them — see ` +\n\t\t\t\t`https://theholocron.github.io/holocron/execution-contexts`\n\t\t);\n\t\tthis.command = command;\n\t\tthis.packages = packages;\n\t}\n}\n\n/**\n * A raw \"package isn't installed here\" error from `import()` /\n * `require.resolve` — `ERR_MODULE_NOT_FOUND` / `MODULE_NOT_FOUND`, or the\n * \"Cannot find package/module\" message Node prints for it.\n */\nexport function isModuleNotFound(err: unknown): boolean {\n\tif (!(err instanceof Error)) return false;\n\tconst code = (err as NodeJS.ErrnoException).code;\n\tif (code === \"ERR_MODULE_NOT_FOUND\" || code === \"MODULE_NOT_FOUND\") return true;\n\treturn /Cannot find (?:package|module)|MODULE_NOT_FOUND/.test(err.message);\n}\n\n/** Did this failure come from the dynamic `import()` not finding the package? */\nfunction isImportFailure(err: Error): boolean {\n\treturn err instanceof LoaderError && err.message.startsWith(\"failed to import\");\n}\n\n/**\n * Throw {@link WorkspaceContextError} when a loaded `PluginLoader` shows\n * the global-install signature: nothing in the registry, at least one\n * failure, and *every* failure is a missing-package error. A no-op in\n * every other case (some capability loaded, non-import failure, or no\n * providers configured at all).\n *\n * Call it right after `await loader.load()` in a `workspace` command.\n */\nexport function assertPluginsResolvable(loader: PluginLoader, command: string): void {\n\tif (loader.loadedKeys().length > 0) return;\n\tconst failures = loader.loadFailures();\n\tif (failures.length === 0) return;\n\tif (!failures.every((f) => isImportFailure(f.error))) return;\n\n\tconst packages = [...new Set(failures.map((f) => f.packageName))];\n\tthrow new WorkspaceContextError(command, packages);\n}\n","import ora from \"ora\";\n\n/**\n * Runs `fn`, showing an ora spinner for its duration in TTY environments.\n * In non-TTY environments (CI, pipes, tests) the spinner is skipped entirely.\n */\nexport async function withSpinner<T>(label: string, fn: () => Promise<T>): Promise<T> {\n\tif (!process.stdout.isTTY) {\n\t\treturn fn();\n\t}\n\tconst spinner = ora(label).start();\n\ttry {\n\t\tconst result = await fn();\n\t\tspinner.succeed();\n\t\treturn result;\n\t} catch (err) {\n\t\tspinner.fail();\n\t\tthrow err;\n\t}\n}\n","import chalk from \"chalk\";\n\nexport const style = {\n\tsuccess: (msg: string) => `${chalk.green(\"✓\")} ${msg}`,\n\twarn: (msg: string) => `${chalk.yellow(\"⚠\")} ${msg}`,\n\tfail: (msg: string) => `${chalk.red(\"✗\")} ${msg}`,\n\tstep: (msg: string) => `${chalk.cyan(\"→\")} ${msg}`,\n\thint: (msg: string) => chalk.dim(msg),\n\tdim: (msg: string) => chalk.dim(msg),\n\theader: (msg: string) => chalk.bold(msg),\n};\n","/**\n * `holocron auth <subcommand>` — manage bootstrap credentials in the\n * OS keyring.\n *\n * Subcommands:\n * auth set <provider> [token] verify + store\n * auth unset <provider> remove\n * auth check <provider> re-verify a stored token\n * auth list every provider with a stored entry\n *\n * See `docs/wiki/specifications/tech-auth-bootstrap.spec.md`.\n *\n * Verification lives in each plugin as a top-level `verifyToken(token)`\n * export. The auth command dynamically imports\n * `@theholocron/holocron-plugin-<provider>` and calls it. Plugins that\n * don't export `verifyToken` can still store — with a warning — because\n * \"no verify path\" shouldn't block credential storage.\n */\n\nimport { createRequire } from \"node:module\";\nimport { pathToFileURL } from \"node:url\";\n\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport { deleteToken, getToken, listStoredProviders, setToken } from \"../auth/keyring.js\";\nimport { resolvePluginPackage } from \"../config/config.js\";\nimport { makeEnv } from \"../env.js\";\nimport { getLogger } from \"../logger.js\";\nimport { isModuleNotFound } from \"../plugin/workspace.js\";\nimport { withSpinner } from \"../ui/progress.js\";\nimport { style } from \"../ui/style.js\";\n\n// ── Plugin-level export shapes (mirrored on every plugin) ────────────\n\nexport interface VerifyTokenSuccess {\n\tok: true;\n\t/** \"workplace: acme\" / \"user: cnewton@x\" — surfaced in success output. */\n\tsubject: string;\n}\n\nexport interface VerifyTokenFailure {\n\tok: false;\n\t/** Reason the token was rejected. Surfaces to the operator. */\n\tmessage: string;\n}\n\nexport type VerifyTokenResult = VerifyTokenSuccess | VerifyTokenFailure;\n\ninterface AuthPluginModule {\n\tverifyToken?: (token: string) => Promise<VerifyTokenResult>;\n\t/** One-line hint printed when no token was supplied. */\n\tAUTH_HINT?: string;\n}\n\nexport type AuthImporter = (packageName: string) => Promise<AuthPluginModule>;\n\nconst defaultImporter: AuthImporter = async (pkg) => {\n\ttry {\n\t\tconst localRequire = createRequire(process.cwd() + \"/\");\n\t\tconst resolved = localRequire.resolve(pkg);\n\t\treturn (await import(pathToFileURL(resolved).href)) as AuthPluginModule;\n\t} catch {\n\t\treturn (await import(pkg)) as AuthPluginModule;\n\t}\n};\n\n// ── Common types ─────────────────────────────────────────────────────\n\nexport type AuthPrint = (line: string) => void;\n\nexport interface AuthCommandStatus {\n\tstatus: \"ok\" | \"fail\" | \"skip\";\n\tmessage?: string;\n}\n\n// ── Token resolution ─────────────────────────────────────────────────\n\n/**\n * Resolve a token from (positional → HOLOCRON_<X> → vendor-native env).\n * Keyring is NOT consulted here — `auth set` writes TO the keyring, so\n * pulling FROM it would just re-store the same value.\n */\nexport function resolveAuthSetToken(input: {\n\tprovider: string;\n\tpositional?: string;\n\tenv?: NodeJS.ProcessEnv;\n}): string | null {\n\tconst e = makeEnv(input.env);\n\tconst upper = input.provider.toUpperCase();\n\tconst holocronKey = `HOLOCRON_${upper}_TOKEN`;\n\treturn input.positional || e.get(holocronKey) || e.get(`${upper}_TOKEN`) || null;\n}\n\n// ── Subcommands ──────────────────────────────────────────────────────\n\nexport interface RunAuthSetInput {\n\tprovider: string;\n\tpositional?: string;\n\tenv?: NodeJS.ProcessEnv;\n\timporter?: AuthImporter;\n\tprint?: AuthPrint;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n\t/** When set, stores the token under `<provider>.<org>` in the keyring. */\n\torg?: string;\n}\n\nexport async function runAuthSet(input: RunAuthSetInput): Promise<AuthCommandStatus> {\n\tconst print = input.print ?? ((l: string) => console.log(l));\n\tconst logger = input.logger ?? getLogger();\n\tconst importer = input.importer ?? defaultImporter;\n\tconst { provider } = input;\n\tconst keyringKey = input.org ? `${provider}.${input.org}` : provider;\n\n\tconst token = resolveAuthSetToken({ provider, positional: input.positional, env: input.env });\n\n\t// Feature sub-keys (e.g. \"github.read\") are stored directly — there is no\n\t// per-feature plugin package to load for verification.\n\tconst isFeatureKey = provider.includes(\".\");\n\tconst packageName = isFeatureKey ? null : resolvePluginPackage(provider);\n\n\tif (!token) {\n\t\tprint(style.fail(`no token supplied for \\`${keyringKey}\\`.`));\n\t\tprint(style.hint(` pass as positional arg: holocron auth set ${provider} <token>`));\n\t\tif (!isFeatureKey) {\n\t\t\tprint(\n\t\t\t\tstyle.hint(` or via env: HOLOCRON_${provider.toUpperCase()}_TOKEN / ${provider.toUpperCase()}_TOKEN`)\n\t\t\t);\n\t\t\tconst hint = await tryLoadHint(importer, packageName!);\n\t\t\tif (hint) {\n\t\t\t\tprint(style.hint(` hint: ${hint}`));\n\t\t\t}\n\t\t}\n\t\tlogger.warn({ provider, keyringKey, reason: \"no token supplied\" }, `auth set: ${keyringKey}`);\n\t\treturn { status: \"fail\", message: \"no token supplied\" };\n\t}\n\n\t// Verify via the plugin if it exports verifyToken (skipped for feature sub-keys).\n\tlet subject: string | undefined;\n\tif (!isFeatureKey && packageName) {\n\t\ttry {\n\t\t\tconst module = await importer(packageName);\n\t\t\tif (typeof module.verifyToken === \"function\") {\n\t\t\t\tconst verified = await module.verifyToken(token);\n\t\t\t\tif (!verified.ok) {\n\t\t\t\t\tprint(style.fail(`token rejected by ${provider}: ${verified.message}`));\n\t\t\t\t\tif (module.AUTH_HINT) print(style.hint(` hint: ${module.AUTH_HINT}`));\n\t\t\t\t\tlogger.warn(\n\t\t\t\t\t\t{ provider, keyringKey, verified: false, reason: verified.message },\n\t\t\t\t\t\t`auth set: ${keyringKey}`\n\t\t\t\t\t);\n\t\t\t\t\treturn { status: \"fail\", message: verified.message };\n\t\t\t\t}\n\t\t\t\tsubject = verified.subject;\n\t\t\t} else {\n\t\t\t\tprint(style.warn(`${provider} plugin has no verifyToken; storing without verification`));\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\tprint(style.warn(`cannot verify token — failed to load ${packageName}: ${msg}`));\n\t\t\tprint(\n\t\t\t\tstyle.hint(` storing token anyway; run 'holocron auth check ${provider}' once the plugin is installed`)\n\t\t\t);\n\t\t}\n\t}\n\n\tconst stored = setToken(keyringKey, token);\n\tif (!stored) {\n\t\tprint(style.fail(`keyring unavailable — token not stored. Use env vars instead.`));\n\t\tlogger.warn({ provider, keyringKey, reason: \"keyring unavailable\" }, `auth set: ${keyringKey}`);\n\t\treturn { status: \"fail\", message: \"keyring unavailable\" };\n\t}\n\n\tprint(style.success(`stored ${keyringKey} token${subject ? ` (${subject})` : \"\"}`));\n\tlogger.info(\n\t\t{ provider, keyringKey, verified: subject !== undefined, ...(subject ? { subject } : {}), status: \"ok\" },\n\t\t`auth set: ${keyringKey}`\n\t);\n\treturn { status: \"ok\", ...(subject ? { message: subject } : {}) };\n}\n\nexport interface RunAuthUnsetInput {\n\tprovider: string;\n\tprint?: AuthPrint;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n}\n\nexport function runAuthUnset(input: RunAuthUnsetInput): AuthCommandStatus {\n\tconst print = input.print ?? ((l: string) => console.log(l));\n\tconst logger = input.logger ?? getLogger();\n\tconst removed = deleteToken(input.provider);\n\tif (removed) {\n\t\tprint(style.success(`removed ${input.provider} token`));\n\t\tlogger.info({ provider: input.provider, status: \"ok\" }, `auth unset: ${input.provider}`);\n\t\treturn { status: \"ok\" };\n\t}\n\tprint(style.dim(`no stored token for ${input.provider}`));\n\tlogger.info({ provider: input.provider, status: \"skip\" }, `auth unset: ${input.provider}`);\n\treturn { status: \"skip\", message: \"nothing to remove\" };\n}\n\nexport interface RunAuthCheckInput {\n\tprovider: string;\n\timporter?: AuthImporter;\n\tprint?: AuthPrint;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n\t/** Set to false to suppress the ora spinner (e.g. when called from runAuthList). */\n\tshowSpinner?: boolean;\n\t/** When set, checks the token stored under `<provider>.<org>` in the keyring. */\n\torg?: string;\n}\n\nexport async function runAuthCheck(input: RunAuthCheckInput): Promise<AuthCommandStatus> {\n\tconst print = input.print ?? ((l: string) => console.log(l));\n\tconst logger = input.logger ?? getLogger();\n\tconst importer = input.importer ?? defaultImporter;\n\tconst { provider } = input;\n\tconst keyringKey = input.org ? `${provider}.${input.org}` : provider;\n\n\tconst token = getToken(keyringKey);\n\tif (!token) {\n\t\tprint(style.dim(`no stored token for ${keyringKey}`));\n\t\tlogger.info({ provider, keyringKey, status: \"skip\", reason: \"no stored token\" }, `auth check: ${keyringKey}`);\n\t\treturn { status: \"skip\", message: \"no stored token\" };\n\t}\n\n\t// Feature sub-keys have no plugin to verify against — report stored only.\n\tif (provider.includes(\".\")) {\n\t\tprint(style.success(`${keyringKey}: token stored (feature key — no plugin verification)`));\n\t\treturn { status: \"ok\", message: \"stored\" };\n\t}\n\n\tconst packageName = resolvePluginPackage(provider);\n\ttry {\n\t\tconst module = await importer(packageName);\n\t\tif (typeof module.verifyToken !== \"function\") {\n\t\t\tprint(style.warn(`${keyringKey}: token stored (plugin has no verifyToken; can't confirm validity)`));\n\t\t\treturn { status: \"ok\", message: \"stored, unverified\" };\n\t\t}\n\t\tconst verify = () => module.verifyToken!(token);\n\t\tconst verified =\n\t\t\tinput.showSpinner !== false ? await withSpinner(`Verifying ${keyringKey} token…`, verify) : await verify();\n\t\tif (verified.ok) {\n\t\t\tprint(style.success(`${keyringKey}: ok — ${verified.subject}`));\n\t\t\tlogger.info(\n\t\t\t\t{ provider, keyringKey, verified: true, subject: verified.subject, status: \"ok\" },\n\t\t\t\t`auth check: ${keyringKey}`\n\t\t\t);\n\t\t\treturn { status: \"ok\", message: verified.subject };\n\t\t}\n\t\tprint(style.fail(`${keyringKey}: rejected — ${verified.message}`));\n\t\tif (module.AUTH_HINT) print(style.hint(` hint: ${module.AUTH_HINT}`));\n\t\tlogger.warn(\n\t\t\t{ provider, keyringKey, verified: false, reason: verified.message, status: \"fail\" },\n\t\t\t`auth check: ${keyringKey}`\n\t\t);\n\t\treturn { status: \"fail\", message: verified.message };\n\t} catch (err) {\n\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t// Global install: the plugin package isn't resolvable here. `auth set` /\n\t\t// `auth list` already work plugin-free — `auth check` degrades to the\n\t\t// same \"we have a token, we just can't confirm it\" report rather than\n\t\t// failing outright (theholocron/holocron#576).\n\t\tif (isModuleNotFound(err)) {\n\t\t\tprint(style.warn(`${keyringKey}: token present — verification skipped (plugin not available here)`));\n\t\t\tlogger.info(\n\t\t\t\t{ provider, keyringKey, status: \"ok\", reason: \"plugin not resolvable\" },\n\t\t\t\t`auth check: ${keyringKey}`\n\t\t\t);\n\t\t\treturn { status: \"ok\", message: \"stored, unverified (plugin not available)\" };\n\t\t}\n\t\tprint(style.fail(`${keyringKey}: cannot verify — ${msg}`));\n\t\tlogger.warn({ provider, keyringKey, reason: msg, status: \"fail\" }, `auth check: ${keyringKey}`);\n\t\treturn { status: \"fail\", message: msg };\n\t}\n}\n\nexport interface RunAuthListInput {\n\timporter?: AuthImporter;\n\tprint?: AuthPrint;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n}\n\nexport async function runAuthList(input: RunAuthListInput = {}): Promise<AuthCommandStatus> {\n\tconst print = input.print ?? ((l: string) => console.log(l));\n\tconst logger = input.logger ?? getLogger();\n\tconst importer = input.importer ?? defaultImporter;\n\tconst providers = listStoredProviders();\n\n\tif (providers.length === 0) {\n\t\tprint(style.dim(\"no stored tokens.\"));\n\t\tprint(style.hint(\"run: holocron auth set <provider> <token>\"));\n\t\tlogger.info({ providers: 0 }, \"auth list: done\");\n\t\treturn { status: \"ok\", message: \"none\" };\n\t}\n\n\tlet ok = 0;\n\tlet fail = 0;\n\tfor (const provider of providers.sort()) {\n\t\tconst check = await runAuthCheck({ provider, importer, print: () => {}, logger, showSpinner: false });\n\t\tconst label = `${provider}${check.message ? ` — ${check.message}` : \"\"}`;\n\t\tif (check.status === \"ok\") {\n\t\t\tok += 1;\n\t\t\tprint(` ${style.success(label)}`);\n\t\t} else if (check.status === \"fail\") {\n\t\t\tfail += 1;\n\t\t\tprint(` ${style.fail(label)}`);\n\t\t} else print(` ${style.dim(`· ${label}`)}`);\n\t}\n\tlogger.info({ providers: providers.length, ok, fail }, \"auth list: done\");\n\treturn { status: \"ok\" };\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────\n\nasync function tryLoadHint(importer: AuthImporter, packageName: string): Promise<string | null> {\n\ttry {\n\t\tconst module = await importer(packageName);\n\t\treturn module.AUTH_HINT ?? null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n","import { checkbox } from \"@inquirer/prompts\";\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport type { LoadedConfig } from \"../config/load-config.js\";\nimport { getLogger } from \"../logger.js\";\nimport type { Deployment, DeploymentRecord, PullRequest, Source } from \"../plugin/capabilities.js\";\nimport { PluginLoader, type RuntimeContext } from \"../plugin/loader.js\";\nimport { assertPluginsResolvable } from \"../plugin/workspace.js\";\nimport { style } from \"../ui/style.js\";\n\nexport interface RunCleanupPreviewInput {\n\tloaded: LoadedConfig;\n\tcontext: RuntimeContext;\n\t/** PR number to look up on the source provider. */\n\tprNumber: number;\n\t/**\n\t * \"owner/name\" override — when provided, the PR is looked up in this repo\n\t * instead of the one the source plugin is scoped to.\n\t */\n\trepo?: string;\n\t/** Cloudflare Pages project name (e.g. \"theholocron-preview\"). */\n\tproject: string;\n\tloader?: PluginLoader;\n\tprint?: (line: string) => void;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n}\n\nexport interface CleanupPreviewReport {\n\tpr: PullRequest;\n\t/** Branch alias used to query Cloudflare (e.g. \"holocron-pr-42\"). */\n\tbranch: string;\n\tfound: number;\n\tdeleted: number;\n\tstatus: \"ok\" | \"none\" | \"aborted\" | \"fail\";\n\tmessage?: string;\n}\n\nfunction prStateLabel(pr: PullRequest): string {\n\tif (pr.merged) return style.success(\"merged\");\n\tif (pr.state === \"closed\") return style.dim(\"closed (not merged)\");\n\treturn style.warn(\"open\");\n}\n\nexport async function runCleanupPreview(input: RunCleanupPreviewInput): Promise<CleanupPreviewReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\t// c8 ignore next -- real PluginLoader construction is integration-level; unit tests always supply loader\n\tconst loader = input.loader ?? new PluginLoader(input.loaded.resolved, input.context);\n\tawait loader.load();\n\tassertPluginsResolvable(loader, \"cleanup-preview\");\n\tlogger.info({ pr: input.prNumber, project: input.project }, \"cleanup-preview: start\");\n\n\t// ── 1. Look up the PR ───────────────────────────────────────────────\n\tif (!loader.has(\"source\")) {\n\t\tthrow new Error(\"source capability is not configured — add a source provider to holocron.config.json\");\n\t}\n\tconst source = loader.get(\"source\") as Source;\n\tif (!source.getPullRequest) {\n\t\tthrow new Error(`${source.providerName} source provider does not support getPullRequest`);\n\t}\n\n\tlet pr: PullRequest;\n\ttry {\n\t\tpr = await source.getPullRequest(input.prNumber, input.repo);\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to fetch PR #${input.prNumber}: ${message}`, { cause: err });\n\t}\n\n\t// Derive the Cloudflare branch alias from the repo name and PR number.\n\t// Matches the convention the deploy-preview workflow uses:\n\t// --branch ${{ github.event.repository.name }}-pr-${{ github.event.pull_request.number }}\n\tconst repoName = (input.repo ?? input.loaded.resolved.repo?.name ?? \"\").split(\"/\").pop()!;\n\tconst branch = `${repoName}-pr-${pr.number}`;\n\n\tprint(\"\");\n\tprint(`${style.header(`PR #${pr.number}`)} — ${pr.title}`);\n\tprint(` Status : ${prStateLabel(pr)} | Branch : ${style.dim(pr.branch)}`);\n\tprint(` URL : ${style.dim(pr.url)}`);\n\tprint(` CF alias : ${style.dim(branch)}`);\n\tprint(\"\");\n\n\t// ── 2. List deployments ─────────────────────────────────────────────\n\tif (!loader.has(\"deployment\")) {\n\t\tthrow new Error(\"deployment capability is not configured — add a deployment provider to holocron.config.json\");\n\t}\n\tconst deploy = loader.get(\"deployment\") as Deployment;\n\tif (!deploy.listPreviewDeployments || !deploy.deletePreviewDeployments) {\n\t\tthrow new Error(`${deploy.providerName} deployment provider does not support preview cleanup`);\n\t}\n\n\tlet deployments: DeploymentRecord[];\n\ttry {\n\t\tdeployments = await deploy.listPreviewDeployments(input.project, branch);\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to list deployments: ${message}`, { cause: err });\n\t}\n\n\tif (deployments.length === 0) {\n\t\tprint(style.dim(`No deployments found for branch ${branch}.`));\n\t\tlogger.info({ pr: pr.number, branch, found: 0, deleted: 0, status: \"none\" }, \"cleanup-preview: done\");\n\t\treturn { pr, branch, found: 0, deleted: 0, status: \"none\" };\n\t}\n\n\tprint(`Found ${deployments.length} deployment${deployments.length === 1 ? \"\" : \"s\"} for ${style.dim(branch)}:`);\n\tprint(\"\");\n\n\tif (pr.state === \"open\") {\n\t\tprint(\n\t\t\tstyle.warn(\n\t\t\t\t`PR #${pr.number} is still open. Deleting its preview deployments will break the live preview link.`\n\t\t\t)\n\t\t);\n\t\tprint(style.warn(\"Nothing is pre-selected — check the deployments you want to remove.\"));\n\t\tprint(\"\");\n\t}\n\n\t// ── 3. Interactive selection ────────────────────────────────────────\n\tconst choices = deployments.map((d) => {\n\t\tconst label = d.id.includes(\":\") ? d.id.split(\":\").pop()! : d.id;\n\t\tconst date = d.createdAt ? style.dim(d.createdAt.slice(0, 10)) : \"\";\n\t\treturn {\n\t\t\tname: `${label} ${date} ${style.dim(d.url)}`,\n\t\t\tvalue: d.id,\n\t\t\tchecked: pr.state !== \"open\",\n\t\t};\n\t});\n\n\tlet selected: string[];\n\ttry {\n\t\tselected = await checkbox({\n\t\t\tmessage: \"Select deployments to delete (space to toggle, a to select all, enter to confirm):\",\n\t\t\tchoices,\n\t\t});\n\t} catch {\n\t\t// Ctrl-C\n\t\tprint(style.dim(\"Aborted.\"));\n\t\treturn { pr, branch, found: deployments.length, deleted: 0, status: \"aborted\" };\n\t}\n\n\tif (selected.length === 0) {\n\t\tprint(style.dim(\"Nothing selected — no deployments deleted.\"));\n\t\treturn { pr, branch, found: deployments.length, deleted: 0, status: \"aborted\" };\n\t}\n\n\t// ── 4. Delete ───────────────────────────────────────────────────────\n\tprint(\"\");\n\ttry {\n\t\tconst count = await deploy.deletePreviewDeployments(input.project, selected);\n\t\tprint(style.success(`Deleted ${count} deployment${count === 1 ? \"\" : \"s\"}.`));\n\t\tlogger.info(\n\t\t\t{ pr: pr.number, branch, found: deployments.length, deleted: count, status: \"ok\" },\n\t\t\t\"cleanup-preview: done\"\n\t\t);\n\t\treturn { pr, branch, found: deployments.length, deleted: count, status: \"ok\" };\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tprint(style.fail(message));\n\t\tlogger.warn(\n\t\t\t{ pr: pr.number, branch, found: deployments.length, reason: message, status: \"fail\" },\n\t\t\t\"cleanup-preview: done\"\n\t\t);\n\t\treturn { pr, branch, found: deployments.length, deleted: 0, status: \"fail\", message };\n\t}\n}\n","import { spawnSync } from \"node:child_process\";\nimport { existsSync, mkdirSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\n\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport { getLogger } from \"../logger.js\";\nimport { style } from \"../ui/style.js\";\n\nfunction encodeTokenForGitHttpAuth(token: string): string {\n\tconst trimmed = token.trim();\n\tif (!trimmed) throw new Error(\"empty token\");\n\t// eslint-disable-next-line no-control-regex\n\tif (/[\\u0000-\\u001F\\u007F\\s]/.test(trimmed)) {\n\t\tthrow new Error(\"token contains whitespace or control characters\");\n\t}\n\treturn encodeURIComponent(trimmed);\n}\n\ninterface GitHubRepo {\n\tname: string;\n\tfull_name: string;\n\tclone_url: string;\n\tarchived: boolean;\n}\n\ntype ExecFn = (cmd: string, args: string[], opts: { cwd: string }) => { status: number | null };\n\nexport interface RunCloneInput {\n\torg: string;\n\t/** Parent directory to clone into. Defaults to ~/Code/<org>. */\n\tdir?: string;\n\ttoken: string;\n\tdryRun?: boolean;\n\tfetch?: typeof globalThis.fetch;\n\texec?: ExecFn;\n\tprint?: (line: string) => void;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n}\n\nexport interface CloneReport {\n\tstatus: \"ok\" | \"fail\" | \"dry-run\";\n\tcloned: number;\n\tskipped: number;\n\tfailed: number;\n\tmessage?: string;\n}\n\nasync function listOrgRepos(org: string, token: string, fetchFn: typeof globalThis.fetch): Promise<GitHubRepo[]> {\n\tconst repos: GitHubRepo[] = [];\n\tlet url: string | null = `https://api.github.com/orgs/${org}/repos?per_page=100&type=all`;\n\n\twhile (url) {\n\t\tconst res = await fetchFn(url, {\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\tAccept: \"application/vnd.github+json\",\n\t\t\t\t\"X-GitHub-Api-Version\": \"2022-11-28\",\n\t\t\t},\n\t\t});\n\n\t\tif (!res.ok) {\n\t\t\tthrow new Error(`GitHub API ${res.status}: ${res.statusText} — check that the token has org:read scope`);\n\t\t}\n\n\t\trepos.push(...((await res.json()) as GitHubRepo[]));\n\n\t\tconst link = res.headers.get(\"link\");\n\t\tconst next = link?.match(/<([^>]+)>;\\s*rel=\"next\"/);\n\t\turl = next ? next[1] : null;\n\t}\n\n\treturn repos;\n}\n\nexport async function runClone(input: RunCloneInput): Promise<CloneReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst fetchFn = input.fetch ?? globalThis.fetch;\n\tconst dryRun = input.dryRun ?? false;\n\tconst targetDir = resolve(input.dir ?? join(homedir(), \"Code\", input.org));\n\tlogger.info({ org: input.org, targetDir, dryRun: dryRun || undefined }, \"clone: start\");\n\tconst exec: ExecFn =\n\t\tinput.exec ??\n\t\t((cmd, args, opts) => {\n\t\t\tconst r = spawnSync(cmd, args, { cwd: opts.cwd, stdio: \"inherit\" });\n\t\t\treturn { status: r.status };\n\t\t});\n\n\tprint(style.header(`Holocron clone — org=${input.org} → ${targetDir}${dryRun ? \" (dry-run)\" : \"\"}`));\n\n\tif (!existsSync(targetDir)) {\n\t\tif (dryRun) {\n\t\t\tprint(style.dim(` would create ${targetDir}`));\n\t\t} else {\n\t\t\tmkdirSync(targetDir, { recursive: true });\n\t\t}\n\t}\n\n\tlet repos: GitHubRepo[];\n\ttry {\n\t\trepos = await listOrgRepos(input.org, input.token, fetchFn);\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tlogger.warn({ org: input.org, reason: message }, \"clone: failed to list org repos\");\n\t\treturn { status: \"fail\", cloned: 0, skipped: 0, failed: 0, message };\n\t}\n\n\tlet cloned = 0;\n\tlet skipped = 0;\n\tlet failed = 0;\n\n\tfor (const repo of repos) {\n\t\t// Strip leading dot so hidden repos (e.g. .github) are visible in Finder.\n\t\tconst dirName = repo.name.startsWith(\".\") ? repo.name.slice(1) : repo.name;\n\t\tconst dest = join(targetDir, dirName);\n\n\t\tif (existsSync(dest)) {\n\t\t\tprint(style.dim(` skip ${repo.full_name}`));\n\t\t\tskipped++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (dryRun) {\n\t\t\tprint(style.dim(` would clone ${repo.full_name} → ${dest}`));\n\t\t\tcloned++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tprint(style.step(` clone ${repo.full_name}`));\n\t\tconst { clone_url } = repo;\n\t\tif (!clone_url.startsWith(\"https://github.com/\")) {\n\t\t\tprint(style.fail(` failed ${repo.full_name} — unexpected clone URL: ${clone_url}`));\n\t\t\tfailed++;\n\t\t\tcontinue;\n\t\t}\n\t\tlet encodedToken: string;\n\t\ttry {\n\t\t\tencodedToken = encodeTokenForGitHttpAuth(input.token);\n\t\t} catch (err) {\n\t\t\tprint(\n\t\t\t\tstyle.fail(\n\t\t\t\t\t` failed ${repo.full_name} — invalid token format: ${err instanceof Error ? err.message : String(err)}`\n\t\t\t\t)\n\t\t\t);\n\t\t\tfailed++;\n\t\t\tcontinue;\n\t\t}\n\t\tconst authedUrl = `https://x-access-token:${encodedToken}@github.com/${clone_url.slice(\"https://github.com/\".length)}`;\n\t\tconst result = exec(\"git\", [\"clone\", \"--\", authedUrl, dest], { cwd: targetDir });\n\n\t\tif (result.status !== 0) {\n\t\t\tprint(style.fail(` failed ${repo.full_name}`));\n\t\t\tfailed++;\n\t\t} else {\n\t\t\tprint(style.success(` cloned ${repo.name}`));\n\t\t\tcloned++;\n\t\t}\n\t}\n\n\tconst summary = `${cloned} cloned, ${skipped} skipped, ${failed} failed`;\n\tprint(\n\t\tdryRun\n\t\t\t? style.dim(`\\n dry-run: ${summary}`)\n\t\t\t: failed > 0\n\t\t\t\t? style.fail(`\\n ${summary}`)\n\t\t\t\t: style.success(`\\n ${summary}`)\n\t);\n\n\tconst status = dryRun ? \"dry-run\" : failed > 0 ? \"fail\" : \"ok\";\n\tlogger[failed > 0 ? \"warn\" : \"info\"]({ org: input.org, status, cloned, skipped, failed }, \"clone: done\");\n\treturn { status, cloned, skipped, failed };\n}\n","/**\n * Every command's **execution context** — the single source of truth for\n * how much of a repo a command needs around it to do its job.\n *\n * `npm i -g @theholocron/cli` gives you the binary and nothing else: no\n * `holocron.config`, no plugin packages. A large slice of the command\n * surface is fine with that; the rest needs a repo, and a few need the\n * provider plugins resolvable as well. Tagging each command lets the CLI\n *\n * 1. fail a `workspace` command **gracefully** when the plugins can't be\n * resolved (see {@link ../plugin/workspace.js}), instead of leaking a\n * raw `Cannot find package '@theholocron/holocron-plugin-*'`, and\n * 2. group `holocron --help` / the docs by what a bare global install\n * actually gets you.\n *\n * Spec: `docs/wiki/specifications/tech-cli-execution-contexts.spec.md`\n * (theholocron/holocron#576). Shared with the interactive-menu registry\n * (theholocron/holocron#438).\n */\n\nexport type ExecutionContext = \"global\" | \"repo-aware\" | \"workspace\";\n\n/**\n * Command → context. Keys are the command name as it lands in yargs'\n * `argv._` — the full path for sub-commands (`\"auth set\"`, `\"upgrade\n * node\"`), the bare verb otherwise.\n *\n * - **`global`** — needs nothing but the CLI binary. Works anywhere.\n * - **`repo-aware`** — reads `./holocron.config` + `./package.json`\n * relative to cwd, but never touches the plugin loader.\n * - **`workspace`** — needs the configured providers' plugin packages to\n * resolve (devDeps in a repo, or `pnpm exec`).\n */\nexport const COMMAND_CONTEXTS = {\n\tversion: \"global\",\n\tclone: \"global\",\n\tnew: \"global\",\n\t\"upgrade node\": \"global\",\n\t\"upgrade deps\": \"global\",\n\t\"plugin create\": \"global\",\n\t\"auth set\": \"global\",\n\t\"auth unset\": \"global\",\n\t\"auth list\": \"global\",\n\t// `auth check` loads a plugin to verify, but degrades to \"token present,\n\t// verification skipped\" when the plugin isn't resolvable — so it's usable\n\t// from a global install. See `runAuthCheck`.\n\t\"auth check\": \"global\",\n\t\"bump-versions\": \"global\",\n\tpublish: \"global\",\n\t\"skills install\": \"global\",\n\t\"skills remove\": \"global\",\n\t\"skills update\": \"global\",\n\t\"lint commit-msg\": \"global\",\n\n\trun: \"repo-aware\",\n\tci: \"repo-aware\",\n\t\"config show\": \"repo-aware\",\n\t// Writes README + package.json metadata from config; never loads a plugin.\n\t\"sync-readme\": \"repo-aware\",\n\n\tdoctor: \"workspace\",\n\tsetup: \"workspace\",\n\t\"secret set\": \"workspace\",\n\t\"secrets sync\": \"workspace\",\n\tdeploy: \"workspace\",\n\t\"cleanup-preview\": \"workspace\",\n\tsync: \"workspace\",\n\t// Pushes generated templates to theholocron/.github — needs the holocron\n\t// monorepo checkout (not plugins), so only ever run with `pnpm exec`.\n\t\"sync-github\": \"workspace\",\n} as const satisfies Record<string, ExecutionContext>;\n\n/**\n * The context for a command name from `argv._`. Falls back to the leading\n * verb (`\"auth foo\"` → `\"auth\"`) and finally `undefined` for a name the\n * map doesn't know — callers treat unknown as \"don't guard\".\n */\nexport function contextForCommand(name: string): ExecutionContext | undefined {\n\tconst map = COMMAND_CONTEXTS as Record<string, ExecutionContext>;\n\tif (map[name]) return map[name];\n\tconst verb = name.split(\" \")[0] ?? \"\";\n\treturn map[verb];\n}\n\n/** Command names in a given context, in registration order. */\nexport function commandsInContext(context: ExecutionContext): string[] {\n\treturn Object.entries(COMMAND_CONTEXTS)\n\t\t.filter(([, c]) => c === context)\n\t\t.map(([name]) => name);\n}\n","/**\n * `holocron deploy` — trigger a deployment via the configured\n * `deployment` capability.\n *\n * Two modes, one command: `runDeploy` (the default — a Git branch,\n * `triggerDeployment()`) and `runDeployFromFiles` (`--files <dir>` —\n * a local directory of source files, `deployFunction()`, no linked\n * repo required — for a consumer with no Git history to deploy from,\n * e.g. Sentinel, shipped as an npm package). Separate functions, not\n * one branching `runDeploy`, because their inputs genuinely differ\n * (`branch` vs `dir`) and their result shapes differ too\n * (`DeploymentRecord` carries `status`/`branch`; `DeployFunctionResult`\n * is deliberately minimal, same as `DeployScriptResult` for Workers).\n *\n * Errors clearly when `deployment` isn't loaded (no provider declared\n * in `holocron.config.json`), or when the configured provider doesn't\n * implement `deployFunction` (it's optional on `Deployment` — not\n * every provider has a files-based deploy API).\n *\n * Dry-run skips the actual deploy call but still verifies the\n * deployment capability (and, for `--files`, `deployFunction`) is\n * present, so operators can sanity-check the wiring without spinning\n * up a build.\n */\n\nimport { readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { join, relative, sep } from \"node:path\";\n\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport type { LoadedConfig } from \"../config/load-config.js\";\nimport { getLogger } from \"../logger.js\";\nimport type { DeployFunctionResult, Deployment, DeploymentRecord, DeploymentTrigger } from \"../plugin/capabilities.js\";\nimport { PluginLoader, type RuntimeContext } from \"../plugin/loader.js\";\nimport { assertPluginsResolvable } from \"../plugin/workspace.js\";\nimport { withSpinner } from \"../ui/progress.js\";\nimport { style } from \"../ui/style.js\";\n\nexport type DeployPrintLine = (line: string) => void;\n\n/**\n * Provider `url` fields (Vercel's REST API, at least) come back as bare\n * hostnames — `\"my-app.vercel.app\"`, no scheme — which terminals don't\n * linkify and browsers won't navigate to unmodified. Printed output\n * should be a URL a human can click/paste; structured log fields keep\n * the raw provider value as-is.\n */\nfunction withScheme(url: string): string {\n\treturn /^https?:\\/\\//.test(url) ? url : `https://${url}`;\n}\n\nexport interface RunDeployInput {\n\tloaded: LoadedConfig;\n\tcontext: RuntimeContext;\n\t/** Vendor project id (e.g., Vercel prj_*). Required. */\n\tprojectId: string;\n\t/** Git branch to deploy. */\n\tbranch: string;\n\t/** Named target — `undefined` means branch preview. */\n\ttarget?: DeploymentTrigger;\n\tloader?: PluginLoader;\n\tprint?: DeployPrintLine;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n}\n\nexport interface DeployReport {\n\t/** Null in dry-run mode (no actual deployment was triggered). */\n\tdeployment: DeploymentRecord | null;\n\tstatus: \"ok\" | \"fail\" | \"dry-run\";\n\tmessage?: string;\n}\n\nexport async function runDeploy(input: RunDeployInput): Promise<DeployReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst loader = input.loader ?? new PluginLoader(input.loaded.resolved, input.context);\n\tawait loader.load();\n\tassertPluginsResolvable(loader, \"deploy\");\n\n\tconst dryRun = input.context.dryRun ?? false;\n\tlogger.info(\n\t\t{\n\t\t\tbranch: input.branch,\n\t\t\ttarget: input.target ?? \"preview\",\n\t\t\tprojectId: input.projectId,\n\t\t\tdryRun: dryRun || undefined,\n\t\t},\n\t\t\"deploy: start\"\n\t);\n\n\tprint(\n\t\tstyle.header(\n\t\t\t`Holocron deploy — branch=${input.branch}${\n\t\t\t\tinput.target ? `, target=${input.target}` : \" (preview)\"\n\t\t\t}${dryRun ? \" (dry-run)\" : \"\"}`\n\t\t)\n\t);\n\n\tif (!loader.has(\"deployment\")) {\n\t\tthrow new Error(\n\t\t\t\"deployment capability is not configured — add a `deployment` provider to holocron.config.json\"\n\t\t);\n\t}\n\tconst deploy = loader.get(\"deployment\") as Deployment;\n\n\tif (dryRun) {\n\t\tconst message = `would: ${deploy.providerName}.triggerDeployment(projectId=${input.projectId}, branch=${input.branch}${\n\t\t\tinput.target ? `, target=${input.target}` : \"\"\n\t\t})`;\n\t\tprint(` ${style.dim(`… ${message}`)}`);\n\t\treturn { deployment: null, status: \"dry-run\", message };\n\t}\n\n\ttry {\n\t\tconst record = await withSpinner(`Deploying ${input.branch}${input.target ? ` → ${input.target}` : \"\"}…`, () =>\n\t\t\tdeploy.triggerDeployment({\n\t\t\t\tprojectId: input.projectId,\n\t\t\t\tbranch: input.branch,\n\t\t\t\t...(input.target ? { target: input.target } : {}),\n\t\t\t})\n\t\t);\n\t\tprint(` ${style.success(`${record.status} — ${withScheme(record.url)}`)}`);\n\t\tlogger.info({ status: record.status, url: record.url, id: record.id }, \"deploy: triggered\");\n\t\treturn { deployment: record, status: \"ok\" };\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tprint(` ${style.fail(message)}`);\n\t\tlogger.warn({ branch: input.branch, reason: message }, \"deploy: failed\");\n\t\treturn { deployment: null, status: \"fail\", message };\n\t}\n}\n\n// ── deploy --files (deployFunction) ─────────────────────────────────────\n\nexport interface RunDeployFromFilesInput {\n\tloaded: LoadedConfig;\n\tcontext: RuntimeContext;\n\t/** Vendor project id (e.g., Vercel prj_*). Required. */\n\tprojectId: string;\n\t/** Local directory to deploy — walked recursively. Files are keyed by\n\t * their path relative to this directory, POSIX-separated. */\n\tdir: string;\n\t/** Named target — `undefined` means preview. */\n\ttarget?: DeploymentTrigger;\n\tloader?: PluginLoader;\n\tprint?: DeployPrintLine;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n\t/** Injectable for testing. */\n\twalkFiles?: (dir: string) => string[];\n\treadFile?: (path: string) => string;\n}\n\nexport interface DeployFilesReport {\n\t/** Null in dry-run mode or on failure — no actual deployment was created. */\n\tdeployment: DeployFunctionResult | null;\n\tstatus: \"ok\" | \"fail\" | \"dry-run\";\n\tmessage?: string;\n}\n\n// Deliberately no \"dist\" here, unlike holocron new's own file-walker this\n// was modeled on: --files exists specifically to deploy build output, so\n// a directory literally named \"dist\" is exactly what a caller usually\n// means to include, not exclude.\nconst SKIP_DIRS = new Set([\".git\", \"node_modules\", \".turbo\"]);\n\n/** Recursively lists absolute file paths under `dir`, skipping VCS/tooling noise. */\nfunction defaultWalkFiles(dir: string): string[] {\n\tconst results: string[] = [];\n\tfor (const entry of readdirSync(dir)) {\n\t\tif (SKIP_DIRS.has(entry)) continue;\n\t\tconst full = join(dir, entry);\n\t\tconst stat = statSync(full);\n\t\tif (stat.isDirectory()) results.push(...defaultWalkFiles(full));\n\t\telse if (stat.isFile()) results.push(full);\n\t}\n\treturn results;\n}\n\n/** `holocron deploy --files <dir>` — the non-git counterpart to `runDeploy`. */\nexport async function runDeployFromFiles(input: RunDeployFromFilesInput): Promise<DeployFilesReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst loader = input.loader ?? new PluginLoader(input.loaded.resolved, input.context);\n\tawait loader.load();\n\tassertPluginsResolvable(loader, \"deploy\");\n\n\tconst dryRun = input.context.dryRun ?? false;\n\tconst walkFiles = input.walkFiles ?? defaultWalkFiles;\n\tconst readFile = input.readFile ?? ((p: string) => readFileSync(p, \"utf8\"));\n\n\tconst files: Record<string, string> = {};\n\tfor (const abs of walkFiles(input.dir)) {\n\t\tconst rel = relative(input.dir, abs).split(sep).join(\"/\");\n\t\tfiles[rel] = readFile(abs);\n\t}\n\tconst fileCount = Object.keys(files).length;\n\n\tlogger.info(\n\t\t{\n\t\t\tdir: input.dir,\n\t\t\tfileCount,\n\t\t\ttarget: input.target ?? \"preview\",\n\t\t\tprojectId: input.projectId,\n\t\t\tdryRun: dryRun || undefined,\n\t\t},\n\t\t\"deploy: start (files)\"\n\t);\n\n\tprint(\n\t\tstyle.header(\n\t\t\t`Holocron deploy — files=${input.dir} (${fileCount} file${fileCount === 1 ? \"\" : \"s\"})${\n\t\t\t\tinput.target ? `, target=${input.target}` : \" (preview)\"\n\t\t\t}${dryRun ? \" (dry-run)\" : \"\"}`\n\t\t)\n\t);\n\n\tif (!loader.has(\"deployment\")) {\n\t\tthrow new Error(\n\t\t\t\"deployment capability is not configured — add a `deployment` provider to holocron.config.json\"\n\t\t);\n\t}\n\tconst deploy = loader.get(\"deployment\") as Deployment;\n\tif (!deploy.deployFunction) {\n\t\tthrow new Error(\n\t\t\t`deployment provider \"${deploy.providerName}\" does not support deploying from files — deployFunction() is not implemented`\n\t\t);\n\t}\n\n\tif (dryRun) {\n\t\tconst message = `would: ${deploy.providerName}.deployFunction(projectId=${input.projectId}, files=${fileCount}${\n\t\t\tinput.target ? `, target=${input.target}` : \"\"\n\t\t})`;\n\t\tprint(` ${style.dim(`… ${message}`)}`);\n\t\treturn { deployment: null, status: \"dry-run\", message };\n\t}\n\n\ttry {\n\t\tconst result = await withSpinner(\n\t\t\t`Deploying ${fileCount} file${fileCount === 1 ? \"\" : \"s\"} from ${input.dir}…`,\n\t\t\t() => deploy.deployFunction!(input.projectId, { files, ...(input.target ? { target: input.target } : {}) })\n\t\t);\n\t\tprint(` ${style.success(withScheme(result.url))}`);\n\t\tlogger.info({ url: result.url, id: result.deploymentId }, \"deploy: triggered (files)\");\n\t\treturn { deployment: result, status: \"ok\" };\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tprint(` ${style.fail(message)}`);\n\t\tlogger.warn({ dir: input.dir, reason: message }, \"deploy: failed (files)\");\n\t\treturn { deployment: null, status: \"fail\", message };\n\t}\n}\n","/**\n * `holocron doctor` — load the config, instantiate every capability,\n * print a per-capability readiness report.\n *\n * Each capability gets a smoke check appropriate to its surface:\n * source → `whoami()`\n * issues → `doctor()` (rich report)\n * secrets → `listSecrets({ kind: 'repo' })`\n * ci → `listRuns({ limit: 1 })`\n * errors → `describe()`\n * logs → `whoami()` (dataset reachability) or `describe()`\n * others → just \"loaded\" (no smoke endpoint defined yet)\n *\n * Output is plain text via a passed-in `print` function so tests can\n * capture lines without ANSI / spinner noise.\n */\n\nimport type { LoadedConfig } from \"../config/load-config.js\";\nimport { getLogger } from \"../logger.js\";\nimport type { Auth, Ci, Errors, Issues, Logs, Secrets, Source, Vault } from \"../plugin/capabilities.js\";\nimport { CARDINALITY } from \"../plugin/capabilities.js\";\nimport { PluginLoader, type RuntimeContext } from \"../plugin/loader.js\";\nimport { assertPluginsResolvable } from \"../plugin/workspace.js\";\nimport { withSpinner } from \"../ui/progress.js\";\nimport { style } from \"../ui/style.js\";\n\nexport type DoctorPrintLine = (line: string) => void;\n\nexport type DoctorStatus = \"ok\" | \"fail\" | \"skip\";\n\nexport interface DoctorRow {\n\tcapability: string;\n\tprovider: string;\n\tstatus: DoctorStatus;\n\tmessage: string;\n}\n\nexport interface DoctorReport {\n\trows: DoctorRow[];\n\tsummary: { ok: number; fail: number; skip: number };\n}\n\nexport interface RunDoctorInput {\n\tloaded: LoadedConfig;\n\tcontext: RuntimeContext;\n\t/** Lets tests inject mock plugins; defaults to native dynamic import. */\n\tloader?: PluginLoader;\n\tprint?: DoctorPrintLine;\n}\n\nexport async function runDoctor(input: RunDoctorInput): Promise<DoctorReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst loader = input.loader ?? new PluginLoader(input.loaded.resolved, input.context);\n\tawait withSpinner(\"Loading plugins…\", () => loader.load());\n\t// A global install has no plugin packages to resolve — say so plainly\n\t// instead of printing a report that's all \"Cannot find package\" rows.\n\tassertPluginsResolvable(loader, \"doctor\");\n\n\tconst rows: DoctorRow[] = [];\n\tconst config = input.loaded.resolved;\n\n\tprint(style.header(`Holocron doctor — ${config.name}`));\n\tprint(style.dim(` config: ${input.loaded.filepath}`));\n\tprint(\"\");\n\n\t// Providers that never loaded (missing token, package not installed) —\n\t// the most actionable rows in the report.\n\tfor (const failure of loader.loadFailures()) {\n\t\trows.push({\n\t\t\tcapability: failure.key,\n\t\t\tprovider: failure.provider,\n\t\t\tstatus: \"fail\",\n\t\t\tmessage: failure.error.message,\n\t\t});\n\t}\n\n\tfor (const key of loader.loadedKeys()) {\n\t\tconst cardinality = CARDINALITY[key];\n\t\tconst entry = config.providers[key];\n\t\tconst providers =\n\t\t\tentry?.cardinality === \"many\"\n\t\t\t\t? entry.tuples.map((t) => t.provider)\n\t\t\t\t: entry?.cardinality === \"single\"\n\t\t\t\t\t? [entry.tuple.provider]\n\t\t\t\t\t: [];\n\n\t\tif (cardinality === \"many\") {\n\t\t\tconst impls = loader.get(key) as unknown as unknown[];\n\t\t\timpls.forEach((_impl, idx) => {\n\t\t\t\trows.push({\n\t\t\t\t\tcapability: key,\n\t\t\t\t\tprovider: providers[idx] ?? \"?\",\n\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\tmessage: \"loaded (no smoke check defined for this capability)\",\n\t\t\t\t});\n\t\t\t});\n\t\t} else {\n\t\t\tconst impl = loader.get(key) as unknown;\n\t\t\tconst row = await smokeCheck(key, providers[0] ?? \"?\", impl);\n\t\t\trows.push(row);\n\t\t}\n\t}\n\n\tconst log = getLogger();\n\t// Render rows\n\tfor (const row of rows) {\n\t\tlog[row.status === \"fail\" ? \"warn\" : \"info\"](\n\t\t\t{ capability: row.capability, provider: row.provider, status: row.status, detail: row.message },\n\t\t\t`doctor: ${row.capability}`\n\t\t);\n\t\tconst label = `${pad(row.capability, 14)} via ${pad(row.provider, 14)} ${row.message}`;\n\t\tif (row.status === \"ok\") print(` ${style.success(label)}`);\n\t\telse if (row.status === \"fail\") print(` ${style.fail(label)}`);\n\t\telse print(` ${style.dim(`· ${label}`)}`);\n\t}\n\n\tconst summary = rows.reduce(\n\t\t(acc, r) => {\n\t\t\tacc[r.status] += 1;\n\t\t\treturn acc;\n\t\t},\n\t\t{ ok: 0, fail: 0, skip: 0 }\n\t);\n\n\tconst summaryLine = `${summary.ok} ok, ${summary.fail} fail, ${summary.skip} skipped`;\n\tprint(\"\");\n\tprint(summary.fail > 0 ? style.fail(summaryLine) : style.success(summaryLine));\n\n\treturn { rows, summary };\n}\n\n// ── smoke checks ────────────────────────────────────────────────────\n\nasync function smokeCheck(key: string, provider: string, impl: unknown): Promise<DoctorRow> {\n\ttry {\n\t\tswitch (key) {\n\t\t\tcase \"source\": {\n\t\t\t\tconst result = await (impl as Source).whoami();\n\t\t\t\treturn mk(key, provider, \"ok\", `whoami: ${result.login}`);\n\t\t\t}\n\t\t\tcase \"issues\": {\n\t\t\t\tconst report = await (impl as Issues).doctor();\n\t\t\t\treturn mk(\n\t\t\t\t\tkey,\n\t\t\t\t\tprovider,\n\t\t\t\t\t\"ok\",\n\t\t\t\t\t`${report.authedAs} / ${report.projectLabel} (${countResolvedLifecycle(report)})`\n\t\t\t\t);\n\t\t\t}\n\t\t\tcase \"secrets\": {\n\t\t\t\tconst names = await (impl as Secrets).listSecrets({ kind: \"repo\" });\n\t\t\t\treturn mk(key, provider, \"ok\", `repo secrets: ${names.length} configured`);\n\t\t\t}\n\t\t\tcase \"ci\": {\n\t\t\t\tconst runs = await (impl as Ci).listRuns({ limit: 1 });\n\t\t\t\treturn mk(\n\t\t\t\t\tkey,\n\t\t\t\t\tprovider,\n\t\t\t\t\t\"ok\",\n\t\t\t\t\truns.length === 0 ? \"no recent runs\" : `most recent: ${runs[0]!.workflowName} (${runs[0]!.status})`\n\t\t\t\t);\n\t\t\t}\n\t\t\tcase \"vault\": {\n\t\t\t\tconst keys = await (impl as Vault).list();\n\t\t\t\treturn mk(key, provider, \"ok\", `${keys.length} keys available`);\n\t\t\t}\n\t\t\tcase \"auth\": {\n\t\t\t\tconst desc = await (impl as Auth).describe();\n\t\t\t\treturn mk(key, provider, \"ok\", `provider: ${desc.provider}; env keys: ${desc.envKeys.join(\", \")}`);\n\t\t\t}\n\t\t\tcase \"errors\": {\n\t\t\t\tconst desc = await (impl as Errors).describe();\n\t\t\t\treturn mk(key, provider, \"ok\", `provider: ${desc.provider}; env keys: ${desc.envKeys.join(\", \")}`);\n\t\t\t}\n\t\t\tcase \"logs\": {\n\t\t\t\tconst logs = impl as Logs;\n\t\t\t\tconst desc = await logs.describe();\n\t\t\t\tif (logs.whoami) {\n\t\t\t\t\tconst who = await logs.whoami();\n\t\t\t\t\treturn mk(key, provider, who.ok ? \"ok\" : \"fail\", `dataset: ${who.dataset}`);\n\t\t\t\t}\n\t\t\t\treturn mk(key, provider, \"ok\", `provider: ${desc.provider}; env keys: ${desc.envKeys.join(\", \")}`);\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn mk(key, provider, \"skip\", \"loaded (no smoke check defined for this capability)\");\n\t\t}\n\t} catch (err) {\n\t\treturn mk(key, provider, \"fail\", err instanceof Error ? err.message : String(err));\n\t}\n}\n\nfunction countResolvedLifecycle(report: Awaited<ReturnType<Issues[\"doctor\"]>>): string {\n\tconst resolved = report.lifecycle.filter((l) => l.resolved).length;\n\treturn `${resolved}/${report.lifecycle.length} lifecycle slots ready`;\n}\n\nfunction mk(capability: string, provider: string, status: DoctorStatus, message: string): DoctorRow {\n\treturn { capability, provider, status, message };\n}\n\nfunction pad(s: string, width: number): string {\n\treturn s.length >= width ? s : s + \" \".repeat(width - s.length);\n}\n","/**\n * `holocron new <type> <name>` — create a GitHub repo from a template and\n * bootstrap it by replacing all template-slug casing variants with the new\n * project name, then generate a `holocron.config.ts` from the answers given\n * during the interactive wizard.\n *\n * Flow:\n * 1. Preflight — verify `gh` CLI is available.\n * 2. Resolve type, name, description, homepage, vault/deployment/agent options.\n * 3. `gh repo create <org>/<name> --template <org>/<type>-template --private --clone`\n * → clones to `<cwd>/<name>/`\n * 4. Detect template slug from cloned package.json.\n * 5. Replace all casing variants of the slug across every text file.\n * 6. Replace `<description>` and `<homepage>` placeholders.\n * 7. Generate and write `holocron.config.ts` based on wizard answers.\n * 8. Commit the patched files (-s for DCO).\n * 9. Unless --no-verify: `pnpm install` in the new repo.\n * 10. Print next steps.\n */\n\nimport { execFileSync, spawnSync } from \"node:child_process\";\nimport { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\n\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport { env } from \"../env.js\";\nimport { getLogger } from \"../logger.js\";\n\n// ── Public API ────────────────────────────────────────────────────────\n\nexport type VaultProvider = \"doppler\" | \"1password\" | \"infisical\" | \"none\";\nexport type DeploymentProvider = \"vercel\" | \"none\";\nexport type AgentChoice = \"claude\" | \"none\";\nexport type RuntimeEnvironment = \"node\" | \"browser\" | \"universal\" | \"none\";\n\nexport interface RunNewInput {\n\ttype: string;\n\tname: string;\n\tdescription?: string;\n\thomepage?: string;\n\tvaultProvider?: VaultProvider;\n\tvaultProject?: string;\n\tvaultConfig?: string;\n\tdeploymentProvider?: DeploymentProvider;\n\tagent?: AgentChoice;\n\truntimeEnvironment?: RuntimeEnvironment;\n\tprotection?: string;\n\topenSource?: boolean;\n\tusesExternalPackages?: boolean;\n\ttopics?: string[];\n\tskills?: string[];\n\t/** Mark the new repo as a GitHub template repository. */\n\tisTemplate?: boolean;\n\t/** GitHub org that owns both the template and the new repo. Default: \"theholocron\". */\n\torg?: string;\n\t/** GitHub admin token forwarded to `holocron setup` during verify. */\n\ttoken?: string;\n\tdryRun?: boolean;\n\tnoVerify?: boolean;\n\t/** Parent directory where the repo will be cloned. Default: process.cwd(). */\n\tcwd?: string;\n\tprint?: (line: string) => void;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n\t/** Injectable subprocess runner for testing. */\n\texec?: (cmd: string, args: string[], opts: { cwd: string; stdio: \"inherit\"; env?: Record<string, string> }) => void;\n\t/** Injectable file writer for testing. */\n\twriteFile?: (filepath: string, content: string) => void;\n\t/** Injectable file reader for testing (returns utf-8 string). */\n\treadFile?: (filepath: string) => string;\n\t/** Injectable directory walker for testing (returns absolute paths). */\n\twalkFiles?: (dir: string) => string[];\n}\n\nexport interface NewReport {\n\tstatus: \"ok\" | \"fail\" | \"dry-run\";\n\trepoDir?: string;\n\tfilesPatched?: string[];\n\tmessage?: string;\n}\n\nexport class NewError extends Error {\n\toverride name = \"NewError\";\n}\n\n// ── Case derivation ───────────────────────────────────────────────────\n\nfunction cap(word: string): string {\n\treturn word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();\n}\n\n/**\n * Derive all common casing variants of a kebab-case slug (e.g.\n * \"cli-template\") and map each to the corresponding form of a\n * kebab-case name (e.g. \"my-tool\").\n *\n * Returns search→replacement pairs, deduplicating single-word slugs\n * that would otherwise produce identical entries.\n */\nexport function deriveVariants(slug: string, name: string): Array<[string, string]> {\n\tconst sw = slug.split(\"-\");\n\tconst nw = name.split(\"-\");\n\n\tconst pairs: Array<[string, string]> = [\n\t\t[slug, name],\n\t\t[sw.join(\"_\"), nw.join(\"_\")],\n\t\t[sw.join(\"_\").toUpperCase(), nw.join(\"_\").toUpperCase()],\n\t\t[sw.map(cap).join(\"\"), nw.map(cap).join(\"\")],\n\t\t[sw[0]!.toLowerCase() + sw.slice(1).map(cap).join(\"\"), nw[0]!.toLowerCase() + nw.slice(1).map(cap).join(\"\")],\n\t\t[sw.map(cap).join(\" \"), nw.map(cap).join(\" \")],\n\t];\n\n\tconst seen = new Set<string>();\n\treturn pairs.filter(([s]) => {\n\t\tif (seen.has(s)) return false;\n\t\tseen.add(s);\n\t\treturn true;\n\t});\n}\n\n// ── Input helpers ─────────────────────────────────────────────────────\n\n/** Validate a repo name: must be lowercase kebab-case. Returns `true` on success or an error string. */\nexport function validateRepoName(v: string): true | string {\n\treturn /^[a-z][a-z0-9-]*$/.test(v.trim()) ? true : \"Must be lowercase kebab-case (e.g. my-tool)\";\n}\n\n/** Parse a comma-separated topics string into a trimmed, non-empty array. */\nexport function parseTopics(raw: string | undefined): string[] {\n\treturn raw\n\t\t? String(raw)\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((t) => t.trim())\n\t\t\t\t.filter(Boolean)\n\t\t: [];\n}\n\n// ── Config generation ─────────────────────────────────────────────────\n\nexport interface HolocronConfigOptions {\n\tname: string;\n\ttype: string;\n\torg?: string;\n\tdescription?: string;\n\thomepage?: string;\n\tvaultProvider?: VaultProvider;\n\tvaultProject?: string;\n\tvaultConfig?: string;\n\tdeploymentProvider?: DeploymentProvider;\n\tagent?: AgentChoice;\n\truntimeEnvironment?: RuntimeEnvironment;\n\tprotection?: string;\n\topenSource?: boolean;\n\tusesExternalPackages?: boolean;\n\ttopics?: string[];\n\tskills?: string[];\n}\n\n/**\n * Generate the content of `holocron.config.ts` for a newly-scaffolded repo.\n * Uses the `node()` preset from `@theholocron/holocron-config` as the baseline\n * and layers in the provider/agent choices made during the wizard.\n */\nexport function generateHolocronConfig(opts: HolocronConfigOptions): string {\n\tconst lines: string[] = [\n\t\t`import { defineConfig } from \"@theholocron/cli\";`,\n\t\t`import { compose, node, typecheck } from \"@theholocron/holocron-config\";`,\n\t\t``,\n\t\t// `compose(node(), typecheck())` is the org baseline preset — the full\n\t\t// task manifest (lint/test/typecheck required, security/review/… ) rides\n\t\t// in via `...preset`, so `holocron setup` can derive CodeQL mode and the\n\t\t// required-check contexts. See theholocron/holocron#642.\n\t\t`const preset = compose(node(), typecheck());`,\n\t\t`export default defineConfig({`,\n\t\t`\\t...preset,`,\n\t];\n\n\tif (opts.description) lines.push(`\\tdescription: ${JSON.stringify(opts.description)},`);\n\tif (opts.homepage) lines.push(`\\thomepage: ${JSON.stringify(opts.homepage)},`);\n\n\tconst topics = opts.topics?.length ? opts.topics : [];\n\tconst hasRuntimeOverride = opts.runtimeEnvironment != null && opts.runtimeEnvironment !== \"node\";\n\tconst hasFullRepo = opts.org != null;\n\n\tif (hasFullRepo) {\n\t\t// Full explicit repo block when org is known (always the case from the CLI).\n\t\tconst repoName = `${opts.org}/${opts.name}`;\n\t\tlines.push(`\\trepo: {`);\n\t\tlines.push(`\\t\\t...preset.repo,`);\n\t\tlines.push(`\\t\\tname: ${JSON.stringify(repoName)},`);\n\t\tlines.push(`\\t\\tteams: [{ slug: \"gatekeepers\", permission: \"maintain\" }],`);\n\t\tlines.push(`\\t\\ttopics: ${JSON.stringify(topics)},`);\n\t\tif (opts.protection && opts.protection !== \"strict\") {\n\t\t\tlines.push(`\\t\\tprotection: ${JSON.stringify(opts.protection)},`);\n\t\t}\n\t\tconst propParts: string[] = [];\n\t\tif (hasRuntimeOverride) propParts.push(`runtime_environment: ${JSON.stringify(opts.runtimeEnvironment)}`);\n\t\tif (opts.openSource === false) propParts.push(`open_source: false`);\n\t\tif (opts.usesExternalPackages === false) propParts.push(`uses_external_packages: false`);\n\t\tif (propParts.length > 0) {\n\t\t\tlines.push(`\\t\\tproperties: { ...preset.repo?.properties, ${propParts.join(\", \")} },`);\n\t\t}\n\t\tlines.push(`\\t},`);\n\t} else if (topics.length > 0 || hasRuntimeOverride) {\n\t\tlines.push(`\\trepo: {`);\n\t\tlines.push(`\\t\\t...preset.repo,`);\n\t\tif (topics.length > 0) lines.push(`\\t\\ttopics: ${JSON.stringify(topics)},`);\n\t\tif (hasRuntimeOverride) {\n\t\t\tlines.push(\n\t\t\t\t`\\t\\tproperties: { ...preset.repo?.properties, runtime_environment: ${JSON.stringify(opts.runtimeEnvironment)} },`\n\t\t\t);\n\t\t}\n\t\tlines.push(`\\t},`);\n\t}\n\t// else: `...preset` already carries `repo` — no explicit block needed.\n\n\tconst hasVault = opts.vaultProvider && opts.vaultProvider !== \"none\";\n\tconst hasDeployment = opts.deploymentProvider && opts.deploymentProvider !== \"none\";\n\n\tif (hasVault || hasDeployment) {\n\t\tlines.push(`\\tproviders: {`);\n\t\tlines.push(`\\t\\t...preset.providers,`);\n\t\tif (opts.vaultProvider === \"doppler\") {\n\t\t\tconst proj = JSON.stringify(opts.vaultProject ?? opts.name);\n\t\t\tconst cfg = JSON.stringify(opts.vaultConfig ?? \"dev\");\n\t\t\tlines.push(`\\t\\tvault: [\"doppler\", { project: ${proj}, config: ${cfg} }],`);\n\t\t} else if (opts.vaultProvider === \"1password\") {\n\t\t\tconst vault = JSON.stringify(opts.vaultProject ?? opts.name);\n\t\t\tlines.push(`\\t\\tvault: [\"1password\", { vault: ${vault} }],`);\n\t\t} else if (opts.vaultProvider === \"infisical\") {\n\t\t\tconst proj = JSON.stringify(opts.vaultProject ?? opts.name);\n\t\t\tlines.push(`\\t\\tvault: [\"infisical\", { project: ${proj} }],`);\n\t\t}\n\t\tif (opts.deploymentProvider === \"vercel\") {\n\t\t\tlines.push(`\\t\\tdeployment: \"vercel\",`);\n\t\t}\n\t\tlines.push(`\\t},`);\n\t}\n\t// else: `...preset` already carries `providers`.\n\n\tif (opts.agent && opts.agent !== \"none\") {\n\t\tlines.push(`\\tagent: ${JSON.stringify(opts.agent)},`);\n\t}\n\n\tif (opts.skills?.length) {\n\t\tlines.push(`\\tskills: ${JSON.stringify(opts.skills)},`);\n\t}\n\n\tlines.push(`});`);\n\tlines.push(``);\n\n\treturn lines.join(\"\\n\");\n}\n\n// ── File discovery ────────────────────────────────────────────────────\n\nconst SKIP_DIRS = new Set([\".git\", \"node_modules\", \"dist\", \".turbo\"]);\n\nfunction defaultWalkFiles(dir: string): string[] {\n\tconst results: string[] = [];\n\tfor (const entry of readdirSync(dir)) {\n\t\tif (SKIP_DIRS.has(entry)) continue;\n\t\tconst full = path.join(dir, entry);\n\t\tconst stat = statSync(full);\n\t\tif (stat.isDirectory()) results.push(...defaultWalkFiles(full));\n\t\telse if (stat.isFile()) results.push(full);\n\t}\n\treturn results;\n}\n\nfunction isBinary(content: string): boolean {\n\tfor (let i = 0; i < Math.min(content.length, 8000); i++) {\n\t\tif (content.charCodeAt(i) === 0) return true;\n\t}\n\treturn false;\n}\n\n// ── Patching ──────────────────────────────────────────────────────────\n\nfunction patchFiles(\n\tdir: string,\n\tvariants: Array<[string, string]>,\n\tdescription: string | undefined,\n\thomepage: string | undefined,\n\truntimeEnvironment: string | undefined,\n\tprint: (line: string) => void,\n\treadFn: (p: string) => string,\n\twriteFn: (p: string, c: string) => void,\n\twalkFn: (d: string) => string[]\n): string[] {\n\tconst patched: string[] = [];\n\tfor (const filepath of walkFn(dir)) {\n\t\tlet content: string;\n\t\ttry {\n\t\t\tcontent = readFn(filepath);\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\t\tif (isBinary(content)) continue;\n\n\t\tconst original = content;\n\t\tfor (const [search, replacement] of variants) {\n\t\t\tcontent = content.split(search).join(replacement);\n\t\t}\n\t\tif (description !== undefined) {\n\t\t\tcontent = content.split(\"<description>\").join(description);\n\t\t\t// Also replace the content of <!-- holocron:description --> blocks so\n\t\t\t// the README description marker is updated even when the template has\n\t\t\t// real prose rather than a bare <description> placeholder.\n\t\t\tcontent = content.replace(\n\t\t\t\t/(<!-- holocron:description -->)[\\s\\S]*?(<!-- \\/holocron:description -->)/g,\n\t\t\t\t`$1\\n${description}\\n$2`\n\t\t\t);\n\t\t}\n\t\tif (homepage !== undefined) {\n\t\t\tcontent = content.split(\"<homepage>\").join(homepage);\n\t\t}\n\t\tif (runtimeEnvironment !== undefined) {\n\t\t\tcontent = content.split(\"<runtime_environment>\").join(runtimeEnvironment);\n\t\t}\n\t\t// Strip template-only blocks — sections relevant only to the template\n\t\t// repo itself (e.g. \"Getting Started\" scaffolding instructions) that\n\t\t// should not appear in projects generated from the template.\n\t\tcontent = content.replace(\n\t\t\t/\\n?<!-- holocron:template-only -->[\\s\\S]*?<!-- \\/holocron:template-only -->\\n?/g,\n\t\t\t\"\"\n\t\t);\n\n\t\tif (content !== original) {\n\t\t\twriteFn(filepath, content);\n\t\t\tprint(` ✓ ${path.relative(dir, filepath)}`);\n\t\t\tpatched.push(filepath);\n\t\t}\n\t}\n\treturn patched;\n}\n\n// ── Preflight ─────────────────────────────────────────────────────────\n\nfunction preflight(): void {\n\tconst result = spawnSync(\"gh\", [\"--version\"], { encoding: \"utf8\" });\n\tif (result.error != null || result.status !== 0) {\n\t\tthrow new NewError(\"`gh` CLI is not installed or not on PATH. Install it from https://cli.github.com\");\n\t}\n}\n\n// ── Defaults ──────────────────────────────────────────────────────────\n\nfunction defaultExec(\n\tcmd: string,\n\targs: string[],\n\topts: { cwd: string; stdio: \"inherit\"; env?: Record<string, string> }\n): void {\n\texecFileSync(cmd, args, {\n\t\tcwd: opts.cwd,\n\t\tstdio: opts.stdio,\n\t\t...(opts.env && Object.keys(opts.env).length > 0 ? { env: { ...process.env, ...opts.env } } : {}),\n\t});\n}\n\nfunction keychainLookup(key: string): string | undefined {\n\tconst result = spawnSync(\"security\", [\"find-generic-password\", \"-s\", \"com.theholocron.cli\", \"-a\", key, \"-w\"], {\n\t\tencoding: \"utf8\",\n\t});\n\treturn result.status === 0 ? result.stdout?.trim() || undefined : undefined;\n}\n\nfunction defaultReadFile(filepath: string): string {\n\treturn readFileSync(filepath, \"utf-8\");\n}\n\nfunction defaultWriteFile(filepath: string, content: string): void {\n\tmkdirSync(path.dirname(filepath), { recursive: true });\n\twriteFileSync(filepath, content, \"utf-8\");\n}\n\n// ── Orchestrator ──────────────────────────────────────────────────────\n\nexport async function runNew(input: RunNewInput): Promise<NewReport> {\n\tconst cwd = input.cwd ?? process.cwd();\n\tconst org = input.org ?? \"theholocron\";\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst execFn = input.exec ?? defaultExec;\n\tconst readFn = input.readFile ?? defaultReadFile;\n\tconst writeFn = input.writeFile ?? defaultWriteFile;\n\tconst walkFn = input.walkFiles ?? defaultWalkFiles;\n\n\tpreflight();\n\n\tconst templateRepo = `${org}/${input.type}-template`;\n\tconst newRepo = `${org}/${input.name}`;\n\tconst repoDir = path.join(cwd, input.name);\n\tlogger.info({ repo: newRepo, template: templateRepo, dryRun: input.dryRun || undefined }, \"new: start\");\n\n\tif (input.dryRun) {\n\t\tprint(` Would create ${newRepo} from template ${templateRepo}`);\n\t\tprint(` Would clone to ${repoDir}`);\n\t\tprint(` Would patch all casing variants of \"${input.type}-template\" → \"${input.name}\"`);\n\t\tif (input.description) print(` Would replace <description> → \"${input.description}\"`);\n\t\tif (input.homepage) print(` Would replace <homepage> → \"${input.homepage}\"`);\n\t\tif (input.runtimeEnvironment) print(` Would replace <runtime_environment> → \"${input.runtimeEnvironment}\"`);\n\t\tprint(` Would generate holocron.config.ts`);\n\t\tlogger.info({ repo: newRepo, status: \"dry-run\" }, \"new: done\");\n\t\treturn { status: \"dry-run\" };\n\t}\n\n\tif (existsSync(repoDir)) {\n\t\tthrow new NewError(`\\`${repoDir}\\` already exists — delete it or pick a different name.`);\n\t}\n\n\tprint(` Creating ${newRepo} from template ${templateRepo}…`);\n\tconst visibility = input.openSource ? \"--public\" : \"--private\";\n\ttry {\n\t\texecFn(\"gh\", [\"repo\", \"create\", newRepo, `--template=${templateRepo}`, visibility, \"--clone\"], {\n\t\t\tcwd,\n\t\t\tstdio: \"inherit\",\n\t\t});\n\t} catch (err) {\n\t\tthrow new NewError(`gh repo create failed: ${err instanceof Error ? err.message : String(err)}`);\n\t}\n\n\tif (input.isTemplate) {\n\t\ttry {\n\t\t\texecFn(\"gh\", [\"repo\", \"edit\", newRepo, \"--template=true\"], { cwd, stdio: \"inherit\" });\n\t\t} catch {\n\t\t\t// non-fatal — template flag can be set manually in repo settings\n\t\t}\n\t}\n\n\t// gh repo create --template does not reliably honor --public/--private on all\n\t// plan/org combinations, so set visibility explicitly after creation.\n\ttry {\n\t\texecFn(\"gh\", [\"repo\", \"edit\", newRepo, `--visibility=${input.openSource ? \"public\" : \"private\"}`], {\n\t\t\tcwd,\n\t\t\tstdio: \"inherit\",\n\t\t});\n\t} catch {\n\t\t// non-fatal — visibility can be changed manually in repo settings\n\t}\n\n\t// Detect template slug from cloned package.json\n\tlet templateSlug = `${input.type}-template`;\n\tconst pkgJsonPath = path.join(repoDir, \"package.json\");\n\tif (existsSync(pkgJsonPath)) {\n\t\ttry {\n\t\t\tconst pkg = JSON.parse(readFn(pkgJsonPath)) as { name?: string };\n\t\t\tif (typeof pkg.name === \"string\") {\n\t\t\t\ttemplateSlug = pkg.name.split(\"/\").at(-1) || templateSlug;\n\t\t\t}\n\t\t} catch {\n\t\t\t// fall back to derived slug\n\t\t}\n\t}\n\n\tprint(` Detected template slug: ${templateSlug}`);\n\tprint(` Patching files…`);\n\n\tconst variants = deriveVariants(templateSlug, input.name);\n\t// Prepend the full org/slug pair so GitHub URLs and scoped package names\n\t// use the correct org. Must come before the slug-only pairs so it takes\n\t// priority — e.g. \"@theholocron/node-template\" becomes \"@<org>/<name>\"\n\t// rather than \"@theholocron/<name>\".\n\tvariants.unshift([`theholocron/${templateSlug}`, `${org}/${input.name}`]);\n\tconst filesPatched = patchFiles(\n\t\trepoDir,\n\t\tvariants,\n\t\tinput.description,\n\t\tinput.homepage,\n\t\tinput.runtimeEnvironment,\n\t\tprint,\n\t\treadFn,\n\t\twriteFn,\n\t\twalkFn\n\t);\n\n\tprint(` ${filesPatched.length} file${filesPatched.length === 1 ? \"\" : \"s\"} patched`);\n\n\t// Always overwrite description and homepage in package.json directly,\n\t// regardless of whether the template used placeholders or real values.\n\tif (input.description !== undefined || input.homepage !== undefined) {\n\t\ttry {\n\t\t\tconst pkg = JSON.parse(readFn(pkgJsonPath)) as Record<string, unknown>;\n\t\t\tif (input.description !== undefined) pkg[\"description\"] = input.description;\n\t\t\tif (input.homepage !== undefined) pkg[\"homepage\"] = input.homepage;\n\t\t\twriteFn(pkgJsonPath, JSON.stringify(pkg, null, 2) + \"\\n\");\n\t\t\tprint(` ✓ package.json (description/homepage)`);\n\t\t} catch {\n\t\t\t// non-fatal — placeholder replacement already covered it\n\t\t}\n\t}\n\n\t// Update the root tsconfig.json \"display\" field by parsing the JSON directly\n\t// rather than relying on a <display_name> placeholder. Templates can use their\n\t// real human-readable display name; we always overwrite it with the title-case\n\t// of the new repo name on scaffolding.\n\tconst displayName = input.name.split(\"-\").map(cap).join(\" \");\n\tconst rootTsconfigPath = path.join(repoDir, \"tsconfig.json\");\n\ttry {\n\t\tconst tsconfig = JSON.parse(readFn(rootTsconfigPath)) as Record<string, unknown>;\n\t\tif (typeof tsconfig[\"display\"] === \"string\") {\n\t\t\ttsconfig[\"display\"] = displayName;\n\t\t\twriteFn(rootTsconfigPath, JSON.stringify(tsconfig, null, 2) + \"\\n\");\n\t\t\tprint(` ✓ tsconfig.json (display)`);\n\t\t}\n\t} catch {\n\t\t// non-fatal — no tsconfig or no display field\n\t}\n\n\t// Generate and write holocron.config.ts\n\tconst configContent = generateHolocronConfig({\n\t\tname: input.name,\n\t\ttype: input.type,\n\t\torg,\n\t\tdescription: input.description,\n\t\thomepage: input.homepage,\n\t\tvaultProvider: input.vaultProvider,\n\t\tvaultProject: input.vaultProject,\n\t\tvaultConfig: input.vaultConfig,\n\t\tdeploymentProvider: input.deploymentProvider,\n\t\tagent: input.agent,\n\t\truntimeEnvironment: input.runtimeEnvironment,\n\t\tprotection: input.protection,\n\t\topenSource: input.openSource,\n\t\tusesExternalPackages: input.usesExternalPackages,\n\t\ttopics: input.topics,\n\t\tskills: input.skills,\n\t});\n\tconst configPath = path.join(repoDir, \"holocron.config.ts\");\n\twriteFn(configPath, configContent);\n\tprint(` Generated holocron.config.ts`);\n\n\texecFn(\"git\", [\"add\", \"-A\"], { cwd: repoDir, stdio: \"inherit\" });\n\texecFn(\"git\", [\"commit\", \"-s\", \"-m\", `chore: bootstrap from ${templateSlug}`], {\n\t\tcwd: repoDir,\n\t\tstdio: \"inherit\",\n\t});\n\n\tif (!input.noVerify) {\n\t\tprint(\"\");\n\t\tprint(\" Installing dependencies…\");\n\t\ttry {\n\t\t\texecFn(\"pnpm\", [\"install\"], { cwd: repoDir, stdio: \"inherit\" });\n\t\t} catch (err) {\n\t\t\tprint(` ✗ pnpm install failed — ${err instanceof Error ? err.message : String(err)}`);\n\t\t\treturn {\n\t\t\t\tstatus: \"fail\",\n\t\t\t\trepoDir,\n\t\t\t\tfilesPatched,\n\t\t\t\tmessage: \"pnpm install failed; inspect output above\",\n\t\t\t};\n\t\t}\n\n\t\tprint(\"\");\n\t\tprint(\" Running holocron setup…\");\n\t\ttry {\n\t\t\tconst setupArgs: string[] = [\"setup\"];\n\t\t\tconst setupEnv: Record<string, string> = {};\n\n\t\t\t// Admin token: drives rulesets, repo settings, workflows, Pages.\n\t\t\t// Prefer the value forwarded via --token; fall back to keychain.\n\t\t\tconst adminToken = input.token ?? keychainLookup(\"github.admin\");\n\t\t\tif (adminToken) setupArgs.push(\"--token\", adminToken);\n\n\t\t\t// Org token: drives team assignments and custom properties.\n\t\t\t// Skip keychain if already in env (subprocess inherits it anyway).\n\t\t\tif (!env.get(\"HOLOCRON_ORG_TOKEN\")) {\n\t\t\t\tconst orgToken = keychainLookup(\"github.org\");\n\t\t\t\tif (orgToken) setupEnv[\"HOLOCRON_ORG_TOKEN\"] = orgToken;\n\t\t\t}\n\n\t\t\t// Deploy token: drives GitHub Pages configuration.\n\t\t\tif (!env.get(\"HOLOCRON_DEPLOY_TOKEN\")) {\n\t\t\t\tconst deployToken = keychainLookup(\"github.deploy\");\n\t\t\t\tif (deployToken) setupEnv[\"HOLOCRON_DEPLOY_TOKEN\"] = deployToken;\n\t\t\t}\n\n\t\t\texecFn(\"holocron\", setupArgs, { cwd: repoDir, stdio: \"inherit\", env: setupEnv });\n\t\t} catch {\n\t\t\tprint(\" ✗ holocron setup failed — run it manually after checking your config\");\n\t\t}\n\t}\n\n\tprint(\"\");\n\tprint(` Scaffolded ${newRepo} (${filesPatched.length} file${filesPatched.length === 1 ? \"\" : \"s\"} patched).`);\n\tprint(\"\");\n\tprint(\" Next:\");\n\tprint(` 1. cd ${repoDir}`);\n\tif (input.noVerify) {\n\t\tprint(` 2. pnpm install`);\n\t\tprint(` 3. holocron setup # wire up secrets, teams, labels, etc.`);\n\t\tprint(` 4. git push -u origin HEAD`);\n\t} else {\n\t\tprint(` 2. git push -u origin HEAD`);\n\t}\n\n\tlogger.info({ repo: newRepo, repoDir, filesPatched, status: \"ok\" }, \"new: done\");\n\treturn { status: \"ok\", repoDir, filesPatched };\n}\n","import { readdirSync, readFileSync, statSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport { getLogger } from \"../logger.js\";\n\nexport interface RunNpmBumpVersionsInput {\n\t/** Next version string (e.g., \"4.2.0\" or \"2.0.0-alpha.1\"). */\n\tversion: string;\n\t/** Working directory (monorepo root). Defaults to process.cwd(). */\n\tcwd?: string;\n\t/** Print what would change without writing anything. */\n\tdryRun?: boolean;\n\tprint?: (line: string) => void;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n\t/** Injectable for testing. */\n\treadFile?: (path: string) => string;\n\twriteFile?: (path: string, content: string) => void;\n\tlistDir?: (path: string) => string[];\n\tisDir?: (path: string) => boolean;\n}\n\nexport type BumpVersionsStatus = \"ok\" | \"fail\" | \"dry-run\";\n\nexport interface NpmBumpVersionsReport {\n\tstatus: BumpVersionsStatus;\n\tbumped: readonly string[];\n\tskipped: readonly string[];\n\tmessage?: string;\n}\n\nexport async function runNpmBumpVersions(input: RunNpmBumpVersionsInput): Promise<NpmBumpVersionsReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst cwd = input.cwd ?? process.cwd();\n\tconst { version, dryRun = false } = input;\n\tconst readFile = input.readFile ?? ((p: string) => readFileSync(p, \"utf8\"));\n\tconst writeFile = input.writeFile ?? ((p: string, c: string) => writeFileSync(p, c));\n\tconst listDir = input.listDir ?? ((p: string) => readdirSync(p) as string[]);\n\tconst isDir = input.isDir ?? ((p: string) => statSync(p).isDirectory());\n\n\tconst bumped: string[] = [];\n\tconst skipped: string[] = [];\n\n\tprint(`Bumping monorepo to ${version}${dryRun ? \" (dry-run)\" : \"\"}…`);\n\tlogger.info({ version, dryRun: dryRun || undefined }, \"npm bump-versions: start\");\n\n\tfunction bumpFile(absPath: string, label: string): void {\n\t\tlet pkg: Record<string, unknown>;\n\t\ttry {\n\t\t\tpkg = JSON.parse(readFile(absPath)) as Record<string, unknown>;\n\t\t} catch {\n\t\t\tprint(` ✗ could not parse ${label}`);\n\t\t\treturn;\n\t\t}\n\t\tconst old = pkg.version as string;\n\t\tif (!dryRun) {\n\t\t\tpkg.version = version;\n\t\t\twriteFile(absPath, JSON.stringify(pkg, null, 2) + \"\\n\");\n\t\t}\n\t\tprint(` ${dryRun ? \"~\" : \"✓\"} ${label}: ${old} → ${version}`);\n\t\tbumped.push(label);\n\t}\n\n\t// Root is always bumped — private means \"don't publish\", not \"don't version\".\n\tbumpFile(join(cwd, \"package.json\"), \"root\");\n\n\tconst packagesDir = join(cwd, \"packages\");\n\tlet entries: string[];\n\ttry {\n\t\tentries = listDir(packagesDir);\n\t} catch {\n\t\t// No packages/ dir — single-package repo; root bump is sufficient.\n\t\tconst status = dryRun ? \"dry-run\" : \"ok\";\n\t\tlogger.info({ version, status, bumped: bumped.length, skipped: skipped.length }, \"npm bump-versions: done\");\n\t\treturn { status, bumped, skipped };\n\t}\n\n\tfor (const entry of entries) {\n\t\tconst pkgDir = join(packagesDir, entry);\n\t\ttry {\n\t\t\tif (!isDir(pkgDir)) continue;\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\t\tconst pkgFile = join(pkgDir, \"package.json\");\n\t\tlet pkg: Record<string, unknown>;\n\t\ttry {\n\t\t\tpkg = JSON.parse(readFile(pkgFile)) as Record<string, unknown>;\n\t\t} catch {\n\t\t\tprint(` ! skipping packages/${entry}: no package.json or malformed JSON`);\n\t\t\tcontinue;\n\t\t}\n\t\tif (pkg.private) {\n\t\t\tprint(` · skipping private package packages/${entry}`);\n\t\t\tskipped.push(`packages/${entry}`);\n\t\t\tcontinue;\n\t\t}\n\t\tbumpFile(pkgFile, `packages/${entry}`);\n\t}\n\n\tconst status = dryRun ? \"dry-run\" : \"ok\";\n\tlogger.info({ version, status, bumped: bumped.length, skipped: skipped.length }, \"npm bump-versions: done\");\n\treturn { status, bumped, skipped };\n}\n","/**\n * Shared input record for every template module.\n *\n * Every template exports `(inputs: TemplateInputs) => string` and reads\n * from this record. Keeping the surface small + typechecked lets the\n * templates stay dumb string builders while the command layer handles\n * normalization + defaulting from user input.\n */\n\nimport type { CapabilityKey } from \"../../plugin/capabilities.js\";\n\nexport interface TemplateInputs {\n\t/** Package slug — e.g., \"clerk\". Lowercase, kebab-case. */\n\tslug: string;\n\t/** Vendor display name — e.g., \"Clerk\". PascalCase. */\n\tvendorName: string;\n\t/** Vendor slug UPPERCASED — e.g., \"CLERK\". Used for env var names + class prefixes. */\n\tvendorUpper: string;\n\t/** Capability the plugin implements — one of the 14 known keys. */\n\tcapability: CapabilityKey;\n\t/** Capability implementation class name — e.g., \"ClerkAuth\". PascalCase. */\n\tcapabilityClass: string;\n\t/** Holocron-namespaced env var — defaults to `HOLOCRON_<VENDOR_UPPER>_TOKEN`. */\n\ttokenEnv: string;\n\t/** Vendor-native env var — e.g., \"CLERK_SECRET_KEY\". */\n\tvendorEnv: string;\n\t/** REST base URL — e.g., \"https://api.clerk.com/v1\". */\n\tbaseUrl: string;\n\t/** Transport. Only \"rest\" is supported in Phase 1 (spec: #77). */\n\ttransport: \"rest\";\n}\n\n/** Derive the standard defaults from a slug + vendor name. */\nexport function deriveDefaults(input: {\n\tslug: string;\n\tvendorName: string;\n\tcapability: CapabilityKey;\n}): Pick<TemplateInputs, \"vendorUpper\" | \"capabilityClass\" | \"tokenEnv\" | \"transport\"> {\n\tconst vendorUpper = input.slug.toUpperCase().replace(/-/g, \"_\");\n\tconst capability = input.capability;\n\tconst capabilityClass = `${input.vendorName}${capability.charAt(0).toUpperCase() + capability.slice(1)}`;\n\treturn {\n\t\tvendorUpper,\n\t\tcapabilityClass,\n\t\ttokenEnv: `HOLOCRON_${vendorUpper}_TOKEN`,\n\t\ttransport: \"rest\",\n\t};\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(inputs: TemplateInputs): string {\n\treturn `import { AuthError, createResolveToken, type ResolveTokenInput } from \"@theholocron/cli\";\n\nexport { AuthError };\nexport type { ResolveTokenInput };\n\nexport const resolveToken = createResolveToken({\n\\tenvName: \"${inputs.tokenEnv}\",\n\\tvendorEnvName: \"${inputs.vendorEnv}\",\n\\tkeyringService: \"${inputs.slug}\",\n\\terrorMessage:\n\\t\\t\"no ${inputs.vendorName} token found. Pass --token <TOKEN>, set ${inputs.tokenEnv} / ${inputs.vendorEnv}, \" +\n\\t\\t\"or run: holocron auth set ${inputs.slug} <TOKEN>\",\n});\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(inputs: TemplateInputs): string {\n\treturn `import { describe, expect, it } from \"vitest\";\n\nimport { AuthError, resolveToken } from \"../auth.js\";\n\nconst noKeyring = () => null;\n\ndescribe(\"resolveToken\", () => {\n\tit(\"prefers --token over env vars + keyring\", () => {\n\t\texpect(\n\t\t\tresolveToken({\n\t\t\t\tcliToken: \"flag\",\n\t\t\t\tenv: { ${inputs.tokenEnv}: \"hlc\", ${inputs.vendorEnv}: \"vendor\" },\n\t\t\t\tkeyring: () => \"kr\",\n\t\t\t})\n\t\t).toBe(\"flag\");\n\t});\n\n\tit(\"prefers ${inputs.tokenEnv} over ${inputs.vendorEnv}\", () => {\n\t\texpect(\n\t\t\tresolveToken({\n\t\t\t\tenv: { ${inputs.tokenEnv}: \"hlc\", ${inputs.vendorEnv}: \"vendor\" },\n\t\t\t\tkeyring: noKeyring,\n\t\t\t})\n\t\t).toBe(\"hlc\");\n\t});\n\n\tit(\"falls back to ${inputs.vendorEnv} when ${inputs.tokenEnv} is unset\", () => {\n\t\texpect(resolveToken({ env: { ${inputs.vendorEnv}: \"vendor\" }, keyring: noKeyring })).toBe(\"vendor\");\n\t});\n\n\tit(\"falls back to keyring when env vars are unset\", () => {\n\t\texpect(resolveToken({ env: {}, keyring: (p) => (p === \"${inputs.slug}\" ? \"kr\" : null) })).toBe(\"kr\");\n\t});\n\n\tit(\"throws AuthError with a helpful message when nothing is set\", () => {\n\t\ttry {\n\t\t\tresolveToken({ env: {}, keyring: noKeyring });\n\t\t\tthrow new Error(\"should have thrown\");\n\t\t} catch (err) {\n\t\t\texpect(err).toBeInstanceOf(AuthError);\n\t\t\texpect((err as Error).message).toMatch(/${inputs.tokenEnv}/);\n\t\t\texpect((err as Error).message).toMatch(/holocron auth set ${inputs.slug}/);\n\t\t}\n\t});\n});\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(inputs: TemplateInputs): string {\n\tconst clientClass = `${inputs.vendorName}RestClient`;\n\tconst capabilityInterface = inputs.capability.charAt(0).toUpperCase() + inputs.capability.slice(1);\n\treturn `/**\n * \\`${inputs.capability}\\` capability for ${inputs.vendorName}.\n *\n * Methods are STUBS — implement them against ${inputs.vendorName}'s\n * REST API per the \\`${capabilityInterface}\\` interface contract in\n * \\`@theholocron/cli\\`.\n *\n * TODO once you've stubbed the interface methods, restore the type\n * import + \\`implements\\` clause:\n * import type { ${capabilityInterface} } from \"@theholocron/cli\";\n * export class ${inputs.capabilityClass} implements ${capabilityInterface} { ... }\n */\n\nimport type { ${clientClass} } from \"../rest.js\";\n\nexport class ${inputs.capabilityClass} {\n\treadonly key = \"${inputs.capability}\" as const;\n\treadonly providerName = \"${inputs.slug}\";\n\n\tconstructor(private readonly rest: () => ${clientClass}) {}\n\n\t// TODO: implement the ${capabilityInterface} interface methods\n\t// (see \\`packages/cli/src/capabilities/index.ts\\`). Each method\n\t// should hit a specific ${inputs.vendorName} REST endpoint via\n\t// \\`this.rest().request(...)\\` — call the thunk so the token is\n\t// resolved lazily. Once methods are stubbed, add\n\t// \\`implements ${capabilityInterface}\\` to the class declaration\n\t// above and remove the \\`as unknown as\\` cast in src/index.ts.\n}\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(inputs: TemplateInputs): string {\n\tconst clientClass = `${inputs.vendorName}RestClient`;\n\treturn `import { describe, it } from \"vitest\";\n\nimport { ${inputs.capabilityClass} } from \"../capabilities/${inputs.capability}.js\";\nimport { ${clientClass} } from \"../rest.js\";\nimport { stubFetch } from \"./helpers.js\";\n\n// Stub client used by the constructor smoke test. Real capability\n// tests replace this with per-method stubs once implementations land.\nfunction makeCapability() {\n\tconst stub = stubFetch([]);\n\tconst rest = new ${clientClass}({ token: \"t\", fetch: stub.fetch });\n\treturn new ${inputs.capabilityClass}(() => rest);\n}\n\ndescribe(\"${inputs.capabilityClass}\", () => {\n\tit(\"constructs with a REST client\", () => {\n\t\tmakeCapability();\n\t});\n\n\t// TODO: implement one test per ${inputs.capability} capability method\n\t// as you fill in the class stubs. See other plugins for reference\n\t// patterns:\n\t// - REST behaviors (URL / method / body / query) via \\`stub.calls\\`\n\t// - Error paths via \\`stubFetch([{ status: 4xx, body: {...} }])\\`\n\t// - Idempotency (409 handling for ensure* methods, if applicable)\n\tit.todo(\"implement per-method tests\");\n});\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(_inputs: TemplateInputs): string {\n\treturn `import root from \"../../eslint.config.js\";\n\nexport default [\n\t...root,\n\t{\n\t\tignores: [\"dist/**\", \"coverage/**\"],\n\t},\n];\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(_inputs: TemplateInputs): string {\n\treturn `import { vi, type Mock } from \"vitest\";\n\nexport interface FetchCall {\n\turl: string;\n\tmethod: string;\n\theaders: Record<string, string>;\n\tbody: unknown;\n}\n\nexport interface FetchStub {\n\tfetch: typeof fetch;\n\tcalls: FetchCall[];\n\tmock: Mock;\n}\n\nexport function stubFetch(responses: Array<{ status?: number; body?: unknown; text?: string }>): FetchStub {\n\tconst calls: FetchCall[] = [];\n\tlet i = 0;\n\tconst mock = vi.fn(async (input: string | URL, init?: RequestInit) => {\n\t\tconst url = typeof input === \"string\" ? input : input.toString();\n\t\tconst body = typeof init?.body === \"string\" ? safeJsonParse(init.body) : (init?.body ?? null);\n\t\tcalls.push({\n\t\t\turl,\n\t\t\tmethod: (init?.method ?? \"GET\").toUpperCase(),\n\t\t\theaders: (init?.headers as Record<string, string>) ?? {},\n\t\t\tbody,\n\t\t});\n\t\tconst next = responses[i++] ?? { status: 200, body: {} };\n\t\tconst status = next.status ?? 200;\n\t\tif (status === 204 || status === 205 || status === 304) {\n\t\t\treturn new Response(null, { status });\n\t\t}\n\t\tconst text = next.text ?? (typeof next.body === \"string\" ? next.body : JSON.stringify(next.body ?? {}));\n\t\treturn new Response(text, { status });\n\t});\n\treturn { fetch: mock as unknown as typeof fetch, calls, mock };\n}\n\nfunction safeJsonParse(s: string): unknown {\n\ttry {\n\t\treturn JSON.parse(s);\n\t} catch {\n\t\treturn s;\n\t}\n}\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(inputs: TemplateInputs): string {\n\treturn `import { describe, expect, it } from \"vitest\";\n\nimport { AUTH_HINT, createPlugin } from \"../index.js\";\nimport { stubFetch } from \"./helpers.js\";\n\ndescribe(\"createPlugin\", () => {\n\tit(\"wires the ${inputs.capability} capability against the given fetch + token\", () => {\n\t\tconst stub = stubFetch([]);\n\t\tconst plugin = createPlugin({\n\t\t\tcliToken: \"test-token\",\n\t\t\tfetch: stub.fetch,\n\t\t});\n\t\texpect(plugin.name).toBe(\"@theholocron/holocron-plugin-${inputs.slug}\");\n\t\texpect(typeof plugin.capabilities.${inputs.capability}).toBe(\"function\");\n\t});\n});\n\ndescribe(\"AUTH_HINT\", () => {\n\tit(\"mentions the holocron auth set command\", () => {\n\t\texpect(AUTH_HINT).toMatch(/holocron auth set ${inputs.slug}/);\n\t});\n});\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(inputs: TemplateInputs): string {\n\treturn (\n\t\tJSON.stringify(\n\t\t\t{\n\t\t\t\tname: `@theholocron/holocron-plugin-${inputs.slug}`,\n\t\t\t\tversion: \"2.0.0-alpha.1\",\n\t\t\t\tdescription: `Holocron plugin for ${inputs.vendorName}. Implements the ${inputs.capability} capability against ${inputs.vendorName}'s REST API, plus exports verifyToken + AUTH_HINT for \\`holocron auth\\`.`,\n\t\t\t\thomepage: `https://github.com/theholocron/holocron/tree/main/packages/holocron-plugin-${inputs.slug}#readme`,\n\t\t\t\tbugs: \"https://github.com/theholocron/holocron/issues\",\n\t\t\t\trepository: {\n\t\t\t\t\ttype: \"git\",\n\t\t\t\t\turl: \"git+https://github.com/theholocron/holocron.git\",\n\t\t\t\t\tdirectory: `packages/holocron-plugin-${inputs.slug}`,\n\t\t\t\t},\n\t\t\t\tlicense: \"MIT\",\n\t\t\t\tauthor: \"Newton Koumantzelis\",\n\t\t\t\ttype: \"module\",\n\t\t\t\tmain: \"./src/index.ts\",\n\t\t\t\texports: { \".\": \"./src/index.ts\" },\n\t\t\t\tscripts: {\n\t\t\t\t\t// delivery.build stays a direct tool invocation, never `holocron\n\t\t\t\t\t// run` — it's what produces the holocron binary, so it can never\n\t\t\t\t\t// depend on holocron already existing. The other three tasks are\n\t\t\t\t\t// safe to gateway through holocron: this template already\n\t\t\t\t\t// declares @theholocron/cli as a real devDependency below, giving\n\t\t\t\t\t// turbo the edge it needs to build cli (and transitively\n\t\t\t\t\t// astromech) before this package's own script ever runs.\n\t\t\t\t\t\"delivery.build\": \"tsdown\",\n\t\t\t\t\t\"sourceQuality.staticAnalysis\": \"holocron run sourceQuality.staticAnalysis --\",\n\t\t\t\t\t\"verification.typeSafety\": \"holocron run verification.typeSafety --\",\n\t\t\t\t\t\"verification.unitTests\": \"holocron run verification.unitTests --\",\n\t\t\t\t\t\"test:watch\": \"vitest\",\n\t\t\t\t\tvalidate: \"tsx scripts/validate.mjs\",\n\t\t\t\t},\n\t\t\t\tpeerDependencies: { \"@theholocron/cli\": \"workspace:*\" },\n\t\t\t\tdevDependencies: {\n\t\t\t\t\t\"@theholocron/cli\": \"workspace:*\",\n\t\t\t\t\t\"@theholocron/tsconfig\": \"catalog:\",\n\t\t\t\t\t\"@tsconfig/node-lts\": \"catalog:\",\n\t\t\t\t\t\"@vitest/coverage-v8\": \"catalog:\",\n\t\t\t\t\teslint: \"catalog:\",\n\t\t\t\t\tglobals: \"catalog:\",\n\t\t\t\t\ttypescript: \"catalog:\",\n\t\t\t\t\tvitest: \"catalog:\",\n\t\t\t\t\ttsdown: \"catalog:\",\n\t\t\t\t\ttsx: \"catalog:\",\n\t\t\t\t},\n\t\t\t\tpublishConfig: {\n\t\t\t\t\taccess: \"public\",\n\t\t\t\t\tmain: \"./dist/index.mjs\",\n\t\t\t\t\ttypes: \"./dist/index.d.mts\",\n\t\t\t\t\texports: {\n\t\t\t\t\t\t\".\": {\n\t\t\t\t\t\t\ttypes: \"./dist/index.d.mts\",\n\t\t\t\t\t\t\timport: \"./dist/index.mjs\",\n\t\t\t\t\t\t\tdefault: \"./dist/index.mjs\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tfiles: [\"dist\", \"README.md\"],\n\t\t\t},\n\t\t\tnull,\n\t\t\t\"\\t\"\n\t\t) + \"\\n\"\n\t);\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(inputs: TemplateInputs): string {\n\tconst clientClass = `${inputs.vendorName}RestClient`;\n\t// Camel-case capability name is used as the factory function name.\n\tconst capabilityInterface = inputs.capability.charAt(0).toUpperCase() + inputs.capability.slice(1);\n\treturn `/**\n * \\`@theholocron/holocron-plugin-${inputs.slug}\\` — entrypoint.\n *\n * Implements the \\`${inputs.capability}\\` capability against ${inputs.vendorName}'s\n * REST API. Also exports \\`verifyToken\\` + \\`AUTH_HINT\\` for\n * \\`holocron auth\\`. See README for auth + config docs.\n *\n * TODO: once you fill in the ${inputs.capabilityClass} methods and add\n * \\`implements ${capabilityInterface}\\` to the class, add the type import:\n * import type { ${capabilityInterface} } from \"@theholocron/cli\";\n * and set \\`: ${capabilityInterface}\\` as the factory return type below.\n */\n\nimport { resolveToken, type ResolveTokenInput } from \"./auth.js\";\nimport { ${inputs.capabilityClass} } from \"./capabilities/${inputs.capability}.js\";\nimport { ${clientClass} } from \"./rest.js\";\n\nexport interface ${inputs.vendorName}PluginOptions extends ResolveTokenInput {\n\t/** Override base URL for tests. */\n\tbaseUrl?: string;\n\t/** Override \\`fetch\\` for tests. */\n\tfetch?: typeof fetch;\n}\n\nexport interface PluginContext {\n\toptions: ${inputs.vendorName}PluginOptions;\n\t/** Memoized client — the token is resolved on first use, not at plugin load. */\n\trest: () => ${clientClass};\n}\n\nexport function createContext(options: ${inputs.vendorName}PluginOptions): PluginContext {\n\tlet rest: ${clientClass} | undefined;\n\treturn {\n\t\toptions,\n\t\trest: () => {\n\t\t\tif (rest) return rest;\n\t\t\tconst restOpts: ConstructorParameters<typeof ${clientClass}>[0] = { token: resolveToken(options) };\n\t\t\tif (options.baseUrl !== undefined) restOpts.baseUrl = options.baseUrl;\n\t\t\tif (options.fetch !== undefined) restOpts.fetch = options.fetch;\n\t\t\treturn (rest = new ${clientClass}(restOpts));\n\t\t},\n\t};\n}\n\nexport function ${inputs.capability}(ctx: PluginContext) {\n\t// Return type inferred at scaffold time — the class doesn't yet\n\t// \\`implements ${capabilityInterface}\\`. Add the type import + the\n\t// \\`: ${capabilityInterface}\\` annotation once methods are stubbed.\n\treturn new ${inputs.capabilityClass}(ctx.rest);\n}\n\nexport function createPlugin(options: ${inputs.vendorName}PluginOptions) {\n\tconst ctx = createContext(options);\n\treturn {\n\t\tname: \"@theholocron/holocron-plugin-${inputs.slug}\",\n\t\tcapabilities: {\n\t\t\t${inputs.capability}: () => ${inputs.capability}(ctx),\n\t\t},\n\t};\n}\n\n/**\n * One-line hint printed by \\`holocron auth set ${inputs.slug}\\` when no\n * token is supplied or the supplied token is rejected. Edit this to\n * point operators at the specific ${inputs.vendorName} docs path for\n * generating a token.\n */\nexport const AUTH_HINT =\n\t\"generate a ${inputs.vendorName} API token, then run: holocron auth set ${inputs.slug} <TOKEN>\";\n\n// ── Public re-exports ────────────────────────────────────────────────\n\nexport * from \"./auth.js\";\nexport { ${clientClass} } from \"./rest.js\";\nexport { ${inputs.capabilityClass} } from \"./capabilities/${inputs.capability}.js\";\nexport { verifyToken } from \"./verify-token.js\";\nexport type { VerifyTokenResult, VerifyTokenSuccess, VerifyTokenFailure } from \"./verify-token.js\";\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(inputs: TemplateInputs): string {\n\treturn `<!-- editorconfig-checker-disable-file -->\n\n# \\`@theholocron/holocron-plugin-${inputs.slug}\\`\n\n${inputs.vendorName} plugin for [Holocron](../cli). Implements the\n\\`${inputs.capability}\\` capability against [${inputs.vendorName}'s REST API](${inputs.baseUrl}),\nplus exports \\`verifyToken\\` + \\`AUTH_HINT\\` for use by \\`holocron auth\\`.\n\n## Install\n\n\\`\\`\\`bash\npnpm add -D @theholocron/holocron-plugin-${inputs.slug}@alpha\n\\`\\`\\`\n\n## Auth\n\nToken resolution order (matches the standard 4-step precedence set by\n\\`docs/wiki/specifications/tech-auth-bootstrap.spec.md\\`):\n\n1. \\`--token <TOKEN>\\` flag on the holocron invocation\n2. \\`${inputs.tokenEnv}\\` env var (preferred — explicit intent)\n3. \\`${inputs.vendorEnv}\\` env var (${inputs.vendorName}-native)\n4. **Keyring** — \\`com.theholocron.cli\\` service, account \\`${inputs.slug}\\`\n5. \\`AuthError\\` naming all four options + the bootstrap hint\n\n## Setup\n\n\\`\\`\\`bash\n# Generate a ${inputs.vendorName} API token (see vendor docs), then:\nholocron auth set ${inputs.slug} <TOKEN>\nholocron auth check ${inputs.slug} # verify\n\\`\\`\\`\n\n## Config\n\n\\`\\`\\`jsonc\n{\n\t\"providers\": {\n\t\t\"${inputs.capability}\": \"${inputs.slug}\",\n\t},\n}\n\\`\\`\\`\n\nPlugin options extend \\`ResolveTokenInput\\` — add whatever ${inputs.vendorName}-\nspecific options you need here (project id, workspace slug, etc.) via\nthe tuple form:\n\n\\`\\`\\`jsonc\n{\n\t\"providers\": {\n\t\t\"${inputs.capability}\": [\"${inputs.slug}\", { \"baseUrl\": \"${inputs.baseUrl}\" }],\n\t},\n}\n\\`\\`\\`\n\n## What's implemented\n\nTODO: fill in as capability methods land.\n\n## Status\n\n**\\`v2.0.0-alpha.1\\`** — scaffolded via \\`holocron plugin create\\`.\nNot yet published; capability methods are stubs.\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(inputs: TemplateInputs): string {\n\tconst factoryName = `create${inputs.vendorName}RestClient`;\n\treturn `import { createRestClient, type RequestOptions, type RestClient } from \"@theholocron/cli\";\n\nexport type { RequestOptions, RestClient };\n\nexport function ${factoryName}(opts: {\n\\ttoken: string;\n\\tbaseUrl?: string;\n\\tfetch?: typeof fetch;\n}): RestClient {\n\\treturn createRestClient({\n\\t\\tbaseUrl: opts.baseUrl ?? \"${inputs.baseUrl}\",\n\\t\\ttoken: opts.token,\n\\t\\tvendor: \"${inputs.vendorName}\",\n\\t\\tfetch: opts.fetch,\n\\t});\n}\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(inputs: TemplateInputs): string {\n\tconst factoryName = `create${inputs.vendorName}RestClient`;\n\treturn `import { ProviderApiError } from \"@theholocron/cli\";\nimport { describe, expect, it } from \"vitest\";\n\nimport { ${factoryName} } from \"../rest.js\";\nimport { stubFetch } from \"./helpers.js\";\n\ndescribe(\"${factoryName}\", () => {\n\\tit(\"sends bearer + accept headers and returns the parsed body\", async () => {\n\\t\\tconst stub = stubFetch([{ status: 200, body: { ok: true } }]);\n\\t\\tconst client = ${factoryName}({ token: \"t\", fetch: stub.fetch });\n\\t\\tconst res = await client.request<{ ok: boolean }>(\"/me\");\n\\t\\texpect(res.ok).toBe(true);\n\\t\\texpect(stub.calls[0]?.headers[\"authorization\"]).toBe(\"Bearer t\");\n\\t\\texpect(stub.calls[0]?.headers[\"accept\"]).toBe(\"application/json\");\n\\t});\n\n\\tit(\"serializes body as JSON and sets content-type when present\", async () => {\n\\t\\tconst stub = stubFetch([{ status: 200, body: {} }]);\n\\t\\tconst client = ${factoryName}({ token: \"t\", fetch: stub.fetch });\n\\t\\tawait client.request<unknown>(\"/resource\", { method: \"POST\", body: { name: \"demo\" } });\n\\t\\texpect(stub.calls[0]?.method).toBe(\"POST\");\n\\t\\texpect(stub.calls[0]?.headers[\"content-type\"]).toBe(\"application/json\");\n\\t\\texpect(stub.calls[0]?.body).toEqual({ name: \"demo\" });\n\\t});\n\n\\tit(\"returns undefined on 204\", async () => {\n\\t\\tconst stub = stubFetch([{ status: 204 }]);\n\\t\\tconst client = ${factoryName}({ token: \"t\", fetch: stub.fetch });\n\\t\\texpect(await client.request<unknown>(\"/whatever\")).toBeUndefined();\n\\t});\n\n\\tit(\"throws ProviderApiError with the HTTP status on non-2xx\", async () => {\n\\t\\tconst stub = stubFetch([{ status: 401, body: { messages: [\"invalid\"] } }]);\n\\t\\tconst client = ${factoryName}({ token: \"bad\", fetch: stub.fetch });\n\\t\\tconst err = await client.request<unknown>(\"/me\").catch((e: unknown) => e);\n\\t\\texpect(err).toBeInstanceOf(ProviderApiError);\n\\t\\texpect((err as ProviderApiError).status).toBe(401);\n\\t});\n\n\\tit(\"wraps transport-level failures with status 0\", async () => {\n\\t\\tconst throwing: typeof fetch = async () => { throw new TypeError(\"fetch failed\"); };\n\\t\\tconst client = ${factoryName}({ token: \"t\", fetch: throwing });\n\\t\\tconst err = await client.request<unknown>(\"/me\").catch((e: unknown) => e);\n\\t\\texpect(err).toBeInstanceOf(ProviderApiError);\n\\t\\texpect((err as ProviderApiError).status).toBe(0);\n\\t});\n\n\\tit(\"trims trailing slashes from the base URL\", () => {\n\\t\\tconst client = ${factoryName}({ token: \"t\", baseUrl: \"${inputs.baseUrl}//\" });\n\\t\\texpect(client.baseUrl).toBe(\"${inputs.baseUrl}\");\n\\t});\n});\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(inputs: TemplateInputs): string {\n\treturn (\n\t\tJSON.stringify(\n\t\t\t{\n\t\t\t\tdisplay: `Holocron Plugin: ${inputs.vendorName}`,\n\t\t\t\textends: \"@tsconfig/node-lts/tsconfig.json\",\n\t\t\t\tcompilerOptions: {\n\t\t\t\t\tbaseUrl: \"./\",\n\t\t\t\t\toutDir: \"./dist\",\n\t\t\t\t\tpaths: { \"@/*\": [\"./src/*\"] },\n\t\t\t\t},\n\t\t\t\tinclude: [\"src/**/*.ts\"],\n\t\t\t\texclude: [\"node_modules\", \"dist\"],\n\t\t\t},\n\t\t\tnull,\n\t\t\t\"\\t\"\n\t\t) + \"\\n\"\n\t);\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(_inputs: TemplateInputs): string {\n\treturn `import { defineConfig } from \"tsdown\";\n\nexport default defineConfig({\n\tentry: [\"src/index.ts\"],\n\tformat: \"esm\",\n\tdts: true,\n\tclean: true,\n\tdeps: { neverBundle: [/^@theholocron\\\\//] },\n});\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\n/**\n * Scaffolds `scripts/validate.mjs` — a smoke-test the operator runs\n * against a live vendor account to verify the plugin's REST endpoints,\n * auth, and response parsing all work in reality (the unit tests only\n * exercise stubbed HTTP responses). READ-ONLY BY DESIGN.\n *\n * Convention: every plugin ships this script + a matching `validate`\n * entry in `package.json`'s scripts block, so operators run\n * `pnpm --filter @theholocron/holocron-plugin-<slug> validate`.\n * Capability-specific args (project id, workspace, etc.) come from\n * positional command-line arguments; the plugin author fills in the\n * exact shape per their vendor.\n *\n * Includes a `hintFor(message)` helper the operator customizes with\n * vendor-specific \"here's the likely fix\" guidance for common error\n * shapes (401 / 403 / 404 / network / 5xx). Points users at docs and\n * setup steps rather than leaving them staring at a raw stack trace.\n */\nexport function render(inputs: TemplateInputs): string {\n\treturn `#!/usr/bin/env node\n/**\n * Read-only smoke test for @theholocron/holocron-plugin-${inputs.slug} against\n * a live ${inputs.vendorName} account.\n *\n * READ-ONLY BY DESIGN. Never calls write(), or bootstrap methods\n * (\\`ensureProject\\`, \\`ensureEnvironment\\`, etc.). Any ERROR line means\n * the plugin needs adjusting — the \\`hintFor\\` helper below points at\n * the most likely fix per error shape.\n *\n * Auth: reads the ${inputs.vendorName} token from holocron's keyring —\n * you must have run \\`pnpm holocron auth set ${inputs.slug} <TOKEN>\\` first.\n *\n * Usage:\n * pnpm --filter @theholocron/holocron-plugin-${inputs.slug} validate <arg1> [arg2] ...\n *\n * TODO: replace the positional args below with whatever your\n * capability's methods need (e.g., project id, environment slug,\n * secret name). Adapt the test steps to your capability's method\n * surface. Model on \\`packages/holocron-plugin-infisical/scripts/validate.mjs\\`.\n */\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars -- filled in by operator\nimport { AuthError, createPlugin, resolveToken, verifyToken } from \"../src/index.ts\";\n\nconst args = process.argv.slice(2);\n\nif (args.length === 0) {\n\tconsole.error(\"usage: pnpm --filter @theholocron/holocron-plugin-${inputs.slug} validate <args>\");\n\tprocess.exit(2);\n}\n\n// Use the plugin's own auth resolution so the validate script honors\n// the same 4-step precedence as the plugin's runtime:\n// --token → ${inputs.tokenEnv} → ${inputs.vendorEnv} → keyring\n// (--token isn't available here since this is a bare Node script;\n// the other three all work.)\nlet token;\ntry {\n\ttoken = resolveToken();\n} catch (err) {\n\tif (err instanceof AuthError) {\n\t\tconsole.error(err.message);\n\t\tconsole.error(\" see: packages/holocron-plugin-${inputs.slug}/README.md#setup\");\n\t\tprocess.exit(2);\n\t}\n\tthrow err;\n}\n\nconsole.log(\"Validating @theholocron/holocron-plugin-${inputs.slug} (READ-ONLY)\");\nconsole.log(\"\");\n\n// ── 1. verifyToken ─────────────────────────────────────────────────\nconsole.log(\"[1/N] verifyToken\");\nconst verifyResult = await verifyToken(token);\nconsole.log(\\` \\${verifyResult.ok ? \"✓\" : \"✗\"} \\${JSON.stringify(verifyResult)}\\`);\nif (!verifyResult.ok) {\n\tconst hint = hintFor(verifyResult.message);\n\tif (hint) console.log(\\` hint: \\${hint}\\`);\n}\nconsole.log(\"\");\n\n// ── 2..N. capability method calls ──────────────────────────────────\n// TODO: implement one \\`runStep\\`-wrapped call per meaningful read-side\n// capability method. Model on the infisical validate.mjs. Never call\n// write / ensure* / other mutating paths.\n//\n// Example:\n// console.log(\"[2/N] vault.list()\");\n// await runStep(async () => {\n// const keys = await vault.list();\n// console.log(\\` ✓ \\${keys.length} secrets\\`);\n// });\n\nconsole.log(\"Done. Fill in capability method calls above before shipping.\");\n\n// ── helpers ────────────────────────────────────────────────────────\n\n/** Wrap a capability call, print ERROR + hint on failure. */\nasync function runStep(body) {\n\ttry {\n\t\tawait body();\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tconsole.log(\\` ✗ ERROR: \\${message}\\`);\n\t\tconst hint = hintFor(message);\n\t\tif (hint) console.log(\\` hint: \\${hint}\\`);\n\t}\n}\n\n/**\n * Point the operator at the most likely fix based on the error shape.\n * Generic defaults below — CUSTOMIZE per your vendor's docs URLs and\n * common permission/config gotchas.\n */\nfunction hintFor(message) {\n\tif (/→ 401/.test(message)) {\n\t\treturn \"token invalid — regenerate per ${inputs.vendorName}'s docs (see README §Setup)\";\n\t}\n\tif (/→ 403/.test(message)) {\n\t\treturn \"token authenticates but lacks scope — check the token/identity has permissions on the resource\";\n\t}\n\tif (/→ 404/.test(message)) {\n\t\treturn \"endpoint or resource not found — verify your positional args match a real resource\";\n\t}\n\tif (/fetch failed|status: 0|network/i.test(message)) {\n\t\treturn \"network error — check the base URL (${inputs.baseUrl}) and connectivity\";\n\t}\n\tif (/→ 5\\\\d\\\\d/.test(message)) {\n\t\treturn \"server error — vendor-side. Retry, and check the vendor's status page if persistent\";\n\t}\n\treturn null;\n}\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(inputs: TemplateInputs): string {\n\tconst clientClass = `${inputs.vendorName}RestClient`;\n\treturn `/**\n * \\`verifyToken\\` — plugin-level export used by \\`holocron auth set\\` +\n * \\`holocron auth check\\`. Hits a lightweight whoami-style endpoint\n * and translates the response into the normalized \\`VerifyTokenResult\\`\n * shape.\n *\n * Kept as a standalone function (not a capability method) so the auth\n * command can call it without initializing the full plugin — plugin\n * construction requires an already-resolved token, which is exactly\n * what we don't have yet at bootstrap time.\n *\n * TODO: replace \\`/me\\` with the ${inputs.vendorName} equivalent of a\n * \"check my token\" endpoint. Common shapes: \\`/user\\`, \\`/whoami\\`,\n * \\`/me\\`, \\`/account\\`.\n */\n\nimport { ${clientClass} } from \"./rest.js\";\n\nexport interface VerifyTokenSuccess {\n\tok: true;\n\tsubject: string;\n}\n\nexport interface VerifyTokenFailure {\n\tok: false;\n\tmessage: string;\n}\n\nexport type VerifyTokenResult = VerifyTokenSuccess | VerifyTokenFailure;\n\ninterface MeResponse {\n\t/** Adjust to whatever ${inputs.vendorName}'s whoami endpoint returns. */\n\tname?: string;\n\temail?: string;\n\tid?: string;\n}\n\nexport interface VerifyTokenOptions {\n\tbaseUrl?: string;\n\tfetch?: typeof fetch;\n}\n\nexport async function verifyToken(token: string, opts: VerifyTokenOptions = {}): Promise<VerifyTokenResult> {\n\tconst restOpts: ConstructorParameters<typeof ${clientClass}>[0] = { token };\n\tif (opts.baseUrl !== undefined) restOpts.baseUrl = opts.baseUrl;\n\tif (opts.fetch !== undefined) restOpts.fetch = opts.fetch;\n\tconst rest = new ${clientClass}(restOpts);\n\ttry {\n\t\tconst me = await rest.request<MeResponse>(\"/me\");\n\t\t// Optional chaining because \\`me\\` is \\`undefined\\` on 204 / empty body.\n\t\tconst subject = me?.email ?? me?.name ?? me?.id ?? \"unknown\";\n\t\treturn { ok: true, subject: \\`user @ \\${subject}\\` };\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\treturn { ok: false, message };\n\t}\n}\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(_inputs: TemplateInputs): string {\n\treturn `import { describe, expect, it } from \"vitest\";\n\nimport { verifyToken } from \"../verify-token.js\";\nimport { stubFetch } from \"./helpers.js\";\n\ndescribe(\"verifyToken\", () => {\n\tit(\"returns ok with a subject when /me returns 200\", async () => {\n\t\tconst stub = stubFetch([{ status: 200, body: { email: \"user@example.com\" } }]);\n\t\tconst result = await verifyToken(\"token\", { fetch: stub.fetch });\n\t\texpect(result.ok).toBe(true);\n\t\tif (result.ok) {\n\t\t\texpect(result.subject).toMatch(/user@example.com/);\n\t\t}\n\t});\n\n\tit(\"returns ok:false with the error message on 401\", async () => {\n\t\tconst stub = stubFetch([{ status: 401, body: { messages: [\"Invalid token\"] } }]);\n\t\tconst result = await verifyToken(\"bad\", { fetch: stub.fetch });\n\t\texpect(result.ok).toBe(false);\n\t\tif (!result.ok) {\n\t\t\texpect(result.message).toMatch(/→ 401/);\n\t\t}\n\t});\n\n\tit(\"returns ok:false when the network layer throws\", async () => {\n\t\tconst throwing: typeof fetch = async () => {\n\t\t\tthrow new TypeError(\"network down\");\n\t\t};\n\t\tconst result = await verifyToken(\"t\", { fetch: throwing });\n\t\texpect(result.ok).toBe(false);\n\t\tif (!result.ok) {\n\t\t\texpect(result.message).toMatch(/network down/);\n\t\t}\n\t});\n});\n`;\n}\n","import type { TemplateInputs } from \"../template-inputs.js\";\n\nexport function render(_inputs: TemplateInputs): string {\n\treturn `import { defineConfig } from \"vitest/config\";\n\nexport default defineConfig({\n\ttest: {\n\t\tenvironment: \"node\",\n\t\tglobals: false,\n\t\tcoverage: {\n\t\t\tprovider: \"v8\",\n\t\t\treporter: [\"text\", \"html\", \"json-summary\"],\n\t\t\tinclude: [\"src/**/*.ts\"],\n\t\t\texclude: [\"src/**/__tests__/**\", \"src/**/*.test.ts\", \"src/index.ts\"],\n\t\t\tthresholds: { lines: 0, functions: 0, branches: 0, statements: 0 },\n\t\t},\n\t},\n});\n`;\n}\n","/**\n * `holocron plugin create <slug> <vendor>` — scaffold a new plugin\n * package matching the proven template.\n *\n * Design: see `docs/wiki/specifications/tool-plugin-create.spec.md`.\n *\n * Flow:\n * 1. Preflight — verify CWD is a workspace root (pnpm-workspace.yaml\n * + packages/ dir present).\n * 2. Slug collision — packages/holocron-plugin-<slug>/ must not exist.\n * 3. Capability sanity — must be one of the 14 known keys; warn for\n * many-cardinality caps.\n * 4. Generate — for each template, write to\n * packages/holocron-plugin-<slug>/<path>.\n * 5. Verify (unless --no-verify) — runs pnpm install +\n * pnpm --filter <pkg> typecheck lint test.\n * 6. Print next steps.\n */\n\nimport { execFileSync } from \"node:child_process\";\nimport { existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\n\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport { getLogger } from \"../../logger.js\";\nimport type { CapabilityKey } from \"../../plugin/capabilities.js\";\nimport { CARDINALITY } from \"../../plugin/capabilities.js\";\nimport { deriveDefaults, type TemplateInputs } from \"./template-inputs.js\";\nimport { render as renderAuth } from \"./templates/auth.js\";\nimport { render as renderAuthTest } from \"./templates/auth-test.js\";\nimport { render as renderCapability } from \"./templates/capability.js\";\nimport { render as renderCapabilityTest } from \"./templates/capability-test.js\";\nimport { render as renderEslintConfig } from \"./templates/eslint-config.js\";\nimport { render as renderHelpers } from \"./templates/helpers.js\";\nimport { render as renderIndexTest } from \"./templates/index-test.js\";\nimport { render as renderPackageJson } from \"./templates/package-json.js\";\nimport { render as renderPluginIndex } from \"./templates/plugin-index.js\";\nimport { render as renderReadme } from \"./templates/readme.js\";\nimport { render as renderRest } from \"./templates/rest.js\";\nimport { render as renderRestTest } from \"./templates/rest-test.js\";\nimport { render as renderTsconfigJson } from \"./templates/tsconfig-json.js\";\nimport { render as renderTsdownConfig } from \"./templates/tsdown-config.js\";\nimport { render as renderValidateScript } from \"./templates/validate-script.js\";\nimport { render as renderVerifyToken } from \"./templates/verify-token.js\";\nimport { render as renderVerifyTokenTest } from \"./templates/verify-token-test.js\";\nimport { render as renderVitestConfig } from \"./templates/vitest-config.js\";\n\n// ── Public API ──────────────────────────────────────────────────────\n\n// ── Wizard resolver ───────────────────────────────────────────────────\n\nexport interface PluginCreateWizardArgs {\n\tcapability?: string;\n\tvendorEnv?: string;\n\tbaseUrl?: string;\n}\n\nexport interface PluginCreateWizardPrompts {\n\tselectCapability: () => Promise<string>;\n\tinputVendorEnv: () => Promise<string>;\n\tinputBaseUrl: () => Promise<string>;\n}\n\n/**\n * Resolve `capability`, `vendorEnv`, and `baseUrl` from argv or by calling\n * the supplied prompt functions for any that are absent. Extracted from\n * `cli.ts` so the resolution logic is unit-testable.\n */\nexport async function resolvePluginCreateInputs(\n\targs: PluginCreateWizardArgs,\n\tprompts: PluginCreateWizardPrompts\n): Promise<{ capability: CapabilityKey; vendorEnv: string; baseUrl: string }> {\n\tconst capability = (args.capability ?? (await prompts.selectCapability())) as CapabilityKey;\n\tconst vendorEnv = args.vendorEnv ?? (await prompts.inputVendorEnv());\n\tconst baseUrl = args.baseUrl ?? (await prompts.inputBaseUrl());\n\treturn { capability, vendorEnv, baseUrl };\n}\n\n// ── Run input / report ────────────────────────────────────────────────\n\nexport interface RunPluginCreateInput {\n\t/** Package slug, e.g., \"clerk\". Kebab-case. */\n\tslug: string;\n\t/** Vendor display name, e.g., \"Clerk\". PascalCase. */\n\tvendorName: string;\n\t/** Capability the plugin implements — one of the 14 known keys. */\n\tcapability: CapabilityKey;\n\t/** Vendor-native env var, e.g., \"CLERK_SECRET_KEY\". */\n\tvendorEnv: string;\n\t/** REST base URL, e.g., \"https://api.clerk.com/v1\". */\n\tbaseUrl: string;\n\t/** Optional token env override. Defaults to `HOLOCRON_<VENDOR>_TOKEN`. */\n\ttokenEnv?: string;\n\t/** Print steps without writing files. */\n\tdryRun?: boolean;\n\t/** Skip the post-scaffold pnpm install/typecheck/lint/test. */\n\tnoVerify?: boolean;\n\t/** Working directory (workspace root). Defaults to `process.cwd()`. */\n\tcwd?: string;\n\t/** Injection point for tests / dry-run wiring. Defaults to fs write. */\n\twriteFile?: (filepath: string, content: string) => void;\n\t/** Print fn — captures orchestrator output. Defaults to console.log. */\n\tprint?: (line: string) => void;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n\t/** Injectable subprocess runner for testing. Defaults to execFileSync. */\n\texec?: (cmd: string, args: string[], opts: { cwd: string; stdio: \"inherit\" }) => void;\n}\n\nexport interface PluginCreateReport {\n\tstatus: \"ok\" | \"fail\";\n\tpackagePath: string;\n\tfilesWritten: string[];\n\tmessage?: string;\n}\n\nexport class PluginCreateError extends Error {\n\toverride name = \"PluginCreateError\";\n}\n\n// ── Templates registry ──────────────────────────────────────────────\n\ninterface TemplateEntry {\n\t/** Path relative to the plugin package root. */\n\tpath: string;\n\trender: (inputs: TemplateInputs) => string;\n}\n\nconst TEMPLATES: TemplateEntry[] = [\n\t// Config (5)\n\t{ path: \"package.json\", render: renderPackageJson },\n\t{ path: \"tsconfig.json\", render: renderTsconfigJson },\n\t{ path: \"vitest.config.ts\", render: renderVitestConfig },\n\t{ path: \"eslint.config.js\", render: renderEslintConfig },\n\t{ path: \"tsdown.config.ts\", render: renderTsdownConfig },\n\t// Docs (1)\n\t{ path: \"README.md\", render: renderReadme },\n\t// Source (5) — capability path uses the dynamic capability slug.\n\t{ path: \"src/auth.ts\", render: renderAuth },\n\t{ path: \"src/rest.ts\", render: renderRest },\n\t{ path: \"src/verify-token.ts\", render: renderVerifyToken },\n\t{ path: \"src/index.ts\", render: renderPluginIndex },\n\t{ path: \"src/capabilities/{{capability}}.ts\", render: renderCapability },\n\t// Tests (6)\n\t{ path: \"src/__tests__/helpers.ts\", render: renderHelpers },\n\t{ path: \"src/__tests__/auth.test.ts\", render: renderAuthTest },\n\t{ path: \"src/__tests__/rest.test.ts\", render: renderRestTest },\n\t{ path: \"src/__tests__/verify-token.test.ts\", render: renderVerifyTokenTest },\n\t{ path: \"src/__tests__/{{capability}}.test.ts\", render: renderCapabilityTest },\n\t{ path: \"src/__tests__/index.test.ts\", render: renderIndexTest },\n\t// Live-account validation script (1) — read-only smoke test.\n\t{ path: \"scripts/validate.mjs\", render: renderValidateScript },\n];\n\n/** Replace `{{capability}}` in a template path with the actual capability key. */\nfunction resolvePath(template: string, inputs: TemplateInputs): string {\n\treturn template.replace(/\\{\\{capability\\}\\}/g, inputs.capability);\n}\n\n// ── Orchestrator ────────────────────────────────────────────────────\n\nexport function runPluginCreate(input: RunPluginCreateInput): PluginCreateReport {\n\tconst cwd = input.cwd ?? process.cwd();\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst write = input.writeFile ?? defaultWrite;\n\n\tpreflight(cwd);\n\tvalidateSlug(input.slug);\n\tvalidateVendorName(input.vendorName);\n\n\tconst packageDir = path.join(cwd, \"packages\", `holocron-plugin-${input.slug}`);\n\tif (existsSync(packageDir)) {\n\t\tthrow new PluginCreateError(`\\`${packageDir}\\` already exists — edit in place or pick a different slug.`);\n\t}\n\n\tvalidateCapability(input.capability, print);\n\n\tconst derived = deriveDefaults({\n\t\tslug: input.slug,\n\t\tvendorName: input.vendorName,\n\t\tcapability: input.capability,\n\t});\n\tconst inputs: TemplateInputs = {\n\t\tslug: input.slug,\n\t\tvendorName: input.vendorName,\n\t\tvendorUpper: derived.vendorUpper,\n\t\tcapability: input.capability,\n\t\tcapabilityClass: derived.capabilityClass,\n\t\ttokenEnv: input.tokenEnv ?? derived.tokenEnv,\n\t\tvendorEnv: input.vendorEnv,\n\t\t// Normalize: strip trailing slashes so the embedded value in the\n\t\t// generated rest-test.ts matches what the client trims at runtime.\n\t\tbaseUrl: trimTrailingSlashes(input.baseUrl),\n\t\ttransport: derived.transport,\n\t};\n\n\tconst filesWritten: string[] = [];\n\tprint(`Scaffolding @theholocron/holocron-plugin-${inputs.slug}${input.dryRun ? \" (dry-run)\" : \"\"}`);\n\tprint(` → ${packageDir}`);\n\tlogger.info(\n\t\t{ slug: inputs.slug, capability: inputs.capability, dryRun: input.dryRun || undefined },\n\t\t\"plugin create: start\"\n\t);\n\tfor (const template of TEMPLATES) {\n\t\tconst resolvedPath = resolvePath(template.path, inputs);\n\t\tconst filepath = path.join(packageDir, resolvedPath);\n\t\tconst content = template.render(inputs);\n\t\tif (input.dryRun) {\n\t\t\tprint(` … would write ${resolvedPath} (${content.length} bytes)`);\n\t\t} else {\n\t\t\twrite(filepath, content);\n\t\t\tprint(` ✓ ${resolvedPath}`);\n\t\t}\n\t\tfilesWritten.push(resolvedPath);\n\t}\n\n\tif (!input.dryRun && !input.noVerify) {\n\t\tconst execFn = input.exec ?? defaultExec;\n\t\tconst pkg = `@theholocron/holocron-plugin-${inputs.slug}`;\n\t\tprint(\"\");\n\t\tprint(\" Verifying scaffold…\");\n\t\ttry {\n\t\t\texecFn(\"pnpm\", [\"install\", \"--frozen-lockfile=false\"], { cwd, stdio: \"inherit\" });\n\t\t\texecFn(\"pnpm\", [\"--filter\", pkg, \"verification.typeSafety\"], { cwd, stdio: \"inherit\" });\n\t\t\texecFn(\"pnpm\", [\"--filter\", pkg, \"sourceQuality.staticAnalysis\"], { cwd, stdio: \"inherit\" });\n\t\t\texecFn(\"pnpm\", [\"--filter\", pkg, \"verification.unitTests\"], { cwd, stdio: \"inherit\" });\n\t\t\tprint(\" ✓ scaffold verified\");\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\t\tprint(` ✗ verify failed — ${message}`);\n\t\t\tlogger.warn(\n\t\t\t\t{ slug: inputs.slug, files: filesWritten.length, reason: message, status: \"fail\" },\n\t\t\t\t\"plugin create: done\"\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tstatus: \"fail\",\n\t\t\t\tpackagePath: packageDir,\n\t\t\t\tfilesWritten,\n\t\t\t\tmessage: \"post-scaffold verify failed; inspect output above\",\n\t\t\t};\n\t\t}\n\t}\n\n\tif (!input.dryRun) {\n\t\tprintNextSteps(print, inputs);\n\t}\n\n\tlogger.info(\n\t\t{\n\t\t\tslug: inputs.slug,\n\t\t\tcapability: inputs.capability,\n\t\t\tfiles: filesWritten.length,\n\t\t\tstatus: input.dryRun ? \"dry-run\" : \"ok\",\n\t\t},\n\t\t\"plugin create: done\"\n\t);\n\treturn { status: \"ok\", packagePath: packageDir, filesWritten };\n}\n\n// ── Internals ───────────────────────────────────────────────────────\n\nfunction preflight(cwd: string): void {\n\tif (!existsSync(path.join(cwd, \"pnpm-workspace.yaml\"))) {\n\t\tthrow new PluginCreateError(\n\t\t\t`\\`pnpm-workspace.yaml\\` not found in \\`${cwd}\\`. Run \\`holocron plugin create\\` from the monorepo root.`\n\t\t);\n\t}\n\tif (!existsSync(path.join(cwd, \"packages\"))) {\n\t\tthrow new PluginCreateError(`\\`packages/\\` directory not found in \\`${cwd}\\`.`);\n\t}\n}\n\n/**\n * npm-package-name conventions: kebab-case, starts with lowercase\n * letter. Rejecting numeric-prefixed slugs also sidesteps the\n * `env.HOLOCRON_1FOO_TOKEN` invalid-identifier trap in the auth\n * template.\n */\nconst SLUG_RE = /^[a-z][a-z0-9-]*$/;\n\nfunction validateSlug(slug: string): void {\n\tif (!SLUG_RE.test(slug)) {\n\t\tthrow new PluginCreateError(\n\t\t\t`invalid slug \"${slug}\" — must be kebab-case: lowercase letter followed by lowercase letters, digits, or hyphens. ` +\n\t\t\t\t`Examples: \"clerk\", \"cloud-flare\", \"doppler\".`\n\t\t);\n\t}\n}\n\n/** PascalCase — starts with uppercase, alphanumeric only. */\nconst VENDOR_NAME_RE = /^[A-Z][a-zA-Z0-9]*$/;\n\nfunction validateVendorName(name: string): void {\n\tif (!VENDOR_NAME_RE.test(name)) {\n\t\tthrow new PluginCreateError(\n\t\t\t`invalid vendor name \"${name}\" — must be PascalCase: starts with uppercase, alphanumeric only. ` +\n\t\t\t\t`Examples: \"Clerk\", \"CloudFlare\", \"Doppler\".`\n\t\t);\n\t}\n}\n\n/**\n * Trim trailing slashes with a plain loop (no regex — matches the\n * rest.ts template's own trimming to stay ReDoS-safe under CodeQL).\n */\nfunction trimTrailingSlashes(url: string): string {\n\tlet out = url;\n\twhile (out.endsWith(\"/\")) out = out.slice(0, -1);\n\treturn out;\n}\n\nfunction validateCapability(capability: CapabilityKey, print: (line: string) => void): void {\n\tif (!(capability in CARDINALITY)) {\n\t\tthrow new PluginCreateError(\n\t\t\t`\\`${capability}\\` is not a known capability. See \\`packages/cli/src/capabilities/index.ts\\`.`\n\t\t);\n\t}\n\tif (CARDINALITY[capability] === \"many\") {\n\t\tprint(\n\t\t\t` ! ${capability} is a many-cardinality capability — multiple providers can be active at once. ` +\n\t\t\t\t\"Confirm your config wiring accordingly.\"\n\t\t);\n\t}\n}\n\nfunction defaultWrite(filepath: string, content: string): void {\n\tmkdirSync(path.dirname(filepath), { recursive: true });\n\twriteFileSync(filepath, content, \"utf8\");\n}\n\nfunction defaultExec(cmd: string, args: string[], opts: { cwd: string; stdio: \"inherit\" }): void {\n\texecFileSync(cmd, args, { cwd: opts.cwd, stdio: opts.stdio });\n}\n\nfunction printNextSteps(print: (line: string) => void, inputs: TemplateInputs): void {\n\tprint(\"\");\n\tprint(` Scaffolded @theholocron/holocron-plugin-${inputs.slug} (18 files).`);\n\tprint(\"\");\n\tprint(\" Next:\");\n\tprint(\n\t\t` 1. pnpm install # picks up the workspace package`\n\t);\n\tprint(` 2. pnpm --filter @theholocron/holocron-plugin-${inputs.slug} typecheck # green`);\n\tprint(` 3. pnpm --filter @theholocron/holocron-plugin-${inputs.slug} lint # green`);\n\tprint(\n\t\t` 4. pnpm --filter @theholocron/holocron-plugin-${inputs.slug} test # green (stubs pass, real tests are it.todo)`\n\t);\n\tprint(` 5. Implement ${inputs.capabilityClass} methods in src/capabilities/${inputs.capability}.ts`);\n\tprint(` 6. Replace it.todo(...) with real tests in src/__tests__/${inputs.capability}.test.ts`);\n\tprint(\" 7. Commit + push when capability is functionally complete.\");\n}\n","/**\n * `holocron publish --initial` — bottles up the chicken-and-egg bootstrap\n * that every new npm-published holocron monorepo hits.\n *\n * npm requires a package to exist before Trusted Publishing can be\n * configured on it. So the first publish has to happen outside the OIDC\n * flow — a browser-auth session (`npm login --auth-type=web`) or an\n * ephemeral automation token. This command drives the login step itself\n * (when `npm whoami` shows you're not authenticated), runs the publish\n * step, and tells you exactly what to do next.\n *\n * Workflow:\n *\n * $ pnpm install --frozen-lockfile\n * $ pnpm build\n * $ pnpm exec tsx packages/cli/src/cli.ts publish --initial\n *\n * `npm login --auth-type=web` runs automatically the first time — no\n * separate manual step. `pnpm install` + `pnpm build` stay outside the\n * command (no pnpm-inside-pnpm).\n *\n * `--initial` is required today — this command only implements the\n * bootstrap publish. A non-initial `holocron publish` (for a manual publish\n * outside the semantic-release/OIDC steady state) isn't built yet; the flag\n * exists so the surface doesn't need another rename when it is.\n *\n * If `NPM_TOKEN` is detected in env, the command prints a final\n * \"revoke this token at <url>\" reminder — same pattern as `rando vc\n * setup` for the ephemeral GH admin PAT.\n */\n\nimport { spawnSync } from \"node:child_process\";\nimport { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport { type CliEnv, makeEnv } from \"../env.js\";\nimport { getLogger } from \"../logger.js\";\n\nexport type PublishPrint = (line: string) => void;\n\nexport type PublishExecResult = {\n\texitCode: number;\n\tstdout: string;\n\tstderr: string;\n};\n\nexport interface RunPublishInput {\n\t/** Working directory (the monorepo or package root). Defaults to process.cwd(). */\n\tcwd?: string;\n\t/** Distribution tag for the publish. Defaults to `'alpha'`. */\n\ttag?: string;\n\t/** Skip the actual publish; print what would happen. */\n\tdryRun?: boolean;\n\t/**\n\t * One-time password (TOTP) from your authenticator app. Required if\n\t * your npm account has \"Require 2FA for read and write\" enabled.\n\t * Reused across all sequential publishes — they fire within a few\n\t * seconds, comfortably inside the TOTP window.\n\t */\n\totp?: string;\n\tprint?: PublishPrint;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n\t/**\n\t * Injectable command runner. Defaults to `spawnSync` with\n\t * `stdio: ['inherit', 'pipe', 'pipe']` so interactive prompts\n\t * (e.g., npm OTP) still work.\n\t *\n\t * Returns exit code + captured stdout/stderr.\n\t */\n\texec?: (cmd: string, args: string[], opts: { cwd: string }) => Promise<PublishExecResult>;\n\t/**\n\t * Injectable `npm login --auth-type=web` runner, invoked when `npm\n\t * whoami` shows no authenticated session. Fully `stdio: 'inherit'` (not\n\t * `exec`'s captured-output shape) — the browser flow prints a URL and\n\t * waits, and the operator needs to see that live. Defaults to a real\n\t * `spawnSync`.\n\t */\n\tlogin?: (cwd: string) => Promise<{ exitCode: number }>;\n\t/** Env vars; passed in for testability. Defaults to process.env. */\n\tenv?: NodeJS.ProcessEnv;\n\t/**\n\t * Override the list of package names shown in the Trusted Publisher\n\t * next-steps output. Auto-discovered from packages/*\\/package.json\n\t * (or the root package.json for a single-package repo) when omitted.\n\t */\n\tpackages?: readonly string[];\n\t/**\n\t * Override the repo name shown in the Trusted Publisher next-steps\n\t * output. Auto-detected from `git remote get-url origin` when omitted.\n\t */\n\trepoName?: string;\n}\n\nexport type PublishStatus = \"ok\" | \"fail\" | \"dry-run\";\n\nexport interface PublishReport {\n\tstatus: PublishStatus;\n\tmessage?: string;\n\t/** Packages that the publish step targeted. */\n\tpackageNames: readonly string[];\n}\n\nexport interface RunSyncTrustInput {\n\t/** Working directory (the monorepo or package root). Defaults to process.cwd(). */\n\tcwd?: string;\n\t/** The workflow filename npm's Trusted Publisher config currently points at. */\n\toldFile: string;\n\t/** The workflow filename to migrate every package's Trusted Publisher config to. */\n\tnewFile: string;\n\t/** `owner/repo` for the GitHub Trusted Publisher config. Defaults to `theholocron/holocron`. */\n\trepo?: string;\n\t/** Skip the actual npm calls; print what would happen. */\n\tdryRun?: boolean;\n\tprint?: PublishPrint;\n\tlogger?: Logger;\n\t/** Injectable command runner — same shape as `RunPublishInput['exec']`. */\n\texec?: (cmd: string, args: string[], opts: { cwd: string }) => Promise<PublishExecResult>;\n\t/** Override the list of package names. Auto-discovered when omitted. */\n\tpackages?: readonly string[];\n}\n\nexport interface SyncTrustPackageResult {\n\tname: string;\n\tstatus: \"ok\" | \"skipped\" | \"needs-auth\" | \"fail\";\n\tmessage?: string;\n}\n\nexport interface SyncTrustReport {\n\tstatus: PublishStatus;\n\tmessage?: string;\n\tpackages: readonly SyncTrustPackageResult[];\n}\n\ninterface NpmTrustEntry {\n\tid?: string;\n\tfile?: string;\n}\ninterface NpmTrustError {\n\terror?: { code?: string; authUrl?: string };\n}\n\n/**\n * `holocron publish --sync-trust <old-file> <new-file>` — bulk-migrates npm\n * Trusted Publisher (OIDC) config to a new workflow filename across every\n * public package. See issue #689 / `scripts/npm-trust-migrate.sh` (the\n * shell-script prototype this supersedes) for the full \"why\": npm ties\n * Trusted Publisher to a workflow FILENAME per package, so renaming the\n * release workflow breaks OIDC publish (`ENEEDAUTH`) until every package's\n * config is updated to match.\n *\n * Requires npm@11.15.0+ (`npm trust`) — always shells out through\n * `npx -y npm@latest` regardless of the locally-installed npm version.\n *\n * npm's `trust` mutations — and reads, once a short-lived OTP grant lapses —\n * require a fresh interactive browser 2FA approval (an `EOTP` error with an\n * `authUrl`). No token bypasses this (npm's own docs: Granular Access Tokens\n * with the bypass-2FA option are explicitly unsupported for trust commands).\n * This command can't drive that browser step itself, so on the first `EOTP`\n * it stops immediately, prints the `authUrl`, and returns — the operator\n * approves it and re-runs; already-migrated packages are skipped on the next\n * pass, so it's safe to resume from wherever it stopped.\n */\nexport async function runSyncTrust(input: RunSyncTrustInput): Promise<SyncTrustReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst cwd = input.cwd ?? process.cwd();\n\tconst repo = input.repo ?? \"theholocron/holocron\";\n\tconst dryRun = input.dryRun ?? false;\n\tconst exec = input.exec ?? defaultExec;\n\tconst packageNames = input.packages ?? discoverPublicPackages(cwd);\n\tconst npm = \"npx\";\n\tconst npmArgs = [\"-y\", \"npm@latest\"];\n\n\tprint(`Holocron publish --sync-trust${dryRun ? \" (dry-run)\" : \"\"}`);\n\tprint(` ${input.oldFile} -> ${input.newFile} (repo: ${repo})`);\n\tprint(` ${packageNames.length} public packages`);\n\tprint(\"\");\n\tlogger.info({ oldFile: input.oldFile, newFile: input.newFile, packages: packageNames.length }, \"sync-trust: start\");\n\n\tif (packageNames.length === 0) {\n\t\tconst message = \"nothing to sync (no packages/* and root package.json is private or unnamed)\";\n\t\tprint(` ✗ ${message}`);\n\t\treturn { status: \"fail\", message, packages: [] };\n\t}\n\n\tif (dryRun) {\n\t\tfor (const name of packageNames) print(` … would sync ${name}`);\n\t\treturn { status: \"dry-run\", message: \"dry-run — no npm calls made\", packages: [] };\n\t}\n\n\tconst results: SyncTrustPackageResult[] = [];\n\n\tfor (const name of packageNames) {\n\t\tprint(`=== ${name} ===`);\n\t\tconst listResult = await exec(npm, [...npmArgs, \"trust\", \"list\", name, \"--json\"], { cwd });\n\t\tconst parsed = parseJson(listResult.stdout);\n\n\t\tif (isEotp(parsed)) {\n\t\t\tconst authUrl = (parsed as NpmTrustError).error?.authUrl ?? \"\";\n\t\t\tprint(` needs fresh 2FA — open and approve: ${authUrl}`);\n\t\t\tprint(\" then re-run; already-migrated packages are skipped.\");\n\t\t\tresults.push({ name, status: \"needs-auth\", message: authUrl });\n\t\t\tlogger.warn({ package: name, authUrl }, \"sync-trust: needs auth, stopping\");\n\t\t\treturn { status: \"fail\", message: \"npm 2FA grant needed — see printed authUrl\", packages: results };\n\t\t}\n\n\t\tconst entry = parsed as NpmTrustEntry;\n\t\tif (entry.file === input.newFile) {\n\t\t\tprint(` already on ${input.newFile}, skipping`);\n\t\t\tresults.push({ name, status: \"skipped\" });\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (entry.id) {\n\t\t\tprint(` revoking existing trust (file=${entry.file ?? \"?\"}, id=${entry.id})`);\n\t\t\tconst revoke = await exec(npm, [...npmArgs, \"trust\", \"revoke\", name, \"--id\", entry.id, \"-y\"], { cwd });\n\t\t\tif (revoke.exitCode !== 0 && isEotp(parseJson(revoke.stdout))) {\n\t\t\t\tconst authUrl = (parseJson(revoke.stdout) as NpmTrustError).error?.authUrl ?? \"\";\n\t\t\t\tprint(` needs fresh 2FA — open and approve: ${authUrl}`);\n\t\t\t\tresults.push({ name, status: \"needs-auth\", message: authUrl });\n\t\t\t\treturn { status: \"fail\", message: \"npm 2FA grant needed — see printed authUrl\", packages: results };\n\t\t\t}\n\t\t} else {\n\t\t\tprint(\" no existing trust config found\");\n\t\t}\n\n\t\tprint(` creating trust: ${input.newFile}`);\n\t\tconst create = await exec(\n\t\t\tnpm,\n\t\t\t[\n\t\t\t\t...npmArgs,\n\t\t\t\t\"trust\",\n\t\t\t\t\"github\",\n\t\t\t\tname,\n\t\t\t\t\"--repo\",\n\t\t\t\trepo,\n\t\t\t\t\"--file\",\n\t\t\t\tinput.newFile,\n\t\t\t\t\"--allow-publish\",\n\t\t\t\t\"--allow-stage-publish\",\n\t\t\t\t\"-y\",\n\t\t\t],\n\t\t\t{ cwd }\n\t\t);\n\t\tif (create.exitCode === 0) {\n\t\t\tprint(\" ✓ ok\");\n\t\t\tresults.push({ name, status: \"ok\" });\n\t\t} else {\n\t\t\tconst createParsed = parseJson(create.stdout);\n\t\t\tif (isEotp(createParsed)) {\n\t\t\t\tconst authUrl = (createParsed as NpmTrustError).error?.authUrl ?? \"\";\n\t\t\t\tprint(` needs fresh 2FA — open and approve: ${authUrl}`);\n\t\t\t\tresults.push({ name, status: \"needs-auth\", message: authUrl });\n\t\t\t\treturn { status: \"fail\", message: \"npm 2FA grant needed — see printed authUrl\", packages: results };\n\t\t\t}\n\t\t\tconst message = create.stderr.trim() || create.stdout.trim() || `exit ${create.exitCode}`;\n\t\t\tprint(` ✗ FAILED: ${message}`);\n\t\t\tresults.push({ name, status: \"fail\", message });\n\t\t}\n\t}\n\n\tconst failed = results.filter((r) => r.status === \"fail\");\n\tlogger.info({ ok: results.filter((r) => r.status === \"ok\").length, failed: failed.length }, \"sync-trust: done\");\n\treturn {\n\t\tstatus: failed.length > 0 ? \"fail\" : \"ok\",\n\t\t...(failed.length > 0 ? { message: `${failed.length} package(s) failed` } : {}),\n\t\tpackages: results,\n\t};\n}\n\nfunction parseJson(raw: string): unknown {\n\ttry {\n\t\treturn JSON.parse(raw) as unknown;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction isEotp(parsed: unknown): boolean {\n\treturn (\n\t\ttypeof parsed === \"object\" &&\n\t\tparsed !== null &&\n\t\t\"error\" in parsed &&\n\t\t(parsed as NpmTrustError).error?.code === \"EOTP\"\n\t);\n}\n\nexport async function runPublish(input: RunPublishInput = {}): Promise<PublishReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst cwd = input.cwd ?? process.cwd();\n\tconst tag = input.tag ?? \"alpha\";\n\tconst dryRun = input.dryRun ?? false;\n\tconst otp = input.otp;\n\tconst env = makeEnv(input.env);\n\tconst exec = input.exec ?? defaultExec;\n\tconst login = input.login ?? defaultLogin;\n\n\t// Two repo layouts: a monorepo (`packages/*`, this repo's own shape) and a\n\t// single package at the root (most `node-template` scaffolds — no\n\t// `packages/` dir). `pnpm -r --filter=./packages/*` silently matches zero\n\t// workspaces in the latter and exits 0 — build the right invocation for\n\t// whichever layout is on disk. Shared between dry-run preview and the\n\t// real call so what we print is exactly what we'd run.\n\tconst isMonorepo = hasPackagesDir(cwd);\n\tconst publishArgs = [\n\t\t...(isMonorepo ? [\"-r\", \"--filter=./packages/*\"] : []),\n\t\t\"publish\",\n\t\t\"--access\",\n\t\t\"public\",\n\t\t\"--no-git-checks\",\n\t\t\"--tag\",\n\t\ttag,\n\t\t...(otp ? [\"--otp\", otp] : []),\n\t];\n\n\tprint(`Holocron publish --initial${dryRun ? \" (dry-run)\" : \"\"}`);\n\tprint(` cwd: ${cwd}`);\n\tprint(` tag: ${tag}`);\n\tlogger.info({ tag, dryRun: dryRun || undefined }, \"publish --initial: start\");\n\tif (otp) print(` otp: <${otp.length} chars>`);\n\tprint(\"\");\n\n\t// ── 1. Verify npm auth — log in automatically if not ────────────────\n\tprint(\" → verifying npm auth (`npm whoami`)…\");\n\tlet whoami = await exec(\"npm\", [\"whoami\"], { cwd });\n\tif (whoami.exitCode !== 0) {\n\t\tprint(\" not authenticated — running `npm login --auth-type=web`…\");\n\t\tlogger.info({}, \"publish --initial: npm login\");\n\t\tconst loginResult = await login(cwd);\n\t\tif (loginResult.exitCode !== 0) {\n\t\t\tconst message = \"npm login failed. Run `npm login --auth-type=web` (or `npm login`) manually, then re-run.\";\n\t\t\tprint(` ✗ ${message}`);\n\t\t\tconst packageNames = input.packages ?? discoverPublicPackages(cwd);\n\t\t\tlogger.warn({ reason: \"npm login failed\" }, \"publish --initial: done\");\n\t\t\treturn { status: \"fail\", message, packageNames };\n\t\t}\n\t\twhoami = await exec(\"npm\", [\"whoami\"], { cwd });\n\t\tif (whoami.exitCode !== 0) {\n\t\t\tconst message = \"npm login completed but `npm whoami` still fails — check your npm account.\";\n\t\t\tprint(` ✗ ${message}`);\n\t\t\tconst packageNames = input.packages ?? discoverPublicPackages(cwd);\n\t\t\tlogger.warn({ reason: \"npm whoami still fails after login\" }, \"publish --initial: done\");\n\t\t\treturn { status: \"fail\", message, packageNames };\n\t\t}\n\t}\n\tconst whoamiName = whoami.stdout.trim() || \"<unknown>\";\n\tprint(` ✓ authed as ${whoamiName}`);\n\n\t// ── 2. Resolve dynamic values needed for next-steps ─────────────────\n\tconst packageNames = input.packages ?? discoverPublicPackages(cwd);\n\tconst repoName = input.repoName ?? (await resolveRepoName(cwd, exec));\n\n\t// A `pnpm --filter=./packages/*` (or a bare `pnpm publish`) that matches\n\t// nothing still exits 0 — catch the no-op before it's mistaken for\n\t// success. Applies to dry-run too: the point is to diagnose the\n\t// misconfiguration, not just the real publish.\n\tif (packageNames.length === 0) {\n\t\tconst message = \"nothing to publish (no packages/* and root package.json is private or unnamed)\";\n\t\tprint(` ✗ ${message}`);\n\t\tlogger.warn({ reason: message }, \"publish --initial: done\");\n\t\treturn { status: \"fail\", message, packageNames };\n\t}\n\n\t// ── 3. Publish ──────────────────────────────────────────────────────\n\tif (dryRun) {\n\t\tprint(\"\");\n\t\tprint(\" … (dry-run) skipping actual publish\");\n\t\tprint(` would run: pnpm ${publishArgs.join(\" \")}`);\n\t\tprintNextSteps(print, env, packageNames, repoName);\n\t\tlogger.info({ tag, status: \"dry-run\", packages: packageNames.length }, \"publish --initial: done\");\n\t\treturn { status: \"dry-run\", message: \"dry-run — no publish executed\", packageNames };\n\t}\n\n\tprint(\"\");\n\tprint(\" → publishing all public @theholocron/* packages…\");\n\tconst publish = await exec(\"pnpm\", publishArgs, { cwd });\n\tif (publish.exitCode !== 0) {\n\t\tconst message = `publish failed (exit ${publish.exitCode}): ${publish.stderr.trim() || publish.stdout.trim() || \"no output\"}`;\n\t\tprint(` ✗ ${message}`);\n\t\t// Detect EOTP and surface the --otp hint right at the failure.\n\t\tif (publish.stdout.includes(\"EOTP\") || publish.stderr.includes(\"EOTP\")) {\n\t\t\tprint(\"\");\n\t\t\tprint(\" → hint: your npm account requires 2FA for writes. Re-run with `--otp <code>`:\");\n\t\t\tprint(` pnpm exec tsx packages/cli/src/cli.ts publish --initial --otp <6-digit-code>`);\n\t\t}\n\t\tlogger.warn({ tag, reason: message }, \"publish --initial: done\");\n\t\treturn { status: \"fail\", message, packageNames };\n\t}\n\tprint(\" ✓ publish complete\");\n\n\t// ── 4. Next-step reminders ──────────────────────────────────────────\n\tprintNextSteps(print, env, packageNames, repoName);\n\tlogger.info({ tag, status: \"ok\", packages: packageNames.length }, \"publish --initial: done\");\n\treturn { status: \"ok\", packageNames };\n}\n\nexport interface RunSteadyPublishInput {\n\t/** Working directory (the monorepo or package root). Defaults to process.cwd(). */\n\tcwd?: string;\n\t/** Distribution tag for the publish. Defaults to `'latest'` (steady-state releases are stable by default; `--initial`'s bootstrap default is `'alpha'`). */\n\ttag?: string;\n\t/** Skip the actual publish; print what would happen. */\n\tdryRun?: boolean;\n\totp?: string;\n\tprint?: PublishPrint;\n\tlogger?: Logger;\n\texec?: (cmd: string, args: string[], opts: { cwd: string }) => Promise<PublishExecResult>;\n\tenv?: NodeJS.ProcessEnv;\n\t/** Override the list of package names/versions. Auto-discovered when omitted. */\n\tpackages?: readonly PublicPackageEntry[];\n\t/** Add `--provenance`. Defaults to `true` — every steady-state publish runs in CI under OIDC, where provenance is free and expected. */\n\tprovenance?: boolean;\n\t/**\n\t * Check `npm view <pkg>@<version>` before publishing each package and\n\t * skip it if that exact version already exists, instead of one bulk\n\t * `pnpm -r publish`. For repos that ship many independently-versioned\n\t * packages where a release doesn't bump every one of them (this repo's\n\t * own lockstep-bump model doesn't need it — every package always gets a\n\t * new version together). Defaults to `false`.\n\t */\n\tskipAlreadyPublished?: boolean;\n}\n\n/**\n * `holocron publish` (no `--initial`) — the steady-state publish\n * `exec.publishCmd` in `release.config.ts` should call, replacing each\n * repo's hand-typed `pnpm -r --filter=./packages/* publish ...` shell (which\n * differs, today, only in monorepo-vs-single-package, provenance on/off, and\n * whether a repo needs to skip already-published packages) with one uniform\n * invocation. Part of the config-resolution workstream, #676 — see\n * `.notes/tech-config-resolution.spec.md`.\n *\n * Deliberately does not do the `--initial` bootstrap dance (npm\n * login-if-needed, Trusted Publisher next-steps printout) — a steady-state\n * publish runs in CI, authenticated via OIDC automatically, no interactive\n * step involved. Reuses `hasPackagesDir()`'s monorepo-vs-single-package\n * detection rather than duplicating it.\n */\nexport async function runSteadyPublish(input: RunSteadyPublishInput = {}): Promise<PublishReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst cwd = input.cwd ?? process.cwd();\n\tconst tag = input.tag ?? \"latest\";\n\tconst dryRun = input.dryRun ?? false;\n\tconst otp = input.otp;\n\tconst exec = input.exec ?? defaultExec;\n\tconst provenance = input.provenance ?? true;\n\tconst skipAlreadyPublished = input.skipAlreadyPublished ?? false;\n\tconst entries = input.packages ?? discoverPublicPackageEntries(cwd);\n\tconst packageNames = entries.map((e) => e.name);\n\n\tprint(`Holocron publish${dryRun ? \" (dry-run)\" : \"\"}`);\n\tprint(` cwd: ${cwd}`);\n\tprint(` tag: ${tag}`);\n\tprint(` provenance: ${provenance}`);\n\tif (skipAlreadyPublished) print(\" skip-already-published: true\");\n\tlogger.info({ tag, provenance, skipAlreadyPublished, dryRun: dryRun || undefined }, \"publish: start\");\n\tif (otp) print(` otp: <${otp.length} chars>`);\n\tprint(\"\");\n\n\tif (entries.length === 0) {\n\t\tconst message = \"nothing to publish (no packages/* and root package.json is private or unnamed)\";\n\t\tprint(` ✗ ${message}`);\n\t\tlogger.warn({ reason: message }, \"publish: done\");\n\t\treturn { status: \"fail\", message, packageNames };\n\t}\n\n\tconst baseFlags = [\"--access\", \"public\", \"--no-git-checks\", \"--tag\", tag, ...(provenance ? [\"--provenance\"] : [])];\n\tconst otpFlags = otp ? [\"--otp\", otp] : [];\n\n\tif (dryRun) {\n\t\tprint(\"\");\n\t\tif (skipAlreadyPublished) {\n\t\t\tfor (const entry of entries) {\n\t\t\t\tprint(` … would check ${entry.name}@${entry.version}, publish if not already on npm`);\n\t\t\t}\n\t\t} else {\n\t\t\tconst isMonorepo = hasPackagesDir(cwd);\n\t\t\tconst args = [...(isMonorepo ? [\"-r\", \"--filter=./packages/*\"] : []), \"publish\", ...baseFlags, ...otpFlags];\n\t\t\tprint(` … (dry-run) skipping actual publish`);\n\t\t\tprint(` would run: pnpm ${args.join(\" \")}`);\n\t\t}\n\t\tlogger.info({ tag, status: \"dry-run\", packages: entries.length }, \"publish: done\");\n\t\treturn { status: \"dry-run\", message: \"dry-run — no publish executed\", packageNames };\n\t}\n\n\tif (skipAlreadyPublished) {\n\t\tprint(\" → publishing packages not already on npm…\");\n\t\tfor (const entry of entries) {\n\t\t\tconst view = await exec(\"npm\", [\"view\", `${entry.name}@${entry.version}`, \"version\"], { cwd });\n\t\t\tif (view.exitCode === 0 && view.stdout.trim()) {\n\t\t\t\tprint(` skip ${entry.name}@${entry.version} (already published)`);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst publish = await exec(\"pnpm\", [\"--filter\", entry.dir, \"publish\", ...baseFlags, ...otpFlags], { cwd });\n\t\t\tif (publish.exitCode !== 0) {\n\t\t\t\tconst message = `publish failed for ${entry.name}@${entry.version} (exit ${publish.exitCode}): ${publish.stderr.trim() || publish.stdout.trim() || \"no output\"}`;\n\t\t\t\tprint(` ✗ ${message}`);\n\t\t\t\tlogger.warn({ tag, package: entry.name, reason: message }, \"publish: done\");\n\t\t\t\treturn { status: \"fail\", message, packageNames };\n\t\t\t}\n\t\t\tprint(` ✓ ${entry.name}@${entry.version}`);\n\t\t}\n\t\tlogger.info({ tag, status: \"ok\", packages: entries.length }, \"publish: done\");\n\t\treturn { status: \"ok\", packageNames };\n\t}\n\n\tprint(\" → publishing all public @theholocron/* packages…\");\n\tconst isMonorepo = hasPackagesDir(cwd);\n\tconst args = [...(isMonorepo ? [\"-r\", \"--filter=./packages/*\"] : []), \"publish\", ...baseFlags, ...otpFlags];\n\tconst publish = await exec(\"pnpm\", args, { cwd });\n\tif (publish.exitCode !== 0) {\n\t\tconst message = `publish failed (exit ${publish.exitCode}): ${publish.stderr.trim() || publish.stdout.trim() || \"no output\"}`;\n\t\tprint(` ✗ ${message}`);\n\t\tif (publish.stdout.includes(\"EOTP\") || publish.stderr.includes(\"EOTP\")) {\n\t\t\tprint(\"\");\n\t\t\tprint(\" → hint: your npm account requires 2FA for writes. Re-run with `--otp <code>`:\");\n\t\t\tprint(` pnpm exec holocron publish --otp <6-digit-code>`);\n\t\t}\n\t\tlogger.warn({ tag, reason: message }, \"publish: done\");\n\t\treturn { status: \"fail\", message, packageNames };\n\t}\n\tprint(\" ✓ publish complete\");\n\tlogger.info({ tag, status: \"ok\", packages: entries.length }, \"publish: done\");\n\treturn { status: \"ok\", packageNames };\n}\n\n// ── helpers ──────────────────────────────────────────────────────────\n\nfunction hasPackagesDir(cwd: string): boolean {\n\treturn existsSync(join(cwd, \"packages\"));\n}\n\n/** Read a `package.json`'s `name`, when it's public (`!private && name`). */\nfunction publicPackageName(pkgPath: string): string | undefined {\n\tif (!existsSync(pkgPath)) return undefined;\n\ttry {\n\t\tconst pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\")) as { name?: string; private?: boolean };\n\t\treturn !pkg.private && pkg.name ? pkg.name : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport interface PublicPackageEntry {\n\tname: string;\n\tversion: string;\n\t/** `pnpm --filter` target: `.` for a single-package repo, `./packages/<dir>` for a monorepo workspace. */\n\tdir: string;\n}\n\n/** Read a `package.json`'s `name` + `version`, when it's public (`!private && name`). */\nfunction publicPackageEntry(pkgPath: string, dir: string): PublicPackageEntry | undefined {\n\tif (!existsSync(pkgPath)) return undefined;\n\ttry {\n\t\tconst pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\")) as {\n\t\t\tname?: string;\n\t\t\tversion?: string;\n\t\t\tprivate?: boolean;\n\t\t};\n\t\treturn !pkg.private && pkg.name && pkg.version ? { name: pkg.name, version: pkg.version, dir } : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Same repo-layout detection as {@link discoverPublicPackages}, but carrying\n * version + a `pnpm --filter`-ready path — {@link runSteadyPublish}'s\n * `skipAlreadyPublished` mode needs both to check `npm view <pkg>@<version>`\n * and publish one workspace at a time.\n */\nfunction discoverPublicPackageEntries(cwd: string): readonly PublicPackageEntry[] {\n\tif (!hasPackagesDir(cwd)) {\n\t\tconst entry = publicPackageEntry(join(cwd, \"package.json\"), \".\");\n\t\treturn entry ? [entry] : [];\n\t}\n\tconst packagesDir = join(cwd, \"packages\");\n\treturn readdirSync(packagesDir, { withFileTypes: true })\n\t\t.filter((e) => e.isDirectory())\n\t\t.flatMap((e) => {\n\t\t\tconst entry = publicPackageEntry(join(packagesDir, e.name, \"package.json\"), `./packages/${e.name}`);\n\t\t\treturn entry ? [entry] : [];\n\t\t});\n}\n\n/**\n * Monorepo (`packages/` present): every public `packages/*` workspace.\n * Single package (no `packages/`): the root `package.json`, if it's public —\n * most `node-template` scaffolds are one package at the repo root.\n */\nfunction discoverPublicPackages(cwd: string): readonly string[] {\n\tif (!hasPackagesDir(cwd)) {\n\t\tconst name = publicPackageName(join(cwd, \"package.json\"));\n\t\treturn name ? [name] : [];\n\t}\n\tconst packagesDir = join(cwd, \"packages\");\n\treturn readdirSync(packagesDir, { withFileTypes: true })\n\t\t.filter((e) => e.isDirectory())\n\t\t.flatMap((e) => {\n\t\t\tconst name = publicPackageName(join(packagesDir, e.name, \"package.json\"));\n\t\t\treturn name ? [name] : [];\n\t\t});\n}\n\nasync function resolveRepoName(cwd: string, exec: NonNullable<RunPublishInput[\"exec\"]>): Promise<string> {\n\tconst result = await exec(\"git\", [\"remote\", \"get-url\", \"origin\"], { cwd });\n\tif (result.exitCode !== 0) return \"unknown\";\n\t// Matches both HTTPS (https://github.com/org/repo.git) and\n\t// SSH (git@github.com:org/repo.git) remote URL formats.\n\tconst match = /[/:]([^/:]+?)(?:\\.git)?$/.exec(result.stdout.trim());\n\treturn match?.[1] ?? \"unknown\";\n}\n\nfunction printNextSteps(print: PublishPrint, env: CliEnv, packageNames: readonly string[], repoName: string): void {\n\tprint(\"\");\n\tprint(\" → next: configure Trusted Publisher for each package on npm:\");\n\tfor (const name of packageNames) {\n\t\tprint(` https://www.npmjs.com/package/${name}/access`);\n\t}\n\tprint(` Publisher: GitHub Actions Org: theholocron Repo: ${repoName} Workflow: delivery.publish.yml`);\n\n\tif (env.get(\"NPM_TOKEN\")) {\n\t\tprint(\"\");\n\t\tprint(\" → cleanup: $NPM_TOKEN was used. Revoke it now (no API for self-revoke; UI-only):\");\n\t\tprint(\" https://www.npmjs.com/settings/~/tokens\");\n\t}\n}\n\nconst defaultExec: NonNullable<RunPublishInput[\"exec\"]> = async (cmd, args, opts) => {\n\tconst result = spawnSync(cmd, args, {\n\t\tcwd: opts.cwd,\n\t\tencoding: \"utf8\",\n\t\tstdio: [\"inherit\", \"pipe\", \"pipe\"],\n\t});\n\treturn {\n\t\texitCode: result.status ?? -1,\n\t\tstdout: result.stdout ?? \"\",\n\t\tstderr: result.stderr ?? \"\",\n\t};\n};\n\n/**\n * Fully interactive — `npm login --auth-type=web` prints a URL and waits for\n * the browser flow to complete; the operator needs to see that live, so all\n * three stdio streams are inherited (unlike `defaultExec`, which pipes\n * stdout/stderr for capture).\n */\nconst defaultLogin: NonNullable<RunPublishInput[\"login\"]> = async (cwd) => {\n\tconst result = spawnSync(\"npm\", [\"login\", \"--auth-type=web\"], { cwd, stdio: \"inherit\" });\n\treturn { exitCode: result.status ?? -1 };\n};\n","/**\n * `holocron secret set` — one-shot single-secret push.\n *\n * Complements `holocron secrets sync` (bulk vault → destinations) for\n * ad-hoc scenarios:\n * - Bootstrap secrets (e.g., NPM_TOKEN on theholocron/holocron itself\n * before the rest of the setup exists)\n * - One-off rotations that don't warrant a vault sync\n * - Setting secrets the vault doesn't track\n *\n * Value source resolution (in priority order):\n * 1. Positional `value` argument\n * 2. `--from-stdin` reads from stdin\n * 3. `--from-env <NAME>` reads from the named env var\n * 4. Implicit: env var matching the secret name (e.g., `NPM_TOKEN`)\n *\n * Errors clearly when no value can be sourced.\n */\n\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport type { LoadedConfig } from \"../config/load-config.js\";\nimport { env } from \"../env.js\";\nimport { getLogger } from \"../logger.js\";\nimport type { Secrets, SecretScope } from \"../plugin/capabilities.js\";\nimport { PluginLoader, type RuntimeContext } from \"../plugin/loader.js\";\nimport { assertPluginsResolvable } from \"../plugin/workspace.js\";\n\nexport type SecretSetPrint = (line: string) => void;\n\nexport interface RunSecretSetInput {\n\tloaded: LoadedConfig;\n\tcontext: RuntimeContext;\n\t/** Secret name (e.g., `NPM_TOKEN`). */\n\tname: string;\n\t/** Secret value. If absent, resolves via stdin / env. */\n\tvalue?: string;\n\t/** Read from stdin instead of positional or env var. */\n\tfromStdin?: boolean;\n\t/** Read from a specific env var rather than implicit-by-name. */\n\tfromEnv?: string;\n\t/** Defaults to `{ kind: 'repo' }`. */\n\tscope?: SecretScope;\n\tloader?: PluginLoader;\n\tprint?: SecretSetPrint;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n\t/** Lets tests inject a stdin reader. Defaults to reading process.stdin. */\n\treadStdin?: () => Promise<string>;\n}\n\nexport interface SecretSetReport {\n\tstatus: \"ok\" | \"fail\" | \"dry-run\";\n\tname: string;\n\tscope: SecretScope;\n\tmessage?: string;\n}\n\nexport async function runSecretSet(input: RunSecretSetInput): Promise<SecretSetReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst loader = input.loader ?? new PluginLoader(input.loaded.resolved, input.context);\n\tawait loader.load();\n\tassertPluginsResolvable(loader, \"secret set\");\n\n\tconst dryRun = input.context.dryRun ?? false;\n\tconst scope: SecretScope = input.scope ?? { kind: \"repo\" };\n\n\tif (!loader.has(\"secrets\")) {\n\t\tthrow new Error(\"`secrets` capability is not configured — add a `secrets` provider to holocron.config.json\");\n\t}\n\n\t// Resolve the value to push, surfacing a clear error when none can be sourced.\n\tconst value = await resolveValue(input);\n\tif (!value) {\n\t\tthrow new Error(\n\t\t\t`no value for secret \\`${input.name}\\` — pass it positionally, via --from-stdin, --from-env <NAME>, or set $${input.name} in the environment`\n\t\t);\n\t}\n\n\tprint(`Holocron secret set — ${input.name} (${describeScope(scope)})${dryRun ? \" (dry-run)\" : \"\"}`);\n\n\tif (dryRun) {\n\t\tconst message = `would: secrets.setSecret(${describeScope(scope)}, ${input.name}, <${value.length} chars>)`;\n\t\tprint(` … ${message}`);\n\t\treturn { status: \"dry-run\", name: input.name, scope, message };\n\t}\n\n\ttry {\n\t\tconst secrets = loader.get(\"secrets\") as Secrets;\n\t\tawait secrets.setSecret(scope, input.name, value);\n\t\tprint(` ✓ set ${input.name} via ${secrets.providerName}`);\n\t\t// `name` is a secret NAME, never the value.\n\t\tlogger.info(\n\t\t\t{ key: input.name, scope: describeScope(scope), provider: secrets.providerName, status: \"ok\" },\n\t\t\t`secret set: ${input.name}`\n\t\t);\n\t\treturn { status: \"ok\", name: input.name, scope };\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tprint(` ✗ ${message}`);\n\t\tlogger.warn({ key: input.name, scope: describeScope(scope), reason: message }, `secret set: ${input.name}`);\n\t\treturn { status: \"fail\", name: input.name, scope, message };\n\t}\n}\n\n// ── helpers ──────────────────────────────────────────────────────────\n\nasync function resolveValue(input: RunSecretSetInput): Promise<string | undefined> {\n\tif (input.value) return input.value;\n\tif (input.fromStdin) {\n\t\tconst reader = input.readStdin ?? defaultReadStdin;\n\t\tconst text = await reader();\n\t\treturn text.replace(/\\r?\\n$/, \"\"); // trim trailing newline\n\t}\n\tif (input.fromEnv) {\n\t\treturn env.get(input.fromEnv);\n\t}\n\t// Implicit: env var with the same name as the secret.\n\treturn env.get(input.name);\n}\n\nasync function defaultReadStdin(): Promise<string> {\n\tconst chunks: Buffer[] = [];\n\treturn new Promise<string>((resolve, reject) => {\n\t\tprocess.stdin.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n\t\tprocess.stdin.on(\"end\", () => resolve(Buffer.concat(chunks).toString(\"utf8\")));\n\t\tprocess.stdin.on(\"error\", reject);\n\t});\n}\n\nfunction describeScope(scope: SecretScope): string {\n\tif (scope.kind === \"repo\") return \"scope=repo\";\n\tif (scope.kind === \"environment\") return `scope=environment:${scope.name}`;\n\treturn `scope=organization:${scope.name}`;\n}\n","/**\n * `holocron secrets sync` — vault → destinations.\n *\n * Reads a named environment from the configured `vault` (1P\n * Environment / similar) as KEY=VALUE pairs, then fans those values\n * out to the configured destinations:\n *\n * - `secrets` capability (e.g., GH Actions secrets) — repo-scope\n * - `deployment` capability (e.g., Vercel env vars) — per-target\n * - local `.env` file (optional, planned for v5.1 — currently skipped\n * with a soft \"not yet\" note)\n *\n * Per-secret routing rules:\n *\n * - All keys go to `deployment` for each target the caller asks for\n * (defaults: production + preview)\n * - `secrets` (GH Actions) defaults to every key, repo-scoped — but a\n * caller can pass `githubSecretKeys` (an allowlist, from repeatable\n * `--github-secret KEY` CLI values) to restrict `secrets` to only\n * those keys, and `githubSecretScope` (same `{ kind }` shape `secret\n * set`'s own `--scope repo|env=NAME|org=NAME` parses to) to apply one\n * scope to all of them. A key not in the allowlist is skipped for\n * `secrets` entirely — still synced to `deployment` if configured.\n * Needed for a vault holding a mix of deploy-only secrets and one\n * CI-consumed, org-wide secret (holocron#781's Sentinel case: 4\n * Vercel-only keys + one org-scoped Axiom ingest token\n * `theholocron/.github`'s dispatched-check workflow also reads).\n *\n * The vault MUST implement `readEnvironment(envId)` (optional method).\n * If it doesn't, the command errors with a hint to populate the keys\n * individually via `holocron secret set` (also planned for v5.1).\n */\n\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport type { LoadedConfig } from \"../config/load-config.js\";\nimport { getLogger } from \"../logger.js\";\nimport type { Deployment, DeploymentTarget, Secrets, SecretScope, Vault } from \"../plugin/capabilities.js\";\nimport { PluginLoader, type RuntimeContext } from \"../plugin/loader.js\";\nimport { assertPluginsResolvable } from \"../plugin/workspace.js\";\nimport { withSpinner } from \"../ui/progress.js\";\nimport { style } from \"../ui/style.js\";\n\nexport type SyncPrintLine = (line: string) => void;\n\nexport type SyncRowStatus = \"ok\" | \"fail\" | \"dry-run\" | \"skip\";\n\nexport interface SyncRow {\n\tdestination: string;\n\t/** e.g., `target=production` for deployment, `scope=repo` for secrets. */\n\tscope: string;\n\tkey: string;\n\tstatus: SyncRowStatus;\n\tmessage?: string;\n}\n\nexport interface SyncReport {\n\trows: SyncRow[];\n\tsummary: { ok: number; fail: number; skip: number; dryRun: number };\n}\n\nexport interface RunSecretsSyncInput {\n\tloaded: LoadedConfig;\n\tcontext: RuntimeContext;\n\t/** Vault environment id to read. */\n\tenvironmentId: string;\n\t/** Deployment targets to sync to. Defaults to ['production', 'preview']. */\n\ttargets?: DeploymentTarget[];\n\t/** Vercel project id (or equivalent). Required if `deployment` is loaded. */\n\tprojectId?: string;\n\t/**\n\t * Allowlist restricting which vault keys reach `secrets`. Omit to push\n\t * every key (the default). See this module's own docstring.\n\t */\n\tgithubSecretKeys?: string[];\n\t/** Scope applied to every `githubSecretKeys` entry. Omit for `{ kind: \"repo\" }` (the default). */\n\tgithubSecretScope?: SecretScope;\n\tloader?: PluginLoader;\n\tprint?: SyncPrintLine;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n}\n\nexport async function runSecretsSync(input: RunSecretsSyncInput): Promise<SyncReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst loader = input.loader ?? new PluginLoader(input.loaded.resolved, input.context);\n\tawait withSpinner(\"Loading plugins…\", () => loader.load());\n\tassertPluginsResolvable(loader, \"secrets sync\");\n\n\tlogger.info(\n\t\t{ environment: input.environmentId, dryRun: (input.context.dryRun ?? false) || undefined },\n\t\t\"secrets sync: start\"\n\t);\n\n\tconst dryRun = input.context.dryRun ?? false;\n\tconst targets = input.targets ?? ([\"production\", \"preview\"] as DeploymentTarget[]);\n\n\tprint(style.header(`Holocron secrets sync — environment ${input.environmentId}${dryRun ? \" (dry-run)\" : \"\"}`));\n\tprint(style.dim(` vault: ${vaultProviderName(loader)}`));\n\tprint(\"\");\n\n\t// ── Read the vault ─────────────────────────────────────────────────\n\tconst vault = loader.get(\"vault\") as Vault;\n\tif (!vault.readEnvironment) {\n\t\tthrow new Error(\n\t\t\t`vault provider (${vault.providerName}) does not implement readEnvironment — sync needs bulk env reads`\n\t\t);\n\t}\n\tconst envVars = await withSpinner(`Reading vault environment ${input.environmentId}…`, () =>\n\t\tvault.readEnvironment!(input.environmentId)\n\t);\n\tconst keys = Object.keys(envVars).sort();\n\tprint(style.step(`read ${keys.length} keys from vault`));\n\tprint(\"\");\n\n\tconst rows: SyncRow[] = [];\n\n\t// ── Push to `secrets` (CI/Actions secrets) ─────────────────────────\n\tif (loader.has(\"secrets\")) {\n\t\tconst secrets = loader.get(\"secrets\") as Secrets;\n\t\tconst scope = input.githubSecretScope ?? { kind: \"repo\" };\n\t\tconst allowedKeys = input.githubSecretKeys ? new Set(input.githubSecretKeys) : undefined;\n\t\tprint(style.step(\"secrets\"));\n\t\tfor (const key of keys) {\n\t\t\t// No allowlist → every key (original default). With one → only\n\t\t\t// listed keys; an unlisted key is skipped for `secrets` entirely\n\t\t\t// (still reaches `deployment` above, if configured).\n\t\t\tif (allowedKeys && !allowedKeys.has(key)) continue;\n\n\t\t\trows.push(\n\t\t\t\tawait runRow(`secrets:${secrets.providerName}`, scopeLabel(scope), key, dryRun, async () => {\n\t\t\t\t\tawait secrets.setSecret(scope, key, envVars[key]!);\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatRow(rows[rows.length - 1]!));\n\t\t}\n\t}\n\n\t// ── Push to `deployment` (Vercel env vars) ─────────────────────────\n\tif (loader.has(\"deployment\")) {\n\t\tconst deploy = loader.get(\"deployment\") as Deployment;\n\t\tif (!input.projectId) {\n\t\t\tprint(style.step(\"deployment\"));\n\t\t\tconst row: SyncRow = {\n\t\t\t\tdestination: `deployment:${deploy.providerName}`,\n\t\t\t\tscope: \"no projectId\",\n\t\t\t\tkey: \"(all)\",\n\t\t\t\tstatus: \"skip\",\n\t\t\t\tmessage: \"projectId required for deployment env-var sync (pass --project-id)\",\n\t\t\t};\n\t\t\trows.push(row);\n\t\t\tprint(formatRow(row));\n\t\t} else {\n\t\t\tfor (const target of targets) {\n\t\t\t\tprint(style.step(`deployment (target=${target})`));\n\t\t\t\tfor (const key of keys) {\n\t\t\t\t\trows.push(\n\t\t\t\t\t\tawait runRow(`deployment:${deploy.providerName}`, `target=${target}`, key, dryRun, async () => {\n\t\t\t\t\t\t\tawait deploy.setEnvVar(input.projectId!, target, key, envVars[key]!);\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t\tprint(formatRow(rows[rows.length - 1]!));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (const r of rows) {\n\t\t// `key` is a secret NAME, never a value — safe to log. The logger also\n\t\t// redacts `secrets[*].value` shapes as defence in depth.\n\t\tlogger[r.status === \"fail\" ? \"warn\" : \"info\"](\n\t\t\t{\n\t\t\t\tdestination: r.destination,\n\t\t\t\tscope: r.scope,\n\t\t\t\tkey: r.key,\n\t\t\t\tstatus: r.status,\n\t\t\t\t...(r.message ? { detail: r.message } : {}),\n\t\t\t},\n\t\t\t`secrets sync: ${r.key} → ${r.destination}`\n\t\t);\n\t}\n\n\tconst summary = rows.reduce(\n\t\t(acc, r) => {\n\t\t\tif (r.status === \"ok\") acc.ok += 1;\n\t\t\telse if (r.status === \"fail\") acc.fail += 1;\n\t\t\telse if (r.status === \"skip\") acc.skip += 1;\n\t\t\telse if (r.status === \"dry-run\") acc.dryRun += 1;\n\t\t\treturn acc;\n\t\t},\n\t\t{ ok: 0, fail: 0, skip: 0, dryRun: 0 }\n\t);\n\n\tlogger[summary.fail > 0 ? \"warn\" : \"info\"]({ ...summary, keys: rows.length }, \"secrets sync: done\");\n\n\tprint(\"\");\n\tconst summaryLine = `${summary.ok} ok, ${summary.fail} fail, ${summary.skip} skipped${\n\t\tdryRun ? `, ${summary.dryRun} would-do` : \"\"\n\t}`;\n\tprint(summary.fail > 0 ? style.fail(summaryLine) : style.success(summaryLine));\n\n\treturn { rows, summary };\n}\n\n// ── helpers ──────────────────────────────────────────────────────────\n\nasync function runRow(\n\tdestination: string,\n\tscope: string,\n\tkey: string,\n\tdryRun: boolean,\n\tbody: () => Promise<void>\n): Promise<SyncRow> {\n\tif (dryRun) {\n\t\treturn { destination, scope, key, status: \"dry-run\" };\n\t}\n\ttry {\n\t\tawait body();\n\t\treturn { destination, scope, key, status: \"ok\" };\n\t} catch (err) {\n\t\treturn {\n\t\t\tdestination,\n\t\t\tscope,\n\t\t\tkey,\n\t\t\tstatus: \"fail\",\n\t\t\tmessage: err instanceof Error ? err.message : String(err),\n\t\t};\n\t}\n}\n\nfunction formatRow(row: SyncRow): string {\n\tconst detail = row.message ? style.dim(` (${row.message})`) : \"\";\n\tconst label = `${row.key}${detail}`;\n\tif (row.status === \"ok\") return ` ${style.success(label)}`;\n\tif (row.status === \"fail\") return ` ${style.fail(label)}`;\n\tif (row.status === \"dry-run\") return ` ${style.dim(`… ${label}`)}`;\n\treturn ` ${style.dim(`· ${label}`)}`;\n}\n\nfunction scopeLabel(scope: SecretScope): string {\n\tif (scope.kind === \"repo\") return \"scope=repo\";\n\tif (scope.kind === \"organization\") return `scope=organization,org=${scope.name}`;\n\treturn `scope=environment,env=${scope.name}`;\n}\n\nfunction vaultProviderName(loader: PluginLoader): string {\n\tif (!loader.has(\"vault\")) return \"<missing>\";\n\treturn (loader.get(\"vault\") as Vault).providerName;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport type { WorkspacePackage } from \"@theholocron/astromech\";\n\nimport type { ResolvedProvidersConfig } from \"../../config/config.js\";\n\n/**\n * Derived custom-properties (#677). Unlike the existing 6 GitHub\n * custom-properties fields (`lifecycle`, `open_source`, `runtime_environment`,\n * `uses_external_packages`, `monorepo`, `branch_protection_level`) — which\n * mirror what `holocron.config.ts` already states explicitly — these four are\n * *derived*: signal that isn't an explicit config field today (framework\n * choice, repo archetype, capability drift). See\n * `.notes/tech-holocron-platform.spec.md` → \"Custom-properties sync — field\n * definitions (#677)\" for the full design.\n */\n\n// \"plugin\" isn't produced by any heuristic below yet — no repo in the org\n// today is a standalone single-purpose plugin at the *repo* level (plugin\n// packages live inside `holocron`'s own `packages/holocron-plugin-*`, which\n// makes `holocron` itself \"platform\", not \"plugin\"). Kept in the union for a\n// future cross-org (`rando`, D10) repo that's nothing but one plugin.\nexport type HolocronProfile = \"library\" | \"cli\" | \"plugin\" | \"template\" | \"app\" | \"docs\" | \"platform\";\n\nexport interface PackageJsonLike {\n\tname?: string;\n\tprivate?: boolean;\n\tbin?: unknown;\n\tdependencies?: Record<string, string>;\n\tdevDependencies?: Record<string, string>;\n}\n\nexport interface DeriveProfileInput {\n\trootPackageJson: PackageJsonLike | null;\n\trepoName: string;\n\tisMonorepo: boolean;\n\t/** `packages/*` package.json contents, monorepo repos only — used to find the primary published artifact. */\n\tworkspacePackageJsons: PackageJsonLike[];\n}\n\n/**\n * Repo archetype, in priority order:\n * 1. `*-template` repo name → `template` (independent of package shape).\n * 2. Monorepo whose primary published artifact is a CLI (some workspace\n * package has `bin`) → `platform` — matches `holocron` itself: the CLI is\n * the deliverable, the plugin packages are supporting infrastructure for\n * it, not separate products.\n * 3. Monorepo with no CLI but at least one non-private workspace package →\n * `library` — matches `clients`/`configs`/`utils`/`themes`/\n * `observability`: a family of published packages, none of them a CLI.\n * Checked *before* falling into the root-package branch below, because\n * these repos' own root `package.json` is private and often carries\n * `@theholocron/astro-config` for a docs site built from the monorepo\n * root — without this check they'd wrongly resolve to `docs` off that\n * root-level signal alone, when the docs site is a secondary concern of\n * a library collection, not what the repo fundamentally is.\n * 4. Single-package repo with `package.json#bin` → `cli`.\n * 5. Docs-only site (astro/starlight present, root package private, no\n * publishable exports) → `docs`.\n * 6. Private, non-publishable, non-docs → `app`.\n * 7. Otherwise, a single publishable package → `library`.\n */\nexport function deriveProfile(input: DeriveProfileInput): HolocronProfile {\n\tif (/-template$/.test(input.repoName)) return \"template\";\n\n\tif (input.isMonorepo) {\n\t\tconst hasPublishedCli = input.workspacePackageJsons.some((pkg) => Boolean(pkg.bin));\n\t\tif (hasPublishedCli) return \"platform\";\n\n\t\tconst hasPublishedLibrary = input.workspacePackageJsons.some((pkg) => pkg.private !== true);\n\t\tif (hasPublishedLibrary) return \"library\";\n\t}\n\n\tconst pkg = input.rootPackageJson;\n\tif (pkg?.bin) return \"cli\";\n\n\tconst deps = { ...pkg?.dependencies, ...pkg?.devDependencies };\n\tconst isDocsSite = Boolean(deps[\"@theholocron/astro-config\"] || deps[\"astro\"]);\n\tif (pkg?.private && isDocsSite) return \"docs\";\n\tif (pkg?.private) return \"app\";\n\n\treturn \"library\";\n}\n\nconst KNOWN_STACK_DEPS = [\n\t\"next\",\n\t\"vite\",\n\t\"astro\",\n\t\"tsdown\",\n\t\"rollup\",\n\t\"webpack\",\n\t\"storybook\",\n\t\"vitest\",\n\t\"playwright\",\n\t\"turbo\",\n] as const;\n\n/**\n * Detected build/framework tooling — the literal \"does this repo need\n * next/vite/tsdown\" signal `holocron.config.ts` has no field for today\n * (framework choice isn't a config concept, unlike `providers`/`tasks`).\n * Curated table, not exhaustive by design — add to `KNOWN_STACK_DEPS` as new\n * frameworks show up rather than trying to detect anything on npm.\n */\nexport function deriveStack(pkg: PackageJsonLike | null): string[] {\n\tconst deps = { ...pkg?.dependencies, ...pkg?.devDependencies };\n\treturn KNOWN_STACK_DEPS.filter((name) => name in deps);\n}\n\n/** The provider capability keys actually wired in `providers: {}` — zero heuristics. */\nexport function deriveCapabilities(providers: ResolvedProvidersConfig | undefined): string[] {\n\treturn Object.keys(providers ?? {}).sort();\n}\n\n/**\n * `source` + `ci` are the minimal baseline every repo `holocron setup`\n * touches wires — every `holocron.config.ts` in this org already satisfies\n * this, so `non-compliant` here means drift (a provider manually removed\n * after setup), not an unmet aspirational policy. Deliberately not a richer\n * per-profile policy yet (e.g. \"a `library` must have `deployment`\") — that's\n * a Phase B (GitHub App) refinement once it can post *why* on a check run.\n */\nconst REQUIRED_BASELINE = [\"source\", \"ci\"] as const;\n\nexport function deriveCompliance(capabilities: readonly string[]): \"compliant\" | \"non-compliant\" {\n\treturn REQUIRED_BASELINE.every((key) => capabilities.includes(key)) ? \"compliant\" : \"non-compliant\";\n}\n\n/**\n * The Phase B refinement `deriveCompliance()`'s own doc comment names —\n * *why* a repo is non-compliant, not just that it is. `[]` when compliant.\n * Same `REQUIRED_BASELINE` `deriveCompliance()` checks against — one\n * table, not two independently-maintained baselines.\n */\nexport function missingCapabilities(capabilities: readonly string[]): string[] {\n\treturn REQUIRED_BASELINE.filter((key) => !capabilities.includes(key));\n}\n\n/**\n * Reads each workspace package's actual `package.json` content (not just\n * `readWorkspacePackages()`'s `{ slug, name, dir }` — `deriveProfile()`'s\n * `platform` detection needs `bin`, which that helper doesn't carry).\n * Missing/invalid files are skipped, matching `readWorkspacePackages()`'s\n * own soft-fail behavior.\n */\nexport async function readWorkspacePackageJsons(\n\trepoRoot: string,\n\tworkspacePackages: readonly WorkspacePackage[]\n): Promise<PackageJsonLike[]> {\n\tconst results: PackageJsonLike[] = [];\n\tfor (const { slug, dir = \"packages\" } of workspacePackages) {\n\t\ttry {\n\t\t\tconst raw = await readFile(join(repoRoot, dir, slug, \"package.json\"), \"utf8\");\n\t\t\tresults.push(JSON.parse(raw) as PackageJsonLike);\n\t\t} catch {\n\t\t\t// no package.json or invalid JSON — skip, same as readWorkspacePackages().\n\t\t}\n\t}\n\treturn results;\n}\n","export const CANONICAL_LABELS = [\n\t{ name: \"bug\", color: \"d73a4a\", description: \"Something isn't working\" },\n\t{ name: \"chore\", color: \"ededed\", description: \"Maintenance, no user-facing change\" },\n\t{ name: \"ci\", color: \"0075ca\", description: \"CI/CD pipeline changes\" },\n\t{ name: \"dependencies\", color: \"0366d6\", description: \"Dependency update\" },\n\t{ name: \"documentation\", color: \"0075ca\", description: \"Documentation only\" },\n\t{ name: \"duplicate\", color: \"cfd3d7\", description: \"Already reported\" },\n\t{ name: \"enhancement\", color: \"a2eeef\", description: \"New feature or request\" },\n\t{ name: \"good first issue\", color: \"7057ff\", description: \"Good for newcomers\" },\n\t{ name: \"help wanted\", color: \"008672\", description: \"Extra attention needed\" },\n\t{ name: \"invalid\", color: \"e4e669\", description: \"Doesn't seem right\" },\n\t{ name: \"performance\", color: \"fbca04\", description: \"Performance improvement\" },\n\t{ name: \"question\", color: \"d876e3\", description: \"Further information requested\" },\n\t{ name: \"refactor\", color: \"cfd3d7\", description: \"Code restructuring\" },\n\t{ name: \"released\", color: \"ededed\", description: \"Included in a release\" },\n\t{ name: \"test\", color: \"bfd4f2\", description: \"Test-related changes\" },\n\t{ name: \"triage\", color: \"e4e669\", description: \"Needs investigation\" },\n\t{ name: \"wontfix\", color: \"ffffff\", description: \"Won't be addressed\" },\n] as const;\n\nexport const STALE_LABELS = [\n\t\"github_actions\",\n\t\"javascript\",\n\t\"autorelease: pending\",\n\t\"autorelease: tagged\",\n\t\"released on @alpha\",\n];\n","# Configuration for sentiment-bot - https://github.com/behaviorbot/sentiment-bot\n\n# *Required* toxicity threshold between 0 and .99 with the higher numbers being the most toxic\n# Anything higher than this threshold will be marked as toxic and commented on\nsentimentBotToxicityThreshold: .7\n\n# *Required* Comment to reply with\nsentimentBotReplyComment: >\n Please be sure to review the [Code of Conduct](https://docs.theholocron.dev/reference/code-of-conduct/) and be respectful of other users.\n","/**\n * Factory that binds `source` and `tool` once and returns all header\n * constructors for auto-generated files. Prefer this over passing source\n * as a positional argument at every call site.\n *\n * @example\n * const { workflowHeader, scaffoldHeader } = createHeader({\n * source: \"packages/cli/src/templates/configs/editorconfig/create-config.ts\",\n * });\n *\n * export function createConfig(): string {\n * return `${workflowHeader()}${body}`;\n * }\n *\n * ## Which header to use\n *\n * | Function | When to use | User can edit? |\n * |-------------------|----------------------------------------------------|----------------|\n * | `workflowHeader` | Files overwritten on every setup / sync-github run | No — \"AUTO-GENERATED — do not edit\" |\n * | `scaffoldHeader` | Files written once; user takes ownership after | Yes — \"Scaffolded — edit this file freely\" |\n *\n * ## `workflowHeader` formats\n *\n * | Format | Comment style | Used for |\n * |---------------------|------------------------|-------------------------------------------------------|\n * | `\"yaml\"` (default) | `# …` lines | YAML workflows, ignore files, `.editorconfig`, labeler|\n * | `\"cjs\"` | `/* … *\\/` block | CommonJS config files (`.cjs`) |\n * | `\"shebang\"` | `#!/bin/sh` + `# …` | Shell scripts (`prepare-commit-msg`, hooks) |\n */\n\n/** Comment style produced by workflowHeader. */\nexport type WorkflowHeaderFormat = \"yaml\" | \"cjs\" | \"shebang\";\n\nexport interface CreateHeaderOptions {\n\t/** Path within theholocron/holocron that owns the file being generated. */\n\tsource: string;\n\t/** CLI command that produces the file. Defaults to \"holocron setup\". */\n\ttool?: string;\n\t/** Set true only when writing to theholocron/.github itself. */\n\tforPrimary?: boolean;\n}\n\nexport interface HeaderFunctions {\n\t/**\n\t * \"AUTO-GENERATED — do not edit\" header for files managed on every run.\n\t *\n\t * format:\n\t * \"yaml\" — `# …` comment lines (YAML, text, ignore files)\n\t * \"cjs\" — `/* … *\\/` block comment (CommonJS modules)\n\t * \"shebang\" — `#!/bin/sh` on line 1, then yaml header (shell scripts)\n\t */\n\tworkflowHeader(format?: WorkflowHeaderFormat): string;\n\t/**\n\t * \"Scaffolded — edit this file freely\" header for one-time generated files\n\t * that the user is expected to take over (e.g. codecov.yml).\n\t */\n\tscaffoldHeader(): string;\n}\n\nexport function createHeader(options: CreateHeaderOptions): HeaderFunctions {\n\tconst { source, tool = \"holocron setup\", forPrimary = false } = options;\n\n\tconst doNotEdit = forPrimary\n\t\t? `AUTO-GENERATED — do not edit in theholocron/.github directly.`\n\t\t: `AUTO-GENERATED — do not edit directly.`;\n\n\treturn {\n\t\tworkflowHeader(format: WorkflowHeaderFormat = \"yaml\"): string {\n\t\t\tif (format === \"cjs\") {\n\t\t\t\treturn [\n\t\t\t\t\t`/* ${doNotEdit}`,\n\t\t\t\t\t` * Source: theholocron/holocron · ${source}`,\n\t\t\t\t\t` * Tool: ${tool}`,\n\t\t\t\t\t` * Changes: edit source in theholocron/holocron`,\n\t\t\t\t\t` */`,\n\t\t\t\t\t``,\n\t\t\t\t].join(\"\\n\");\n\t\t\t}\n\n\t\t\tconst yamlLines = [\n\t\t\t\t`# ${doNotEdit}`,\n\t\t\t\t`# Source: theholocron/holocron · ${source}`,\n\t\t\t\t`# Tool: ${tool}`,\n\t\t\t\t`# Changes: edit source in theholocron/holocron`,\n\t\t\t\t``,\n\t\t\t].join(\"\\n\");\n\n\t\t\tif (format === \"shebang\") {\n\t\t\t\treturn `#!/bin/sh\\n\\n${yamlLines}`;\n\t\t\t}\n\n\t\t\treturn yamlLines;\n\t\t},\n\n\t\tscaffoldHeader(): string {\n\t\t\treturn [\n\t\t\t\t`# Scaffolded by holocron setup — edit this file freely.`,\n\t\t\t\t`# Source: theholocron/holocron · ${source}`,\n\t\t\t\t``,\n\t\t\t].join(\"\\n\");\n\t\t},\n\t};\n}\n",".github/*\nCHANGELOG.md\nLICENSE\n","","import { createHeader } from \"../../../utils/create-header.js\";\nimport alexignore from \"./alexignore\";\nimport alexrc from \"./alexrc.json\";\n\nconst { workflowHeader } = createHeader({\n\tsource: \"packages/cli/src/templates/configs/alexjs/create-config.ts\",\n});\n\nexport function createRcConfig(): string {\n\treturn JSON.stringify(alexrc, null, 2) + \"\\n\";\n}\n\nexport function createIgnoreConfig(): string {\n\treturn `${workflowHeader()}${alexignore}`;\n}\n","__HOLOCRON_SCRIPT__ lint commit-msg \"$1\"\n","import { createHeader } from \"../../../utils/create-header.js\";\nimport commitMsgBody from \"./commit-msg\";\n\nconst { workflowHeader } = createHeader({\n\tsource: \"packages/cli/src/templates/configs/commit-msg/create-config.ts\",\n});\n\n/**\n * `.husky/commit-msg` — lints the commit message via `holocron lint\n * commit-msg` (holocron#789), the real programmatic replacement for\n * shelling out to `commitlint --edit`. Installed by `holocron setup` when\n * hooks are enabled. Same `__HOLOCRON_SCRIPT__` substitution as `pre-push`.\n *\n * @param holocronScript - the command that invokes the CLI. Defaults to\n * `pnpm exec holocron`; the source repo passes `node packages/cli/dist/cli.mjs`.\n */\nexport function createConfig(holocronScript = \"pnpm exec holocron\"): string {\n\treturn `${workflowHeader(\"shebang\")}${commitMsgBody.replace(\"__HOLOCRON_SCRIPT__\", holocronScript)}`;\n}\n","import { createHeader } from \"../../../utils/create-header.js\";\n\nconst { workflowHeader } = createHeader({\n\tsource: \"packages/cli/src/templates/configs/devmoji/create-config.ts\",\n});\n\nexport function createConfig(): string {\n\treturn [\n\t\tworkflowHeader(\"cjs\"),\n\t\t`/* eslint-disable */`,\n\t\t`const { defineConfig } = require(\"@theholocron/devmoji-config\");`,\n\t\t`module.exports = defineConfig();`,\n\t\t``,\n\t].join(\"\\n\");\n}\n","root = true\n\n[*]\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\nindent_style = tab\nindent_size = 4\n\n[.gitattributes]\nindent_style = space\nindent_size = 2\n\n[*.{json,yml,yaml}]\nindent_style = space\nindent_size = 2\n\n[*.{md,mdx}]\ntrim_trailing_whitespace = false\nindent_style = unset\n\n[.*{rc,ignore}]\nindent_style = space\nindent_size = 2\n","import { createHeader } from \"../../../utils/create-header.js\";\nimport editorconfigBody from \"./editorconfig\";\n\nconst { workflowHeader } = createHeader({\n\tsource: \"packages/cli/src/templates/configs/editorconfig/create-config.ts\",\n});\n\nexport function createConfig(): string {\n\treturn `${workflowHeader()}${editorconfigBody}`;\n}\n","","import editorconfigChecker from \"./editorconfig-checker.json\";\n\n/**\n * The generated `.editorconfig-checker.json`.\n *\n * Deliberately carries no `\"Version\"` key: editorconfig-checker treats it as a\n * hard gate and exits non-zero the moment the running binary's version differs\n * — which it does the instant a contributor's local install (Homebrew tracks\n * latest) drifts from the version super-linter bundles in CI, breaking\n * `holocron run lint` / the pre-push hook for everyone (#618). The config\n * options here (`Exclude`, `Disable`) are stable across releases, so pinning\n * buys nothing.\n */\nexport function createConfig(): string {\n\treturn JSON.stringify(editorconfigChecker, null, 2) + \"\\n\";\n}\n","# Run GitLeaks against staged changes only — a full `gitleaks git` history\n# scan re-flags every pre-existing (already-merged) finding on every commit,\n# permanently blocking the repo once any false positive lands in history.\n# CI's super-linter GITLEAKS validator is likewise scoped to changed files.\ngitleaks protect --staged --no-banner\n\n# Exit with non-zero if secrets are detected by GitLeaks\nif [ $? -ne 0 ]; then\n\techo \"Secrets detected by GitLeaks, aborting commit!\"\n\texit 1\nfi\n\n# Run lint-staged with a custom config\nnpx lint-staged --config @theholocron/lint-staged-config\n","import { createHeader } from \"../../../utils/create-header.js\";\nimport preCommitBody from \"./pre-commit\";\n\nconst { workflowHeader } = createHeader({\n\tsource: \"packages/cli/src/templates/configs/pre-commit/create-config.ts\",\n});\n\n/**\n * `.husky/pre-commit` — runs GitLeaks (scoped to staged changes) and\n * lint-staged before every commit. Installed by `holocron setup` when hooks\n * are enabled (default for `protection: \"strict\"`). `git commit --no-verify`\n * bypasses it.\n *\n * `gitleaks protect --staged` (not `gitleaks git`) is deliberate: the latter\n * scans the entire commit history on every invocation, so once any false\n * positive lands in a past commit — a fake test token, an example key in a\n * doc — every future commit is permanently blocked, regardless of what's\n * actually staged.\n */\nexport function createConfig(): string {\n\treturn `${workflowHeader(\"shebang\")}${preCommitBody}`;\n}\n","# Run the merge-gating checks locally before pushing — the same set CI runs.\n# Bypass once with: git push --no-verify\n\n# CI runners (semantic-release, super-linter auto-commit, bots) push without a\n# built dev environment — the hook has nothing to add there.\n[ -n \"$CI\" ] && exit 0\n\n__HOLOCRON_SCRIPT__ ci\n","import { createHeader } from \"../../../utils/create-header.js\";\nimport prePushBody from \"./pre-push\";\n\nconst { workflowHeader } = createHeader({\n\tsource: \"packages/cli/src/templates/configs/pre-push/create-config.ts\",\n});\n\n/**\n * `.husky/pre-push` — runs `holocron ci` (the merge-gating checks, in CI order)\n * before every push. Installed by `holocron setup` when hooks are enabled\n * (default for `protection: \"strict\"`). `git push --no-verify` bypasses it.\n *\n * @param holocronScript - the command that invokes the CLI. Defaults to\n * `pnpm exec holocron`; the source repo passes `node packages/cli/dist/cli.mjs`.\n */\nexport function createConfig(holocronScript = \"pnpm exec holocron\"): string {\n\treturn `${workflowHeader(\"shebang\")}${prePushBody.replace(\"__HOLOCRON_SCRIPT__\", holocronScript)}`;\n}\n","NAME=$(git config user.name)\nEMAIL=$(git config user.email)\n\nif [ -z \"$NAME\" ]; then\n\techo \"empty git config user.name\"\n\texit 1\nfi\n\nif [ -z \"$EMAIL\" ]; then\n\techo \"empty git config user.email\"\n\texit 1\nfi\n\ngit interpret-trailers --if-exists doNothing --trailer \\\n\t\"Signed-off-by: $NAME <$EMAIL>\" \\\n\t--in-place \"$1\"\n\n# --config <resolved shared path> (config-resolution workstream, #676) — falls\n# back to devmoji's own auto-discovery of a local devmoji.config.cjs when the\n# shared package's built dist/ isn't present (not installed, or a stale\n# install predating this file).\nDEVMOJI_CONFIG=\"node_modules/@theholocron/devmoji-config/dist/index.cjs\"\nif [ -f \"$DEVMOJI_CONFIG\" ]; then\n\tnpx devmoji --config \"$DEVMOJI_CONFIG\" -e\nelse\n\tnpx devmoji -e\nfi\n","import { createHeader } from \"../../../utils/create-header.js\";\nimport prepareCommitMsgBody from \"./prepare-commit-msg\";\n\nconst { workflowHeader } = createHeader({\n\tsource: \"packages/cli/src/templates/configs/prepare-commit-msg/create-config.ts\",\n});\n\nexport function createConfig(): string {\n\treturn `${workflowHeader(\"shebang\")}${prepareCommitMsgBody}`;\n}\n","pnpm-lock.yaml\n","---\nextends: default\n\nignore-from-file:\n - .gitignore\n - .yamlignore\n\nrules:\n comments:\n min-spaces-from-content: 1\n require-starting-space: true\n\n comments-indentation: {}\n\n document-start:\n ignore: |\n .github/*.yml\n\n indentation:\n spaces: consistent\n indent-sequences: consistent\n\n line-length: disable\n","import { createHeader } from \"../../../utils/create-header.js\";\nimport yamlignoreBody from \"./.yamlignore\";\nimport yamllintBody from \"./.yamllint.yml\";\n\nconst { workflowHeader } = createHeader({\n\tsource: \"packages/cli/src/templates/configs/yamllint/create-config.ts\",\n});\n\nexport function createConfig(): string {\n\treturn `${workflowHeader()}${yamllintBody}`;\n}\n\nexport function createIgnoreConfig(): string {\n\treturn `${workflowHeader()}${yamlignoreBody}`;\n}\n","allowRemediationCommits:\n individual: true\n","version: 2\nupdates:\n - package-ecosystem: npm\n directory: /\n schedule:\n interval: weekly\n commit-message:\n prefix: \"chore(deps)\"\n prefix-development: \"chore(deps-dev)\"\n groups:\n security-patches:\n applies-to: security-updates\n patterns:\n - \"*\"\n all-dependencies:\n update-types:\n - minor\n - patch\n\n - package-ecosystem: github-actions\n directory: /\n schedule:\n interval: weekly\n commit-message:\n prefix: \"chore(deps)\"\n groups:\n all-actions:\n patterns:\n - \"*\"\n","bug:\n - \"^fix\"\n\nchore:\n - '^chore(?!\\(deps)'\n\nci:\n - \"^ci\"\n\ndependencies:\n - '^chore\\(deps'\n\ndocumentation:\n - \"^docs\"\n\nenhancement:\n - \"^feat\"\n\nperformance:\n - \"^perf\"\n\nrefactor:\n - \"^refactor\"\n\ntest:\n - \"^test\"\n","---\nid: ADR-XXXX\ntitle: \"\"\nstatus: proposed\ndate: YYYY-MM-DD\nowners: []\nspecs: []\ndiscussion:\n github:\nsupersedes: []\nsuperseded-by: []\ntags: []\n---\n\n# [Short title of the decision]\n\n- Status: [proposed | accepted | rejected | deprecated | superseded by ADR-XXXX]\n- Date: YYYY-MM-DD\n\n## Context and Problem Statement\n\n2–3 sentences describing the situation that forced this decision.\n\n## Decision Drivers\n\n- [driver 1 — a constraint, goal, or value]\n- [driver 2]\n\n## Considered Options\n\n- [Option A]\n- [Option B]\n- [Option C — do nothing]\n\n## Decision Outcome\n\nChosen option: **[Option A]**, because [one-sentence justification].\n\n### Positive Consequences\n\n- …\n\n### Negative Consequences\n\n- …\n\n## Pros and Cons of the Options\n\n### [Option A]\n\n- Good, because [argument]\n- Bad, because [argument]\n\n### [Option B]\n\n- Good, because [argument]\n- Bad, because [argument]\n","/**\n * Canonical AI engineering workflow role prompts.\n *\n * Written to `.agents/prompts/<role>.md` by `holocron setup` when `agent` is\n * configured. Paths are gitignored and regenerated on every setup run so the\n * content always reflects the current CLI version.\n *\n * Source: docs/wiki/specifications/ai-engineering-workflow.spec.md\n */\n\nimport decisionsTemplate from \"../../templates/decisions-template.md\";\n\nexport const DECISIONS_TEMPLATE = decisionsTemplate;\n\nexport const AGENT_PROMPTS: Record<string, string> = {\n\t\"discovery.md\": `# Discovery Agent\n\nYou are performing engineering discovery.\n\nYour goal is to understand the problem and the existing system before\nproposing implementation changes.\n\nRead the relevant issue, repository code, documentation, specifications,\nand ADRs.\n\nInvestigate:\n- current behavior\n- relevant architecture\n- dependencies\n- constraints\n- existing patterns\n- affected packages/services\n- compatibility concerns\n- security concerns\n- operational concerns\n\nDo not implement anything.\nDo not assume the proposed solution is correct.\n\nProduce:\n1. Problem summary\n2. Current system behavior\n3. Relevant architecture\n4. Constraints\n5. Systems/packages likely affected\n6. Unknowns or open questions\n7. Risks\n8. Decisions that may require architectural discussion\n9. Recommended next step\n\nIf you discover a meaningful architectural choice, explicitly identify it\nrather than silently making the decision.\n`,\n\n\t\"design.md\": `# Design Agent\n\nYou are acting as a software architect.\n\nUsing the issue, discovery findings, existing architecture, specifications,\nand ADRs, propose a design for this change.\n\nDo not write implementation code.\n\nIdentify the important engineering decisions required.\n\nFor each meaningful decision:\n1. Explain the decision that must be made.\n2. Describe viable alternatives.\n3. Explain advantages and disadvantages.\n4. Identify operational and maintenance consequences.\n5. Recommend an approach and explain why.\n\nTreat existing accepted ADRs as architectural constraints.\nDo not contradict an accepted ADR without explicitly identifying the conflict.\n\nAt the end, produce:\n- Recommended design\n- Open questions\n- Decisions requiring ADRs\n- Decisions that are implementation details and do not require ADRs\n- Suggested specification scope\n\nDo not create ADRs merely because a choice exists. An ADR is warranted only\nwhen the decision is significant enough that a future engineer may reasonably\nask why one approach was selected over another.\n`,\n\n\t\"discussion.md\": `# Discussion / RFC Agent\n\nConvert the design analysis into a GitHub Discussion suitable for engineering\nreview.\n\nInclude:\n\n# Problem\n# Context\n# Constraints\n\n# Options\nFor each option:\n- description\n- advantages\n- disadvantages\n- operational consequences\n- implementation complexity\n\n# Recommended Direction\nState the recommendation clearly as a proposal, not a decision.\n\n# Open Questions\n# Decision Requested\n\nAvoid implementation-level details unless they materially affect the\narchitectural choice.\n`,\n\n\t\"adr.md\": `# ADR Author\n\nCreate an Architecture Decision Record from the accepted engineering decision.\n\nUse the accepted GitHub Discussion as the primary source of decision history.\n\nCapture the final architectural conclusion, not the full discussion.\n\nInclude:\n- Title\n- Status\n- Date\n- Context\n- Decision\n- Rationale\n- Alternatives considered\n- Consequences\n- Related issue, Discussion, and specifications\n\nClearly distinguish between the final decision, supporting rationale, and\nalternatives that were rejected.\n\nDo not introduce new architectural decisions.\n\nIf the Discussion does not contain enough information to state a decision\nconfidently, identify the missing information instead of inventing it.\n\n## Format\n\nUse MADR format. Copy the template and number sequentially:\n\n\\`\\`\\`sh\ncp docs/wiki/decisions/template.md docs/wiki/decisions/000N-short-title.md\n\\`\\`\\`\n\nSave to \\`docs/wiki/decisions/NNNN-<slug>.md\\`.\n`,\n\n\t\"spec.md\": `# Specification Agent\n\nYou are acting as a technical specification author.\n\nCreate a specification for the requested capability using:\n- the GitHub issue\n- accepted design decisions\n- accepted ADRs\n- existing system behavior\n- relevant repository documentation\n\nTreat accepted ADRs as architectural constraints.\n\nThe specification should describe WHAT the system must do, not how to implement it.\n\nInclude:\n- Objective\n- Background\n- Goals / Non-goals\n- Existing behavior\n- Required behavior\n- Interfaces\n- Data model\n- Validation\n- State transitions\n- Error handling\n- Authorization / security\n- Observability\n- Compatibility requirements\n- Edge cases\n- Testing requirements\n- Acceptance criteria\n- Related ADRs and issues\n\nThe specification should be detailed enough that another engineer or AI agent\ncould implement the feature without seeing the original planning conversation.\n\nIMPORTANT: Do not silently make new architectural decisions. If the specification\nrequires a decision that has not been established, mark it as an unresolved\ndesign question and surface it for discussion.\n\n## Process rule\n\nFile a GitHub issue BEFORE writing the spec. The spec's frontmatter \\`issue:\\`\nfield must reference it. Order: Issue → Spec → PR → Review → merge.\n`,\n\n\t\"implementation-plan.md\": `# Implementation Planner\n\nYou are acting as an implementation planner.\n\nTreat the accepted specification and ADRs as authoritative.\n\nInspect the repository and produce a concrete implementation plan for\nsatisfying the specification. Do not redesign the feature.\n\nIdentify:\n- packages/services affected\n- files likely affected\n- new files required\n- schema changes and migrations\n- API changes\n- configuration changes\n- tests required\n- observability changes\n- documentation changes\n- deployment or rollout requirements\n\nProduce an ordered implementation plan. Each step should include:\n1. Goal\n2. Files or modules affected\n3. Expected change\n4. Tests required\n5. Dependencies on earlier steps\n\nIdentify tasks that can safely be implemented in parallel.\n\nIf repository reality conflicts with the specification or ADRs, stop that\nportion of the plan and explicitly describe the conflict. Do not silently\nalter the design to work around it.\n`,\n\n\t\"implement.md\": `# Implementation Agent\n\nYou are implementing an accepted engineering specification.\n\nAuthority order:\n1. Accepted ADRs\n2. Accepted specification\n3. Approved implementation plan\n4. Existing repository conventions\n\nImplement the approved plan.\n\nDo not change product behavior described by the specification.\nDo not contradict accepted ADRs.\nDo not introduce new architectural patterns unless required by the specification.\nFollow existing repository conventions where they do not conflict with the spec.\n\nFor each implementation step:\n- make the required change\n- add or update tests\n- preserve backward compatibility where required\n- add appropriate observability\n- update relevant documentation\n\nIf you discover that repository reality makes the specification impossible or\nrequires a new architectural decision:\n\nSTOP that portion of implementation.\n\nDescribe:\n- what the specification requires\n- what the repository currently supports\n- why they conflict\n- what decision is required\n\nDo not silently invent a new design.\n`,\n\n\t\"review.md\": `# Review Agent\n\nYou are acting as an independent engineering reviewer.\n\nReview the implementation against:\n1. The GitHub issue\n2. Accepted ADRs\n3. The accepted specification\n4. The implementation plan\n5. Repository conventions\n\nDo not assume the implementation is correct simply because tests pass.\n\nEvaluate:\n\n## Specification Compliance\nIdentify every requirement in the specification and determine whether it is\nimplemented.\n\n## ADR Compliance\nIdentify any behavior or architecture that conflicts with accepted ADRs.\n\n## Correctness\nLook for logical errors, invalid state transitions, race conditions, missing\nvalidation, and incorrect assumptions.\n\n## Security\nReview authentication, authorization, data exposure, input handling, and\ntrust boundaries.\n\n## Failure Behavior\nReview errors, retries, partial failures, rollback behavior, and recovery.\n\n## Observability\nConfirm appropriate logs, metrics, traces, and diagnostic information.\n\n## Compatibility\nCheck backward compatibility and migration behavior.\n\n## Testing\nIdentify missing test cases — especially failure paths, boundary conditions,\nauthorization, state transitions, concurrency, and regression cases.\n\n## Scope\nIdentify unrelated changes or unnecessary complexity.\n\nProduce findings ordered by severity. For each finding include:\n- severity\n- location\n- violated requirement or principle\n- explanation\n- recommended correction\n\nFinally provide:\n- specification requirements fully satisfied\n- specification requirements partially satisfied\n- specification requirements missing\n- ADR violations\n- overall recommendation\n`,\n\n\t\"verify.md\": `# Verification Agent\n\nVerify this implementation against the accepted specification.\n\nTreat each acceptance criterion as independently testable.\n\nCreate a requirement matrix containing:\n- requirement\n- implementation location\n- test coverage\n- status (PASS | PARTIAL | FAIL | NOT TESTED)\n- notes\n\nDo not infer compliance merely because related code exists.\nVerify the actual behavior where possible.\nIdentify any specification language that is ambiguous or impossible to verify.\n`,\n};\n\nexport const DECISIONS_README = `# Decisions\n\nArchitectural Decision Records live here. Each file captures one architectural\ndecision, the options that were considered, and the rationale for the choice made.\n\n## Creating a new decision\n\nCopy the template and number it sequentially:\n\n\\`\\`\\`sh\ncp docs/wiki/decisions/template.md docs/wiki/decisions/000N-short-title.md\n\\`\\`\\`\n\n\\`madr\\` has no CLI — creation is manual. Frontmatter is validated in CI\nvia \\`scripts/validate-adrs.mjs\\` (runs as part of the Lint workflow).\n\n## Status values\n\n| Status | Meaning |\n| ------------ | --------------------------------------------- |\n| \\`proposed\\` | Under discussion — not yet accepted |\n| \\`accepted\\` | In effect |\n| \\`rejected\\` | Considered and declined |\n| \\`deprecated\\` | Was accepted; no longer relevant |\n| \\`superseded\\` | Replaced by a later decision (link in frontmatter) |\n\n## Index\n\n| ID | Title | Status |\n| -- | ----- | ------ |\n`;\n\nexport const STANDARDS_README = `# Standards\n\nOrg-wide engineering standards — conventions, practices, and guidelines that\napply across all repos in the org.\n\n> **Drafts** live in \\`.notes/\\` until accepted, then graduate here.\n`;\n\nexport const SPECIFICATIONS_README = `# Specifications\n\nAccepted specs for planned or in-progress features. Each spec captures what\nthe system must do — not how to implement it.\n\n> **Drafts** live in \\`.notes/*.spec.md\\` until accepted, then graduate here.\n`;\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { AGENT_PROMPTS } from \"./agent-prompts-data.js\";\n\nconst AGENTS_PROMPTS_ROOT = \".agents/prompts\";\nconst PROMPTS_GITIGNORE_START = \"# managed by holocron setup — prompts\";\nconst PROMPTS_GITIGNORE_END = \"# end managed by holocron setup — prompts\";\n\nexport async function installAgentPrompts({ repoRoot }: { repoRoot: string }): Promise<string> {\n\tconst promptsDir = join(repoRoot, AGENTS_PROMPTS_ROOT);\n\tawait mkdir(promptsDir, { recursive: true });\n\n\tfor (const [filename, content] of Object.entries(AGENT_PROMPTS)) {\n\t\tawait writeFile(join(promptsDir, filename), content, \"utf8\");\n\t}\n\n\tconst gitignorePath = join(repoRoot, \".gitignore\");\n\tconst existing = await readFile(gitignorePath, \"utf8\").catch(() => \"\");\n\tconst block = [PROMPTS_GITIGNORE_START, `/${AGENTS_PROMPTS_ROOT}/`, PROMPTS_GITIGNORE_END].join(\"\\n\");\n\tlet updated: string;\n\tif (existing.includes(PROMPTS_GITIGNORE_START)) {\n\t\tconst start = existing.indexOf(PROMPTS_GITIGNORE_START);\n\t\tconst end = existing.indexOf(PROMPTS_GITIGNORE_END, start);\n\t\tconst afterBlock = end !== -1 ? existing.slice(end + PROMPTS_GITIGNORE_END.length) : \"\\n\";\n\t\tupdated = existing.slice(0, start) + block + afterBlock;\n\t} else {\n\t\tupdated = (existing.trimEnd() ? existing.trimEnd() + \"\\n\\n\" : \"\") + block + \"\\n\";\n\t}\n\tawait writeFile(gitignorePath, updated, \"utf8\");\n\n\treturn `wrote ${Object.keys(AGENT_PROMPTS).length} prompt files to ${AGENTS_PROMPTS_ROOT}/`;\n}\n","import type { Source } from \"../../plugin/capabilities.js\";\nimport { ProviderApiError } from \"../../plugin/capabilities.js\";\nimport type { SetupStepResult } from \"./run-step.js\";\n\nexport const RULESET_NAME = \"holocron-default-branch\";\n\nexport function buildClassicProtectionPayload(requiredChecks: string[] = []): Record<string, unknown> {\n\treturn {\n\t\trequired_status_checks: requiredChecks.length > 0 ? { strict: false, contexts: requiredChecks } : null,\n\t\tenforce_admins: false,\n\t\trequired_pull_request_reviews: {\n\t\t\trequired_approving_review_count: 0,\n\t\t\tdismiss_stale_reviews: false,\n\t\t\trequire_code_owner_reviews: false,\n\t\t},\n\t\trestrictions: null,\n\t\tallow_force_pushes: false,\n\t\tallow_deletions: false,\n\t};\n}\n\nexport function buildRulesetPayload(requiredChecks: string[] = []): Record<string, unknown> {\n\tconst rules: Record<string, unknown>[] = [\n\t\t{ type: \"deletion\" },\n\t\t{ type: \"non_fast_forward\" },\n\t\t{\n\t\t\ttype: \"pull_request\",\n\t\t\tparameters: {\n\t\t\t\trequired_approving_review_count: 0,\n\t\t\t\tdismiss_stale_reviews_on_push: false,\n\t\t\t\trequire_code_owner_review: false,\n\t\t\t\trequire_last_push_approval: false,\n\t\t\t\trequired_review_thread_resolution: true,\n\t\t\t\t// GitHub defaults this to `true`. It bumps the required approval\n\t\t\t\t// count to 1 for a PR with unverified / unattributed commits —\n\t\t\t\t// which, with `required_approving_review_count: 0` and a single\n\t\t\t\t// maintainer, is an unsatisfiable block (the author can't\n\t\t\t\t// self-approve). Admin bypass already covers the real risk.\n\t\t\t\trequire_extra_approval_for_unattributed_changes: false,\n\t\t\t},\n\t\t},\n\t];\n\tif (requiredChecks.length > 0) {\n\t\trules.push({\n\t\t\ttype: \"required_status_checks\",\n\t\t\tparameters: {\n\t\t\t\trequired_status_checks: requiredChecks.map((context) => ({ context })),\n\t\t\t\tstrict_required_status_checks_policy: false,\n\t\t\t},\n\t\t});\n\t}\n\treturn {\n\t\tname: RULESET_NAME,\n\t\ttarget: \"branch\",\n\t\tenforcement: \"active\",\n\t\t// Repository admins (role 4) can bypass — required for semantic-release\n\t\t// and other automation that pushes directly to the default branch.\n\t\tbypass_actors: [{ actor_id: 4, actor_type: \"RepositoryRole\", bypass_mode: \"always\" }],\n\t\tconditions: { ref_name: { include: [\"~DEFAULT_BRANCH\"], exclude: [] } },\n\t\trules,\n\t};\n}\n\n// Tries the modern Rulesets API first, falls back to classic branch protection\n// if rulesets return 403 (requires GitHub Team+ on private repos), and gracefully\n// skips if both APIs are unavailable (GitHub Free on private repos).\nexport async function upsertBranchProtection(\n\tsource: Source,\n\tdryRun: boolean,\n\trequiredChecks: string[]\n): Promise<SetupStepResult> {\n\tconst step = `upsert ruleset ${RULESET_NAME}`;\n\tif (dryRun) return { capability: \"source\", step, status: \"dry-run\" };\n\n\t// Attempt 1: modern rulesets\n\ttry {\n\t\tconst existing = await source.listRulesets();\n\t\tconst found = existing.find((r) => r.name === RULESET_NAME);\n\t\tif (found) {\n\t\t\tawait source.updateRuleset(found.id, buildRulesetPayload(requiredChecks));\n\t\t\treturn { capability: \"source\", step, status: \"ok\", message: \"updated\" };\n\t\t}\n\t\tawait source.createRuleset(buildRulesetPayload(requiredChecks));\n\t\treturn { capability: \"source\", step, status: \"ok\", message: \"created\" };\n\t} catch (err) {\n\t\tif (!(err instanceof ProviderApiError) || err.status !== 403) {\n\t\t\treturn {\n\t\t\t\tcapability: \"source\",\n\t\t\t\tstep,\n\t\t\t\tstatus: \"fail\",\n\t\t\t\tmessage: err instanceof Error ? err.message : String(err),\n\t\t\t};\n\t\t}\n\t}\n\n\t// Attempt 2: classic branch protection (free-plan fallback)\n\ttry {\n\t\tconst repo = await source.getRepo();\n\t\tawait source.protectBranch(repo.defaultBranch, buildClassicProtectionPayload(requiredChecks));\n\t\treturn { capability: \"source\", step, status: \"ok\", message: `classic protection on ${repo.defaultBranch}` };\n\t} catch (err) {\n\t\tif (err instanceof ProviderApiError && err.status === 403) {\n\t\t\treturn {\n\t\t\t\tcapability: \"source\",\n\t\t\t\tstep,\n\t\t\t\tstatus: \"skip\",\n\t\t\t\tmessage: \"branch protection unavailable on private repos without GitHub Pro/Team\",\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tcapability: \"source\",\n\t\t\tstep,\n\t\t\tstatus: \"fail\",\n\t\t\tmessage: err instanceof Error ? err.message : String(err),\n\t\t};\n\t}\n}\n","import { access, mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\nimport { DECISIONS_README, DECISIONS_TEMPLATE, SPECIFICATIONS_README, STANDARDS_README } from \"./agent-prompts-data.js\";\n\nasync function writeIfAbsent(filePath: string, content: string): Promise<boolean> {\n\ttry {\n\t\tawait access(filePath);\n\t\treturn false; // already exists — skip\n\t} catch {\n\t\tawait mkdir(dirname(filePath), { recursive: true });\n\t\tawait writeFile(filePath, content, \"utf8\");\n\t\treturn true;\n\t}\n}\n\nexport async function installEngineeringStructure({ repoRoot }: { repoRoot: string }): Promise<string> {\n\tconst results: string[] = [];\n\n\tconst writes: Array<[string, string]> = [\n\t\t[join(repoRoot, \"docs/wiki/decisions/template.md\"), DECISIONS_TEMPLATE],\n\t\t[join(repoRoot, \"docs/wiki/decisions/README.md\"), DECISIONS_README],\n\t\t[join(repoRoot, \"docs/wiki/standards/README.md\"), STANDARDS_README],\n\t\t[join(repoRoot, \"docs/wiki/specifications/README.md\"), SPECIFICATIONS_README],\n\t];\n\n\tfor (const [path, content] of writes) {\n\t\tconst wrote = await writeIfAbsent(path, content);\n\t\tif (wrote) results.push(path.replace(repoRoot + \"/\", \"\"));\n\t}\n\n\treturn results.length > 0 ? `created: ${results.join(\", \")}` : \"all files already exist — nothing to write\";\n}\n","import type { RepoSettings } from \"../../plugin/capabilities.js\";\n\nexport const BALANCED_REPO_SETTINGS: RepoSettings = {\n\tallow_squash_merge: true,\n\tallow_merge_commit: false,\n\tallow_rebase_merge: false,\n\tallow_auto_merge: true,\n\tallow_update_branch: true,\n\tdelete_branch_on_merge: true,\n\thas_issues: true,\n\thas_discussions: true,\n\thas_projects: true,\n\thas_wiki: false,\n\t// web_commit_signoff_required is intentionally omitted: GitHub rejects this\n\t// field when the organization already enforces it at org level (422). Org-level\n\t// enforcement already covers every repo — no per-repo override is needed.\n};\n","import type { LoadedConfig } from \"../../config/load-config.js\";\nimport { getLogger } from \"../../logger.js\";\nimport { ProviderApiError } from \"../../plugin/capabilities.js\";\nimport type { RuntimeContext } from \"../../plugin/loader.js\";\nimport { PluginLoader } from \"../../plugin/loader.js\";\n\nexport type SetupPrintLine = (line: string) => void;\n\nexport type SetupStatus = \"ok\" | \"fail\" | \"skip\" | \"dry-run\";\n\n/** Why a step failed with HTTP 403. */\nexport type FailReason = \"permissions\" | \"plan\";\n\nexport interface SetupStepResult {\n\tcapability: string;\n\tstep: string;\n\tstatus: SetupStatus;\n\tmessage?: string;\n\t/** Set when status === \"fail\" and the error was a 403. */\n\treason?: FailReason;\n}\n\nexport interface SetupReport {\n\tsteps: SetupStepResult[];\n\tsummary: { ok: number; fail: number; skip: number; dryRun: number };\n}\n\nexport interface RunSetupInput {\n\tloaded: LoadedConfig;\n\tcontext: RuntimeContext;\n\t/** Lets tests inject a pre-loaded loader; defaults to native dynamic import. */\n\tloader?: PluginLoader;\n\tprint?: SetupPrintLine;\n\t/** Injectable keyring backend. Tests pass `() => null` to skip real OS keychain lookups. */\n\tkeyring?: (key: string) => string | null;\n\t/**\n\t * `--hooks` / `--no-hooks` override for git-hook installation. `undefined`\n\t * defers to `config.hooks`, then to `protection: \"strict\"`.\n\t */\n\thooks?: boolean;\n}\n\nexport async function runStep(\n\tcapability: string,\n\tstep: string,\n\tdryRun: boolean,\n\tbody: () => Promise<string | void>,\n\topts: { skipCodes?: number[] } = {}\n): Promise<SetupStepResult> {\n\tconst result = await execStep(capability, step, dryRun, body, opts);\n\tconst { status, message, reason } = result;\n\tgetLogger()[status === \"fail\" ? \"warn\" : \"info\"](\n\t\t{ capability, step, status, ...(message ? { detail: message } : {}), ...(reason ? { reason } : {}) },\n\t\t`${capability}.${step}`\n\t);\n\treturn result;\n}\n\nasync function execStep(\n\tcapability: string,\n\tstep: string,\n\tdryRun: boolean,\n\tbody: () => Promise<string | void>,\n\topts: { skipCodes?: number[] } = {}\n): Promise<SetupStepResult> {\n\tif (dryRun) {\n\t\treturn { capability, step, status: \"dry-run\" };\n\t}\n\ttry {\n\t\tconst note = await body();\n\t\tconst result: SetupStepResult = { capability, step, status: \"ok\" };\n\t\tif (typeof note === \"string\") result.message = note;\n\t\treturn result;\n\t} catch (err) {\n\t\tif (err instanceof ProviderApiError) {\n\t\t\tif (err.status !== undefined && opts.skipCodes?.includes(err.status)) {\n\t\t\t\treturn { capability, step, status: \"skip\", message: err.message };\n\t\t\t}\n\t\t\tif (err.status === 403) {\n\t\t\t\tconst reason = classify403(err);\n\t\t\t\t// Plan-restriction 403s mean the feature is unavailable on the current\n\t\t\t\t// plan — not a setup failure, just a capability gap. Report as skip.\n\t\t\t\treturn { capability, step, status: reason === \"plan\" ? \"skip\" : \"fail\", message: err.message, reason };\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\tcapability,\n\t\t\tstep,\n\t\t\tstatus: \"fail\",\n\t\t\tmessage: err instanceof Error ? err.message : String(err),\n\t\t};\n\t}\n}\n\nexport function classify403(err: ProviderApiError): FailReason {\n\tconst detailText =\n\t\ttypeof err.details === \"string\"\n\t\t\t? err.details\n\t\t\t: typeof err.details === \"object\" && err.details !== null && \"message\" in err.details\n\t\t\t\t? String((err.details as { message?: unknown }).message)\n\t\t\t\t: \"\";\n\tconst text = `${err.message} ${detailText}`.toLowerCase();\n\tif (\n\t\ttext.includes(\"advanced security\") ||\n\t\ttext.includes(\"not enabled for this repository\") ||\n\t\ttext.includes(\"upgrade\") ||\n\t\ttext.includes(\"not available on\")\n\t) {\n\t\treturn \"plan\";\n\t}\n\treturn \"permissions\";\n}\n\nimport { style } from \"../../ui/style.js\";\n\nexport function formatStep(step: SetupStepResult): string {\n\tconst tag = step.reason === \"permissions\" ? \" [permissions]\" : step.reason === \"plan\" ? \" [plan restriction]\" : \"\";\n\tconst detail = step.message ? style.dim(` (${step.message})`) : \"\";\n\tconst label = `${step.step}${tag}${detail}`;\n\tif (step.status === \"ok\") return ` ${style.success(label)}`;\n\tif (step.status === \"fail\") return ` ${style.fail(label)}`;\n\tif (step.status === \"dry-run\") return ` ${style.dim(`… ${label}`)}`;\n\treturn ` ${style.dim(`· ${label}`)}`;\n}\n","import { spawnSync } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport { copyFile, mkdir, readdir, readFile, rm, stat, symlink, unlink, writeFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join, relative } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\ninterface SkillLockEntry {\n\tsource: string;\n\tsourceType: \"github\";\n\tskillPath: string;\n\tcomputedHash?: string;\n}\n\ninterface SkillsLock {\n\tversion: number;\n\tskills: Record<string, SkillLockEntry>;\n}\n\nasync function fetchExternalSkill(entry: SkillLockEntry): Promise<{ content: string; stale: boolean }> {\n\tif (entry.sourceType !== \"github\") {\n\t\t/* c8 ignore next */\n\t\tthrow new Error(`unsupported sourceType: ${entry.sourceType}`);\n\t}\n\tconst url = `https://raw.githubusercontent.com/${entry.source}/HEAD/${entry.skillPath}`;\n\tconst res = await fetch(url);\n\tif (!res.ok) throw new Error(`HTTP ${res.status} fetching ${url}`);\n\tconst content = await res.text();\n\tconst stale = !!entry.computedHash && createHash(\"sha256\").update(content).digest(\"hex\") !== entry.computedHash;\n\treturn { content, stale };\n}\n\nconst AGENTS_SKILLS_ROOT = \".agents/skills\";\n\n/** Relative path of the agent-specific symlink. undefined = unsupported agent. */\nexport const AGENT_SYMLINK_PATHS: Partial<Record<string, (name: string) => string>> = {\n\tclaude: (name) => `.claude/skills/${name}`,\n};\n\nconst GITIGNORE_BLOCK_START = \"# managed by holocron setup — skills\";\n// Safety invariant: GITIGNORE_BLOCK_START must NOT be a substring of\n// GITIGNORE_BLOCK_END. The \"# end \" prefix currently guarantees this — if\n// either string is edited, verify the invariant still holds so that\n// indexOf(GITIGNORE_BLOCK_START) cannot match inside the end marker.\nconst GITIGNORE_BLOCK_END = \"# end managed by holocron setup — skills\";\n\nexport async function installSkills({\n\tagent,\n\tskills,\n\trepoRoot,\n}: {\n\tagent: string;\n\tskills: string[];\n\trepoRoot: string;\n}): Promise<string> {\n\tconst symlinkFn = AGENT_SYMLINK_PATHS[agent];\n\tif (!symlinkFn) {\n\t\treturn `agent \"${agent}\" has no known skill install path — skipping`;\n\t}\n\n\tconst require = createRequire(pathToFileURL(join(repoRoot, \"package.json\")));\n\tlet skillsRoot: string;\n\ttry {\n\t\tskillsRoot = dirname(require.resolve(\"@theholocron/skills/package.json\"));\n\t} catch {\n\t\tconst result = spawnSync(\"pnpm\", [\"add\", \"-D\", \"@theholocron/skills\"], {\n\t\t\tcwd: repoRoot,\n\t\t\tstdio: \"inherit\",\n\t\t});\n\t\tif (result.status !== 0) {\n\t\t\tthrow new Error(\"failed to auto-install @theholocron/skills\");\n\t\t}\n\t\ttry {\n\t\t\tskillsRoot = dirname(require.resolve(\"@theholocron/skills/package.json\"));\n\t\t} catch {\n\t\t\tthrow new Error(\"failed to auto-install @theholocron/skills\");\n\t\t}\n\t}\n\n\tconst gitignorePath = join(repoRoot, \".gitignore\");\n\tconst existingContent = await readFile(gitignorePath, \"utf8\").catch(() => \"\");\n\tconst previouslyInstalled = parsePreviousSkills(existingContent, symlinkFn);\n\tconst currentSet = new Set(skills);\n\tconst stale = previouslyInstalled.filter((n) => !currentSet.has(n));\n\tfor (const name of stale) {\n\t\tawait rm(join(repoRoot, symlinkFn(name)), { force: true }).catch(() => undefined);\n\t\tawait rm(join(repoRoot, AGENTS_SKILLS_ROOT, name), { recursive: true, force: true }).catch(() => undefined);\n\t}\n\n\tconst installed: string[] = [];\n\tconst missing: string[] = [];\n\n\tfor (const name of skills) {\n\t\tconst srcDir = join(skillsRoot, \"src\", name);\n\n\t\ttry {\n\t\t\tawait stat(srcDir);\n\t\t} catch {\n\t\t\tmissing.push(name);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst agentsDir = join(repoRoot, AGENTS_SKILLS_ROOT, name);\n\t\tawait copyDirRecursive(srcDir, agentsDir);\n\n\t\tconst symlinkPath = join(repoRoot, symlinkFn(name));\n\t\tawait mkdir(dirname(symlinkPath), { recursive: true });\n\t\ttry {\n\t\t\tawait unlink(symlinkPath);\n\t\t} catch {\n\t\t\t// didn't exist — that's fine\n\t\t}\n\t\tawait symlink(relative(dirname(symlinkPath), agentsDir).replace(/\\\\/g, \"/\"), symlinkPath);\n\n\t\tinstalled.push(name);\n\t}\n\n\tconst externalFailed: string[] = [];\n\tconst externalStale: string[] = [];\n\tif (missing.length > 0) {\n\t\tlet lock: SkillsLock | null = null;\n\t\ttry {\n\t\t\tlock = JSON.parse(await readFile(join(skillsRoot, \"skills-lock.json\"), \"utf8\")) as SkillsLock;\n\t\t} catch {\n\t\t\t// No lock file or parse error — all missing remain unknown.\n\t\t}\n\t\tif (lock?.skills) {\n\t\t\tfor (const name of [...missing]) {\n\t\t\t\tconst entry = lock.skills[name];\n\t\t\t\tif (!entry) continue;\n\t\t\t\ttry {\n\t\t\t\t\tconst { content, stale: isStale } = await fetchExternalSkill(entry);\n\t\t\t\t\tconst agentsDir = join(repoRoot, AGENTS_SKILLS_ROOT, name);\n\t\t\t\t\tawait mkdir(agentsDir, { recursive: true });\n\t\t\t\t\tawait writeFile(join(agentsDir, \"SKILL.md\"), content);\n\t\t\t\t\tconst symlinkPath = join(repoRoot, symlinkFn(name));\n\t\t\t\t\tawait mkdir(dirname(symlinkPath), { recursive: true });\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait unlink(symlinkPath);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// didn't exist — that's fine\n\t\t\t\t\t}\n\t\t\t\t\tawait symlink(relative(dirname(symlinkPath), agentsDir).replace(/\\\\/g, \"/\"), symlinkPath);\n\t\t\t\t\tmissing.splice(missing.indexOf(name), 1);\n\t\t\t\t\tinstalled.push(name);\n\t\t\t\t\tif (isStale) externalStale.push(name);\n\t\t\t\t} catch {\n\t\t\t\t\tmissing.splice(missing.indexOf(name), 1);\n\t\t\t\t\texternalFailed.push(name);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (installed.length > 0 || stale.length > 0 || missing.length > 0 || externalFailed.length > 0) {\n\t\tawait updateSkillsGitignore(\n\t\t\tgitignorePath,\n\t\t\texistingContent,\n\t\t\t[...installed, ...missing, ...externalFailed],\n\t\t\tsymlinkFn\n\t\t);\n\t}\n\n\tconst parts: string[] = [`installed ${installed.length}`];\n\tif (stale.length > 0) parts.push(`pruned: ${stale.join(\", \")}`);\n\tif (externalStale.length > 0)\n\t\tparts.push(`stale: ${externalStale.join(\", \")} (run \\`holocron skills update\\` to refresh)`);\n\tif (externalFailed.length > 0) parts.push(`fetch failed: ${externalFailed.join(\", \")}`);\n\tif (missing.length > 0) parts.push(`unknown: ${missing.join(\", \")}`);\n\treturn parts.join(\"; \");\n}\n\nexport function parsePreviousSkills(gitignoreContent: string, symlinkFn: (n: string) => string): string[] {\n\tif (!gitignoreContent.includes(GITIGNORE_BLOCK_START)) return [];\n\tconst startIdx = gitignoreContent.indexOf(GITIGNORE_BLOCK_START);\n\tconst endIdx = gitignoreContent.indexOf(GITIGNORE_BLOCK_END, startIdx);\n\tconst block = endIdx !== -1 ? gitignoreContent.slice(startIdx, endIdx) : gitignoreContent.slice(startIdx);\n\tconst placeholder = \"__placeholder__\";\n\tconst symlinkPrefix = `/${symlinkFn(placeholder)}`.replace(placeholder, \"\");\n\treturn block\n\t\t.split(\"\\n\")\n\t\t.filter((line) => line.startsWith(symlinkPrefix))\n\t\t.map((line) => line.slice(symlinkPrefix.length));\n}\n\nasync function copyDirRecursive(src: string, dest: string): Promise<void> {\n\tawait mkdir(dest, { recursive: true });\n\tconst entries = await readdir(src, { withFileTypes: true });\n\tfor (const entry of entries) {\n\t\tconst srcPath = join(src, entry.name);\n\t\tconst destPath = join(dest, entry.name);\n\t\tif (entry.isDirectory()) {\n\t\t\tawait copyDirRecursive(srcPath, destPath);\n\t\t} else {\n\t\t\tawait copyFile(srcPath, destPath);\n\t\t}\n\t}\n}\n\nasync function updateSkillsGitignore(\n\tgitignorePath: string,\n\texistingContent: string,\n\tskills: string[],\n\tsymlinkFn: (name: string) => string\n): Promise<void> {\n\tconst entries = [`/${AGENTS_SKILLS_ROOT}/`, ...skills.map((n) => `/${symlinkFn(n)}`)];\n\tconst block = [GITIGNORE_BLOCK_START, ...entries, GITIGNORE_BLOCK_END].join(\"\\n\");\n\n\tlet content: string;\n\tif (existingContent.includes(GITIGNORE_BLOCK_START)) {\n\t\tconst start = existingContent.indexOf(GITIGNORE_BLOCK_START);\n\t\tconst end = existingContent.indexOf(GITIGNORE_BLOCK_END, start);\n\t\tconst afterBlock = end !== -1 ? existingContent.slice(end + GITIGNORE_BLOCK_END.length) : \"\\n\";\n\t\tcontent = existingContent.slice(0, start) + block + afterBlock;\n\t} else {\n\t\tcontent = (existingContent.trimEnd() ? existingContent.trimEnd() + \"\\n\\n\" : \"\") + block + \"\\n\";\n\t}\n\n\tawait writeFile(gitignorePath, content, \"utf8\");\n}\n","/**\n * `holocron setup` — orchestrates per-capability setup actions across\n * every plugin loaded from `holocron.config.json`.\n *\n * Per CLAUDE.md soft-skip: each step is wrapped in a try/catch and\n * failures don't abort subsequent capabilities. The summary at the end\n * reports counts so the operator can see what worked + what didn't.\n *\n * Per the Standards: when `ctx.dryRun` is true, mutating calls are\n * replaced with \"would\" log lines. Read-only probes (e.g.,\n * `vault.list`) still run so the operator sees real state.\n *\n * The orchestrator knows about specific capability methods by name\n * (e.g., `source.enableVulnerabilityAlerts`). This deliberate coupling\n * makes the \"what does setup do\" contract explicit and concrete —\n * decoupling via a per-capability `setupSteps()` method would be more\n * extensible but pushes the same knowledge into N plugins instead of\n * one central place.\n */\n\nimport { access, readFile, writeFile } from \"node:fs/promises\";\nimport { basename, join } from \"node:path\";\n\nimport { createAstromech, extractPreviewConfig, KNOWN_WORKFLOWS, readWorkspacePackages } from \"@theholocron/astromech\";\nimport type { TasksConfig } from \"@theholocron/astromech/config\";\n\nimport { AuthError, createFeatureResolver } from \"../../auth/auth-resolver.js\";\nimport { getLogger } from \"../../logger.js\";\nimport type {\n\tAuth,\n\tDeployment,\n\tDns,\n\tDnsRecordRequest,\n\tEnvironments,\n\tErrors,\n\tLogs,\n\tSecrets,\n\tSource,\n\tTooling,\n\tVault,\n\tWiki,\n\tWorkers,\n} from \"../../plugin/capabilities.js\";\nimport { PluginLoader } from \"../../plugin/loader.js\";\nimport { assertPluginsResolvable } from \"../../plugin/workspace.js\";\nimport sentimentBotConfig from \"../../templates/config.yml\";\nimport {\n\tcreateIgnoreConfig as createAlexignore,\n\tcreateRcConfig as createAlexrc,\n} from \"../../templates/configs/alexjs/index.js\";\nimport { createConfig as createCommitMsg } from \"../../templates/configs/commit-msg/index.js\";\nimport { createConfig as createDevmoji } from \"../../templates/configs/devmoji/index.js\";\nimport { createConfig as createEditorconfig } from \"../../templates/configs/editorconfig/index.js\";\nimport { createConfig as createEditorconfigChecker } from \"../../templates/configs/editorconfig-checker/index.js\";\nimport { createConfig as createPreCommit } from \"../../templates/configs/pre-commit/index.js\";\nimport { createConfig as createPrePush } from \"../../templates/configs/pre-push/index.js\";\nimport { createConfig as createPrepareCommitMsg } from \"../../templates/configs/prepare-commit-msg/index.js\";\nimport {\n\tcreateConfig as createYamllint,\n\tcreateIgnoreConfig as createYamlignore,\n} from \"../../templates/configs/yamllint/index.js\";\nimport dcoConfig from \"../../templates/dco.yml\";\nimport dependabotConfig from \"../../templates/dependabot.yml\";\nimport labelerConfig from \"../../templates/labeler.yml\";\nimport { withSpinner } from \"../../ui/progress.js\";\nimport { style } from \"../../ui/style.js\";\nimport { createHeader } from \"../../utils/create-header.js\";\nimport { installAgentPrompts } from \"./agent-prompts.js\";\nimport { upsertBranchProtection } from \"./branch-protection.js\";\nimport {\n\tderiveCapabilities,\n\tderiveCompliance,\n\tderiveProfile,\n\tderiveStack,\n\treadWorkspacePackageJsons,\n} from \"./derived-properties.js\";\nimport { installEngineeringStructure } from \"./engineering.js\";\nimport { CANONICAL_LABELS, STALE_LABELS } from \"./labels.js\";\nimport { BALANCED_REPO_SETTINGS } from \"./repo-settings.js\";\nimport type { RunSetupInput, SetupReport, SetupStepResult } from \"./run-step.js\";\nimport { formatStep, runStep } from \"./run-step.js\";\nimport { AGENT_SYMLINK_PATHS, installSkills } from \"./skills.js\";\n\nconst { workflowHeader } = createHeader({\n\tsource: \"packages/cli/src/commands/setup/run-setup.ts\",\n\ttool: \"holocron setup\",\n});\n// Thin-caller workflow content comes from astromech.thinCallers(), not this\n// file — a separate binding so its header points contributors at the actual\n// template/generation logic (packages/astromech/src/thin-callers.ts), same as\n// the workflowHeader() calls further down that write genuinely cli-owned\n// templates (labeler.yml, dependabot.yml, dco.yml, config.yml).\nconst { workflowHeader: thinCallerHeader } = createHeader({\n\tsource: \"packages/astromech/src/thin-callers.ts\",\n\ttool: \"holocron setup\",\n});\n\nexport async function runSetup(input: RunSetupInput): Promise<SetupReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = getLogger();\n\tconst loader = input.loader ?? new PluginLoader(input.loaded.resolved, input.context);\n\tawait withSpinner(\"Loading plugins…\", () => loader.load());\n\tassertPluginsResolvable(loader, \"setup\");\n\n\tconst config = input.loaded.resolved;\n\tconst dryRun = input.context.dryRun ?? false;\n\tconst steps: SetupStepResult[] = [];\n\tconst repo = config.repo;\n\tconst effectivePreset = repo?.protection;\n\n\t// Git hooks: `--hooks`/`--no-hooks` wins, then `config.hooks`, then default\n\t// on for `protection: \"strict\"`.\n\tconst hooksEnabled =\n\t\tinput.hooks ??\n\t\t(typeof config.hooks === \"boolean\"\n\t\t\t? config.hooks\n\t\t\t: typeof config.hooks === \"object\"\n\t\t\t\t? config.hooks.prePush !== false\n\t\t\t\t: effectivePreset === \"strict\");\n\n\tprint(style.header(`Holocron setup — ${config.name}${dryRun ? \" (dry-run)\" : \"\"}`));\n\tprint(style.dim(` config: ${input.loaded.filepath}`));\n\tprint(\"\");\n\n\t// ── source: security toggles + repo policy ──────────────────────────\n\tif (loader.has(\"source\")) {\n\t\tconst source = loader.get(\"source\") as Source;\n\t\tprint(style.step(\"source\"));\n\t\tconst SECURITY_SKIP_CODES: Partial<Record<string, number[]>> = {\n\t\t\tenableSecretScanning: [422],\n\t\t\tenablePrivateVulnerabilityReporting: [404],\n\t\t};\n\t\tfor (const method of [\n\t\t\t\"enableVulnerabilityAlerts\",\n\t\t\t\"enableAutomatedSecurityFixes\",\n\t\t\t\"enableSecretScanning\",\n\t\t\t\"enablePrivateVulnerabilityReporting\",\n\t\t\t\"enableDependencyGraph\",\n\t\t] as const) {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\n\t\t\t\t\t\"source\",\n\t\t\t\t\tmethod,\n\t\t\t\t\tdryRun,\n\t\t\t\t\tasync () => {\n\t\t\t\t\t\tawait source[method]();\n\t\t\t\t\t},\n\t\t\t\t\t{ skipCodes: SECURITY_SKIP_CODES[method] }\n\t\t\t\t)\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\n\t\tconst usesAdvancedCodeQL = (config.tasks ?? [])\n\t\t\t.map((e) => (typeof e === \"string\" ? e : e.name))\n\t\t\t.includes(\"security.codeScanning\");\n\t\tsteps.push(\n\t\t\tawait runStep(\n\t\t\t\t\"source\",\n\t\t\t\tusesAdvancedCodeQL ? \"disableDefaultCodeScanning\" : \"enableCodeScanning\",\n\t\t\t\tdryRun,\n\t\t\t\tasync () => {\n\t\t\t\t\tif (usesAdvancedCodeQL) {\n\t\t\t\t\t\tawait source.disableDefaultCodeScanning();\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn await source.enableCodeScanning();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t)\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\n\t\tif (effectivePreset && effectivePreset !== \"none\") {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"source\", \"updateRepoSettings\", dryRun, async () => {\n\t\t\t\t\tawait source.updateRepoSettings({\n\t\t\t\t\t\t...BALANCED_REPO_SETTINGS,\n\t\t\t\t\t\t...(repo?.defaultBranch ? { default_branch: repo.defaultBranch } : {}),\n\t\t\t\t\t});\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\n\t\t\tconst tasksConfig: TasksConfig = { tasks: config.tasks as TasksConfig[\"tasks\"] };\n\t\t\tif (config.extraRequiredChecks) tasksConfig.extraRequiredChecks = config.extraRequiredChecks;\n\t\t\tconst requiredChecks =\n\t\t\t\teffectivePreset === \"strict\"\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t\"DCO\",\n\t\t\t\t\t\t\t...createAstromech({\n\t\t\t\t\t\t\t\tcwd: input.context.repoRoot,\n\t\t\t\t\t\t\t\tconfig: tasksConfig,\n\t\t\t\t\t\t\t\tlogger,\n\t\t\t\t\t\t\t}).requiredChecks(),\n\t\t\t\t\t\t]\n\t\t\t\t\t: [];\n\t\t\tsteps.push(await upsertBranchProtection(source, dryRun, requiredChecks));\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\t}\n\n\t// ── source: workflow thin wrappers ──────────────────────────────────\n\tconst tasks = config.tasks;\n\tif (loader.has(\"source\") && tasks && tasks.length > 0) {\n\t\tconst source = loader.get(\"source\") as Source;\n\t\tprint(style.step(\"workflows\"));\n\n\t\t// astromech renders every thin caller from the manifest (lint linter set,\n\t\t// deploy paths, deploy+preview) and validates it — a bad manifest throws\n\t\t// here, aborting setup, same as before. Iterate the manifest (not the map)\n\t\t// so step reporting keeps the config's order.\n\t\tconst files = createAstromech({\n\t\t\tcwd: input.context.repoRoot,\n\t\t\tconfig: { tasks: tasks as TasksConfig[\"tasks\"] },\n\t\t\torgContext: { org: config.org, domain: config.domain },\n\t\t\tlogger,\n\t\t}).thinCallers();\n\n\t\tfor (const entry of tasks) {\n\t\t\tconst name = typeof entry === \"string\" ? entry : entry.name;\n\t\t\t// knowledge.docs / knowledge.components have no static\n\t\t\t// WORKFLOW_TEMPLATES entry (their content is always\n\t\t\t// combined-generated, astromech.ts) — not in KNOWN_WORKFLOWS, but\n\t\t\t// not \"unknown\" either.\n\t\t\tconst isCombinedContentOnly = name === \"knowledge.docs\" || name === \"knowledge.components\";\n\n\t\t\tif (!KNOWN_WORKFLOWS.has(name) && !isCombinedContentOnly) {\n\t\t\t\tsteps.push({\n\t\t\t\t\tcapability: \"source\",\n\t\t\t\t\tstep: `write workflow ${name}`,\n\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\tmessage: `unknown workflow \"${name}\" — no template available`,\n\t\t\t\t});\n\t\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// The combined-content family (delivery.deploy, knowledge.docs,\n\t\t\t// knowledge.components) all key their generated file by task name\n\t\t\t// already — no special-casing needed, unlike the old hardcoded\n\t\t\t// \"deploy.yml\" filename.\n\t\t\tconst filename = `${name}.yml`;\n\t\t\tconst content = files.get(filename);\n\t\t\tif (content === undefined) continue; // ci: false — nothing to write\n\n\t\t\tconst withPreview = content.includes(\"workflows/preview.yml@main\");\n\t\t\tconst step = withPreview ? `write workflow ${name} (with preview)` : `write workflow ${name}`;\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"source\", step, dryRun, async () => {\n\t\t\t\t\tawait source.writeWorkflowFile(filename, `${thinCallerHeader()}${content}`);\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\t}\n\n\t// ── source: labeler config ───────────────────────────────────────────\n\tif (\n\t\tloader.has(\"source\") &&\n\t\t(config.tasks ?? []).map((e) => (typeof e === \"string\" ? e : e.name)).includes(\"bookkeeping\")\n\t) {\n\t\tconst source = loader.get(\"source\") as Source;\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write .github/labeler.yml\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\".github/labeler.yml\", `${workflowHeader()}${labelerConfig}`);\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t}\n\n\t// ── source: dependabot + dco config ─────────────────────────────────\n\tif (loader.has(\"source\") && effectivePreset !== \"none\") {\n\t\tconst source = loader.get(\"source\") as Source;\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write .github/dependabot.yml\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\".github/dependabot.yml\", `${workflowHeader()}${dependabotConfig}`);\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write .github/dco.yml\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\".github/dco.yml\", `${workflowHeader()}${dcoConfig}`);\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t}\n\n\t// ── source: static config files ──────────────────────────────────────\n\tif (loader.has(\"source\")) {\n\t\tconst source = loader.get(\"source\") as Source;\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write .github/config.yml\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\".github/config.yml\", `${workflowHeader()}${sentimentBotConfig}`);\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write .alexrc.json\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\".alexrc.json\", createAlexrc());\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write .alexignore\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\".alexignore\", createAlexignore());\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write .yamllint.yml\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\".yamllint.yml\", createYamllint());\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write .yamlignore\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\".yamlignore\", createYamlignore());\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write .editorconfig\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\".editorconfig\", createEditorconfig());\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write .editorconfig-checker.json\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\".editorconfig-checker.json\", createEditorconfigChecker());\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write devmoji.config.cjs\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\"devmoji.config.cjs\", createDevmoji());\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write .husky/prepare-commit-msg\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\".husky/prepare-commit-msg\", createPrepareCommitMsg());\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\tsteps.push(\n\t\t\tawait runStep(\"source\", \"write .husky/commit-msg\", dryRun, async () => {\n\t\t\t\tawait source.writeRepoFile(\".husky/commit-msg\", createCommitMsg(config.holocronScript));\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\tif (hooksEnabled) {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"source\", \"write .husky/pre-push\", dryRun, async () => {\n\t\t\t\t\tawait source.writeRepoFile(\".husky/pre-push\", createPrePush(config.holocronScript));\n\t\t\t\t\treturn \"runs `holocron ci` before push — bypass with `git push --no-verify`\";\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"source\", \"write .husky/pre-commit\", dryRun, async () => {\n\t\t\t\t\tawait source.writeRepoFile(\".husky/pre-commit\", createPreCommit());\n\t\t\t\t\treturn \"runs GitLeaks (staged-only) + lint-staged before commit\";\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\tif (config.syncScripts !== false) {\n\t\t\t\tsteps.push(\n\t\t\t\t\tawait runStep(\"source\", \"set package.json prepare script\", dryRun, async () => {\n\t\t\t\t\t\treturn (await ensurePrepareScript(input.context.repoRoot))\n\t\t\t\t\t\t\t? \"prepare now runs husky\"\n\t\t\t\t\t\t\t: \"already runs husky\";\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\t}\n\t\t} else {\n\t\t\tsteps.push({\n\t\t\t\tcapability: \"source\",\n\t\t\t\tstep: \"write .husky/pre-push\",\n\t\t\t\tstatus: \"skip\",\n\t\t\t\tmessage: \"git hooks disabled\",\n\t\t\t});\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\tsteps.push({\n\t\t\t\tcapability: \"source\",\n\t\t\t\tstep: \"write .husky/pre-commit\",\n\t\t\t\tstatus: \"skip\",\n\t\t\t\tmessage: \"git hooks disabled\",\n\t\t\t});\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\t\t{\n\t\t\tconst configuredWorkflowNames = (config.tasks ?? []).map((e) => (typeof e === \"string\" ? e : e.name));\n\t\t\tconst hasTestWorkflow = configuredWorkflowNames.includes(\"verification.unitTests\");\n\t\t\tconst existing = await readFile(join(input.context.repoRoot, \"codecov.yml\"), \"utf8\").catch(() => null);\n\t\t\tif (!hasTestWorkflow && existing == null) {\n\t\t\t\tsteps.push({\n\t\t\t\t\tcapability: \"source\",\n\t\t\t\t\tstep: \"write codecov.yml\",\n\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\tmessage: \"no test workflow configured\",\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tsteps.push(\n\t\t\t\t\tawait runStep(\"source\", \"write codecov.yml\", dryRun, async () => {\n\t\t\t\t\t\tconst content = createAstromech({ cwd: input.context.repoRoot, logger }).codecovConfig(\n\t\t\t\t\t\t\texisting\n\t\t\t\t\t\t);\n\t\t\t\t\t\tawait source.writeRepoFile(\"codecov.yml\", content);\n\t\t\t\t\t\tconst packageCount = readWorkspacePackages(input.context.repoRoot).length;\n\t\t\t\t\t\treturn packageCount > 0 ? `${packageCount} components` : \"no components\";\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t}\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\t\t{\n\t\t\tconst astromechTurbo = createAstromech({\n\t\t\t\tcwd: input.context.repoRoot,\n\t\t\t\tconfig: { tasks: config.tasks as TasksConfig[\"tasks\"] },\n\t\t\t\tlogger,\n\t\t\t});\n\t\t\tconst content = astromechTurbo.turboConfig();\n\n\t\t\tif (content === null) {\n\t\t\t\tsteps.push({\n\t\t\t\t\tcapability: \"source\",\n\t\t\t\t\tstep: \"write turbo.json\",\n\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\tmessage: \"no fan-out-eligible tasks configured\",\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tsteps.push(\n\t\t\t\t\tawait runStep(\"source\", \"write turbo.json\", dryRun, async () => {\n\t\t\t\t\t\tawait source.writeRepoFile(\"turbo.json\", content);\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\n\t\t\t\t// #692: a root that's genuinely a directly-buildable package (not\n\t\t\t\t// just an orchestrator) silently vanishes from `turbo run <task>`\n\t\t\t\t// once turbo.json exists, unless it's an explicit workspace\n\t\t\t\t// member — fix pnpm-workspace.yaml in the same step that\n\t\t\t\t// introduces the risk.\n\t\t\t\tconst rootPkgRaw = await readFile(join(input.context.repoRoot, \"package.json\"), \"utf8\").catch(\n\t\t\t\t\t() => null\n\t\t\t\t);\n\t\t\t\tconst rootPkg = rootPkgRaw ? (JSON.parse(rootPkgRaw) as { scripts?: Record<string, string> }) : null;\n\t\t\t\tconst workspaceYaml = await readFile(join(input.context.repoRoot, \"pnpm-workspace.yaml\"), \"utf8\").catch(\n\t\t\t\t\t() => \"\"\n\t\t\t\t);\n\t\t\t\tconst rootScripts = rootPkg?.scripts ?? {};\n\t\t\t\tconst workspaceFix = astromechTurbo.ensureRootWorkspaceMember(workspaceYaml, rootScripts);\n\t\t\t\tif (workspaceFix.changed) {\n\t\t\t\t\tsteps.push(\n\t\t\t\t\t\tawait runStep(\n\t\t\t\t\t\t\t\"source\",\n\t\t\t\t\t\t\t\"fix pnpm-workspace.yaml (root workspace member, #692)\",\n\t\t\t\t\t\t\tdryRun,\n\t\t\t\t\t\t\tasync () => {\n\t\t\t\t\t\t\t\tawait source.writeRepoFile(\"pnpm-workspace.yaml\", workspaceFix.content);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// turbo.json alone is inert without turbo itself installed — see\n\t\t\t\t// ensureTurboDependency()'s own docstring for how this was found.\n\t\t\t\tif (rootPkgRaw) {\n\t\t\t\t\tconst depFix = astromechTurbo.ensureTurboDependency(rootPkgRaw, workspaceFix.content);\n\t\t\t\t\tif (depFix.changed) {\n\t\t\t\t\t\tsteps.push(\n\t\t\t\t\t\t\tawait runStep(\"source\", \"add turbo devDependency\", dryRun, async () => {\n\t\t\t\t\t\t\t\tawait source.writeRepoFile(\"package.json\", depFix.content);\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\n\t\tif (source.syncLabels) {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"source\", \"sync labels\", dryRun, async () => {\n\t\t\t\t\treturn source.syncLabels!(CANONICAL_LABELS, STALE_LABELS);\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\n\t\tconst properties: Record<string, string | string[]> = {};\n\n\t\tif (effectivePreset && effectivePreset !== \"none\")\n\t\t\tproperties[\"holocron_branch_protection_level\"] = effectivePreset;\n\n\t\tconst isMonorepo = await access(join(input.context.repoRoot, \"pnpm-workspace.yaml\"))\n\t\t\t.then(() => true)\n\t\t\t.catch(() => false);\n\t\tproperties[\"monorepo\"] = String(isMonorepo);\n\n\t\tconst manual = repo?.properties ?? {};\n\t\tif (manual.lifecycle) properties[\"lifecycle\"] = manual.lifecycle;\n\t\tif (manual.open_source !== undefined) properties[\"open_source\"] = String(manual.open_source);\n\t\tif (manual.runtime_environment) properties[\"runtime_environment\"] = manual.runtime_environment;\n\t\tif (manual.uses_external_packages !== undefined)\n\t\t\tproperties[\"uses_external_packages\"] = String(manual.uses_external_packages);\n\n\t\t// #677 — derived fields, distinct from the manual ones above: signal\n\t\t// that isn't an explicit holocron.config.ts field today (framework\n\t\t// choice, repo archetype, capability drift).\n\t\t{\n\t\t\tconst rootPackageJson = await readFile(join(input.context.repoRoot, \"package.json\"), \"utf8\")\n\t\t\t\t.then((raw) => JSON.parse(raw) as Parameters<typeof deriveStack>[0])\n\t\t\t\t.catch(() => null);\n\t\t\tconst workspacePackages = readWorkspacePackages(input.context.repoRoot);\n\t\t\tconst workspacePackageJsons = await readWorkspacePackageJsons(input.context.repoRoot, workspacePackages);\n\t\t\tproperties[\"holocron_profile\"] = deriveProfile({\n\t\t\t\trootPackageJson,\n\t\t\t\trepoName: basename(input.context.repoRoot),\n\t\t\t\tisMonorepo,\n\t\t\t\tworkspacePackageJsons,\n\t\t\t});\n\t\t\tproperties[\"holocron_stack\"] = deriveStack(rootPackageJson);\n\t\t\tconst capabilities = deriveCapabilities(config.providers);\n\t\t\tproperties[\"holocron_capabilities\"] = capabilities;\n\t\t\tproperties[\"holocron_compliance\"] = deriveCompliance(capabilities);\n\t\t}\n\n\t\tif (source.syncProperties) {\n\t\t\tsteps.push(await runStep(\"source\", \"sync properties\", dryRun, () => source.syncProperties!(properties)));\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\n\t\tconst topics = repo?.topics ?? [];\n\t\tif (topics.length > 0 && source.syncTopics) {\n\t\t\tsteps.push(await runStep(\"source\", \"sync topics\", dryRun, () => source.syncTopics!(topics)));\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\n\t\tif (config.description && source.syncDescription) {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"source\", \"sync description\", dryRun, () => source.syncDescription!(config.description!))\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\n\t\tif (config.homepage && source.syncHomepage) {\n\t\t\tsteps.push(await runStep(\"source\", \"sync homepage\", dryRun, () => source.syncHomepage!(config.homepage!)));\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\n\t\tconst teams = repo?.teams ?? [];\n\t\tif (teams.length > 0) {\n\t\t\tif (source.syncTeams) {\n\t\t\t\tsteps.push(\n\t\t\t\t\tawait runStep(\"source\", \"sync teams\", dryRun, () => source.syncTeams!(teams), { skipCodes: [422] })\n\t\t\t\t);\n\t\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\n\t\t\t\tconst repoCoord = input.context.repo ?? repo?.name ?? \"\";\n\t\t\t\tconst org = repoCoord.includes(\"/\") ? repoCoord.split(\"/\")[0]! : \"\";\n\t\t\t\tconst writeableTeams = teams\n\t\t\t\t\t.map((t) => (typeof t === \"string\" ? { slug: t, permission: \"push\" as const } : t))\n\t\t\t\t\t.filter((t) => [\"push\", \"maintain\", \"admin\"].includes(t.permission));\n\t\t\t\tif (org && writeableTeams.length > 0) {\n\t\t\t\t\tsteps.push(\n\t\t\t\t\t\tawait runStep(\"source\", \"write .github/CODEOWNERS\", dryRun, async () => {\n\t\t\t\t\t\t\tconst content = writeableTeams.map((t) => `* @${org}/${t.slug}`).join(\"\\n\") + \"\\n\";\n\t\t\t\t\t\t\tawait source.writeRepoFile(\".github/CODEOWNERS\", content);\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tsteps.push({\n\t\t\t\t\tcapability: \"source\",\n\t\t\t\t\tstep: \"sync teams\",\n\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\tmessage: \"provider does not implement syncTeams\",\n\t\t\t\t});\n\t\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── environments ────────────────────────────────────────────────────\n\tif (loader.has(\"environments\")) {\n\t\tconst envs = loader.get(\"environments\") as Environments;\n\t\tprint(style.step(\"environments\"));\n\t\tfor (const envName of [\"staging\", \"production\"]) {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"environments\", `upsert ${envName}`, dryRun, async () => {\n\t\t\t\t\tawait envs.upsertEnvironment({ name: envName });\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\t}\n\n\t// ── docs: configure GitHub Pages ────────────────────────────────────\n\tif (loader.has(\"source\") && config.docs) {\n\t\tconst source = loader.get(\"source\") as Source;\n\t\tconst resolveDeployToken = createFeatureResolver({\n\t\t\tenvName: \"HOLOCRON_DEPLOY_TOKEN\",\n\t\t\tkeyringKey: \"github.deploy\",\n\t\t});\n\t\tlet deployToken: string | undefined;\n\t\ttry {\n\t\t\tdeployToken = resolveDeployToken({ keyring: input.keyring });\n\t\t} catch (err) {\n\t\t\tif (!(err instanceof AuthError)) throw err;\n\t\t}\n\t\tprint(style.step(\"docs\"));\n\t\tif (!deployToken) {\n\t\t\tsteps.push({\n\t\t\t\tcapability: \"source\",\n\t\t\t\tstep: \"configure GitHub Pages\",\n\t\t\t\tstatus: \"skip\",\n\t\t\t\tmessage:\n\t\t\t\t\t\"no deploy token found — set HOLOCRON_DEPLOY_TOKEN or run: holocron auth set github.deploy <PAT>\",\n\t\t\t});\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t} else if (source.configurePages) {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"source\", \"configure GitHub Pages\", dryRun, async () => {\n\t\t\t\t\tawait source.configurePages!(config.docs!, deployToken);\n\t\t\t\t\tconst parts: string[] = [config.docs!.build];\n\t\t\t\t\tif (config.docs!.domain) parts.push(`domain: ${config.docs!.domain}`);\n\t\t\t\t\tif (config.docs!.https) parts.push(\"https: enforced\");\n\t\t\t\t\treturn parts.join(\", \");\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\t}\n\n\t// ── wiki: provision engineering wiki config ──────────────────────────\n\tif (loader.has(\"wiki\")) {\n\t\tconst wiki = loader.get(\"wiki\") as Wiki;\n\t\tprint(style.step(\"wiki\"));\n\t\tsteps.push(\n\t\t\tawait runStep(\"wiki\", \"provision wiki config\", dryRun, async () => {\n\t\t\t\treturn await wiki.provision({ name: config.name });\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\n\t\tconst wikiDns = wiki.dnsRecord?.();\n\t\tconst wikiProxy = wiki.proxyConfig?.();\n\t\tif (wikiDns && loader.has(\"dns\")) {\n\t\t\tconst dns = loader.get(\"dns\") as Dns;\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"dns\", `upsertRecord ${wikiDns.record.name}`, dryRun, async () => {\n\t\t\t\t\tawait dns.upsertRecord(wikiDns.zone, {\n\t\t\t\t\t\t...wikiDns.record,\n\t\t\t\t\t\tttl: 1,\n\t\t\t\t\t\t...(wikiProxy ? { proxied: true } : {}),\n\t\t\t\t\t});\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\n\t\tif (wikiProxy && wikiDns && loader.has(\"workers\")) {\n\t\t\tconst workers = loader.get(\"workers\") as Workers;\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"workers\", `upsertProxy ${wikiDns.record.name}`, dryRun, async () => {\n\t\t\t\t\tawait workers.upsertProxy(wikiDns.record.name, wikiProxy);\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\t}\n\n\t// ── deployment: ensure project + preview infrastructure ─────────────\n\tif (loader.has(\"deployment\")) {\n\t\tconst deploy = loader.get(\"deployment\") as Deployment;\n\t\tprint(style.step(\"deployment\"));\n\n\t\t// delivery.deploy, knowledge.docs, and knowledge.components all share the\n\t\t// same combined production+preview mechanism (astromech.ts) — any one of\n\t\t// them can carry the preview config that drives project/DNS provisioning.\n\t\tconst deployEntry = (config.tasks ?? [])\n\t\t\t.map((e) => (typeof e === \"string\" ? { name: e } : e))\n\t\t\t.find(\n\t\t\t\t(e) => e.name === \"delivery.deploy\" || e.name === \"knowledge.docs\" || e.name === \"knowledge.components\"\n\t\t\t);\n\t\tconst previewCfg = deployEntry?.with\n\t\t\t? extractPreviewConfig(deployEntry.with as Record<string, unknown>, {\n\t\t\t\t\torg: config.org,\n\t\t\t\t\tdomain: config.domain,\n\t\t\t\t})\n\t\t\t: null;\n\t\tconst ensureCustomDomain = async (projectId: string, hostname: string) => {\n\t\t\tif (!deploy.ensureCustomDomain) return;\n\t\t\tconst customDomainDns = { value: null as DnsRecordRequest | null };\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"deployment\", `ensureCustomDomain ${hostname}`, dryRun, async () => {\n\t\t\t\t\tcustomDomainDns.value = await deploy.ensureCustomDomain!(projectId, hostname);\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\n\t\t\tif (customDomainDns.value && loader.has(\"dns\")) {\n\t\t\t\tconst dns = loader.get(\"dns\") as Dns;\n\t\t\t\tconst dnsRecord = customDomainDns.value;\n\t\t\t\tsteps.push(\n\t\t\t\t\tawait runStep(\"dns\", `upsertRecord ${dnsRecord.record.name}`, dryRun, async () => {\n\t\t\t\t\t\tawait dns.upsertRecord(dnsRecord.zone, { ...dnsRecord.record, ttl: 1 });\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\t}\n\t\t};\n\n\t\tif (!previewCfg) {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"deployment\", `ensureProject ${config.name}`, dryRun, async () => {\n\t\t\t\t\tawait deploy.ensureProject({ name: config.name });\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\tif (deploy.domain) {\n\t\t\t\tawait ensureCustomDomain(config.name, deploy.domain);\n\t\t\t}\n\t\t}\n\n\t\tif (previewCfg) {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"deployment\", `ensureProject ${previewCfg.project}`, dryRun, async () => {\n\t\t\t\t\tawait deploy.ensureProject({ name: previewCfg.project });\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\n\t\tif (previewCfg?.domain) {\n\t\t\tawait ensureCustomDomain(previewCfg.project, previewCfg.domain);\n\t\t}\n\n\t\t// Cloudflare Pages doesn't expose its DNS challenge, so retain its\n\t\t// provider-specific apex + wildcard records. Other providers return\n\t\t// their required record from ensureCustomDomain() above.\n\t\tif (previewCfg?.domain && deploy.providerName === \"cloudflare\" && loader.has(\"dns\")) {\n\t\t\tconst dns = loader.get(\"dns\") as Dns;\n\t\t\tconst wildcardDomain = `*.${previewCfg.domain}`;\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"dns\", `upsertRecord ${previewCfg.domain}`, dryRun, async () => {\n\t\t\t\t\tawait dns.upsertRecord(previewCfg.domain!, {\n\t\t\t\t\t\ttype: \"CNAME\",\n\t\t\t\t\t\tname: previewCfg.domain!,\n\t\t\t\t\t\tcontent: `${previewCfg.project}.pages.dev`,\n\t\t\t\t\t\tttl: 1,\n\t\t\t\t\t});\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"dns\", `upsertRecord ${wildcardDomain}`, dryRun, async () => {\n\t\t\t\t\tawait dns.upsertRecord(previewCfg.domain!, {\n\t\t\t\t\t\ttype: \"CNAME\",\n\t\t\t\t\t\tname: wildcardDomain,\n\t\t\t\t\t\tcontent: `${previewCfg.project}.pages.dev`,\n\t\t\t\t\t\tttl: 1,\n\t\t\t\t\t});\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\t}\n\n\t// ── auth: ensure webhook app (optional method) ──────────────────────\n\tif (loader.has(\"auth\")) {\n\t\tconst auth = loader.get(\"auth\") as Auth;\n\t\tprint(style.step(\"auth\"));\n\t\tif (auth.ensureWebhookApp) {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"auth\", \"ensureWebhookApp\", dryRun, async () => {\n\t\t\t\t\tconst result = await auth.ensureWebhookApp!();\n\t\t\t\t\treturn `webhook ${result.alreadyExists ? \"exists\" : \"created\"}`;\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t} else {\n\t\t\tsteps.push({\n\t\t\t\tcapability: \"auth\",\n\t\t\t\tstep: \"ensureWebhookApp\",\n\t\t\t\tstatus: \"skip\",\n\t\t\t\tmessage: \"provider does not implement ensureWebhookApp\",\n\t\t\t});\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\t}\n\n\t// ── vault: bootstrap project + configs, then read-only probe ───────\n\tif (loader.has(\"vault\")) {\n\t\tconst vault = loader.get(\"vault\") as Vault;\n\t\tprint(style.step(\"vault\"));\n\n\t\tif (vault.ensureProject) {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"vault\", `ensureProject ${config.name}`, dryRun, async () => {\n\t\t\t\t\tconst result = await vault.ensureProject!(config.name);\n\t\t\t\t\treturn `project ${result.alreadyExists ? \"exists\" : \"created\"}`;\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\n\t\tif (vault.ensureEnvironment) {\n\t\t\tfor (const envName of [\"dev\", \"stg\", \"prd\"]) {\n\t\t\t\tsteps.push(\n\t\t\t\t\tawait runStep(\"vault\", `ensureEnvironment ${envName}`, dryRun, async () => {\n\t\t\t\t\t\tconst result = await vault.ensureEnvironment!(config.name, envName);\n\t\t\t\t\t\treturn `${envName} ${result.alreadyExists ? \"exists\" : \"created\"}`;\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst keys = await vault.list();\n\t\t\tsteps.push({\n\t\t\t\tcapability: \"vault\",\n\t\t\t\tstep: \"list\",\n\t\t\t\tstatus: \"ok\",\n\t\t\t\tmessage: `${keys.length} keys available`,\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tsteps.push({\n\t\t\t\tcapability: \"vault\",\n\t\t\t\tstep: \"list\",\n\t\t\t\tstatus: \"fail\",\n\t\t\t\tmessage: err instanceof Error ? err.message : String(err),\n\t\t\t});\n\t\t}\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t}\n\n\t// ── errors: provision the tracker project + push the DSN to secrets ─\n\tif (loader.has(\"errors\")) {\n\t\tconst errors = loader.get(\"errors\") as Errors;\n\t\tprint(style.step(\"errors\"));\n\n\t\tif (errors.ensureProject) {\n\t\t\tlet dsn: string | undefined;\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"errors\", `ensureProject ${config.name}`, dryRun, async () => {\n\t\t\t\t\tconst result = await errors.ensureProject!({ name: config.name });\n\t\t\t\t\tdsn = result.dsn;\n\t\t\t\t\treturn `project ${result.alreadyExists ? \"exists\" : \"created\"}`;\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\n\t\t\tif (dsn && loader.has(\"secrets\")) {\n\t\t\t\tconst secrets = loader.get(\"secrets\") as Secrets;\n\t\t\t\tconst { envKeys } = await errors.describe();\n\t\t\t\tfor (const key of envKeys) {\n\t\t\t\t\tsteps.push(\n\t\t\t\t\t\tawait runStep(\"errors\", `secrets set ${key}`, dryRun, async () => {\n\t\t\t\t\t\t\tawait secrets.setSecret({ kind: \"repo\" }, key, dsn!);\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── logs: provision the aggregation datasets ───────────────────────\n\tif (loader.has(\"logs\")) {\n\t\tconst logs = loader.get(\"logs\") as Logs;\n\t\tprint(style.step(\"logs\"));\n\n\t\tif (logs.ensureDataset) {\n\t\t\tfor (const dataset of [\"holocron-ci\", \"holocron-local\"]) {\n\t\t\t\tsteps.push(\n\t\t\t\t\tawait runStep(\"logs\", `ensureDataset ${dataset}`, dryRun, async () => {\n\t\t\t\t\t\tconst result = await logs.ensureDataset!(dataset);\n\t\t\t\t\t\treturn `${dataset} ${result.alreadyExists ? \"exists\" : \"created\"}`;\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── tooling: sync each (many cardinality) ───────────────────────────\n\tif (loader.has(\"tooling\")) {\n\t\tconst tools = loader.get(\"tooling\") as Tooling[];\n\t\tprint(style.step(\"tooling\"));\n\t\tfor (const tool of tools) {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"tooling\", `${tool.providerName}.sync`, dryRun, async () => {\n\t\t\t\t\tawait tool.sync();\n\t\t\t\t})\n\t\t\t);\n\t\t\tprint(formatStep(steps[steps.length - 1]!));\n\t\t}\n\t}\n\n\t// ── skills: install agent skills from registry ──────────────────────\n\tif (config.skills && config.skills.length > 0 && config.agent) {\n\t\tprint(style.step(\"skills\"));\n\t\tif (!(config.agent in AGENT_SYMLINK_PATHS)) {\n\t\t\tsteps.push({\n\t\t\t\tcapability: \"skills\",\n\t\t\t\tstep: \"install skills\",\n\t\t\t\tstatus: \"skip\",\n\t\t\t\tmessage: `agent \"${config.agent}\" has no known skill install path`,\n\t\t\t});\n\t\t} else {\n\t\t\tsteps.push(\n\t\t\t\tawait runStep(\"skills\", \"install skills\", dryRun, async () => {\n\t\t\t\t\treturn await installSkills({\n\t\t\t\t\t\tagent: config.agent!,\n\t\t\t\t\t\tskills: config.skills!,\n\t\t\t\t\t\trepoRoot: input.context.repoRoot,\n\t\t\t\t\t});\n\t\t\t\t})\n\t\t\t);\n\t\t}\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t}\n\n\t// ── prompts: write agent role prompts to .agents/prompts/ ────────────\n\tif (config.agent) {\n\t\tprint(style.step(\"prompts\"));\n\t\tsteps.push(\n\t\t\tawait runStep(\"prompts\", \"install agent prompts\", dryRun, async () => {\n\t\t\t\treturn await installAgentPrompts({ repoRoot: input.context.repoRoot });\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t}\n\n\t// ── engineering: provision docs/decisions/ and docs/engineering/ ─────\n\tif (config.docs) {\n\t\tprint(style.step(\"engineering\"));\n\t\tsteps.push(\n\t\t\tawait runStep(\"engineering\", \"provision engineering structure\", dryRun, async () => {\n\t\t\t\treturn await installEngineeringStructure({ repoRoot: input.context.repoRoot });\n\t\t\t})\n\t\t);\n\t\tprint(formatStep(steps[steps.length - 1]!));\n\t}\n\n\tconst summary = steps.reduce(\n\t\t(acc, s) => {\n\t\t\tif (s.status === \"ok\") acc.ok += 1;\n\t\t\telse if (s.status === \"fail\") acc.fail += 1;\n\t\t\telse if (s.status === \"skip\") acc.skip += 1;\n\t\t\telse if (s.status === \"dry-run\") acc.dryRun += 1;\n\t\t\treturn acc;\n\t\t},\n\t\t{ ok: 0, fail: 0, skip: 0, dryRun: 0 }\n\t);\n\n\tprint(\"\");\n\tconst summaryLine = ` ${summary.ok} ok, ${summary.fail} fail, ${summary.skip} skipped${\n\t\tdryRun ? `, ${summary.dryRun} would-do` : \"\"\n\t}`;\n\tprint(summary.fail > 0 ? style.fail(summaryLine.trim()) : style.success(summaryLine.trim()));\n\n\tconst skippedSteps = steps.filter((s) => s.status === \"skip\");\n\tif (skippedSteps.length > 0) {\n\t\tprint(\"\");\n\t\tprint(style.hint(\" Skipped:\"));\n\t\tfor (const s of skippedSteps) {\n\t\t\t/* v8 ignore next -- all skip steps set message; empty fallback is defensive */\n\t\t\tprint(style.hint(` · ${s.step}${s.message ? ` (${s.message})` : \"\"}`));\n\t\t}\n\t}\n\n\tif (steps.some((s) => s.reason === \"permissions\")) {\n\t\tprint(\"\");\n\t\tprint(style.warn(\"Some steps failed with 403 (insufficient token permissions).\"));\n\t\tprint(style.hint(\" Repo-scoped operations (rulesets, settings, workflows) require a\"));\n\t\tprint(style.hint(\" fine-grained PAT passed via --token or HOLOCRON_ADMIN_TOKEN:\"));\n\t\tprint(\"\");\n\t\tprint(style.hint(\" · Administration — read and write\"));\n\t\tprint(style.hint(\" · Code scanning alerts — read and write\"));\n\t\tprint(style.hint(\" · Contents — read and write\"));\n\t\tprint(style.hint(\" · Secret scanning alerts — read and write\"));\n\t\tprint(style.hint(\" · Workflows — read and write\"));\n\t\tprint(style.hint(\" · Metadata — read (added automatically)\"));\n\t\tprint(\"\");\n\t\tprint(style.hint(\" Org-scoped operations (teams, custom properties) require\"));\n\t\tprint(style.hint(\" HOLOCRON_ORG_TOKEN — a fine-grained PAT with resource owner set to the org:\"));\n\t\tprint(\"\");\n\t\tprint(style.hint(\" · Administration — read and write (repository permission)\"));\n\t\tprint(style.hint(\" · Members — read (organization permission)\"));\n\t\tprint(style.hint(\" · Organization custom properties — read and write (organization permission)\"));\n\t\tprint(style.hint(\" · Metadata — read (repository permission, auto-included)\"));\n\t\tprint(\"\");\n\t\tprint(style.hint(\" Create tokens at: https://github.com/settings/personal-access-tokens/new\"));\n\t\tprint(style.hint(\" Then re-run: holocron setup --token <your-admin-pat>\"));\n\t\tprint(style.hint(\" Store org token: HOLOCRON_ORG_TOKEN env var or keyring key github.org\"));\n\t}\n\n\treturn { steps, summary };\n}\n\n/**\n * Ensure `package.json#scripts.prepare` runs `husky` so git hooks register on\n * install. Merge-only: an existing `prepare` that does more than husky (e.g.\n * `turbo run build` — needed where root config files import a workspace\n * package's `dist/`, theholocron/holocron#654) is preserved and husky is\n * appended. Leaves every other script untouched. Returns `true` when it wrote\n * a change, `false` when already runs husky or there is no `package.json`.\n */\nasync function ensurePrepareScript(repoRoot: string): Promise<boolean> {\n\tconst pkgPath = join(repoRoot, \"package.json\");\n\tlet content: string;\n\ttry {\n\t\tcontent = await readFile(pkgPath, \"utf8\");\n\t} catch {\n\t\treturn false;\n\t}\n\tconst pkg = JSON.parse(content) as { scripts?: Record<string, string> };\n\tconst scripts = pkg.scripts ?? {};\n\tconst current = scripts.prepare?.trim() ?? \"\";\n\t// Already invokes husky (bare, or as a step in a chain) → nothing to do.\n\tif (/(^|[\\s&|;])husky($|[\\s&|;])/.test(current)) return false;\n\tscripts.prepare = current ? `${current} && husky` : \"husky\";\n\tpkg.scripts = scripts;\n\tawait writeFile(pkgPath, JSON.stringify(pkg, null, 2) + \"\\n\", \"utf8\");\n\treturn true;\n}\n","/**\n * `holocron skills` — install, remove, and update agent skills from @theholocron/skills.\n *\n * Unlike `holocron setup`, this command is purely local (no GitHub token\n * required). It reads `agent` and `skills` from the config and installs\n * the listed skills into `.agents/skills/<name>/` with a symlink at the\n * agent-specific path (e.g. `.claude/skills/<name>` for Claude Code).\n *\n * `holocron skills remove [name]` and `holocron skills update [name]` delegate\n * to the corresponding `npx skills` subcommands from the upstream skills CLI.\n */\n\nimport { spawnSync } from \"node:child_process\";\n\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport type { LoadedConfig } from \"../config/load-config.js\";\nimport { getLogger } from \"../logger.js\";\nimport type { RuntimeContext } from \"../plugin/loader.js\";\nimport { installSkills } from \"./setup/index.js\";\n\n// ── shared exec ──────────────────────────────────────────────────────────────\n\ntype ExecFn = (cmd: string, args: string[], opts: { cwd: string }) => { exitCode: number };\n\nconst defaultExec: ExecFn = (cmd, args, opts) => {\n\tconst result = spawnSync(cmd, args, { cwd: opts.cwd, stdio: \"inherit\" });\n\treturn { exitCode: result.status ?? -1 };\n};\n\n// ── install ──────────────────────────────────────────────────────────────────\n\nexport interface RunSkillsInput {\n\tloaded: LoadedConfig;\n\tcontext: RuntimeContext;\n\tprint?: (line: string) => void;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n}\n\nexport async function runSkillsInstall(input: RunSkillsInput): Promise<void> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst config = input.loaded.resolved;\n\n\tif (!config.agent || !config.skills?.length) {\n\t\tprint(\"Nothing to install — set `agent` and `skills` in holocron.config.ts\");\n\t\tlogger.info({ status: \"skip\", reason: \"no agent/skills configured\" }, \"skills install: done\");\n\t\treturn;\n\t}\n\n\tif (input.context.dryRun) {\n\t\tprint(`Would install ${config.skills.length} skill(s) for agent: ${config.agent}`);\n\t\tfor (const name of config.skills) {\n\t\t\tprint(` → would install: ${name}`);\n\t\t}\n\t\tlogger.info({ agent: config.agent, skills: config.skills, status: \"dry-run\" }, \"skills install: done\");\n\t\treturn;\n\t}\n\n\tprint(`Installing ${config.skills.length} skill(s) for agent: ${config.agent}`);\n\tlogger.info({ agent: config.agent, count: config.skills.length }, \"skills install: start\");\n\ttry {\n\t\tconst result = await installSkills({\n\t\t\tagent: config.agent,\n\t\t\tskills: config.skills,\n\t\t\trepoRoot: input.context.repoRoot,\n\t\t});\n\t\tprint(` → ${result}`);\n\t\tlogger.info({ agent: config.agent, skills: config.skills, status: \"ok\" }, \"skills install: done\");\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tprint(` ✗ ${message}`);\n\t\tlogger.warn({ agent: config.agent, reason: message, status: \"fail\" }, \"skills install: done\");\n\t}\n}\n\n// ── remove ───────────────────────────────────────────────────────────────────\n\nexport interface RunSkillsRemoveInput {\n\tcontext: RuntimeContext;\n\t/** Skill name(s) to remove. Omit to remove all installed skills. */\n\tnames?: string[];\n\texec?: ExecFn;\n\tlogger?: Logger;\n}\n\nexport interface SkillsRemoveReport {\n\tstatus: \"ok\" | \"fail\" | \"dry-run\";\n}\n\nexport function runSkillsRemove(input: RunSkillsRemoveInput): SkillsRemoveReport {\n\tconst { dryRun, repoRoot } = input.context;\n\tconst exec = input.exec ?? defaultExec;\n\tconst logger = input.logger ?? getLogger();\n\tconst args = [\"skills\", \"remove\", ...(input.names ?? [])];\n\n\tif (dryRun) {\n\t\tlogger.info({ argv: args }, `Would run: npx ${args.join(\" \")}`);\n\t\treturn { status: \"dry-run\" };\n\t}\n\n\tconst { exitCode } = exec(\"npx\", args, { cwd: repoRoot });\n\treturn { status: exitCode === 0 ? \"ok\" : \"fail\" };\n}\n\n// ── update ───────────────────────────────────────────────────────────────────\n\nexport interface RunSkillsUpdateInput {\n\tcontext: RuntimeContext;\n\t/** When given, update only this skill. Omit to update all. */\n\tname?: string;\n\texec?: ExecFn;\n\tlogger?: Logger;\n}\n\nexport interface SkillsUpdateReport {\n\tstatus: \"ok\" | \"fail\" | \"dry-run\";\n}\n\nexport function runSkillsUpdate(input: RunSkillsUpdateInput): SkillsUpdateReport {\n\tconst { dryRun, repoRoot } = input.context;\n\tconst exec = input.exec ?? defaultExec;\n\tconst logger = input.logger ?? getLogger();\n\tconst args = [\"skills\", \"update\", ...(input.name ? [input.name] : [])];\n\n\tif (dryRun) {\n\t\tlogger.info({ argv: args }, `Would run: npx ${args.join(\" \")}`);\n\t\treturn { status: \"dry-run\" };\n\t}\n\n\tconst { exitCode } = exec(\"npx\", args, { cwd: repoRoot });\n\treturn { status: exitCode === 0 ? \"ok\" : \"fail\" };\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport type { PackagesRegistry } from \"@theholocron/components-doc/markdown\";\nimport { generateReadme } from \"@theholocron/components-doc/markdown\";\nimport type { Logger } from \"@theholocron/observability/core\";\nimport { getClients, getConfigs, getDocs, getPlugins, getSkills, getThemes, getUtils } from \"@theholocron/registry-doc\";\n\nimport type { LoadedConfig } from \"../config/load-config.js\";\nimport { getLogger } from \"../logger.js\";\nimport type { RuntimeContext } from \"../plugin/loader.js\";\nimport { style } from \"../ui/style.js\";\n\nconst MARKER_INSTALL_START = \"<!-- holocron:installation -->\";\nconst MARKER_INSTALL_END = \"<!-- /holocron:installation -->\";\n\nconst REGISTRY_MAP: Record<string, () => PackagesRegistry> = {\n\t\"@theholocron/clients\": getClients,\n\t\"@theholocron/configs\": getConfigs,\n\t\"@theholocron/docs\": getDocs,\n\t\"@theholocron/holocron\": getPlugins,\n\t\"@theholocron/skills\": getSkills,\n\t\"@theholocron/themes\": getThemes,\n\t\"@theholocron/utils\": getUtils,\n};\n\ninterface PackageJson {\n\tname?: string;\n\thomepage?: string;\n\tprivate?: boolean;\n\tmain?: string;\n\texports?: unknown;\n\tbin?: Record<string, string> | string;\n\tpeerDependencies?: Record<string, string>;\n\tscripts?: Record<string, string>;\n\tworkspaces?: string[];\n}\n\nexport interface RunSyncReadmeInput {\n\tloaded: LoadedConfig;\n\tcontext: RuntimeContext;\n\tprint?: (line: string) => void;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n\treadFileFn?: (path: string, encoding: BufferEncoding) => Promise<string>;\n\twriteFileFn?: (path: string, content: string, encoding: BufferEncoding) => Promise<void>;\n}\n\nexport interface SyncReadmeReport {\n\tstatus: \"ok\" | \"fail\" | \"dry-run\";\n\tupdated: boolean;\n\tmessage?: string;\n}\n\nfunction generateInstallBlock(pkg: PackageJson, homepage = \"\"): string {\n\tconst { name = \"\", bin, peerDependencies = {} } = pkg;\n\tconst isCli = Boolean(bin);\n\tconst isReact = Boolean(peerDependencies[\"react\"]);\n\t// A private package with no bin and nothing importable (no `main`, no\n\t// `exports`) is a workspace root or template — not something to `pnpm\n\t// install` or `import` from.\n\tconst isConsumable = isCli || !pkg.private || Boolean(pkg.main) || pkg.exports !== undefined;\n\tconst lines: string[] = [];\n\n\tlines.push(\"## Installation\", \"\");\n\n\tif (!isConsumable) {\n\t\tlines.push(\n\t\t\t\"This repository is a workspace root — it is not published. See the\",\n\t\t\t\"packages under [`packages/`](./packages) for the tools it ships.\"\n\t\t);\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\tif (isCli) {\n\t\tlines.push(\"```bash\", `npm install --global ${name}`, \"```\");\n\t} else {\n\t\tlines.push(\"```bash\", `pnpm install ${name}`, \"```\");\n\t}\n\n\tlines.push(\"\", \"## Usage\", \"\");\n\n\tif (isCli) {\n\t\tconst commands =\n\t\t\ttypeof bin === \"string\" ? [name.split(\"/\").at(-1)!] : Object.keys(bin as Record<string, string>);\n\t\tlines.push(\"```bash\");\n\t\tfor (const cmd of commands) {\n\t\t\tlines.push(`${cmd} --help`);\n\t\t}\n\t\tlines.push(\"```\");\n\t} else if (isReact) {\n\t\tlines.push(\"```tsx\", `import {} from \"${name}\";`, \"\", \"function App() {\", ` return <></>;`, \"}\", \"```\");\n\t} else if (homepage) {\n\t\t// Exports aren't known at sync time — link the docs rather than emit a\n\t\t// meaningless empty-brace import.\n\t\tlines.push(`See the [documentation](${homepage}) for the API.`);\n\t} else {\n\t\tlines.push(\"See the package documentation for the API.\");\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\n/**\n * Replace content between `<!-- holocron:marker -->` / `<!-- /holocron:marker -->` tags.\n * Returns the updated README string, or the original if the marker pair is absent.\n */\nfunction replaceMarkerBlock(readme: string, marker: string, content: string): string {\n\tconst start = `<!-- holocron:${marker} -->`;\n\tconst end = `<!-- /holocron:${marker} -->`;\n\tconst lines = readme.split(\"\\n\");\n\tconst startIdx = lines.findIndex((l) => l.trim() === start);\n\tconst endIdx = lines.findIndex((l) => l.trim() === end);\n\tif (startIdx === -1 || endIdx === -1 || endIdx <= startIdx) return readme;\n\tlines.splice(startIdx + 1, endIdx - startIdx - 1, \"\", ...content.split(\"\\n\"), \"\");\n\treturn lines.join(\"\\n\");\n}\n\n/**\n * Apply all README updates in a single read-write cycle.\n * Returns true if the README was found (even if no changes were needed).\n */\nasync function updateReadme(\n\trepoRoot: string,\n\tinstallBlock: string,\n\tsections: Record<string, string>,\n\tdryRun: boolean,\n\treadFileFn: (path: string, encoding: BufferEncoding) => Promise<string>,\n\twriteFileFn: (path: string, content: string, encoding: BufferEncoding) => Promise<void>\n): Promise<boolean> {\n\tconst readmePath = join(repoRoot, \"README.md\");\n\tlet content: string;\n\ttry {\n\t\tcontent = await readFileFn(readmePath, \"utf8\");\n\t} catch {\n\t\treturn false;\n\t}\n\n\tlet updated = content;\n\n\t// Replace existing marker blocks for generated sections\n\tfor (const [marker, text] of Object.entries(sections)) {\n\t\tupdated = replaceMarkerBlock(updated, marker, text);\n\t}\n\n\t// Replace or insert installation block\n\tconst lines = updated.split(\"\\n\");\n\tconst startIdx = lines.findIndex((l) => l.trim() === MARKER_INSTALL_START);\n\tconst endIdx = lines.findIndex((l) => l.trim() === MARKER_INSTALL_END);\n\tconst blockLines = installBlock.split(\"\\n\");\n\n\tif (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {\n\t\tlines.splice(startIdx + 1, endIdx - startIdx - 1, \"\", ...blockLines, \"\");\n\t\tupdated = lines.join(\"\\n\");\n\t} else {\n\t\tconst descEnd = lines.findIndex((l) => l.trim() === \"<!-- /holocron:description -->\");\n\t\tconst insertAfter = descEnd !== -1 ? descEnd : lines.findIndex((l) => /^# /.test(l));\n\t\tif (insertAfter === -1) return false;\n\t\tlines.splice(insertAfter + 1, 0, \"\", MARKER_INSTALL_START, \"\", ...blockLines, \"\", MARKER_INSTALL_END);\n\t\tupdated = lines.join(\"\\n\");\n\t}\n\n\tif (!dryRun) {\n\t\tawait writeFileFn(readmePath, updated, \"utf8\");\n\t}\n\treturn true;\n}\n\nasync function updateIndexMdxDescription(\n\trepoRoot: string,\n\tdescription: string,\n\tdryRun: boolean,\n\treadFileFn: (path: string, encoding: BufferEncoding) => Promise<string>,\n\twriteFileFn: (path: string, content: string, encoding: BufferEncoding) => Promise<void>\n): Promise<void> {\n\tconst mdxPath = join(repoRoot, \"docs\", \"src\", \"content\", \"docs\", \"index.mdx\");\n\tlet content: string;\n\ttry {\n\t\tcontent = await readFileFn(mdxPath, \"utf8\");\n\t} catch {\n\t\treturn; // file doesn't exist — skip silently\n\t}\n\tconst updated = content.replace(/^(description:\\s*).*$/m, `$1${description}`);\n\tif (updated !== content && !dryRun) {\n\t\tawait writeFileFn(mdxPath, updated, \"utf8\");\n\t}\n}\n\nexport async function runSyncReadme(input: RunSyncReadmeInput): Promise<SyncReadmeReport> {\n\tconst { loaded, context, print = console.log, readFileFn = readFile, writeFileFn = writeFile } = input;\n\tconst logger = input.logger ?? getLogger();\n\n\tconst { repoRoot, dryRun = false } = context;\n\n\tconst namespaces = loaded.resolved.env?.namespaces ?? [];\n\n\tprint(style.header(`Syncing README installation block${dryRun ? \" (dry-run)\" : \"\"}…`));\n\tif (namespaces.length > 0) {\n\t\tprint(style.hint(` namespaces: ${namespaces.join(\", \")}`));\n\t}\n\n\t// Read package.json\n\tlet pkg: PackageJson;\n\ttry {\n\t\tconst raw = await readFileFn(join(repoRoot, \"package.json\"), \"utf8\");\n\t\tpkg = JSON.parse(raw) as PackageJson;\n\t} catch {\n\t\tlogger.warn({ repoRoot, reason: \"could not read package.json\" }, \"sync readme: done\");\n\t\treturn { status: \"fail\", updated: false, message: \"Could not read package.json\" };\n\t}\n\n\t// Assemble generated sections (4.3)\n\tconst description = loaded.resolved.description ?? \"\";\n\tconst homepage = loaded.resolved.homepage ?? pkg.homepage ?? \"\";\n\tconst scripts = pkg.scripts ?? {};\n\tconst packages = pkg.name ? REGISTRY_MAP[pkg.name]?.() : undefined;\n\n\tconst sections = generateReadme({ description, homepage, scripts, packages });\n\tconst markerSections: Record<string, string> = {\n\t\t...(sections.packages !== undefined && { packages: sections.packages }),\n\t\tdevelopment: sections.development,\n\t\treleases: sections.releases,\n\t};\n\n\t// Single read-write pass for all README changes\n\tconst installBlock = generateInstallBlock(pkg, homepage);\n\tconst updated = await updateReadme(repoRoot, installBlock, markerSections, dryRun, readFileFn, writeFileFn);\n\n\tif (!updated) {\n\t\tprint(style.warn(\"README.md not found or has no writable location for installation block\"));\n\t\tlogger.warn({ repoRoot, reason: \"README.md not found / no marker block\" }, \"sync readme: done\");\n\t\treturn { status: \"fail\", updated: false, message: \"README.md update failed\" };\n\t}\n\n\t// Update docs/src/content/docs/index.mdx frontmatter description (4.4)\n\tif (description) {\n\t\tawait updateIndexMdxDescription(repoRoot, description, dryRun, readFileFn, writeFileFn);\n\t}\n\n\tprint(dryRun ? style.hint(\" would update README.md\") : style.success(\" updated README.md\"));\n\tconst status = dryRun ? \"dry-run\" : \"ok\";\n\tlogger.info({ repoRoot, status, updated }, \"sync readme: done\");\n\treturn { status, updated };\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { createRestClient } from \"@theholocron/http-client\";\n\nimport type { LoadedConfig } from \"../config/load-config.js\";\nimport type { RuntimeContext } from \"../plugin/loader.js\";\nimport type { SetupStepResult } from \"./setup/index.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface WikiRepo {\n\tdisplayName: string;\n\tbasepath: string;\n\t/** Full custom domain with basepath, e.g. \"wiki.theholocron.dev/skills\". */\n\tdomain?: string;\n}\n\nexport interface RunSyncWikiInput {\n\tloaded: LoadedConfig;\n\tcontext: RuntimeContext;\n\ttoken?: string;\n\tfetch?: typeof globalThis.fetch;\n}\n\n// ---------------------------------------------------------------------------\n// Token resolution\n// ---------------------------------------------------------------------------\n\nfunction resolveToken(input: RunSyncWikiInput): string | undefined {\n\treturn (\n\t\tinput.token ??\n\t\tinput.context.cliToken ??\n\t\tprocess.env.HOLOCRON_READ_TOKEN ??\n\t\tprocess.env.GH_TOKEN ??\n\t\tprocess.env.GITHUB_TOKEN\n\t);\n}\n\n// ---------------------------------------------------------------------------\n// Config parsing helpers\n// ---------------------------------------------------------------------------\n\nfunction deriveBasepath(domain: string | undefined, repoName: string): string {\n\tif (domain) {\n\t\tconst slashIdx = domain.indexOf(\"/\");\n\t\tif (slashIdx !== -1) return domain.slice(slashIdx + 1);\n\t}\n\treturn repoName;\n}\n\nfunction toNavLabel(basepath: string): string {\n\treturn basepath\n\t\t.split(\"-\")\n\t\t.map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n\t\t.join(\" \");\n}\n\ninterface OrgRepo {\n\tname: string;\n\tfull_name: string;\n\tarchived: boolean;\n}\n\ninterface FileContents {\n\tcontent: string;\n\tencoding: string;\n}\n\nfunction extractFromJson(raw: string, repoName: string): WikiRepo | null {\n\tlet config: Record<string, unknown>;\n\ttry {\n\t\tconfig = JSON.parse(raw) as Record<string, unknown>;\n\t} catch {\n\t\treturn null;\n\t}\n\tconst providers = config.providers as Record<string, unknown> | undefined;\n\tif (!providers?.wiki) return null;\n\n\tconst wikiEntry = providers.wiki;\n\tlet domain: string | undefined;\n\n\tif (Array.isArray(wikiEntry) && wikiEntry.length === 2) {\n\t\tconst opts = wikiEntry[1] as Record<string, unknown>;\n\t\tdomain = typeof opts.domain === \"string\" ? opts.domain : undefined;\n\t}\n\n\tconst basepath = deriveBasepath(domain, repoName);\n\treturn { displayName: toNavLabel(basepath), basepath, ...(domain ? { domain } : {}) };\n}\n\nfunction extractFromTs(raw: string, repoName: string): WikiRepo | null {\n\tconst hasWikiProvider = /providers\\s*:\\s*\\{[^}]*\\bwiki\\b/s.test(raw);\n\tconst hasWikiPreset = /\\bwikiCapability\\b|\\bwiki\\s*\\(\\s*\\)/.test(raw);\n\t/* c8 ignore next */\n\tif (!hasWikiProvider && !hasWikiPreset) return null;\n\n\tconst domainMatch = raw.match(/\\bdomain\\s*:\\s*[\"']([^\"']+)[\"']/);\n\tconst domain = domainMatch?.[1];\n\n\tconst basepath = deriveBasepath(domain, repoName);\n\treturn { displayName: toNavLabel(basepath), basepath, ...(domain ? { domain } : {}) };\n}\n\n// ---------------------------------------------------------------------------\n// Discovery\n// ---------------------------------------------------------------------------\n\nexport async function discoverWikiRepos(\n\torg: string,\n\ttoken: string,\n\tfetchFn?: typeof globalThis.fetch\n): Promise<WikiRepo[]> {\n\tconst rest = createRestClient({\n\t\tbaseUrl: \"https://api.github.com\",\n\t\ttoken,\n\t\textraHeaders: {\n\t\t\taccept: \"application/vnd.github+json\",\n\t\t\t\"x-github-api-version\": \"2022-11-28\",\n\t\t},\n\t\tvendor: \"GitHub\",\n\t\tfetch: fetchFn,\n\t});\n\n\tconst allRepos: OrgRepo[] = [];\n\tlet page = 1;\n\twhile (true) {\n\t\tconst batch = await rest.request<OrgRepo[]>(`/orgs/${org}/repos`, {\n\t\t\tquery: { per_page: \"100\", page: String(page), type: \"all\" },\n\t\t});\n\t\tallRepos.push(...batch);\n\t\tif (batch.length < 100) break;\n\t\tpage++;\n\t}\n\n\tconst repos: WikiRepo[] = [];\n\n\tfor (const repo of allRepos.filter((r) => !r.archived)) {\n\t\tlet found: WikiRepo | null = null;\n\n\t\ttry {\n\t\t\tconst contents = await rest.request<FileContents>(`/repos/${repo.full_name}/contents/holocron.config.json`);\n\t\t\tif (contents.encoding === \"base64\") {\n\t\t\t\tconst raw = Buffer.from(contents.content.replace(/\\s/g, \"\"), \"base64\").toString(\"utf8\");\n\t\t\t\tfound = extractFromJson(raw, repo.name);\n\t\t\t}\n\t\t} catch {\n\t\t\t// no JSON config — try TS\n\t\t}\n\n\t\tif (!found) {\n\t\t\ttry {\n\t\t\t\tconst contents = await rest.request<FileContents>(\n\t\t\t\t\t`/repos/${repo.full_name}/contents/holocron.config.ts`\n\t\t\t\t);\n\t\t\t\tif (contents.encoding === \"base64\") {\n\t\t\t\t\tconst raw = Buffer.from(contents.content.replace(/\\s/g, \"\"), \"base64\").toString(\"utf8\");\n\t\t\t\t\tfound = extractFromTs(raw, repo.name);\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// no config found — skip\n\t\t\t}\n\t\t}\n\n\t\tif (found) repos.push(found);\n\t}\n\n\trepos.sort((a, b) => a.basepath.localeCompare(b.basepath));\n\treturn repos;\n}\n\n// ---------------------------------------------------------------------------\n// navbar-links block builder\n// ---------------------------------------------------------------------------\n\n/**\n * Builds the complete navbar-links YAML block for a given repo.\n *\n * Includes:\n * - A GitHub button linking to the repo itself (always first)\n * - A single \"Wiki\" dropdown containing minimal links to every other\n * wiki-enabled repo (excluding self), keeping the navbar uncluttered\n * regardless of how many repos are in the org.\n *\n * The block is replaced wholesale on each sync so removed/added wikis\n * stay in sync automatically.\n */\nexport function buildNavbarLinks(repos: WikiRepo[], currentBasepath: string, repoFullName: string): string {\n\tconst lines = [`navbar-links:`, ` - type: github`, ` value: https://github.com/${repoFullName}`];\n\n\tconst others = repos.filter((r) => r.basepath !== currentBasepath);\n\tif (others.length > 0) {\n\t\tlines.push(` - type: dropdown`, ` text: Other Projects`, ` icon: fa-duotone fa-book`, ` links:`);\n\t\tfor (const repo of others) {\n\t\t\tconst url = repo.domain ? `https://${repo.domain}` : `https://wiki.theholocron.dev/${repo.basepath}`;\n\t\t\tlines.push(` - href: ${url}`, ` text: ${repo.displayName}`);\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// fern/docs.yml updater\n// ---------------------------------------------------------------------------\n\n/**\n * Idempotently ensures `edit-this-page:` (inside instances) is present and\n * replaces `navbar-links:` with the provided shared block.\n *\n * Returns true when the file was modified.\n * Throws when fern/docs.yml does not exist.\n */\nexport async function mergeWikiConfig(\n\tdocsYmlPath: string,\n\tconfig: { owner: string; repoName: string; navbarBlock: string }\n): Promise<boolean> {\n\tlet content: string;\n\ttry {\n\t\tcontent = await readFile(docsYmlPath, \"utf8\");\n\t} catch {\n\t\tthrow new Error(`fern/docs.yml not found at ${docsYmlPath}`);\n\t}\n\n\tlet updated = content;\n\n\t// 1. Ensure edit-this-page: is nested inside the instances block entry.\n\tif (!updated.includes(\"edit-this-page:\")) {\n\t\tconst editBlock = [\n\t\t\t` edit-this-page:`,\n\t\t\t` github:`,\n\t\t\t` owner: ${config.owner}`,\n\t\t\t` repo: ${config.repoName}`,\n\t\t\t` branch: main`,\n\t\t].join(\"\\n\");\n\n\t\tif (/^ {4}multi-source: true$/m.test(updated)) {\n\t\t\tupdated = updated.replace(/^( {4}multi-source: true)$/m, `$1\\n${editBlock}`);\n\t\t} else if (/^ {4}custom-domain: .+$/m.test(updated)) {\n\t\t\tupdated = updated.replace(/^( {4}custom-domain: .+)$/m, `$1\\n${editBlock}`);\n\t\t} else {\n\t\t\t// Fallback: insert after the \" - url:\" list item line\n\t\t\tupdated = updated.replace(/^( {2}- url: .+)$/m, `$1\\n${editBlock}`);\n\t\t}\n\t}\n\n\t// 2. Replace navbar-links: wholesale so removed/added wikis stay in sync.\n\tconst navbarRe = /^navbar-links:(?:\\n[ \\t][^\\n]*)*/m;\n\tif (navbarRe.test(updated)) {\n\t\tupdated = updated.replace(navbarRe, config.navbarBlock);\n\t} else if (/^colors:/m.test(updated)) {\n\t\tupdated = updated.replace(/^(colors:)/m, `${config.navbarBlock}\\n\\n$1`);\n\t} else {\n\t\tupdated = updated.trimEnd() + \"\\n\\n\" + config.navbarBlock + \"\\n\";\n\t}\n\n\tif (updated !== content) {\n\t\tawait writeFile(docsYmlPath, updated, \"utf8\");\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n// ---------------------------------------------------------------------------\n// Validate\n// ---------------------------------------------------------------------------\n\n/**\n * Checks that fern/docs.yml has the required wiki header fields.\n * Returns a list of missing field names; empty means valid.\n */\nexport async function validateWikiConfig(docsYmlPath: string): Promise<string[]> {\n\tlet content: string;\n\ttry {\n\t\tcontent = await readFile(docsYmlPath, \"utf8\");\n\t} catch {\n\t\treturn [\"fern/docs.yml not found\"];\n\t}\n\n\tconst missing: string[] = [];\n\tif (!content.includes(\"edit-this-page:\")) missing.push(\"edit-this-page\");\n\tif (!content.includes(\"navbar-links:\")) missing.push(\"navbar-links\");\n\treturn missing;\n}\n\n// ---------------------------------------------------------------------------\n// runSyncWiki\n// ---------------------------------------------------------------------------\n\nexport async function runSyncWiki(input: RunSyncWikiInput): Promise<SetupStepResult> {\n\tconst config = input.loaded.resolved;\n\tconst dryRun = input.context.dryRun ?? false;\n\n\tif (!config.providers.wiki) {\n\t\treturn { capability: \"local\", step: \"sync wiki\", status: \"skip\", message: \"no wiki provider configured\" };\n\t}\n\n\tconst rawRepo = input.context.repo ?? config.repo?.name;\n\tif (!rawRepo) {\n\t\treturn { capability: \"local\", step: \"sync wiki\", status: \"skip\", message: \"no repo configured\" };\n\t}\n\n\tconst [owner, repoName] = rawRepo.split(\"/\") as [string, string | undefined];\n\tif (!owner || !repoName) {\n\t\treturn {\n\t\t\tcapability: \"local\",\n\t\t\tstep: \"sync wiki\",\n\t\t\tstatus: \"skip\",\n\t\t\tmessage: \"repo must be owner/name format\",\n\t\t};\n\t}\n\n\tconst org = config.org ?? owner;\n\n\tconst token = resolveToken(input);\n\tif (!token) {\n\t\treturn {\n\t\t\tcapability: \"local\",\n\t\t\tstep: \"sync wiki\",\n\t\t\tstatus: \"skip\",\n\t\t\tmessage: \"no GitHub token available (set HOLOCRON_READ_TOKEN or GH_TOKEN)\",\n\t\t};\n\t}\n\n\tif (dryRun) {\n\t\treturn { capability: \"local\", step: \"sync wiki\", status: \"dry-run\" };\n\t}\n\n\tconst docsYmlPath = join(input.context.repoRoot, \"fern\", \"docs.yml\");\n\n\ttry {\n\t\tconst repos = await discoverWikiRepos(org, token, input.fetch);\n\n\t\t// Derive the current repo's basepath from its own wiki config so we\n\t\t// can exclude it from the nav links it renders for itself.\n\t\t// config.providers.wiki is already resolved to { tuple: { options } } form.\n\t\tconst wikiOpts = (config.providers.wiki as unknown as { tuple?: { options?: Record<string, unknown> } })?.tuple\n\t\t\t?.options;\n\t\tconst domain = typeof wikiOpts?.domain === \"string\" ? wikiOpts.domain : undefined;\n\t\tconst currentBasepath = deriveBasepath(domain, repoName);\n\n\t\tconst navbarBlock = buildNavbarLinks(repos, currentBasepath, rawRepo);\n\n\t\tconst changed = await mergeWikiConfig(docsYmlPath, { owner, repoName, navbarBlock });\n\t\treturn {\n\t\t\tcapability: \"local\",\n\t\t\tstep: \"sync wiki\",\n\t\t\tstatus: \"ok\",\n\t\t\tmessage: changed ? `updated (${repos.length} wiki repos discovered)` : \"already up to date\",\n\t\t};\n\t} catch (err) {\n\t\treturn {\n\t\t\tcapability: \"local\",\n\t\t\tstep: \"sync wiki\",\n\t\t\tstatus: \"fail\",\n\t\t\tmessage: err instanceof Error ? err.message : /* c8 ignore next */ String(err),\n\t\t};\n\t}\n}\n","import { access, mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { basename, join } from \"node:path\";\n\nimport { createAstromech, KNOWN_WORKFLOWS, readWorkspacePackages } from \"@theholocron/astromech\";\nimport type { TasksConfig } from \"@theholocron/astromech/config\";\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport type { LoadedConfig } from \"../config/load-config.js\";\nimport { getLogger } from \"../logger.js\";\nimport type { Source } from \"../plugin/capabilities.js\";\nimport { PluginLoader, type RuntimeContext } from \"../plugin/loader.js\";\nimport { createHeader } from \"../utils/create-header.js\";\nimport type { SetupPrintLine, SetupReport, SetupStepResult } from \"./setup/index.js\";\nimport {\n\tCANONICAL_LABELS,\n\tderiveCapabilities,\n\tderiveCompliance,\n\tderiveProfile,\n\tderiveStack,\n\treadWorkspacePackageJsons,\n\tSTALE_LABELS,\n} from \"./setup/index.js\";\n\n// The only content this file ever prefixes with workflowHeader() is thin-caller\n// workflow content from astromech.thinCallers() — sync.ts just writes it. The\n// actual template/generation logic a contributor would edit lives there.\nconst { workflowHeader } = createHeader({\n\tsource: \"packages/astromech/src/thin-callers.ts\",\n\ttool: \"holocron sync\",\n});\nimport { runSyncReadme } from \"./sync-readme.js\";\nimport { runSyncWiki } from \"./sync-wiki.js\";\n\nexport const SYNC_STEPS = [\n\t\"labels\",\n\t\"properties\",\n\t\"teams\",\n\t\"topics\",\n\t\"keywords\",\n\t\"description\",\n\t\"homepage\",\n\t\"readme\",\n\t\"workflows\",\n\t\"scripts\",\n\t\"turbo\",\n\t\"wiki\",\n] as const;\nexport type SyncStep = (typeof SYNC_STEPS)[number];\n\n// Steps that write to the local filesystem only — no provider token needed.\nconst LOCAL_STEPS = new Set<SyncStep>([\n\t\"keywords\",\n\t\"description\",\n\t\"homepage\",\n\t\"readme\",\n\t\"workflows\",\n\t\"scripts\",\n\t\"turbo\",\n\t\"wiki\",\n]);\n\nexport interface RunSyncInput {\n\tloaded: LoadedConfig;\n\tcontext: RuntimeContext;\n\tsteps?: string[];\n\tloader?: PluginLoader;\n\tprint?: SetupPrintLine;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n}\n\nexport async function runSync(input: RunSyncInput): Promise<SetupReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst loader = input.loader ?? new PluginLoader(input.loaded.resolved, input.context);\n\n\tconst config = input.loaded.resolved;\n\tconst dryRun = input.context.dryRun ?? false;\n\tconst requestedSteps = input.steps;\n\tconst steps: SetupStepResult[] = [];\n\n\tlogger.info({ config: config.name, steps: requestedSteps ?? \"all\", dryRun: dryRun || undefined }, \"sync: start\");\n\n\t// `load()` soft-skips any plugin it can't load (missing token, package\n\t// not installed). Remote steps then push a `skip` result when\n\t// `source` is absent; local steps (keywords, description, readme…)\n\t// write to disk regardless.\n\tawait loader.load();\n\tfor (const failure of loader.loadFailures()) {\n\t\tlogger.warn(\n\t\t\t{ capability: failure.key, provider: failure.provider, reason: failure.error.message },\n\t\t\t`sync: plugin ${failure.provider} unavailable`\n\t\t);\n\t}\n\n\tprint(`Holocron sync — ${config.name}${dryRun ? \" (dry-run)\" : \"\"}`);\n\tprint(` config: ${input.loaded.filepath}`);\n\tprint(\"\");\n\n\tif (loader.has(\"source\")) {\n\t\tconst source = loader.get(\"source\") as Source;\n\t\tprint(\" → source\");\n\n\t\tfor (const stepName of SYNC_STEPS) {\n\t\t\tif (requestedSteps !== undefined && !requestedSteps.includes(stepName)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// Local steps are handled below, outside this block.\n\t\t\tif (LOCAL_STEPS.has(stepName)) continue;\n\n\t\t\tif (stepName === \"labels\") {\n\t\t\t\tif (source.syncLabels) {\n\t\t\t\t\tsteps.push(\n\t\t\t\t\t\tawait runSyncStep(\"source\", \"sync labels\", dryRun, () =>\n\t\t\t\t\t\t\tsource.syncLabels!(CANONICAL_LABELS, STALE_LABELS)\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t} else {\n\t\t\t\t\tsteps.push({\n\t\t\t\t\t\tcapability: \"source\",\n\t\t\t\t\t\tstep: \"sync labels\",\n\t\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\t\tmessage: \"provider does not implement syncLabels\",\n\t\t\t\t\t});\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (stepName === \"properties\") {\n\t\t\t\tif (source.syncProperties) {\n\t\t\t\t\tconst repo = config.repo;\n\t\t\t\t\tconst properties: Record<string, string | string[]> = {};\n\t\t\t\t\tconst effectivePreset = repo?.protection;\n\t\t\t\t\tif (effectivePreset && effectivePreset !== \"none\")\n\t\t\t\t\t\tproperties[\"holocron_branch_protection_level\"] = effectivePreset;\n\t\t\t\t\tconst isMonorepo = await access(join(input.context.repoRoot, \"pnpm-workspace.yaml\"))\n\t\t\t\t\t\t.then(() => true)\n\t\t\t\t\t\t.catch(() => false);\n\t\t\t\t\tproperties[\"monorepo\"] = String(isMonorepo);\n\t\t\t\t\tconst manual = repo?.properties ?? {};\n\t\t\t\t\tif (manual.lifecycle) properties[\"lifecycle\"] = manual.lifecycle;\n\t\t\t\t\tif (manual.open_source !== undefined) properties[\"open_source\"] = String(manual.open_source);\n\t\t\t\t\tif (manual.runtime_environment) properties[\"runtime_environment\"] = manual.runtime_environment;\n\t\t\t\t\tif (manual.uses_external_packages !== undefined)\n\t\t\t\t\t\tproperties[\"uses_external_packages\"] = String(manual.uses_external_packages);\n\n\t\t\t\t\t// #677 — derived fields, distinct from the manual ones above: signal\n\t\t\t\t\t// that isn't an explicit holocron.config.ts field today (framework\n\t\t\t\t\t// choice, repo archetype, capability drift).\n\t\t\t\t\t{\n\t\t\t\t\t\tconst rootPackageJson = await readFile(join(input.context.repoRoot, \"package.json\"), \"utf8\")\n\t\t\t\t\t\t\t.then((raw) => JSON.parse(raw) as Parameters<typeof deriveStack>[0])\n\t\t\t\t\t\t\t.catch(() => null);\n\t\t\t\t\t\tconst workspacePackages = readWorkspacePackages(input.context.repoRoot);\n\t\t\t\t\t\tconst workspacePackageJsons = await readWorkspacePackageJsons(\n\t\t\t\t\t\t\tinput.context.repoRoot,\n\t\t\t\t\t\t\tworkspacePackages\n\t\t\t\t\t\t);\n\t\t\t\t\t\tproperties[\"holocron_profile\"] = deriveProfile({\n\t\t\t\t\t\t\trootPackageJson,\n\t\t\t\t\t\t\trepoName: basename(input.context.repoRoot),\n\t\t\t\t\t\t\tisMonorepo,\n\t\t\t\t\t\t\tworkspacePackageJsons,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tproperties[\"holocron_stack\"] = deriveStack(rootPackageJson);\n\t\t\t\t\t\tconst capabilities = deriveCapabilities(config.providers);\n\t\t\t\t\t\tproperties[\"holocron_capabilities\"] = capabilities;\n\t\t\t\t\t\tproperties[\"holocron_compliance\"] = deriveCompliance(capabilities);\n\t\t\t\t\t}\n\n\t\t\t\t\tsteps.push(\n\t\t\t\t\t\tawait runSyncStep(\"source\", \"sync properties\", dryRun, () => source.syncProperties!(properties))\n\t\t\t\t\t);\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t} else {\n\t\t\t\t\tsteps.push({\n\t\t\t\t\t\tcapability: \"source\",\n\t\t\t\t\t\tstep: \"sync properties\",\n\t\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\t\tmessage: \"provider does not implement syncProperties\",\n\t\t\t\t\t});\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (stepName === \"teams\") {\n\t\t\t\tconst teams = config.repo?.teams ?? [];\n\t\t\t\tif (teams.length === 0) {\n\t\t\t\t\tsteps.push({\n\t\t\t\t\t\tcapability: \"source\",\n\t\t\t\t\t\tstep: \"sync teams\",\n\t\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\t\tmessage: \"no teams configured\",\n\t\t\t\t\t});\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t} else if (source.syncTeams) {\n\t\t\t\t\tsteps.push(await runSyncStep(\"source\", \"sync teams\", dryRun, () => source.syncTeams!(teams)));\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\n\t\t\t\t\tconst repoCoord = input.context.repo ?? config.repo?.name ?? \"\";\n\t\t\t\t\tconst org = repoCoord.includes(\"/\") ? repoCoord.split(\"/\")[0]! : \"\";\n\t\t\t\t\tconst writeableTeams = teams\n\t\t\t\t\t\t.map((t) => (typeof t === \"string\" ? { slug: t, permission: \"push\" as const } : t))\n\t\t\t\t\t\t.filter((t) => [\"push\", \"maintain\", \"admin\"].includes(t.permission));\n\t\t\t\t\tif (org && writeableTeams.length > 0) {\n\t\t\t\t\t\tsteps.push(\n\t\t\t\t\t\t\tawait runSyncStep(\"source\", \"write .github/CODEOWNERS\", dryRun, async () => {\n\t\t\t\t\t\t\t\tconst content = writeableTeams.map((t) => `* @${org}/${t.slug}`).join(\"\\n\") + \"\\n\";\n\t\t\t\t\t\t\t\tawait source.writeRepoFile(\".github/CODEOWNERS\", content);\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t);\n\t\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tsteps.push({\n\t\t\t\t\t\tcapability: \"source\",\n\t\t\t\t\t\tstep: \"sync teams\",\n\t\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\t\tmessage: \"provider does not implement syncTeams\",\n\t\t\t\t\t});\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (stepName === \"topics\") {\n\t\t\t\tconst topics = config.repo?.topics ?? [];\n\t\t\t\tif (topics.length === 0) {\n\t\t\t\t\tsteps.push({\n\t\t\t\t\t\tcapability: \"source\",\n\t\t\t\t\t\tstep: \"sync topics\",\n\t\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\t\tmessage: \"no topics configured\",\n\t\t\t\t\t});\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t} else if (source.syncTopics) {\n\t\t\t\t\tsteps.push(await runSyncStep(\"source\", \"sync topics\", dryRun, () => source.syncTopics!(topics)));\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t} else {\n\t\t\t\t\tsteps.push({\n\t\t\t\t\t\tcapability: \"source\",\n\t\t\t\t\t\tstep: \"sync topics\",\n\t\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\t\tmessage: \"provider does not implement syncTopics\",\n\t\t\t\t\t});\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Report unknown step names\n\t\tif (requestedSteps) {\n\t\t\tfor (const name of requestedSteps) {\n\t\t\t\tif (!(SYNC_STEPS as ReadonlyArray<string>).includes(name)) {\n\t\t\t\t\tsteps.push({\n\t\t\t\t\t\tcapability: \"source\",\n\t\t\t\t\t\tstep: `sync ${name}`,\n\t\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\t\tmessage: `unknown step \"${name}\"`,\n\t\t\t\t\t});\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── local-only steps (no provider token required) ──────────────────\n\t// keywords, description, homepage, readme, and workflows write to local\n\t// files and optionally push to GitHub when source is loaded. They run\n\t// outside the `if (loader.has(\"source\"))` block so they work without a token.\n\n\tfor (const stepName of [\n\t\t\"keywords\",\n\t\t\"description\",\n\t\t\"homepage\",\n\t\t\"readme\",\n\t\t\"workflows\",\n\t\t\"scripts\",\n\t\t\"turbo\",\n\t\t\"wiki\",\n\t] as const) {\n\t\tif (requestedSteps !== undefined && !requestedSteps.includes(stepName)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (stepName === \"keywords\") {\n\t\t\tconst topics = config.repo?.topics ?? [];\n\t\t\tif (topics.length === 0) {\n\t\t\t\tsteps.push({\n\t\t\t\t\tcapability: \"local\",\n\t\t\t\t\tstep: \"sync keywords\",\n\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\tmessage: \"no topics configured\",\n\t\t\t\t});\n\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t} else {\n\t\t\t\tsteps.push(\n\t\t\t\t\tawait runSyncStep(\"local\", \"sync keywords\", dryRun, async () => {\n\t\t\t\t\t\tconst wrote = await writePackageJsonField(input.context.repoRoot, \"keywords\", topics);\n\t\t\t\t\t\treturn wrote\n\t\t\t\t\t\t\t? `${topics.length} keywords written`\n\t\t\t\t\t\t\t: `${topics.length} topics (no package.json)`;\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t}\n\t\t}\n\n\t\tif (stepName === \"description\") {\n\t\t\tconst description = config.description;\n\t\t\tif (!description) {\n\t\t\t\tsteps.push({\n\t\t\t\t\tcapability: \"local\",\n\t\t\t\t\tstep: \"sync description\",\n\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\tmessage: \"no description configured\",\n\t\t\t\t});\n\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t} else {\n\t\t\t\tconst source = loader.has(\"source\") ? (loader.get(\"source\") as Source) : null;\n\t\t\t\tsteps.push(\n\t\t\t\t\tawait runSyncStep(\"local\", \"sync description\", dryRun, async () => {\n\t\t\t\t\t\tconst pkgWrote = await writePackageJsonField(\n\t\t\t\t\t\t\tinput.context.repoRoot,\n\t\t\t\t\t\t\t\"description\",\n\t\t\t\t\t\t\tdescription\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst readmeWrote = await updateReadmeDescription(input.context.repoRoot, description);\n\t\t\t\t\t\tif (source?.syncDescription) {\n\t\t\t\t\t\t\tawait source.syncDescription(description);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst parts: string[] = [];\n\t\t\t\t\t\tif (pkgWrote) parts.push(\"package.json\");\n\t\t\t\t\t\tif (readmeWrote) parts.push(\"README.md\");\n\t\t\t\t\t\tif (source?.syncDescription) parts.push(\"GitHub\");\n\t\t\t\t\t\treturn parts.length > 0 ? parts.join(\", \") + \" updated\" : \"description synced\";\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t}\n\t\t}\n\n\t\tif (stepName === \"homepage\") {\n\t\t\tconst homepage = config.homepage;\n\t\t\tif (!homepage) {\n\t\t\t\tsteps.push({\n\t\t\t\t\tcapability: \"local\",\n\t\t\t\t\tstep: \"sync homepage\",\n\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\tmessage: \"no homepage configured\",\n\t\t\t\t});\n\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t} else {\n\t\t\t\tconst source = loader.has(\"source\") ? (loader.get(\"source\") as Source) : null;\n\t\t\t\tsteps.push(\n\t\t\t\t\tawait runSyncStep(\"local\", \"sync homepage\", dryRun, async () => {\n\t\t\t\t\t\tconst pkgWrote = await writePackageJsonField(input.context.repoRoot, \"homepage\", homepage);\n\t\t\t\t\t\tif (source?.syncHomepage) {\n\t\t\t\t\t\t\tawait source.syncHomepage(homepage);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst parts: string[] = [];\n\t\t\t\t\t\tif (pkgWrote) parts.push(\"package.json\");\n\t\t\t\t\t\tif (source?.syncHomepage) parts.push(\"GitHub\");\n\t\t\t\t\t\treturn parts.length > 0 ? parts.join(\", \") + \" updated\" : \"homepage synced\";\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t}\n\t\t}\n\n\t\tif (stepName === \"readme\") {\n\t\t\tconst report = await runSyncReadme({ loaded: input.loaded, context: input.context, print: () => {} });\n\t\t\tsteps.push({\n\t\t\t\tcapability: \"local\",\n\t\t\t\tstep: \"sync readme\",\n\t\t\t\tstatus: report.status === \"ok\" ? \"ok\" : report.status === \"dry-run\" ? \"dry-run\" : \"skip\",\n\t\t\t\t...(report.message ? { message: report.message } : {}),\n\t\t\t});\n\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t}\n\n\t\tif (stepName === \"workflows\") {\n\t\t\tconst taskEntries = config.tasks ?? [];\n\t\t\tif (taskEntries.length === 0) {\n\t\t\t\tsteps.push({\n\t\t\t\t\tcapability: \"local\",\n\t\t\t\t\tstep: \"sync workflows\",\n\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\tmessage: \"no tasks configured\",\n\t\t\t\t});\n\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t} else {\n\t\t\t\t// astromech renders every thin caller from the manifest (lint linter\n\t\t\t\t// set, deploy paths, deploy+preview). Iterate the manifest (not the\n\t\t\t\t// map) so step reporting keeps the config's order.\n\t\t\t\tconst files = createAstromech({\n\t\t\t\t\tcwd: input.context.repoRoot,\n\t\t\t\t\tconfig: { tasks: config.tasks as TasksConfig[\"tasks\"] },\n\t\t\t\t\torgContext: { org: config.org, domain: config.domain },\n\t\t\t\t\tlogger,\n\t\t\t\t}).thinCallers();\n\n\t\t\t\tfor (const entry of taskEntries) {\n\t\t\t\t\tconst name = typeof entry === \"string\" ? entry : entry.name;\n\t\t\t\t\t// knowledge.docs / knowledge.components have no static\n\t\t\t\t\t// WORKFLOW_TEMPLATES entry (their content is always\n\t\t\t\t\t// combined-generated, astromech.ts) — not in KNOWN_WORKFLOWS,\n\t\t\t\t\t// but not \"unknown\" either.\n\t\t\t\t\tconst isCombinedContentOnly = name === \"knowledge.docs\" || name === \"knowledge.components\";\n\n\t\t\t\t\tif (!KNOWN_WORKFLOWS.has(name) && !isCombinedContentOnly) {\n\t\t\t\t\t\tsteps.push({\n\t\t\t\t\t\t\tcapability: \"local\",\n\t\t\t\t\t\t\tstep: `sync workflow ${name}`,\n\t\t\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\t\t\tmessage: `unknown workflow \"${name}\" — no template available`,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\t// The combined-content family (delivery.deploy, knowledge.docs,\n\t\t\t\t\t// knowledge.components) all key their generated file by task\n\t\t\t\t\t// name already — no special-casing needed.\n\t\t\t\t\tconst filename = `${name}.yml`;\n\t\t\t\t\tconst content = files.get(filename);\n\t\t\t\t\tif (content === undefined) continue; // ci: false — nothing to write\n\n\t\t\t\t\tconst withPreview = content.includes(\"workflows/preview.yml@main\");\n\t\t\t\t\tconst step = `sync workflow ${name}${withPreview ? \" (with preview)\" : \"\"}`;\n\t\t\t\t\tsteps.push(\n\t\t\t\t\t\tawait runSyncStep(\"local\", step, dryRun, async () => {\n\t\t\t\t\t\t\tawait writeWorkflowFile(input.context.repoRoot, filename, `${workflowHeader()}${content}`);\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (stepName === \"scripts\") {\n\t\t\tif (config.syncScripts === false) {\n\t\t\t\tsteps.push({\n\t\t\t\t\tcapability: \"local\",\n\t\t\t\t\tstep: \"sync scripts\",\n\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\tmessage: \"syncScripts: false\",\n\t\t\t\t});\n\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t} else {\n\t\t\t\tconst tasksConfig: TasksConfig = { tasks: config.tasks as TasksConfig[\"tasks\"] };\n\t\t\t\tif (config.holocronScript !== undefined) tasksConfig.holocronScript = config.holocronScript;\n\t\t\t\tconst astromechScripts = createAstromech({\n\t\t\t\t\tcwd: input.context.repoRoot,\n\t\t\t\t\tconfig: tasksConfig,\n\t\t\t\t\tlogger,\n\t\t\t\t});\n\t\t\t\tconst desired = astromechScripts.packageScripts();\n\t\t\t\t// #747: which of `desired`'s keys turbo.json would fan out — the\n\t\t\t\t// only ones an existing direct-tool root script is ever protected\n\t\t\t\t// for. See mergePackageJsonScripts()'s own docstring.\n\t\t\t\tconst turboContent = astromechScripts.turboConfig();\n\t\t\t\tconst turboEligible = new Set<string>(\n\t\t\t\t\tturboContent\n\t\t\t\t\t\t? Object.keys((JSON.parse(turboContent) as { tasks: Record<string, unknown> }).tasks)\n\t\t\t\t\t\t: []\n\t\t\t\t);\n\n\t\t\t\tsteps.push(\n\t\t\t\t\tawait runSyncStep(\"local\", \"sync scripts\", dryRun, async () => {\n\t\t\t\t\t\tconst changed = await mergePackageJsonScripts(input.context.repoRoot, desired, turboEligible);\n\t\t\t\t\t\tif (changed === null) return \"no package.json\";\n\t\t\t\t\t\tif (changed.length === 0) return `${Object.keys(desired).length} scripts already current`;\n\t\t\t\t\t\treturn `${changed.join(\", \")} set`;\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t}\n\t\t}\n\n\t\tif (stepName === \"turbo\") {\n\t\t\tconst astromechTurbo = createAstromech({\n\t\t\t\tcwd: input.context.repoRoot,\n\t\t\t\tconfig: { tasks: config.tasks as TasksConfig[\"tasks\"] },\n\t\t\t\tlogger,\n\t\t\t});\n\t\t\tconst content = astromechTurbo.turboConfig();\n\n\t\t\tif (content === null) {\n\t\t\t\tsteps.push({\n\t\t\t\t\tcapability: \"local\",\n\t\t\t\t\tstep: \"sync turbo.json\",\n\t\t\t\t\tstatus: \"skip\",\n\t\t\t\t\tmessage: \"no fan-out-eligible tasks configured\",\n\t\t\t\t});\n\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t} else {\n\t\t\t\tsteps.push(\n\t\t\t\t\tawait runSyncStep(\"local\", \"sync turbo.json\", dryRun, async () => {\n\t\t\t\t\t\tawait writeFile(join(input.context.repoRoot, \"turbo.json\"), content, \"utf8\");\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\n\t\t\t\t// #692: fix pnpm-workspace.yaml in the same step that introduces\n\t\t\t\t// the risk — see run-setup.ts's identical wiring for the full\n\t\t\t\t// explanation.\n\t\t\t\tconst rootPkgRaw = await readFile(join(input.context.repoRoot, \"package.json\"), \"utf8\").catch(\n\t\t\t\t\t() => null\n\t\t\t\t);\n\t\t\t\tconst rootPkg = rootPkgRaw ? (JSON.parse(rootPkgRaw) as { scripts?: Record<string, string> }) : null;\n\t\t\t\tconst workspaceYaml = await readFile(join(input.context.repoRoot, \"pnpm-workspace.yaml\"), \"utf8\").catch(\n\t\t\t\t\t() => \"\"\n\t\t\t\t);\n\t\t\t\tconst rootScripts = rootPkg?.scripts ?? {};\n\t\t\t\tconst workspaceFix = astromechTurbo.ensureRootWorkspaceMember(workspaceYaml, rootScripts);\n\t\t\t\tif (workspaceFix.changed) {\n\t\t\t\t\tsteps.push(\n\t\t\t\t\t\tawait runSyncStep(\n\t\t\t\t\t\t\t\"local\",\n\t\t\t\t\t\t\t\"fix pnpm-workspace.yaml (root workspace member, #692)\",\n\t\t\t\t\t\t\tdryRun,\n\t\t\t\t\t\t\tasync () => {\n\t\t\t\t\t\t\t\tawait writeFile(\n\t\t\t\t\t\t\t\t\tjoin(input.context.repoRoot, \"pnpm-workspace.yaml\"),\n\t\t\t\t\t\t\t\t\tworkspaceFix.content,\n\t\t\t\t\t\t\t\t\t\"utf8\"\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t}\n\n\t\t\t\t// turbo.json alone is inert without turbo itself installed —\n\t\t\t\t// see ensureTurboDependency()'s own docstring for how this was\n\t\t\t\t// found (a global-version fallback that silently broke on an\n\t\t\t\t// unrelated turbo install).\n\t\t\t\tif (rootPkgRaw) {\n\t\t\t\t\tconst depFix = astromechTurbo.ensureTurboDependency(rootPkgRaw, workspaceFix.content);\n\t\t\t\t\tif (depFix.changed) {\n\t\t\t\t\t\tsteps.push(\n\t\t\t\t\t\t\tawait runSyncStep(\"local\", \"add turbo devDependency\", dryRun, async () => {\n\t\t\t\t\t\t\t\tawait writeFile(join(input.context.repoRoot, \"package.json\"), depFix.content, \"utf8\");\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t);\n\t\t\t\t\t\tprint(formatSyncStep(steps[steps.length - 1]!));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (stepName === \"wiki\") {\n\t\t\tconst result = await runSyncWiki({ loaded: input.loaded, context: input.context });\n\t\t\tsteps.push(result);\n\t\t\tprint(formatSyncStep(result));\n\t\t}\n\t}\n\n\tfor (const s of steps) {\n\t\tlogger[s.status === \"fail\" ? \"warn\" : \"info\"](\n\t\t\t{ capability: s.capability, step: s.step, status: s.status, ...(s.message ? { detail: s.message } : {}) },\n\t\t\t`sync: ${s.step}`\n\t\t);\n\t}\n\n\tconst summary = steps.reduce(\n\t\t(acc, s) => {\n\t\t\tif (s.status === \"ok\") acc.ok += 1;\n\t\t\telse if (s.status === \"fail\") acc.fail += 1;\n\t\t\telse if (s.status === \"skip\") acc.skip += 1;\n\t\t\telse if (s.status === \"dry-run\") acc.dryRun += 1;\n\t\t\treturn acc;\n\t\t},\n\t\t{ ok: 0, fail: 0, skip: 0, dryRun: 0 }\n\t);\n\n\tlogger[summary.fail > 0 ? \"warn\" : \"info\"]({ ...summary }, \"sync: done\");\n\n\tprint(\"\");\n\tprint(\n\t\t` ${summary.ok} ok, ${summary.fail} fail, ${summary.skip} skipped${\n\t\t\tdryRun ? `, ${summary.dryRun} would-do` : \"\"\n\t\t}`\n\t);\n\n\treturn { steps, summary };\n}\n\nasync function runSyncStep(\n\tcapability: string,\n\tstep: string,\n\tdryRun: boolean,\n\tbody: () => Promise<string | void>\n): Promise<SetupStepResult> {\n\tif (dryRun) {\n\t\treturn { capability, step, status: \"dry-run\" };\n\t}\n\ttry {\n\t\tconst note = await body();\n\t\tconst result: SetupStepResult = { capability, step, status: \"ok\" };\n\t\tif (typeof note === \"string\") result.message = note;\n\t\treturn result;\n\t} catch (err) {\n\t\treturn {\n\t\t\tcapability,\n\t\t\tstep,\n\t\t\tstatus: \"fail\",\n\t\t\tmessage: err instanceof Error ? err.message : String(err),\n\t\t};\n\t}\n}\n\nfunction formatSyncStep(step: SetupStepResult): string {\n\tconst icon = step.status === \"ok\" ? \"✓\" : step.status === \"fail\" ? \"✗\" : step.status === \"dry-run\" ? \"…\" : \"·\";\n\tconst detail = step.message ? ` (${step.message})` : \"\";\n\treturn ` ${icon} ${step.step}${detail}`;\n}\n\nasync function writePackageJsonField(repoRoot: string, field: string, value: unknown): Promise<boolean> {\n\tconst pkgPath = join(repoRoot, \"package.json\");\n\tlet content: string;\n\ttry {\n\t\tcontent = await readFile(pkgPath, \"utf8\");\n\t} catch {\n\t\treturn false;\n\t}\n\tconst pkg = JSON.parse(content) as Record<string, unknown>;\n\tpkg[field] = value;\n\tawait writeFile(pkgPath, JSON.stringify(pkg, null, 2) + \"\\n\", \"utf8\");\n\treturn true;\n}\n\n/**\n * Merge `desired` script entries into `package.json#scripts` — sets only the\n * listed keys, never touches the rest. Returns the sorted list of keys that\n * drifted (empty when all current), or `null` when there is no `package.json`.\n *\n * `turboEligible` (#747): task names `turbo.json` fans out — the same set\n * {@link EnsureRootWorkspaceMemberResult} above already keys off. For those\n * only, an *existing* script that isn't the generated `holocron run <task>\n * --` wrapper is left untouched: root may genuinely be a directly-buildable\n * package (not an orchestrator) with its own real command (`tsc --noEmit`,\n * `vitest run`, …) for that task. Overwriting it would silently discard the\n * real command and, once `turbo.json` exists and root is a real workspace\n * member (#692), reintroduce infinite recursion — `turbo run <task>` →\n * root's own `<task>` script → the wrapper → `holocron run <task>` sees\n * `turbo.json` still defines the task → `turbo run <task>` again, forever.\n * Every other key (non-turbo tasks, `holocron`, `prepare`, …) has no\n * legitimate direct-command alternative and stays fully generator-owned.\n */\nasync function mergePackageJsonScripts(\n\trepoRoot: string,\n\tdesired: Record<string, string>,\n\tturboEligible: ReadonlySet<string>\n): Promise<string[] | null> {\n\tconst pkgPath = join(repoRoot, \"package.json\");\n\tlet content: string;\n\ttry {\n\t\tcontent = await readFile(pkgPath, \"utf8\");\n\t} catch {\n\t\treturn null;\n\t}\n\tconst pkg = JSON.parse(content) as Record<string, unknown>;\n\tconst scripts = (pkg.scripts ?? {}) as Record<string, string>;\n\tconst changed: string[] = [];\n\tfor (const [name, command] of Object.entries(desired)) {\n\t\tconst existing = scripts[name];\n\t\tif (turboEligible.has(name) && existing !== undefined && !isGeneratedRunWrapper(existing, name)) continue;\n\t\tif (existing !== command) {\n\t\t\tscripts[name] = command;\n\t\t\tchanged.push(name);\n\t\t}\n\t}\n\tif (changed.length === 0) return [];\n\tpkg.scripts = scripts;\n\tawait writeFile(pkgPath, JSON.stringify(pkg, null, 2) + \"\\n\", \"utf8\");\n\treturn changed.sort();\n}\n\n/**\n * Matches the exact shape `packageScripts()` generates for `taskName` —\n * `<bin> run <taskName> --`, `<bin>` normally `holocron` but substitutable\n * (`holocronScript`, itself allowed to be multi-word, e.g. `\"node\npackages/cli/dist/cli.mjs\"` — see its own test). Checking the *suffix*\n * rather than the whole string means an old wrapper survives a\n * `holocronScript` rename intact — it's still recognized as a wrapper (safe\n * to update to the new one), not mistaken for a real command.\n */\nfunction isGeneratedRunWrapper(command: string, taskName: string): boolean {\n\treturn command.endsWith(` run ${taskName} --`);\n}\n\nconst README_DESC_START = \"<!-- holocron:description -->\";\nconst README_DESC_END = \"<!-- /holocron:description -->\";\n\nasync function updateReadmeDescription(repoRoot: string, description: string): Promise<boolean> {\n\tconst readmePath = join(repoRoot, \"README.md\");\n\tlet content: string;\n\ttry {\n\t\tcontent = await readFile(readmePath, \"utf8\");\n\t} catch {\n\t\treturn false;\n\t}\n\tconst lines = content.split(\"\\n\");\n\n\tconst startIdx = lines.findIndex((l) => l.trim() === README_DESC_START);\n\tconst endIdx = lines.findIndex((l) => l.trim() === README_DESC_END);\n\tif (startIdx !== -1) {\n\t\tif (endIdx === -1 || endIdx <= startIdx) return false;\n\t\tlines.splice(startIdx + 1, endIdx - startIdx - 1, description);\n\t\tawait writeFile(readmePath, lines.join(\"\\n\"), \"utf8\");\n\t\treturn true;\n\t}\n\n\tconst h1Index = lines.findIndex((l) => /^# /.test(l));\n\tif (h1Index === -1) return false;\n\n\tlines.splice(h1Index + 1, 0, \"\", README_DESC_START, description, README_DESC_END);\n\tawait writeFile(readmePath, lines.join(\"\\n\"), \"utf8\");\n\treturn true;\n}\n\nasync function writeWorkflowFile(repoRoot: string, filename: string, content: string): Promise<void> {\n\tconst dir = join(repoRoot, \".github\", \"workflows\");\n\tawait mkdir(dir, { recursive: true });\n\tawait writeFile(join(dir, filename), content, \"utf8\");\n}\n","/**\n * Holocron-specific credential resolution for the telemetry sinks — the env\n * chain plus Holocron's own shipped fallbacks. This is **CLI policy**, not part\n * of the portable adapter set: `sentry-sink.ts` / `posthog-sink.ts` take a\n * resolved DSN / key and never read the environment. When the adapters move to\n * `@theholocron/observability` (#635) this module stays here.\n *\n * errors: HOLOCRON_SENTRY_DSN → SENTRY_DSN → FALLBACK_DSN\n * analytics: HOLOCRON_POSTHOG_PROJECT_TOKEN → POSTHOG_PROJECT_TOKEN → FALLBACK_POSTHOG_PROJECT_TOKEN\n * host: HOLOCRON_POSTHOG_HOST → POSTHOG_HOST → DEFAULT_POSTHOG_HOST\n *\n * The `SENTRY_DSN` / `POSTHOG_PROJECT_TOKEN` fallbacks are the vendor-native\n * names a consumer repo sets to route CLI telemetry to its own project. The\n * built-in fallbacks are ingest-only keys — publishable by design, same risk\n * model as ADR-0007 / ADR-0008.\n */\n\nimport { env } from \"../env.js\";\n\n/** Holocron's own Sentry project — the fallback when no env var points elsewhere. */\nconst FALLBACK_DSN = \"https://95cbb72ad5636c94e119a5405ee8f55f@o4508238154104832.ingest.us.sentry.io/4511810950791168\";\n\n/** Holocron's own PostHog project write key — ingest-only. */\nconst FALLBACK_POSTHOG_PROJECT_TOKEN = \"phc_AC4vFCvYzwnzmG7Vg5nEc3PZKZztoPyfKp4Lb9BbXcLK\"; // gitleaks:allow\n\nconst DEFAULT_POSTHOG_HOST = \"https://us.i.posthog.com\";\n\n/** Resolve the Sentry DSN. `\"\"` → error telemetry disabled. */\nexport function resolveDsn(): string {\n\treturn env.get(\"HOLOCRON_SENTRY_DSN\") ?? env.get(\"SENTRY_DSN\") ?? FALLBACK_DSN;\n}\n\n/** Resolve the PostHog project key. `\"\"` → usage analytics disabled. */\nexport function resolvePostHogKey(): string {\n\treturn (\n\t\tenv.get(\"HOLOCRON_POSTHOG_PROJECT_TOKEN\") ?? env.get(\"POSTHOG_PROJECT_TOKEN\") ?? FALLBACK_POSTHOG_PROJECT_TOKEN\n\t);\n}\n\n/** Resolve the PostHog ingest host. */\nexport function resolvePostHogHost(): string {\n\treturn env.get(\"HOLOCRON_POSTHOG_HOST\") ?? env.get(\"POSTHOG_HOST\") ?? DEFAULT_POSTHOG_HOST;\n}\n","/**\n * CLI self-telemetry orchestration — errors (Sentry), usage analytics (PostHog).\n *\n * This module holds *no* vendor SDK import. Each concern sits behind an\n * interface from `@theholocron/observability` ({@link ErrorSink} /\n * {@link AnalyticsSink}); the `SentrySink` / `PostHogSink` adapters there are\n * the only `@sentry/node` / `posthog-node` call sites, and a `Noop*Sink` is\n * installed when telemetry is off. Same seam the package's `Logger` uses for\n * Pino.\n *\n * Activation is env-var + shipped-fallback, resolved here (`telemetry/resolve.ts`)\n * and passed to the sink — the adapters read no environment. The single kill\n * switch is `HOLOCRON_TELEMETRY=false` (legacy alias `NO_HOLOCRON_TELEMETRY`);\n * see ADR-0007 / ADR-0008.\n */\n\nimport { createHash } from \"node:crypto\";\nimport { hostname, userInfo } from \"node:os\";\n\nimport { PostHogSink } from \"@theholocron/observability/analytics\";\nimport {\n\ttype AnalyticsSink,\n\ttype CommandSpan,\n\ttype ErrorSink,\n\tNoopAnalyticsSink,\n\tNoopErrorSink,\n\tredactObject,\n} from \"@theholocron/observability/core\";\nimport { SentrySink } from \"@theholocron/observability/errors\";\n\nimport type { TelemetryConfig } from \"./config/config.js\";\nimport { env } from \"./env.js\";\nimport { getRunId } from \"./logger.js\";\nimport { resolveDsn, resolvePostHogHost, resolvePostHogKey } from \"./telemetry/resolve.js\";\n\n// ── sinks ────────────────────────────────────────────────────────────────────\n\nlet errors: ErrorSink = new NoopErrorSink();\nlet analytics: AnalyticsSink = new NoopAnalyticsSink();\n\n// ── gate ─────────────────────────────────────────────────────────────────────\n\n/**\n * The shared opt-out. `HOLOCRON_TELEMETRY=false` (going-forward) or\n * `NO_HOLOCRON_TELEMETRY` (any truthy value, back-compat) disables all sinks.\n */\nfunction isEnabled(): boolean {\n\treturn env.get(\"HOLOCRON_TELEMETRY\") !== \"false\" && !env.get(\"NO_HOLOCRON_TELEMETRY\");\n}\n\n// ── identity ─────────────────────────────────────────────────────────────────\n\nlet commandStartedAt = 0;\nlet currentCommand = \"unknown\";\nlet lastErrorType: string | undefined;\nlet currentSpan: CommandSpan | undefined;\n\n/**\n * Anonymous, stable per-machine id — `sha256(hostname + username)` truncated\n * (ADR-0008). One-way: no raw hostname or username is ever transmitted.\n */\nfunction machineId(): string {\n\ttry {\n\t\treturn createHash(\"sha256\").update(`${hostname()} ${userInfo().username}`).digest(\"hex\").slice(0, 32);\n\t} catch {\n\t\treturn \"unknown\";\n\t}\n}\n\n/** Properties every analytics event carries — pivot key to the Axiom trace. */\nfunction baseProps(): Record<string, unknown> {\n\tconst runId = getRunId();\n\treturn {\n\t\tcommand: currentCommand,\n\t\tci: Boolean(env.get(\"CI\")),\n\t\t...(runId ? { runId } : {}),\n\t};\n}\n\n// ── lifecycle ────────────────────────────────────────────────────────────────\n\nexport function init(version: string): void {\n\tconst dsn = resolveDsn();\n\tif (isEnabled() && dsn !== \"\") {\n\t\terrors = new SentrySink();\n\t\terrors.init({\n\t\t\tdsn,\n\t\t\trelease: `holocron@${version}`,\n\t\t\tenvironment: env.get(\"CI\") ? \"ci\" : \"local\",\n\t\t\ttags: { os: process.platform, node: process.version, ci: String(Boolean(env.get(\"CI\"))) },\n\t\t});\n\t}\n\tconst posthogKey = resolvePostHogKey();\n\tif (isEnabled() && posthogKey !== \"\") {\n\t\tanalytics = new PostHogSink({ key: posthogKey, host: resolvePostHogHost() });\n\t\tanalytics.identify(machineId(), {\n\t\t\tci: Boolean(env.get(\"CI\")),\n\t\t\tos: process.platform,\n\t\t\tnode: process.version,\n\t\t\tcli: version,\n\t\t\t...(env.get(\"HOLOCRON_ORG\") ? { org: env.get(\"HOLOCRON_ORG\") } : {}),\n\t\t});\n\t}\n}\n\n/**\n * Apply the `telemetry` config block — the committed override layer, run once\n * per command *after* config loads (so it lands after {@link init}). Env still\n * wins: this only ever *narrows* what `init` turned on, never re-enables.\n *\n * - `enabled: false` → swap both sinks to no-ops for the rest of the run.\n * - `analytics: \"none\"` → drop usage analytics only; error reporting stays.\n *\n * A live sink is drained best-effort before it is dropped so an in-flight\n * Sentry session / PostHog queue still leaves the process cleanly.\n */\nexport function applyConfig(cfg: TelemetryConfig | undefined): void {\n\tif (!cfg) return;\n\n\t// Best-effort drain — never let a rejected close() surface as an unhandled\n\t// rejection from this sync path.\n\tconst drain = (p: Promise<unknown>): void => {\n\t\tp.catch(() => {});\n\t};\n\n\tif (cfg.enabled === false) {\n\t\tdrain(errors.flush());\n\t\tdrain(analytics.shutdown());\n\t\terrors = new NoopErrorSink();\n\t\tanalytics = new NoopAnalyticsSink();\n\t\treturn;\n\t}\n\n\tif (cfg.analytics === \"none\") {\n\t\tdrain(analytics.shutdown());\n\t\tanalytics = new NoopAnalyticsSink();\n\t}\n}\n\n/** Capture a PostHog event. Every `properties` object runs through the scrubber. */\nexport function event(name: string, properties: Record<string, unknown> = {}): void {\n\tanalytics.capture(machineId(), name, redactObject({ ...baseProps(), ...properties }));\n}\n\nexport function startCommand(name: string): (ok: boolean) => void {\n\tcurrentCommand = name;\n\tcommandStartedAt = Date.now();\n\tlastErrorType = undefined;\n\tcurrentSpan = errors.startSpan(name);\n\n\tevent(\"command_started\", { dry_run: process.argv.includes(\"--dry-run\") });\n\n\treturn (ok: boolean) => {\n\t\tcurrentSpan?.setStatus(ok);\n\t\tcurrentSpan?.end();\n\t\tevent(ok ? \"command_completed\" : \"command_failed\", {\n\t\t\tstatus: ok ? \"ok\" : \"fail\",\n\t\t\tduration_ms: Date.now() - commandStartedAt,\n\t\t\t...(ok || !lastErrorType ? {} : { error_type: lastErrorType }),\n\t\t});\n\t};\n}\n\nexport function captureException(err: unknown): void {\n\tlastErrorType = err instanceof Error ? err.constructor.name : \"Error\";\n\terrors.captureException(err);\n}\n\nexport function endSession(): void {\n\terrors.endSession();\n}\n\nexport async function flush(): Promise<void> {\n\tawait errors.flush();\n\tawait analytics.shutdown();\n\terrors = new NoopErrorSink();\n\tanalytics = new NoopAnalyticsSink();\n}\n\n// ── test hook ────────────────────────────────────────────────────────────────\n\n/** Drop the sinks + command state back to their no-op defaults. */\nexport function resetTelemetry(): void {\n\terrors = new NoopErrorSink();\n\tanalytics = new NoopAnalyticsSink();\n\tcommandStartedAt = 0;\n\tcurrentCommand = \"unknown\";\n\tlastErrorType = undefined;\n\tcurrentSpan = undefined;\n}\n","import { createHash } from \"node:crypto\";\nimport { mkdirSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\n\nimport { reusableTemplates } from \"@theholocron/astromech\";\nimport { createGitHubClient } from \"@theholocron/github-client\";\nimport { ProviderApiError } from \"@theholocron/http-client\";\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport { getLogger } from \"../logger.js\";\nimport { event as telemetryEvent } from \"../telemetry.js\";\n\nconst DEFAULT_REPO = \"theholocron/.github\";\n\nexport type SyncGithubStatus = \"ok\" | \"fail\" | \"dry-run\";\n\nexport interface RunSyncGithubInput {\n\t/** GitHub personal access token with repo write access. */\n\ttoken: string;\n\t/** Target org/repo. Defaults to \"theholocron/.github\". */\n\trepo?: string;\n\t/**\n\t * Push files to this branch instead of the default branch.\n\t * If the branch doesn't exist it is created from the default branch HEAD.\n\t * Combine with `createPr: true` to open a PR after the push.\n\t */\n\tbranch?: string;\n\t/** After pushing to `branch`, open a PR to the default branch. No-op if `branch` is unset. */\n\tcreatePr?: boolean;\n\t/** Commit message for the sync commit. */\n\tmessage?: string;\n\tdryRun?: boolean;\n\t/**\n\t * Write generated files to this local directory instead of pushing to the GitHub API.\n\t * Useful for local validation (e.g. actionlint) before a real sync run.\n\t * When set, no API calls are made and token is not required.\n\t */\n\toutputDir?: string;\n\tprint?: (line: string) => void;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n\t/** Injectable for testing. */\n\tfetch?: typeof globalThis.fetch;\n}\n\nexport interface SyncGithubReport {\n\tstatus: SyncGithubStatus;\n\tcreated: number;\n\tupdated: number;\n\tunchanged: number;\n\t/** URL of the opened PR, when createPr is true and changes were made. */\n\tprUrl?: string;\n\tmessage?: string;\n}\n\ntype FileBatch = Array<{ path: string; content: string }>;\n\n/**\n * The file set `sync-github` pushes to `theholocron/.github` — the reusable\n * `workflow_call` implementations, composite actions and starter-workflow\n * metadata, generated by `@theholocron/astromech`. Secondary repos get nothing:\n * their thin callers are managed by `holocron sync --steps workflows`, which\n * executes the resolved config (regex parsing here can't resolve preset spreads\n * like `...tasks` from `nodeDocs()` — see issue #464).\n */\nfunction buildBatch(repo: string): FileBatch {\n\tif (repo !== DEFAULT_REPO) return [];\n\treturn [...reusableTemplates()].map(([path, content]) => ({ path, content }));\n}\n\n/** Git blob SHA: sha1(\"blob {len}\\0{content}\") — used to detect unchanged files. */\nexport function gitBlobSha(content: string): string {\n\tconst buf = Buffer.from(content, \"utf8\");\n\treturn createHash(\"sha1\").update(`blob ${buf.length}\\0`).update(buf).digest(\"hex\");\n}\n\nexport async function runSyncGithub(input: RunSyncGithubInput): Promise<SyncGithubReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst repo = input.repo ?? DEFAULT_REPO;\n\tconst { token, dryRun = false, branch, createPr = false } = input;\n\tconst message = input.message ?? `chore: sync from theholocron/holocron`;\n\n\tconst client = createGitHubClient({ token, fetch: input.fetch });\n\n\tprint(`holocron sync-github${dryRun ? \" (dry-run)\" : \"\"}`);\n\tprint(` repo: ${repo}`);\n\tif (branch) print(` branch: ${branch}`);\n\tprint(\"\");\n\n\tlogger.info({ repo, branch, createPr: createPr || undefined, dryRun: dryRun || undefined }, \"sync-github: start\");\n\n\t/** Single exit point — one structured line per invocation, whatever the path. */\n\tconst done = (r: SyncGithubReport): SyncGithubReport => {\n\t\tlogger[r.status === \"fail\" ? \"warn\" : \"info\"](\n\t\t\t{\n\t\t\t\trepo,\n\t\t\t\tstatus: r.status,\n\t\t\t\tcreated: r.created,\n\t\t\t\tupdated: r.updated,\n\t\t\t\tunchanged: r.unchanged,\n\t\t\t\t...(r.message ? { reason: r.message } : {}),\n\t\t\t\t...(r.prUrl ? { pr: r.prUrl } : {}),\n\t\t\t},\n\t\t\t\"sync-github: done\"\n\t\t);\n\t\ttelemetryEvent(\"sync_github_run\", {\n\t\t\trepo,\n\t\t\tstatus: r.status,\n\t\t\t...(branch ? { branch } : {}),\n\t\t\trepos_targeted: 1,\n\t\t\tfiles_changed: r.created + r.updated,\n\t\t\tpr_opened: Boolean(r.prUrl),\n\t\t});\n\t\treturn r;\n\t};\n\n\t// ── output-dir: write all files to disk without any API calls ───────────\n\tif (input.outputDir) {\n\t\tconst batch = buildBatch(repo);\n\t\tfor (const file of batch) {\n\t\t\tconst dest = join(input.outputDir, file.path);\n\t\t\tmkdirSync(dirname(dest), { recursive: true });\n\t\t\twriteFileSync(dest, file.content, \"utf8\");\n\t\t}\n\t\tprint(` ${batch.length} files written to ${input.outputDir}`);\n\t\treturn done({ status: \"ok\", created: batch.length, updated: 0, unchanged: 0 });\n\t}\n\n\t// ── 1. Resolve target branch ─────────────────────────────────────────────\n\tlet targetBranch = branch;\n\tlet defaultBranch: string | undefined;\n\tif (!targetBranch || createPr) {\n\t\ttry {\n\t\t\tconst repoData = await client.repos.getRepo(repo);\n\t\t\tdefaultBranch = repoData.default_branch;\n\t\t\tif (!targetBranch) targetBranch = defaultBranch;\n\t\t} catch {\n\t\t\tconst msg = \"failed to fetch repo metadata\";\n\t\t\tprint(` ✗ ${msg}`);\n\t\t\treturn done({ status: \"fail\", created: 0, updated: 0, unchanged: 0, message: msg });\n\t\t}\n\t}\n\n\t// ── 2. Get HEAD commit → base tree ───────────────────────────────────────\n\tconst baseBranch = createPr && defaultBranch ? defaultBranch : targetBranch!;\n\tlet headSha: string;\n\tlet baseTreeSha: string;\n\tlet existingBlobs: Map<string, string>;\n\ttry {\n\t\tconst ref = await client.git.getRef(repo, baseBranch);\n\t\theadSha = ref.object.sha;\n\t\tconst commit = await client.git.getCommit(repo, headSha);\n\t\tbaseTreeSha = commit.tree.sha;\n\t\tconst treeData = await client.git.getTree(repo, baseTreeSha, true);\n\t\texistingBlobs = new Map(treeData.tree.filter((i) => i.type === \"blob\").map((i) => [i.path, i.sha]));\n\t} catch (err) {\n\t\tconst msg = err instanceof Error ? err.message : `Branch ${baseBranch} not found`;\n\t\tprint(` ✗ ${msg}`);\n\t\treturn done({ status: \"fail\", created: 0, updated: 0, unchanged: 0, message: msg });\n\t}\n\n\t// ── 3. Build file batch ─────────────────────────────────────────────────\n\t// Secondary-repo thin callers are managed by `holocron sync --steps workflows`.\n\tconst batch = buildBatch(repo);\n\n\t// ── 5. Detect changes ────────────────────────────────────────────────────\n\tlet created = 0;\n\tlet updated = 0;\n\tlet unchanged = 0;\n\tconst changedFiles: Array<{ path: string; content: string }> = [];\n\n\tfor (const file of batch) {\n\t\tconst localSha = gitBlobSha(file.content);\n\t\tconst existingSha = existingBlobs.get(file.path);\n\n\t\tif (existingSha === localSha) {\n\t\t\tprint(` · unchanged ${file.path}`);\n\t\t\tunchanged++;\n\t\t} else if (existingSha) {\n\t\t\tprint(` ${dryRun ? \"~\" : \"✓\"} updated ${file.path}`);\n\t\t\tlogger.debug({ file: file.path, change: \"updated\" }, \"sync-github: file\");\n\t\t\tupdated++;\n\t\t\tif (!dryRun) changedFiles.push(file);\n\t\t} else {\n\t\t\tprint(` ${dryRun ? \"~\" : \"✓\"} created ${file.path}`);\n\t\t\tlogger.debug({ file: file.path, change: \"created\" }, \"sync-github: file\");\n\t\t\tcreated++;\n\t\t\tif (!dryRun) changedFiles.push(file);\n\t\t}\n\t}\n\n\tprint(\"\");\n\tprint(` ${created} created, ${updated} updated, ${unchanged} unchanged`);\n\n\tif (dryRun || changedFiles.length === 0) {\n\t\treturn done({ status: dryRun ? \"dry-run\" : \"ok\", created, updated, unchanged });\n\t}\n\n\t// ── 6. Create blobs for changed files ────────────────────────────────────\n\tconst treeEntries: Array<{ path: string; mode: string; type: string; sha: string }> = [];\n\tfor (const file of changedFiles) {\n\t\ttry {\n\t\t\tconst blob = await client.git.createBlob(repo, file.content);\n\t\t\ttreeEntries.push({ path: file.path, mode: \"100644\", type: \"blob\", sha: blob.sha });\n\t\t} catch (err) {\n\t\t\tconst msg = `failed to create blob for ${file.path}: ${err instanceof Error ? err.message : String(err)}`;\n\t\t\tprint(` ✗ ${msg}`);\n\t\t\treturn done({ status: \"fail\", created, updated, unchanged, message: msg });\n\t\t}\n\t}\n\n\t// ── 7. Create tree ───────────────────────────────────────────────────────\n\tlet newTreeSha: string;\n\ttry {\n\t\tconst newTree = await client.git.createTree(repo, treeEntries, baseTreeSha);\n\t\tnewTreeSha = newTree.sha;\n\t} catch (err) {\n\t\tconst msg = `failed to create tree: ${err instanceof Error ? err.message : String(err)}`;\n\t\tprint(` ✗ ${msg}`);\n\t\treturn done({ status: \"fail\", created, updated, unchanged, message: msg });\n\t}\n\n\t// ── 8. Create commit ─────────────────────────────────────────────────────\n\tlet newCommitSha: string;\n\ttry {\n\t\tconst newCommit = await client.git.createCommit(repo, message, newTreeSha, [headSha]);\n\t\tnewCommitSha = newCommit.sha;\n\t} catch (err) {\n\t\tconst msg = `failed to create commit: ${err instanceof Error ? err.message : String(err)}`;\n\t\tprint(` ✗ ${msg}`);\n\t\treturn done({ status: \"fail\", created, updated, unchanged, message: msg });\n\t}\n\n\t// ── 9. Update (or create) branch ref ────────────────────────────────────\n\ttry {\n\t\tif (createPr && branch) {\n\t\t\ttry {\n\t\t\t\tawait client.git.createRef(repo, `refs/heads/${branch}`, newCommitSha);\n\t\t\t} catch (err) {\n\t\t\t\tif (!(err instanceof ProviderApiError) || err.status !== 422) throw err;\n\t\t\t\t// Branch already exists from a previous partial run — force-update it.\n\t\t\t\tawait client.git.updateRef(repo, `heads/${branch}`, newCommitSha, true);\n\t\t\t}\n\t\t} else {\n\t\t\tawait client.git.updateRef(repo, `heads/${targetBranch!}`, newCommitSha);\n\t\t}\n\t} catch (err) {\n\t\tconst msg = `failed to update ref: ${err instanceof Error ? err.message : String(err)}`;\n\t\tprint(` ✗ ${msg}`);\n\t\treturn done({ status: \"fail\", created, updated, unchanged, message: msg });\n\t}\n\n\t// ── 10. Open PR if requested ─────────────────────────────────────────────\n\tlet prUrl: string | undefined;\n\tif (branch && createPr && !dryRun) {\n\t\ttry {\n\t\t\tconst pr = await client.git.createPull(repo, {\n\t\t\t\ttitle: message.split(\"\\n\")[0]!,\n\t\t\t\thead: branch,\n\t\t\t\tbase: \"main\",\n\t\t\t\tbody: \"Auto-generated by `holocron sync-github`. Review and merge to apply template updates.\",\n\t\t\t});\n\t\t\tprUrl = pr.html_url;\n\t\t\tprint(` → PR opened: ${prUrl}`);\n\t\t} catch (err) {\n\t\t\tconst alreadyExists =\n\t\t\t\terr instanceof ProviderApiError && err.status === 422 && String(err.details).includes(\"already exists\");\n\t\t\tif (alreadyExists) {\n\t\t\t\tprint(` → PR already open for ${branch} — branch updated, ready to merge`);\n\t\t\t} else {\n\t\t\t\tprint(` ⚠ PR creation failed: ${err instanceof Error ? err.message : String(err)}`);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn done({ status: \"ok\", created, updated, unchanged, prUrl });\n}\n","/**\n * `holocron upgrade deps` — bring a repo's `@theholocron/*` dependency pins and\n * its `holocron.config.ts` up to the current major.\n *\n * Two concerns:\n *\n * 1. **Catalog pins.** Every `@theholocron/*` entry in `pnpm-workspace.yaml`\n * (`catalog:` and every named `catalogs.*`) is bumped to the latest published\n * version, preserving the range prefix (`^` / `~`). Never downgrades.\n * 2. **`holocron.config.ts` migration.** `@theholocron/holocron-config@8`\n * dropped the 7.x preset shape (`const { repo, workflows, providers } =\n * node()` + `repo.requiredChecks` + `workflows:`) for a composed-preset\n * (`const preset = node()` + `...preset` + `tasks:` + `extraRequiredChecks:`).\n * This applies the mechanical transforms and flags anything that needs a\n * human eye.\n *\n * After running, `pnpm install && holocron ci`.\n */\n\nimport { readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport { getLogger } from \"../logger.js\";\n\n// ── npm registry ─────────────────────────────────────────────────────────────\n\nexport type FetchLatest = (pkg: string) => Promise<string | null>;\n\nconst FETCH_TIMEOUT_MS = 4000;\n\n/** Resolve a package's `latest` dist-tag from the npm registry. */\nexport const fetchLatestFromNpm: FetchLatest = async (pkg) => {\n\ttry {\n\t\tconst res = await fetch(`https://registry.npmjs.org/${encodeURIComponent(pkg)}`, {\n\t\t\tsignal: AbortSignal.timeout(FETCH_TIMEOUT_MS),\n\t\t\theaders: { accept: \"application/vnd.npm.install-v1+json\" },\n\t\t});\n\t\tif (!res.ok) return null;\n\t\tconst data = (await res.json()) as { \"dist-tags\"?: Record<string, string> };\n\t\treturn data[\"dist-tags\"]?.[\"latest\"] ?? null;\n\t} catch {\n\t\treturn null;\n\t}\n};\n\n// ── semver (just enough) ─────────────────────────────────────────────────────\n\n/** `a > b` for `x.y.z` release versions (prerelease tags are ignored). */\nexport function gt(a: string, b: string): boolean {\n\tconst pa = a.split(\".\").map((n) => parseInt(n, 10));\n\tconst pb = b.split(\".\").map((n) => parseInt(n, 10));\n\tfor (let i = 0; i < 3; i++) {\n\t\tconst x = pa[i] ?? 0;\n\t\tconst y = pb[i] ?? 0;\n\t\tif (x !== y) return x > y;\n\t}\n\treturn false;\n}\n\n// ── 1. catalog pins ──────────────────────────────────────────────────────────\n\nconst CATALOG_LINE = /^(\\s*['\"]?)(@theholocron\\/[a-z0-9-]+)(['\"]?\\s*:\\s*['\"]?)([~^]?)(\\d+\\.\\d+\\.\\d+[\\w.-]*)(['\"]?\\s*)$/;\n\nexport interface CatalogBump {\n\tpkg: string;\n\tfrom: string;\n\tto: string;\n}\n\n/**\n * Rewrite every `@theholocron/*` pin in a `pnpm-workspace.yaml` to `latest`,\n * keeping the range prefix. `latest` is looked up once per package.\n */\nexport async function bumpCatalogs(\n\tcontent: string,\n\tfetchLatest: FetchLatest\n): Promise<{ content: string; bumps: CatalogBump[] }> {\n\tconst lines = content.split(\"\\n\");\n\tconst wanted = new Set<string>();\n\tfor (const line of lines) {\n\t\tconst m = CATALOG_LINE.exec(line);\n\t\tif (m) wanted.add(m[2]!);\n\t}\n\n\tconst latest = new Map<string, string | null>();\n\tawait Promise.all(\n\t\t[...wanted].map(async (pkg) => {\n\t\t\tlatest.set(pkg, await fetchLatest(pkg));\n\t\t})\n\t);\n\n\tconst bumps: CatalogBump[] = [];\n\tconst out = lines.map((line) => {\n\t\tconst m = CATALOG_LINE.exec(line);\n\t\tif (!m) return line;\n\t\tconst [, pre, pkg, mid, prefix, current, post] = m;\n\t\tconst next = latest.get(pkg!);\n\t\tif (!next || next === current || !gt(next, current!)) return line;\n\t\tbumps.push({ pkg: pkg!, from: current!, to: next });\n\t\treturn `${pre}${pkg}${mid}${prefix}${next}${post}`;\n\t});\n\n\treturn { content: out.join(\"\\n\"), bumps };\n}\n\n// ── 2. holocron.config.ts migration (7.x → 8.x) ──────────────────────────────\n\nexport interface ConfigMigration {\n\tcontent: string;\n\tchanged: boolean;\n\ttransforms: string[];\n\twarnings: string[];\n}\n\n/** True if the file still uses the 7.x preset shape. */\nexport function isLegacyConfig(content: string): boolean {\n\t// Only the 7.x markers count: a `workflows:` key, a `...repo.requiredChecks`\n\t// spread, or a preset destructure that pulls `workflows`. A config already on\n\t// `compose()` + `tasks:` + `extraRequiredChecks:` that merely destructures\n\t// `{ repo, providers }` is valid 8.x — touching it strands `...tasks` /\n\t// `...extraRequiredChecks` on the removed binding.\n\treturn (\n\t\t/\\.\\.\\.repo\\.requiredChecks/.test(content) ||\n\t\t/^\\s*workflows\\s*:/m.test(content) ||\n\t\t/const\\s*\\{[^}]*\\bworkflows\\b[^}]*\\}\\s*=\\s*(compose\\(|[a-zA-Z]+\\()/.test(content)\n\t);\n}\n\n/**\n * Apply the mechanical 7.x → 8.x transforms to a `holocron.config.ts`. Best\n * effort — the result should always be reviewed and run through `holocron ci`.\n */\nexport function migrateConfig(content: string): ConfigMigration {\n\tconst transforms: string[] = [];\n\tconst warnings: string[] = [];\n\tlet s = content;\n\n\tif (!isLegacyConfig(s)) {\n\t\treturn { content, changed: false, transforms, warnings };\n\t}\n\n\t// `const { repo, workflows, ... } = <preset>;` → `const preset = <preset>;`\n\tlet destructured: string[] = [];\n\ts = s.replace(\n\t\t/const\\s*\\{([^}]*)\\}\\s*=\\s*((?:compose\\([\\s\\S]*?\\)|[a-zA-Z]+\\([\\s\\S]*?\\)))\\s*;/,\n\t\t(_m, names: string, expr: string) => {\n\t\t\tdestructured = names\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((n) => n.trim().split(\":\")[0]!.trim())\n\t\t\t\t.filter(Boolean);\n\t\t\ttransforms.push(\"destructured preset → `const preset = …`\");\n\t\t\treturn `const preset = ${expr.trim()};`;\n\t\t}\n\t);\n\n\t// Any binding that was destructured and is still spread bare (`...tasks`,\n\t// `...extraRequiredChecks`, …) now has to come off `preset`.\n\tfor (const name of destructured) {\n\t\tif (name === \"repo\" || name === \"providers\" || name === \"workflows\") continue; // handled explicitly below\n\t\tconst bare = new RegExp(`\\\\.\\\\.\\\\.${name}\\\\b(?!\\\\.)`, \"g\");\n\t\tif (bare.test(s)) {\n\t\t\ts = s.replace(bare, `...preset.${name}`);\n\t\t\ttransforms.push(`\\`...${name}\\` → \\`...preset.${name}\\``);\n\t\t}\n\t}\n\n\t// Inject `...preset,` as the first key of defineConfig({ … })\n\tif (/const preset =/.test(s) && !/\\.\\.\\.preset\\b/.test(s)) {\n\t\ts = s.replace(/(defineConfig\\(\\{\\s*\\n)/, `$1\\t...preset,\\n`);\n\t\ttransforms.push(\"spread `...preset` into defineConfig()\");\n\t}\n\n\t// Drop the top-level destructure pass-throughs — `...preset` covers them.\n\ts = s.replace(/^\\torg,\\n/m, \"\");\n\ts = s.replace(/^\\tdomain,\\n/m, \"\");\n\ts = s.replace(/^\\tdocs,\\n/m, \"\");\n\n\t// Spread renames\n\tif (/\\.\\.\\.repo\\.properties/.test(s)) {\n\t\ts = s.replace(/\\.\\.\\.repo\\.properties/g, \"...preset.repo?.properties\");\n\t\ttransforms.push(\"`...repo.properties` → `...preset.repo?.properties`\");\n\t}\n\tif (/([{[,]\\s*)\\.\\.\\.repo\\b(?!\\.)/.test(s)) {\n\t\ts = s.replace(/([{[,]\\s*)\\.\\.\\.repo\\b(?!\\.)/g, \"$1...preset.repo\");\n\t\ttransforms.push(\"`...repo` → `...preset.repo`\");\n\t}\n\tif (/\\.\\.\\.providers\\b/.test(s)) {\n\t\ts = s.replace(/\\.\\.\\.providers\\b/g, \"...preset.providers\");\n\t\ttransforms.push(\"`...providers` → `...preset.providers`\");\n\t}\n\n\t// `repo.requiredChecks` is gone — the derived checks come from `tasks`.\n\t// Pull the custom entries out to a top-level `extraRequiredChecks`.\n\tconst rc = /(\\n\\s*)requiredChecks\\s*:\\s*\\[\\s*\\n?\\s*\\.\\.\\.repo\\.requiredChecks\\s*,?\\s*([\\s\\S]*?)\\n\\s*\\]\\s*,/.exec(s);\n\tif (rc) {\n\t\tconst custom = rc[2]!.trim().replace(/,\\s*$/, \"\");\n\t\ts = s.replace(rc[0], \"\");\n\t\tif (custom) {\n\t\t\tconst block = `\\textraRequiredChecks: [\\n\\t\\t${custom\n\t\t\t\t.split(\"\\n\")\n\t\t\t\t.map((l) => l.trim())\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.join(\"\\n\\t\\t\")}\\n\\t],\\n`;\n\t\t\ts = s.replace(/(defineConfig\\(\\{\\s*\\n(?:\\t\\.\\.\\.preset,\\n)?)/, `$1${block}`);\n\t\t\ttransforms.push(\"`repo.requiredChecks` custom entries → top-level `extraRequiredChecks`\");\n\t\t\twarnings.push(\"check the moved `extraRequiredChecks` — the preset already contributes lint/test/typecheck\");\n\t\t} else {\n\t\t\ts = s.replace(/,(\\s*)\\.\\.\\.repo\\.requiredChecks/g, \"$1\");\n\t\t\ttransforms.push(\"dropped `...repo.requiredChecks`\");\n\t\t}\n\t}\n\n\t// `workflows:` → `tasks:` (`...workflows` → `...preset.tasks`)\n\tif (/^\\s*workflows\\s*:/m.test(s)) {\n\t\ts = s.replace(/(\\n\\s*)workflows(\\s*:\\s*\\[)/, \"$1tasks$2\");\n\t\ts = s.replace(/\\.\\.\\.workflows\\b/g, \"...preset.tasks\");\n\t\ttransforms.push(\"`workflows:` → `tasks:` (`...workflows` → `...preset.tasks`)\");\n\t\twarnings.push(\n\t\t\t\"review the `tasks` array — a bare workflow name that should gate merges now needs `{ name, required: true }`\"\n\t\t);\n\t}\n\n\treturn { content: s, changed: s !== content, transforms, warnings };\n}\n\n// ── public API ───────────────────────────────────────────────────────────────\n\nexport interface RunUpgradeDepsInput {\n\t/** Repo root. Defaults to `process.cwd()`. */\n\tcwd?: string;\n\t/** Print what would change without writing. */\n\tdryRun?: boolean;\n\t/** Skip the `holocron.config.ts` migration (pins only). */\n\tpinsOnly?: boolean;\n\tprint?: (line: string) => void;\n\tlogger?: Logger;\n\treadFile?: (path: string) => string;\n\twriteFile?: (path: string, content: string) => void;\n\tfetchLatest?: FetchLatest;\n}\n\nexport type UpgradeDepsStatus = \"ok\" | \"fail\" | \"dry-run\";\n\nexport interface UpgradeDepsReport {\n\tstatus: UpgradeDepsStatus;\n\tbumps: readonly CatalogBump[];\n\tconfigMigrated: boolean;\n\tconfigWarnings: readonly string[];\n\tmessage?: string;\n}\n\nexport async function runUpgradeDeps(input: RunUpgradeDepsInput = {}): Promise<UpgradeDepsReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst cwd = input.cwd ?? process.cwd();\n\tconst dryRun = input.dryRun ?? false;\n\tconst pinsOnly = input.pinsOnly ?? false;\n\tconst _readFile = input.readFile ?? ((p: string) => readFileSync(p, \"utf8\"));\n\tconst _writeFile = input.writeFile ?? ((p: string, c: string) => writeFileSync(p, c));\n\tconst fetchLatest = input.fetchLatest ?? fetchLatestFromNpm;\n\n\tlogger.info({ dryRun: dryRun || undefined, pinsOnly: pinsOnly || undefined }, \"upgrade deps: start\");\n\tprint(`Upgrading @theholocron/* dependencies${dryRun ? \" (dry-run)\" : \"\"}…`);\n\n\t// ── 1. catalog pins ──\n\tconst wsPath = join(cwd, \"pnpm-workspace.yaml\");\n\tlet bumps: CatalogBump[] = [];\n\ttry {\n\t\tconst ws = _readFile(wsPath);\n\t\tconst result = await bumpCatalogs(ws, fetchLatest);\n\t\tbumps = result.bumps;\n\t\tif (bumps.length > 0) {\n\t\t\tif (!dryRun) _writeFile(wsPath, result.content);\n\t\t\tprint(\"\");\n\t\t\tprint(` pnpm-workspace.yaml — ${bumps.length} pin${bumps.length === 1 ? \"\" : \"s\"}`);\n\t\t\tfor (const b of bumps) print(` ${dryRun ? \"~\" : \"✓\"} ${b.pkg} ${b.from} → ${b.to}`);\n\t\t} else {\n\t\t\tprint(\" · pnpm-workspace.yaml — @theholocron/* pins already current\");\n\t\t}\n\t} catch {\n\t\tprint(\" · no pnpm-workspace.yaml — skipping catalog pins\");\n\t}\n\n\t// ── 2. holocron.config.ts migration ──\n\tlet configMigrated = false;\n\tlet configWarnings: string[] = [];\n\tif (!pinsOnly) {\n\t\tfor (const name of [\"holocron.config.ts\", \"holocron.config.js\"]) {\n\t\t\tlet cfg: string;\n\t\t\ttry {\n\t\t\t\tcfg = _readFile(join(cwd, name));\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst m = migrateConfig(cfg);\n\t\t\tif (!m.changed) {\n\t\t\t\tprint(` · ${name} — already on the current preset API`);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!dryRun) _writeFile(join(cwd, name), m.content);\n\t\t\tconfigMigrated = true;\n\t\t\tconfigWarnings = m.warnings;\n\t\t\tprint(\"\");\n\t\t\tprint(` ${name} — ${dryRun ? \"would migrate\" : \"migrated\"} to the 8.x preset API`);\n\t\t\tfor (const t of m.transforms) print(` ${dryRun ? \"~\" : \"✓\"} ${t}`);\n\t\t\tfor (const w of m.warnings) print(` ⚠ ${w}`);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tprint(\"\");\n\tif (bumps.length === 0 && !configMigrated) {\n\t\tprint(\"Nothing to do — already up to date.\");\n\t} else {\n\t\tprint(`Next: ${dryRun ? \"run without --dry-run, then \" : \"\"}\\`pnpm install && holocron ci\\``);\n\t\tif (configMigrated) print(\" review holocron.config.ts before committing.\");\n\t}\n\n\tconst status: UpgradeDepsStatus = dryRun ? \"dry-run\" : \"ok\";\n\tlogger.info({ bumps: bumps.length, configMigrated, warnings: configWarnings.length, status }, \"upgrade deps: done\");\n\treturn { status, bumps, configMigrated, configWarnings };\n}\n","import { readdirSync, readFileSync, statSync, writeFileSync } from \"node:fs\";\nimport { basename, join } from \"node:path\";\n\nimport type { Logger } from \"@theholocron/observability/core\";\n\nimport { getLogger } from \"../logger.js\";\n\n// Directories to skip when walking the repo tree\nconst SKIP_DIRS = new Set([\"node_modules\", \".git\", \"dist\", \"coverage\", \"build\", \".turbo\", \".next\", \"out\"]);\n\n// ── per-file-type patch functions ─────────────────────────────────────────────\n// Each returns the new file content, or null if nothing in that file changed.\n\nfunction patchPackageJson(content: string, from: number, to: number): string | null {\n\tlet pkg: Record<string, unknown>;\n\ttry {\n\t\tpkg = JSON.parse(content) as Record<string, unknown>;\n\t} catch {\n\t\treturn null;\n\t}\n\n\tlet changed = false;\n\n\tconst engines = pkg.engines as Record<string, string> | undefined;\n\tif (engines?.node && /^>=\\d+(?:\\.0\\.0)?$/.test(engines.node)) {\n\t\tconst major = parseInt(engines.node.match(/\\d+/)![0]!, 10);\n\t\tif (major === from) {\n\t\t\tengines.node = `>=${to}.0.0`;\n\t\t\tchanged = true;\n\t\t}\n\t}\n\n\tfor (const field of [\"devDependencies\", \"dependencies\"] as const) {\n\t\tconst deps = pkg[field] as Record<string, string> | undefined;\n\t\tif (!deps?.[\"@types/node\"]) continue;\n\t\t// Only update exact semver ranges; leave catalog: pins alone\n\t\tif (deps[\"@types/node\"] === `^${from}.0.0`) {\n\t\t\tdeps[\"@types/node\"] = `^${to}.0.0`;\n\t\t\tchanged = true;\n\t\t}\n\t}\n\n\treturn changed ? JSON.stringify(pkg, null, 2) + \"\\n\" : null;\n}\n\nfunction patchYaml(content: string, from: number, to: number): string | null {\n\t// node-version: 20 / node-version: '20' / node-version: \"20\"\n\tconst updated = content.replace(/node-version:\\s+['\"]?(\\d+)['\"]?/g, (match, ver) =>\n\t\tver === String(from) ? match.replace(String(from), String(to)) : match\n\t);\n\treturn updated !== content ? updated : null;\n}\n\nfunction patchPinFile(content: string, from: number, to: number): string | null {\n\t// .nvmrc / .node-version — \"20\" or \"20.x.y\" on the first line\n\tconst trimmed = content.trim();\n\tif (trimmed === String(from) || trimmed.startsWith(`${from}.`)) {\n\t\treturn `${to}\\n`;\n\t}\n\treturn null;\n}\n\nfunction patchDockerfile(content: string, from: number, to: number): string | null {\n\t// FROM node:20 / FROM node:20-alpine / FROM node:20.11.0\n\tconst updated = content.replace(/^(FROM\\s+node:)(\\d+)/gm, (match, prefix, ver) =>\n\t\tver === String(from) ? `${prefix}${to}` : match\n\t);\n\treturn updated !== content ? updated : null;\n}\n\nfunction patchToolVersions(content: string, from: number, to: number): string | null {\n\t// nodejs 20 / nodejs 20.11.0\n\tconst updated = content.replace(/^(nodejs\\s+)(\\d+)/gm, (match, prefix, ver) =>\n\t\tver === String(from) ? `${prefix}${to}` : match\n\t);\n\treturn updated !== content ? updated : null;\n}\n\ninterface Pattern {\n\tmatches: (filename: string) => boolean;\n\tpatch: (content: string, from: number, to: number) => string | null;\n}\n\nconst PATTERNS: Pattern[] = [\n\t{ matches: (n) => n === \"package.json\", patch: patchPackageJson },\n\t{ matches: (n) => n.endsWith(\".yml\") || n.endsWith(\".yaml\"), patch: patchYaml },\n\t{ matches: (n) => n === \".nvmrc\" || n === \".node-version\", patch: patchPinFile },\n\t{ matches: (n) => n === \"Dockerfile\" || n.startsWith(\"Dockerfile.\"), patch: patchDockerfile },\n\t{ matches: (n) => n === \".tool-versions\", patch: patchToolVersions },\n];\n\n// ── auto-detect current major from the repo ───────────────────────────────────\n\nfunction detectFrom(cwd: string, _readFile: (p: string) => string): number | null {\n\tfor (const name of [\".nvmrc\", \".node-version\"]) {\n\t\ttry {\n\t\t\tconst major = parseInt(_readFile(join(cwd, name)).trim(), 10);\n\t\t\tif (!isNaN(major)) return major;\n\t\t} catch {\n\t\t\t/* absent */\n\t\t}\n\t}\n\ttry {\n\t\tconst pkg = JSON.parse(_readFile(join(cwd, \"package.json\"))) as Record<string, unknown>;\n\t\tconst node = (pkg.engines as Record<string, string> | undefined)?.node;\n\t\tif (node) {\n\t\t\tconst m = node.match(/(\\d+)/);\n\t\t\tif (m) return parseInt(m[1]!, 10);\n\t\t}\n\t} catch {\n\t\t/* absent */\n\t}\n\treturn null;\n}\n\n// ── default file walker ───────────────────────────────────────────────────────\n\nfunction defaultWalkFiles(dir: string): string[] {\n\tconst results: string[] = [];\n\n\tfunction walk(current: string): void {\n\t\tlet entries: string[];\n\t\ttry {\n\t\t\tentries = readdirSync(current);\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\t\tfor (const entry of entries) {\n\t\t\tif (SKIP_DIRS.has(entry)) continue;\n\t\t\tconst abs = join(current, entry);\n\t\t\ttry {\n\t\t\t\tif (statSync(abs).isDirectory()) walk(abs);\n\t\t\t\telse results.push(abs);\n\t\t\t} catch {\n\t\t\t\t/* skip unreadable */\n\t\t\t}\n\t\t}\n\t}\n\n\twalk(dir);\n\treturn results;\n}\n\n// ── public API ────────────────────────────────────────────────────────────────\n\nexport interface RunUpgradeNodeInput {\n\t/** Target Node.js major version (e.g., 22). */\n\tto: number;\n\t/** Source major version. Auto-detected from .nvmrc / engines.node when omitted. */\n\tfrom?: number;\n\t/** Working directory (repo root). Defaults to process.cwd(). */\n\tcwd?: string;\n\t/** Print what would change without writing anything. */\n\tdryRun?: boolean;\n\t/**\n\t * Extra file paths (relative to cwd) to scan in addition to the normal\n\t * walk. Use for non-conventional locations not covered by the pattern\n\t * registry (e.g., custom Dockerfiles, .tool-versions in a subdirectory).\n\t * Sourced from `upgrade.node.extra` in holocron.config.json.\n\t */\n\textra?: string[];\n\tprint?: (line: string) => void;\n\t/** Structured-logging sink — sibling of `print`. Defaults to the command-bound root. */\n\tlogger?: Logger;\n\t/** Injectable for testing. */\n\treadFile?: (path: string) => string;\n\twriteFile?: (path: string, content: string) => void;\n\twalkFiles?: (dir: string) => string[];\n}\n\nexport type UpgradeNodeStatus = \"ok\" | \"fail\" | \"dry-run\";\n\nexport interface UpgradeNodeReport {\n\tstatus: UpgradeNodeStatus;\n\tupdated: readonly string[];\n\tmessage?: string;\n}\n\nexport async function runUpgradeNode(input: RunUpgradeNodeInput): Promise<UpgradeNodeReport> {\n\tconst print = input.print ?? ((line: string) => console.log(line));\n\tconst logger = input.logger ?? getLogger();\n\tconst cwd = input.cwd ?? process.cwd();\n\tconst { to, dryRun = false, extra = [] } = input;\n\tconst _readFile = input.readFile ?? ((p: string) => readFileSync(p, \"utf8\"));\n\tconst _writeFile = input.writeFile ?? ((p: string, c: string) => writeFileSync(p, c));\n\tconst _walkFiles = input.walkFiles ?? defaultWalkFiles;\n\n\tconst from = input.from ?? detectFrom(cwd, _readFile);\n\tif (from === null) {\n\t\tconst message = \"could not detect current Node version — pass --from <major>\";\n\t\tlogger.warn({ to, reason: message }, \"upgrade node: done\");\n\t\treturn { status: \"fail\", updated: [], message };\n\t}\n\n\tlogger.info({ from, to, dryRun: dryRun || undefined }, \"upgrade node: start\");\n\n\tif (from === to) {\n\t\tprint(`Already at Node.js ${to} — nothing to do.`);\n\t\tlogger.info({ from, to, updated: 0, status: \"ok\" }, \"upgrade node: done\");\n\t\treturn { status: \"ok\", updated: [] };\n\t}\n\n\tprint(`Upgrading Node.js ${from} → ${to}${dryRun ? \" (dry-run)\" : \"\"}…`);\n\n\tconst updated: string[] = [];\n\tconst scanned = [..._walkFiles(cwd), ...extra.map((p) => join(cwd, p))];\n\n\tfor (const abs of scanned) {\n\t\tconst name = basename(abs);\n\t\tconst pattern = PATTERNS.find((p) => p.matches(name));\n\t\tif (!pattern) continue;\n\n\t\tlet content: string;\n\t\ttry {\n\t\t\tcontent = _readFile(abs);\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst patched = pattern.patch(content, from, to);\n\t\tif (patched === null) continue;\n\n\t\tconst rel = abs.startsWith(cwd + \"/\") ? abs.slice(cwd.length + 1) : abs;\n\t\tif (!dryRun) _writeFile(abs, patched);\n\t\tprint(` ${dryRun ? \"~\" : \"✓\"} ${rel}`);\n\t\tlogger.debug({ file: rel, from, to }, \"upgrade node: patched\");\n\t\tupdated.push(rel);\n\t}\n\n\tif (updated.length === 0) {\n\t\tprint(` · no files contained Node.js ${from} pins`);\n\t}\n\n\tconst status = dryRun ? \"dry-run\" : \"ok\";\n\tlogger.info({ from, to, updated: updated.length, status }, \"upgrade node: done\");\n\treturn { status, updated };\n}\n","/**\n * Lints one commit message string against an already-loaded commitlint\n * config. The genuinely environment-independent half of commit-message\n * linting (holocron#789) — *obtaining* a `QualifiedConfig` differs by\n * caller (Sentinel isolates itself from any ambient config since it runs\n * standalone, away from a real repo checkout; `lintCommitMsgFile` below\n * just lets cosmiconfig discover the invoking repo's own\n * `commitlint.config.*`, matching `commitlint --edit`'s own contract) —\n * but linting one message against a loaded config is identical either way.\n *\n * Real `@commitlint/lint` — the same programmatic API `@commitlint/cli`\n * itself uses internally — never a reimplementation of commitlint's rules.\n */\n\nimport lint from \"@commitlint/lint\";\nimport type { LintOptions, ParserPreset, QualifiedConfig } from \"@commitlint/types\";\n\nexport interface CommitMessageViolation {\n\t/** Rule name, e.g. `\"subject-empty\"`. */\n\trule: string;\n\t/** commitlint's own message for the failure, e.g. `\"subject may not be empty\"`. */\n\tmessage: string;\n}\n\n/** `parserPreset.parserOpts`, if the loaded config sets one — same lookup `@commitlint/cli`'s own `selectParserOpts()` does. */\nfunction selectParserOpts(parserPreset: ParserPreset | undefined): ParserPreset[\"parserOpts\"] {\n\treturn parserPreset?.parserOpts;\n}\n\nexport async function lintCommitMessage(message: string, loaded: QualifiedConfig): Promise<CommitMessageViolation[]> {\n\tconst opts: LintOptions = {\n\t\t// `@theholocron/commitlint-config` sets no parserPreset of its own\n\t\t// (relies on commitlint's built-in default parser) or a non-empty\n\t\t// `ignores` today beyond the one dependabot-bump matcher it does set —\n\t\t// both `?? {}`/`?? []` are real fallbacks for a config that could set\n\t\t// either, not dead code, even though this org's own shared config\n\t\t// never exercises the \"unset\" side for `ignores` and never exercises\n\t\t// the \"set\" side for `parserPreset`.\n\t\t/* istanbul ignore next -- see comment above */\n\t\tparserOpts: selectParserOpts(loaded.parserPreset) ?? {},\n\t\tplugins: loaded.plugins,\n\t\t/* istanbul ignore next -- see comment above */\n\t\tignores: loaded.ignores ?? [],\n\t\tdefaultIgnores: loaded.defaultIgnores !== false,\n\t};\n\n\tconst outcome = await lint(message, loaded.rules, opts);\n\tif (outcome.valid) return [];\n\treturn outcome.errors.map((error) => ({ rule: error.name, message: error.message }));\n}\n","/**\n * `holocron lint commit-msg <file>` — a real programmatic replacement for\n * shelling out to `commitlint --edit \"$1\"` from `.husky/commit-msg`\n * (holocron#789). Matches that CLI's own contract exactly: `file` is a\n * path to the commit message being written (the arg git's `commit-msg`\n * hook passes as `$1`), no `--config` override needed — `@commitlint/load`\n * runs from `cwd` with no seed, so cosmiconfig's own normal upward search\n * discovers the invoking repo's real `commitlint.config.*` file, exactly\n * as `commitlint --edit` (no `--config` flag) already does today. Unlike\n * Sentinel's `loadIsolatedConfig()`, no isolation is needed here — this\n * runs inside a real repo checkout with a real `node_modules`, not\n * standalone on a server.\n */\n\nimport { readFile } from \"node:fs/promises\";\n\nimport load from \"@commitlint/load\";\n\nimport { type CommitMessageViolation, lintCommitMessage } from \"./lint-message.js\";\n\nexport interface LintCommitMsgFileResult {\n\tvalid: boolean;\n\tviolations: CommitMessageViolation[];\n}\n\nexport async function lintCommitMsgFile(filePath: string, cwd = process.cwd()): Promise<LintCommitMsgFileResult> {\n\tconst message = await readFile(filePath, \"utf8\");\n\tconst loaded = await load({}, { cwd });\n\tconst violations = await lintCommitMessage(message, loaded);\n\treturn { valid: violations.length === 0, violations };\n}\n","/**\n * `holocron.config.{ts,js,mjs,cjs,json}` loader.\n *\n * File discovery + module loading (typed configs via `tsx`, no build\n * step) is delegated to `@theholocron/datapad`. This module keeps the\n * holocron-specific parts: filling `name` / `repo.name` defaults and\n * running the config through `resolveConfig`.\n *\n * Probe order is TS-first (`.ts` → `.js` → `.mjs` → `.cjs` → `.json`) —\n * see ADR-0010 / issue #75 / #81.\n */\n\nimport { execFile } from \"node:child_process\";\nimport { readFile } from \"node:fs/promises\";\nimport { basename, dirname, join } from \"node:path\";\nimport { promisify } from \"node:util\";\n\nimport { loadTasksConfig } from \"@theholocron/astromech/config\";\nimport { ConfigFileError, loadConfigFile } from \"@theholocron/datapad\";\n\nconst execFileAsync = promisify(execFile);\n\nimport type { HolocronConfig, ResolvedHolocronConfig } from \"./config.js\";\nimport { resolveConfig } from \"./config.js\";\n\nexport { ConfigFileError } from \"@theholocron/datapad\";\n\nexport interface LoadedConfig {\n\tresolved: ResolvedHolocronConfig;\n\t/** Absolute path to the file the config was read from. */\n\tfilepath: string;\n}\n\n/**\n * Read + parse + resolve `holocron.config.*` from the given directory.\n * Throws {@link ConfigFileError} when nothing is found or a file cannot\n * be loaded, or `ConfigError` when the config is invalid.\n */\nexport async function loadConfig(cwd: string): Promise<LoadedConfig> {\n\tconst found = await loadConfigFile<HolocronConfig>({ cwd, name: \"holocron\" });\n\tif (!found) {\n\t\tthrow new ConfigFileError(\n\t\t\t`no holocron.config.{ts,js,mjs,cjs,json} found in ${cwd}. Create one — see the README for the schema.`\n\t\t);\n\t}\n\tconst withDefaults = await deriveDefaults(dirname(found.filepath), found.config);\n\treturn { resolved: resolveConfig(withDefaults), filepath: found.filepath };\n}\n\nasync function deriveDefaults(configDir: string, raw: HolocronConfig): Promise<HolocronConfig> {\n\tconst result = { ...raw };\n\tif (!result.name) {\n\t\tresult.name = (await readPackageJsonName(configDir)) ?? basename(configDir);\n\t}\n\tif (result.repo && !result.repo.name) {\n\t\tconst repoName = await readGitRemote(configDir);\n\t\tif (repoName) result.repo = { ...result.repo, name: repoName };\n\t}\n\n\t// Layer in the task manifest. `holocron.config`'s `tasks` key is one input;\n\t// a dedicated `astromech.config.{ts,js,mjs,json}` is merged on top (it wins\n\t// on scalars, task arrays concatenate). Doing it here keeps `holocron setup`\n\t// / `sync` / `doctor` on the same manifest that `holocron run` / `holocron\n\t// ci` resolve directly via `loadTasksConfig`.\n\tconst manifest = await loadTasksConfig(configDir);\n\tif (manifest.tasks) result.tasks = manifest.tasks;\n\tif (manifest.syncScripts !== undefined) result.syncScripts = manifest.syncScripts;\n\tif (manifest.holocronScript !== undefined) result.holocronScript = manifest.holocronScript;\n\tif (manifest.hooks !== undefined) result.hooks = manifest.hooks;\n\tif (manifest.extraRequiredChecks) {\n\t\tresult.extraRequiredChecks = [...(result.extraRequiredChecks ?? []), ...manifest.extraRequiredChecks];\n\t}\n\n\treturn result;\n}\n\nasync function readPackageJsonName(dir: string): Promise<string | undefined> {\n\ttry {\n\t\tconst content = await readFile(join(dir, \"package.json\"), \"utf8\");\n\t\tconst pkg = JSON.parse(content) as { name?: string };\n\t\treturn typeof pkg.name === \"string\" ? pkg.name.replace(/^@[^/]+\\//, \"\") : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nasync function readGitRemote(dir: string): Promise<string | undefined> {\n\ttry {\n\t\tconst { stdout } = await execFileAsync(\"git\", [\"remote\", \"get-url\", \"origin\"], { cwd: dir });\n\t\treturn parseGitRemoteUrl(stdout.trim());\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction parseGitRemoteUrl(url: string): string | undefined {\n\tconst httpsMatch = url.match(/github\\.com\\/([^/]+\\/[^/]+?)(?:\\.git)?$/);\n\tif (httpsMatch) return httpsMatch[1]!;\n\tconst sshMatch = url.match(/github\\.com:([^/]+\\/[^/]+?)(?:\\.git)?$/);\n\tif (sshMatch) return sshMatch[1]!;\n\treturn undefined;\n}\n","/**\n * The interactive fallback — replaces every \"run --help to see commands\"\n * dead end with a prompt. Three layers, all driven by {@link COMMAND_REGISTRY}:\n *\n * 1. `holocron` with no command → searchable picker over every command\n * 2. a parent command with no sub → `select()` over that group's commands\n * 3. a leaf command missing a → `input()` / `select()` per positional\n * required positional\n *\n * Layers 1–2 are driven from `cli.ts`'s `$0` handlers via {@link launchMenu}:\n * pick a command, prompt for its required positionals, then **spawn a fresh\n * `holocron <command> …` child process** (`stdio: \"inherit\"`) rather than\n * re-entering yargs' own parse pipeline — see the spec's \"spawn vs re-parse\"\n * section (theholocron/holocron#438) for why. Layer 3 is driven directly from\n * each leaf command's own handler in `cli.ts`, calling\n * {@link promptForPositionals} for just that one command — no spawn needed,\n * the handler already has everything else it needs.\n *\n * Every prompt is preceded by a `process.stdin.isTTY` check. A non-TTY run\n * (CI, a script, a pipe) throws {@link NonInteractiveError} instead of\n * hanging on `@inquirer/prompts` (which otherwise throws its own\n * `ExitPromptError` the moment stdin closes) — `cli.ts`'s `USER_FACING_ERRORS`\n * catch prints its message cleanly, restoring the old demandCommand-style\n * hard failure for non-interactive callers.\n */\n\nimport { spawn } from \"node:child_process\";\n\nimport { input, select } from \"@inquirer/prompts\";\nimport search from \"@inquirer/search\";\n\nimport { listStoredProviders } from \"./auth/keyring.js\";\n\n/** Raised when a prompt is needed but stdin isn't a TTY — see the module doc. */\nexport class NonInteractiveError extends Error {\n\toverride name = \"NonInteractiveError\";\n}\n\nexport interface PositionalPrompt {\n\t/** The yargs positional's camelCased argv key (e.g. `\"newVersion\"`). */\n\tkey: string;\n\t/**\n\t * The literal token in the command string, when it differs from `key`\n\t * (yargs positionals are kebab-case there — `<new-version>` — but\n\t * camelCased in argv). Shown in the non-interactive fallback message.\n\t * Defaults to `key`.\n\t */\n\tcliArg?: string;\n\t/** Label shown to the user. */\n\tmessage: string;\n\ttype: \"input\" | \"select\";\n\t/**\n\t * Required when `type === \"select\"`. A plain list for a fixed set, or a\n\t * thunk for a set resolved at prompt time (e.g. `auth unset`'s provider\n\t * choices are whatever currently has a stored token — there's no fixed\n\t * provider list, providers are open-ended plugin packages).\n\t */\n\tchoices?: string[] | (() => string[]);\n\t/** Optional `input()` validation — e.g. numeric positionals. */\n\tvalidate?: (value: string) => boolean | string;\n}\n\nexport interface CommandEntry {\n\t/** Full command name as typed at the CLI, e.g. `\"auth set\"`. */\n\tname: string;\n\t/** One-liner, matches the yargs registration's description. */\n\tdescription: string;\n\t/** Required positionals only, in order. Empty when the command needs none. */\n\tpositionals: PositionalPrompt[];\n\t/** Parent command, for Layer 2 grouping: `\"auth\" | \"skills\" | \"upgrade\"`. */\n\tgroup?: string;\n}\n\nconst numeric = (value: string): boolean | string => (/^\\d+$/.test(value) ? true : \"enter a number\");\n\n/**\n * The full command surface, hand-maintained in parallel with `cli.ts`'s\n * yargs registrations (this module does not introspect yargs at runtime).\n * `run <task>` is deliberately excluded — it's CI/scripting-oriented, and an\n * interactive prompt in front of it would work against that. `lint\n * commit-msg <file>` is excluded for the same reason: it's invoked\n * exclusively from `.husky/commit-msg \"$1\"`, never typed by a human.\n */\nexport const COMMAND_REGISTRY: CommandEntry[] = [\n\t{ name: \"version\", description: \"Print the CLI version\", positionals: [] },\n\t{\n\t\tname: \"clone\",\n\t\tdescription: \"Clone all repos in a GitHub org as siblings under a single directory\",\n\t\tpositionals: [],\n\t},\n\t{ name: \"doctor\", description: \"Load the config and run a smoke check against every provider\", positionals: [] },\n\t{ name: \"setup\", description: \"Apply infra setup actions across every configured capability\", positionals: [] },\n\t{\n\t\tname: \"secret set\",\n\t\tdescription: \"Set a single secret via the configured `secrets` capability\",\n\t\tpositionals: [{ key: \"name\", message: \"Secret name:\", type: \"input\" }],\n\t},\n\t{\n\t\tname: \"secrets sync\",\n\t\tdescription: \"Read a vault environment + fan KEY=VALUEs out to secrets + deployment env vars\",\n\t\tpositionals: [{ key: \"environmentId\", message: \"Vault environment id:\", type: \"input\" }],\n\t},\n\t{\n\t\tname: \"deploy\",\n\t\tdescription: \"Trigger a deployment via the configured `deployment` capability\",\n\t\tpositionals: [{ key: \"branch\", message: \"Branch to deploy:\", type: \"input\" }],\n\t},\n\t{\n\t\tname: \"cleanup-preview\",\n\t\tdescription: \"List and delete Cloudflare Pages preview deployments for a GitHub PR\",\n\t\tpositionals: [{ key: \"pr\", message: \"PR number:\", type: \"input\", validate: numeric }],\n\t},\n\t{\n\t\tname: \"bump-versions\",\n\t\tdescription: \"Bump all non-private package versions in lockstep (semantic-release prepareCmd)\",\n\t\tpositionals: [{ key: \"newVersion\", cliArg: \"new-version\", message: \"New version:\", type: \"input\" }],\n\t},\n\t{\n\t\tname: \"publish\",\n\t\tdescription: \"Publish @theholocron/* packages to npm\",\n\t\tpositionals: [],\n\t},\n\t{\n\t\tname: \"sync\",\n\t\tdescription:\n\t\t\t\"Sync state from config to the provider and local files (labels, properties, teams, topics, keywords, description, homepage, readme, workflows, scripts, wiki)\",\n\t\tpositionals: [],\n\t},\n\t{ name: \"ci\", description: \"Run the merge-gating checks locally, in CI order — 'will CI pass?'\", positionals: [] },\n\t{\n\t\tname: \"sync-github\",\n\t\tdescription: \"Sync workflow templates and composite actions to theholocron/.github\",\n\t\tpositionals: [],\n\t},\n\t{\n\t\tname: \"sync-readme\",\n\t\tdescription: \"Sync the Installation + Usage block in README.md from package.json\",\n\t\tpositionals: [],\n\t},\n\t{ name: \"config show\", description: \"Print the resolved holocron config\", positionals: [] },\n\t{\n\t\tname: \"new\",\n\t\tdescription: \"Scaffold a new repo from a GitHub template (e.g. cli, react, nextjs, node, monorepo, base)\",\n\t\tpositionals: [],\n\t},\n\t{\n\t\tname: \"plugin create\",\n\t\tdescription: \"Scaffold a new @theholocron/holocron-plugin-<slug> package\",\n\t\tpositionals: [\n\t\t\t{ key: \"slug\", message: \"Package slug (kebab-case):\", type: \"input\" },\n\t\t\t{ key: \"vendor\", message: \"Vendor display name (PascalCase):\", type: \"input\" },\n\t\t],\n\t},\n\t{\n\t\tname: \"skills install\",\n\t\tdescription: \"Copy skills from @theholocron/skills into .agents/ with agent symlinks\",\n\t\tpositionals: [],\n\t\tgroup: \"skills\",\n\t},\n\t{\n\t\tname: \"skills remove\",\n\t\tdescription: \"Remove installed skills via npx skills remove\",\n\t\tpositionals: [],\n\t\tgroup: \"skills\",\n\t},\n\t{\n\t\tname: \"skills update\",\n\t\tdescription: \"Update installed skills to their latest upstream versions via npx skills update\",\n\t\tpositionals: [],\n\t\tgroup: \"skills\",\n\t},\n\t{\n\t\tname: \"upgrade node\",\n\t\tdescription: \"Scan the repo and update every Node.js version pin to a new major\",\n\t\tpositionals: [{ key: \"to\", message: \"Target Node.js major version:\", type: \"input\", validate: numeric }],\n\t\tgroup: \"upgrade\",\n\t},\n\t{\n\t\tname: \"upgrade deps\",\n\t\tdescription: \"Bump every @theholocron/* pin to latest and migrate holocron.config.ts to the current preset API\",\n\t\tpositionals: [],\n\t\tgroup: \"upgrade\",\n\t},\n\t{\n\t\tname: \"auth set\",\n\t\tdescription: \"Verify + store a bootstrap token for a provider\",\n\t\tpositionals: [{ key: \"provider\", message: \"Provider name:\", type: \"input\" }],\n\t\tgroup: \"auth\",\n\t},\n\t{\n\t\tname: \"auth unset\",\n\t\tdescription: \"Remove a stored bootstrap token\",\n\t\tpositionals: [{ key: \"provider\", message: \"Provider:\", type: \"select\", choices: listStoredProviders }],\n\t\tgroup: \"auth\",\n\t},\n\t{\n\t\tname: \"auth check\",\n\t\tdescription: \"Re-verify a stored bootstrap token\",\n\t\tpositionals: [{ key: \"provider\", message: \"Provider:\", type: \"select\", choices: listStoredProviders }],\n\t\tgroup: \"auth\",\n\t},\n\t{\n\t\tname: \"auth list\",\n\t\tdescription: \"List every provider with a stored bootstrap token\",\n\t\tpositionals: [],\n\t\tgroup: \"auth\",\n\t},\n];\n\n/** Look up a {@link CommandEntry} by its full name — for Layer 3 call sites in `cli.ts`. */\nexport function getEntry(name: string): CommandEntry {\n\tconst entry = COMMAND_REGISTRY.find((e) => e.name === name);\n\tif (!entry) throw new Error(`interactive-menu: no COMMAND_REGISTRY entry named \"${name}\"`);\n\treturn entry;\n}\n\n/**\n * Searchable autocomplete over `entries` — the Layer 1 top-level picker, and\n * (passed a `group`-filtered subset) the Layer 2 parent-command picker.\n * `select()` would work too at these list sizes, but `search()` degrades\n * gracefully as the surface grows and costs nothing when it doesn't.\n */\nexport async function pickCommand(\n\tentries: CommandEntry[],\n\tmessage = \"What would you like to do?\"\n): Promise<CommandEntry> {\n\tconst byName = new Map(entries.map((e) => [e.name, e]));\n\tconst picked = await search<string>({\n\t\tmessage,\n\t\tsource: (term) => searchChoices(entries, term),\n\t});\n\t// `source` only ever returns names drawn from `entries`, so this is always defined.\n\treturn byName.get(picked)!;\n}\n\n/**\n * `@inquirer/search`'s `source` callback, factored out as a plain function —\n * unit-testable directly instead of only through a mocked `search()` call.\n * Empty/undefined `term` (nothing typed yet) returns every entry.\n */\nexport function searchChoices(\n\tentries: CommandEntry[],\n\tterm: string | undefined\n): Array<{ name: string; value: string; description: string }> {\n\tconst pool = !term ? entries : entries.filter((e) => matches(e, term));\n\treturn pool.map((e) => ({ name: e.name, value: e.name, description: e.description }));\n}\n\nfunction matches(entry: CommandEntry, term: string): boolean {\n\tconst needle = term.toLowerCase();\n\treturn entry.name.toLowerCase().includes(needle) || entry.description.toLowerCase().includes(needle);\n}\n\n/**\n * For each of `entry.positionals` not already present in `argv`, prompts for\n * it (`input()` or `select()`, per the positional's `type`) and returns the\n * resolved values in positional order — ready to append to a spawned child's\n * argv, or to use directly in the current handler (Layer 3).\n *\n * Throws {@link NonInteractiveError} the first time it would need to prompt\n * on a non-TTY stdin, and again if a `select` positional's choices resolve\n * empty (nothing to pick from — e.g. `auth unset` with no stored tokens).\n */\nexport async function promptForPositionals(entry: CommandEntry, argv: Record<string, unknown>): Promise<string[]> {\n\tconst out: string[] = [];\n\tfor (const positional of entry.positionals) {\n\t\tconst existing = argv[positional.key];\n\t\tif (existing !== undefined && existing !== \"\") {\n\t\t\tout.push(String(existing));\n\t\t\tcontinue;\n\t\t}\n\t\tif (!process.stdin.isTTY) {\n\t\t\tthrow new NonInteractiveError(\n\t\t\t\t`\\`${entry.name}\\` needs \"${positional.key}\" — pass it directly: holocron ${entry.name} <${positional.cliArg ?? positional.key}>`\n\t\t\t);\n\t\t}\n\t\tif (positional.type === \"select\") {\n\t\t\tconst choices =\n\t\t\t\ttypeof positional.choices === \"function\" ? positional.choices() : (positional.choices ?? []);\n\t\t\tif (choices.length === 0) {\n\t\t\t\tthrow new NonInteractiveError(\n\t\t\t\t\t`\\`${entry.name}\\`: no ${positional.key} to choose from — nothing stored yet`\n\t\t\t\t);\n\t\t\t}\n\t\t\tout.push(await select({ message: positional.message, choices: choices.map((c) => ({ value: c })) }));\n\t\t} else {\n\t\t\tout.push(\n\t\t\t\tawait input({\n\t\t\t\t\tmessage: positional.message,\n\t\t\t\t\t...(positional.validate ? { validate: positional.validate } : {}),\n\t\t\t\t})\n\t\t\t);\n\t\t}\n\t}\n\treturn out;\n}\n\n/**\n * `--token` (repeatable), `--org`, `--cwd`, `--dry-run` — the global flags a\n * menu-launched child should inherit from the parent invocation. Everything\n * else (command-specific options) was never captured by the top-level `$0`\n * handler in the first place, so there's nothing else to forward.\n */\nexport function forwardedFlags(argv: Record<string, unknown>): string[] {\n\tconst out: string[] = [];\n\tconst tokens = argv.token as string[] | undefined;\n\tfor (const t of tokens ?? []) out.push(\"--token\", t);\n\tif (typeof argv.org === \"string\") out.push(\"--org\", argv.org);\n\tif (typeof argv.cwd === \"string\") out.push(\"--cwd\", argv.cwd);\n\tif (argv.dryRun === true) out.push(\"--dry-run\");\n\treturn out;\n}\n\n/** `entry.name` split into tokens, resolved positionals appended, then forwarded flags. */\nexport function buildChildArgv(\n\tentry: CommandEntry,\n\tpositionals: string[],\n\tparentArgv: Record<string, unknown>\n): string[] {\n\treturn [...entry.name.split(\" \"), ...positionals, ...forwardedFlags(parentArgv)];\n}\n\n/** Spawn `holocron <...args>` inheriting stdio; resolve with its exit code. */\nfunction spawnChild(args: string[]): Promise<number> {\n\treturn new Promise((resolve) => {\n\t\tconst child = spawn(process.execPath, [process.argv[1]!, ...args], { stdio: \"inherit\" });\n\t\tchild.on(\"exit\", (code) => resolve(code ?? 0));\n\t\tchild.on(\"error\", () => resolve(1));\n\t});\n}\n\n/**\n * Layers 1 and 2: pick a command from `entries`, prompt for its required\n * positionals, spawn it as a fresh `holocron` invocation, and set\n * `process.exitCode` from the child — the caller (a `$0` handler in\n * `cli.ts`) returns normally afterward so the parent's own telemetry\n * flush / update-notifier tail still runs. The parent's own\n * `command_completed` event fires with command name \"unknown\" (the\n * middleware ran before any command was picked) — left as-is rather than\n * suppressed; it's a real, useful signal (\"the menu got used\").\n */\nexport async function launchMenu(\n\tentries: CommandEntry[],\n\tparentArgv: Record<string, unknown>,\n\tpickMessage?: string,\n\tnonInteractiveMessage = \"Run `holocron --help` to see available commands.\"\n): Promise<void> {\n\tif (!process.stdin.isTTY) {\n\t\tthrow new NonInteractiveError(nonInteractiveMessage);\n\t}\n\tconst picked = await pickCommand(entries, pickMessage);\n\tconst positionals = await promptForPositionals(picked, {});\n\tconst childArgv = buildChildArgv(picked, positionals, parentArgv);\n\tprocess.exitCode = await spawnChild(childArgv);\n}\n","import { mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport chalk from \"chalk\";\n\nimport { env } from \"./env.js\";\n\nconst PACKAGE_NAME = \"@theholocron/cli\";\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000;\nconst FETCH_TIMEOUT_MS = 3000;\n\ninterface CacheEntry {\n\tlatestVersion: string;\n\tcheckedAt: number;\n}\n\nfunction getCacheDir(): string {\n\treturn env.get(\"HOLOCRON_CACHE_DIR\") ?? join(homedir(), \".cache\", \"holocron\");\n}\n\nfunction getCachePath(): string {\n\treturn join(getCacheDir(), \"update-check.json\");\n}\n\nfunction readCache(): CacheEntry | null {\n\ttry {\n\t\treturn JSON.parse(readFileSync(getCachePath(), \"utf8\")) as CacheEntry;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction writeCache(entry: CacheEntry): void {\n\ttry {\n\t\tmkdirSync(getCacheDir(), { recursive: true });\n\t\twriteFileSync(getCachePath(), JSON.stringify(entry));\n\t} catch {\n\t\t// silently ignore — update check is best-effort\n\t}\n}\n\nasync function fetchLatestVersion(channel: string): Promise<string | null> {\n\ttry {\n\t\tconst res = await fetch(`https://registry.npmjs.org/${encodeURIComponent(PACKAGE_NAME)}`, {\n\t\t\tsignal: AbortSignal.timeout(FETCH_TIMEOUT_MS),\n\t\t});\n\t\tif (!res.ok) return null;\n\t\tconst data = (await res.json()) as { \"dist-tags\": Record<string, string> };\n\t\treturn data[\"dist-tags\"][channel] ?? data[\"dist-tags\"][\"latest\"] ?? null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction getChannel(version: string): string {\n\tconst match = /^[^-]+-([a-zA-Z]+)/.exec(version);\n\treturn match?.[1] ?? \"latest\";\n}\n\nexport function isUpdateAvailable(current: string, latest: string): boolean {\n\tconst normalize = (v: string) => v.replace(/^v/, \"\");\n\tconst c = normalize(current);\n\tconst l = normalize(latest);\n\tif (c === l) return false;\n\n\tconst splitPre = (v: string): [string, string] => {\n\t\tconst idx = v.indexOf(\"-\");\n\t\treturn idx === -1 ? [v, \"\"] : [v.slice(0, idx), v.slice(idx + 1)];\n\t};\n\n\tconst [cRelease, cPre] = splitPre(c);\n\tconst [lRelease, lPre] = splitPre(l);\n\n\tconst parseRelease = (r: string) => r.split(\".\").map(Number);\n\tconst cParts = parseRelease(cRelease);\n\tconst lParts = parseRelease(lRelease);\n\n\tfor (let i = 0; i < Math.max(cParts.length, lParts.length); i++) {\n\t\tconst cv = cParts[i] ?? 0;\n\t\tconst lv = lParts[i] ?? 0;\n\t\tif (lv > cv) return true;\n\t\tif (lv < cv) return false;\n\t}\n\n\t// Release parts equal — compare prerelease\n\tif (!lPre && cPre) return true; // stable > prerelease\n\tif (lPre && !cPre) return false; // prerelease < stable\n\n\t// Both prerelease — compare segment by segment\n\tconst cPreParts = cPre.split(\".\");\n\tconst lPreParts = lPre.split(\".\");\n\tfor (let i = 0; i < Math.max(cPreParts.length, lPreParts.length); i++) {\n\t\tconst cv = cPreParts[i] ?? \"\";\n\t\tconst lv = lPreParts[i] ?? \"\";\n\t\tconst cvNum = Number(cv);\n\t\tconst lvNum = Number(lv);\n\t\tif (!isNaN(cvNum) && !isNaN(lvNum)) {\n\t\t\tif (lvNum > cvNum) return true;\n\t\t\tif (lvNum < cvNum) return false;\n\t\t} else {\n\t\t\tif (lv > cv) return true;\n\t\t\tif (lv < cv) return false;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nfunction formatNotice(current: string, latest: string): string {\n\tconst installCmd = `npm install -g ${PACKAGE_NAME}`;\n\t// Measure raw strings before applying chalk so we avoid control-char regexes.\n\tconst raw1 = `Update available: ${current} → ${latest}`;\n\tconst raw2 = `Run ${installCmd} to update`;\n\tconst width = Math.max(raw1.length, raw2.length) + 4;\n\tconst bar = chalk.yellow(\"─\".repeat(width));\n\tconst border = chalk.yellow(\"│\");\n\tconst pad = (raw: string, styled: string) => `${border} ${styled}${\" \".repeat(width - 2 - raw.length)} ${border}`;\n\treturn [\n\t\t\"\",\n\t\tchalk.yellow(`╭${bar}╮`),\n\t\tpad(raw1, `Update available: ${chalk.dim(current)} → ${chalk.green(latest)}`),\n\t\tpad(raw2, `Run ${chalk.cyan(installCmd)} to update`),\n\t\tchalk.yellow(`╰${bar}╯`),\n\t\t\"\",\n\t].join(\"\\n\");\n}\n\nexport async function checkForUpdates(currentVersion: string): Promise<(() => void) | null> {\n\tif (env.get(\"CI\") || env.get(\"NO_UPDATE_NOTIFIER\")) return null;\n\n\tconst channel = getChannel(currentVersion);\n\tconst cache = readCache();\n\tconst now = Date.now();\n\n\tlet latestVersion: string | null = null;\n\n\tif (cache && now - cache.checkedAt < CACHE_TTL_MS) {\n\t\tlatestVersion = cache.latestVersion;\n\t} else {\n\t\tlatestVersion = await fetchLatestVersion(channel);\n\t\tif (latestVersion) writeCache({ latestVersion, checkedAt: now });\n\t}\n\n\tif (!latestVersion || !isUpdateAvailable(currentVersion, latestVersion)) return null;\n\n\treturn () => {\n\t\tprocess.stderr.write(formatNotice(currentVersion, latestVersion as string) + \"\\n\");\n\t};\n}\n","import { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nimport { input, select } from \"@inquirer/prompts\";\nimport { createAstromech } from \"@theholocron/astromech\";\nimport { loadTasksConfig } from \"@theholocron/astromech/config\";\nimport type { LogLevel } from \"@theholocron/observability/core\";\nimport yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\n\nimport { AuthError, createFeatureResolver } from \"./auth/auth-resolver.js\";\nimport { type ParsedTokenArgs, parseTokenArgs, TokenParseError } from \"./auth/token-args.js\";\nimport { runAuthCheck, runAuthList, runAuthSet, runAuthUnset } from \"./commands/auth.js\";\nimport { runCleanupPreview } from \"./commands/cleanup-preview.js\";\nimport { runClone } from \"./commands/clone.js\";\nimport { commandsInContext } from \"./commands/contexts.js\";\nimport { runDeploy, runDeployFromFiles } from \"./commands/deploy.js\";\nimport { runDoctor } from \"./commands/doctor.js\";\nimport { NewError, parseTopics, runNew, validateRepoName } from \"./commands/new.js\";\nimport { runNpmBumpVersions } from \"./commands/npm-bump-versions.js\";\nimport { PluginCreateError, resolvePluginCreateInputs, runPluginCreate } from \"./commands/plugin-create/index.js\";\nimport { runPublish, runSteadyPublish, runSyncTrust } from \"./commands/publish.js\";\nimport { runSecretSet } from \"./commands/secret-set.js\";\nimport { runSecretsSync } from \"./commands/secrets-sync.js\";\nimport { runSetup } from \"./commands/setup/index.js\";\nimport { runSkillsInstall, runSkillsRemove, runSkillsUpdate } from \"./commands/skills.js\";\nimport { runSync } from \"./commands/sync.js\";\nimport { runSyncGithub } from \"./commands/sync-github.js\";\nimport { runSyncReadme } from \"./commands/sync-readme.js\";\nimport { runUpgradeDeps } from \"./commands/upgrade-deps.js\";\nimport { runUpgradeNode } from \"./commands/upgrade-node.js\";\nimport { lintCommitMsgFile } from \"./commit-lint/lint-commit-msg-file.js\";\nimport type { TelemetryConfig } from \"./config/config.js\";\nimport { loadConfig } from \"./config/load-config.js\";\nimport { env } from \"./env.js\";\nimport { COMMAND_REGISTRY, getEntry, launchMenu, promptForPositionals } from \"./interactive-menu.js\";\nimport { buildCliLogger, type BuildCliLoggerOpts, getLogger, getRunId } from \"./logger.js\";\nimport { CARDINALITY } from \"./plugin/capabilities.js\";\nimport { applyConfig, captureException, endSession, flush, init, startCommand } from \"./telemetry.js\";\nimport { checkForUpdates } from \"./update-notifier.js\";\n\nconst resolveCloneToken = createFeatureResolver({ envName: \"HOLOCRON_READ_TOKEN\", keyringKey: \"github.read\" });\nconst resolveSyncToken = createFeatureResolver({ envName: \"HOLOCRON_SYNC_TOKEN\", keyringKey: \"github.sync\" });\n\n/**\n * Error class names whose `.message` is a complete, actionable sentence —\n * the top-level catch prints it and suppresses the stack trace.\n */\nconst USER_FACING_ERRORS = new Set([\"WorkspaceContextError\", \"ConfigFileError\", \"NonInteractiveError\"]);\n\nconst { version: CLI_VERSION } = JSON.parse(readFileSync(new URL(\"../package.json\", import.meta.url), \"utf-8\")) as {\n\tversion: string;\n};\n\n/** Whether to print the correlation id at command end (`--debug` / `--verbose`). */\nlet printRunId = false;\n\n/**\n * Resolves the active org in priority order:\n * 1. `--org` CLI flag\n * 2. `HOLOCRON_ORG` env var\n * 3. `org` from `holocron.config.ts`\n */\nfunction resolveOrg(argv: { org?: string }, config: { org?: string }): string | undefined {\n\treturn argv.org ?? env.get(\"HOLOCRON_ORG\") ?? config.org;\n}\n\n/**\n * `buildCliLogger` options derived from a loaded `holocron.config` — the\n * level, the Axiom dataset, and the resolved org for a keyring-backed\n * Axiom token. Used by every handler that has already called `loadConfig`.\n */\nfunction cliLoggerOpts(\n\targv: { org?: string; verbose?: boolean; quiet?: boolean },\n\tresolved: { org?: string; log?: { level?: LogLevel; axiom?: { dataset?: string } } }\n): BuildCliLoggerOpts {\n\treturn {\n\t\tconfigLevel: resolved.log?.level,\n\t\tconfigAxiomDataset: resolved.log?.axiom?.dataset,\n\t\torg: resolveOrg(argv, resolved),\n\t};\n}\n\n/**\n * Fold a loaded `holocron.config` into the running process: reconfigure the\n * logger from `log:`, then apply the `telemetry:` override layer. Every handler\n * that has called `loadConfig` runs this, so a repo's `telemetry.enabled: false`\n * (or `analytics: \"none\"`) is honoured for that command. Env still wins —\n * `applyConfig` only narrows what `init` already turned on.\n */\nfunction applyResolvedConfig(\n\targv: { org?: string; verbose?: boolean; quiet?: boolean },\n\tresolved: {\n\t\torg?: string;\n\t\tlog?: { level?: LogLevel; axiom?: { dataset?: string } };\n\t\ttelemetry?: TelemetryConfig;\n\t}\n): void {\n\tbuildCliLogger(argv, cliLoggerOpts(argv, resolved));\n\tapplyConfig(resolved.telemetry);\n}\n\n/** Parses --token values and returns the context spread, or null on parse error (exits with code 1). */\nfunction tokenContext(rawTokens: string[] | undefined): ParsedTokenArgs | null {\n\tif (!rawTokens?.length) return {};\n\ttry {\n\t\treturn parseTokenArgs(rawTokens);\n\t} catch (err) {\n\t\tif (err instanceof TokenParseError) {\n\t\t\tgetLogger().error(`--token: ${err.message}`);\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn null;\n\t\t}\n\t\tthrow err;\n\t}\n}\n\ninit(CLI_VERSION);\nconst updateCheckPromise = checkForUpdates(CLI_VERSION);\n\nlet finishCommand: (ok: boolean) => void = () => {};\n/** Set by `.fail()` once it has printed an error, so the outer catch doesn't repeat it. */\nlet errorReported = false;\n\ntry {\n\tawait yargs(hideBin(process.argv))\n\t\t.scriptName(\"\")\n\t\t.usage(\"holocron <command> [options]\")\n\t\t// Keep everything after `--` in `argv['--']` instead of folding it into\n\t\t// `argv._`. `holocron run <task> [job] -- <args>` forwards `<args>` to the\n\t\t// underlying tool (`lhci autorun --config=…`, `turbo run build -- …`); the\n\t\t// telemetry command name reads `argv._` and must not pick these up.\n\t\t.parserConfiguration({ \"populate--\": true })\n\t\t// ── global options (apply to every subcommand) ──────────────────────\n\t\t.option(\"dry-run\", {\n\t\t\ttype: \"boolean\",\n\t\t\tdefault: false,\n\t\t\tdescribe:\n\t\t\t\t\"Print what would be mutated without calling capability mutators. \" +\n\t\t\t\t\"Commands branch on this; read-only commands ignore it.\",\n\t\t})\n\t\t.option(\"token\", {\n\t\t\ttype: \"string\",\n\t\t\tarray: true,\n\t\t\tdescribe:\n\t\t\t\t\"Vendor token override for plugins. \" +\n\t\t\t\t\"Bare form: --token <value> (fallback for all plugins, single-plugin commands). \" +\n\t\t\t\t\"Keyed form: --token vendor=value (targets a specific provider; repeat for each). \" +\n\t\t\t\t\"Example: --token github=ghp_xxx --token vercel=v_yyy\",\n\t\t})\n\t\t.option(\"org\", {\n\t\t\ttype: \"string\",\n\t\t\tdescribe:\n\t\t\t\t\"Active org name for namespaced keyring lookup. \" +\n\t\t\t\t\"Overrides HOLOCRON_ORG env var and the `org` field in holocron.config.ts. \" +\n\t\t\t\t\"Example: --org theholocron\",\n\t\t})\n\t\t.option(\"cwd\", {\n\t\t\ttype: \"string\",\n\t\t\tdefault: process.cwd(),\n\t\t\tdescribe: \"Directory to search for holocron.config.json\",\n\t\t})\n\t\t.option(\"verbose\", {\n\t\t\ttype: \"boolean\",\n\t\t\tdefault: false,\n\t\t\tdescribe: \"Set the log level to debug — full structured operational output.\",\n\t\t})\n\t\t.option(\"debug\", {\n\t\t\ttype: \"boolean\",\n\t\t\tdefault: false,\n\t\t\tdescribe: \"Print the run ID at command end for Axiom lookup. Does not change the log level.\",\n\t\t})\n\t\t.option(\"quiet\", {\n\t\t\ttype: \"boolean\",\n\t\t\tdefault: false,\n\t\t\tdescribe: \"Set the log level to error — suppress info and warn.\",\n\t\t})\n\t\t.middleware((argv) => {\n\t\t\tconst name = (argv._ as string[]).slice(0, 2).join(\" \") || \"unknown\";\n\t\t\tprintRunId = Boolean(argv.debug || argv.verbose);\n\t\t\t// Establish the root logger first (command name + flags + env) so its\n\t\t\t// `runId` is available to tag telemetry events. Handlers that load a\n\t\t\t// config call `buildCliLogger(argv, { configLevel })` again to fold in\n\t\t\t// the lowest-priority level + Axiom-dataset sources.\n\t\t\tbuildCliLogger(argv, { command: name, org: argv.org });\n\t\t\tfinishCommand = startCommand(name);\n\t\t})\n\t\t// ── commands ────────────────────────────────────────────────────────\n\t\t.command(\n\t\t\t\"version\",\n\t\t\t\"Print the CLI version\",\n\t\t\t() => {},\n\t\t\t() => {\n\t\t\t\tconsole.log(`holocron ${CLI_VERSION}`);\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"clone\",\n\t\t\t\"Clone all repos in a GitHub org as siblings under a single directory\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.option(\"org\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdemandOption: true,\n\t\t\t\t\t\tdescribe: \"GitHub org to clone (e.g., theholocron)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"dir\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Parent directory to clone into (default: ~/Code/<org>)\",\n\t\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tconst tokens = tokenContext(argv.token);\n\t\t\t\tif (!tokens) return;\n\t\t\t\tlet token: string;\n\t\t\t\ttry {\n\t\t\t\t\ttoken = resolveCloneToken({ cliToken: tokens.cliTokens?.[\"github\"] ?? tokens.cliToken });\n\t\t\t\t} catch (err) {\n\t\t\t\t\tgetLogger().error(`clone: ${err instanceof AuthError ? err.message : String(err)}`);\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst report = await runClone({\n\t\t\t\t\torg: argv.org,\n\t\t\t\t\ttoken,\n\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t...(argv.dir ? { dir: argv.dir } : {}),\n\t\t\t\t});\n\t\t\t\tif (report.status === \"fail\") process.exitCode = 1;\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"doctor\",\n\t\t\t\"Load the config and run a smoke check against every provider\",\n\t\t\t(y) =>\n\t\t\t\ty.option(\"repo\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescribe: 'Repo coords (\"owner/name\"). Defaults to plugin-specific resolution.',\n\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tconst tokens = tokenContext(argv.token);\n\t\t\t\tif (!tokens) return;\n\t\t\t\tconst loaded = await loadConfig(argv.cwd);\n\t\t\t\tapplyResolvedConfig(argv, loaded.resolved);\n\t\t\t\tconst report = await runDoctor({\n\t\t\t\t\tloaded,\n\t\t\t\t\tcontext: {\n\t\t\t\t\t\trepoRoot: argv.cwd,\n\t\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t\t...(argv.repo ? { repo: argv.repo } : {}),\n\t\t\t\t\t\t...tokens,\n\t\t\t\t\t\torg: resolveOrg(argv, loaded.resolved),\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tif (report.summary.fail > 0) {\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"setup\",\n\t\t\t\"Apply infra setup actions across every configured capability\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.option(\"repo\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: 'Repo coords (\"owner/name\"). Defaults to plugin-specific resolution.',\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"hooks\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"Install git hooks (.husky/pre-push → holocron ci). Default: on for protection:'strict'. --no-hooks to skip.\",\n\t\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tconst tokens = tokenContext(argv.token);\n\t\t\t\tif (!tokens) return;\n\t\t\t\tconst loaded = await loadConfig(argv.cwd);\n\t\t\t\tapplyResolvedConfig(argv, loaded.resolved);\n\t\t\t\tconst report = await runSetup({\n\t\t\t\t\tloaded,\n\t\t\t\t\tcontext: {\n\t\t\t\t\t\trepoRoot: argv.cwd,\n\t\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t\t...(argv.repo ? { repo: argv.repo } : {}),\n\t\t\t\t\t\t...tokens,\n\t\t\t\t\t\torg: resolveOrg(argv, loaded.resolved),\n\t\t\t\t\t},\n\t\t\t\t\t...(argv.hooks !== undefined ? { hooks: argv.hooks as boolean } : {}),\n\t\t\t\t});\n\t\t\t\tif (report.summary.fail > 0) {\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"skills\",\n\t\t\t\"Manage agent skills from the @theholocron/skills registry\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.command(\n\t\t\t\t\t\t\"install\",\n\t\t\t\t\t\t\"Copy skills from @theholocron/skills into .agents/ with agent symlinks\",\n\t\t\t\t\t\t() => {},\n\t\t\t\t\t\tasync (argv) => {\n\t\t\t\t\t\t\tconst loaded = await loadConfig(argv.cwd);\n\t\t\t\t\t\t\tawait runSkillsInstall({ loaded, context: { repoRoot: argv.cwd, dryRun: argv.dryRun } });\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\t\t\t\t\t.command(\n\t\t\t\t\t\t\"remove [names..]\",\n\t\t\t\t\t\t\"Remove installed skills via npx skills remove\",\n\t\t\t\t\t\t(yy) =>\n\t\t\t\t\t\t\tyy.positional(\"names\", {\n\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\tarray: true,\n\t\t\t\t\t\t\t\tdescribe: \"Skill name(s) to remove (omit to remove all installed skills)\",\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t(argv) => {\n\t\t\t\t\t\t\tconst report = runSkillsRemove({\n\t\t\t\t\t\t\t\tcontext: { repoRoot: argv.cwd, dryRun: argv.dryRun },\n\t\t\t\t\t\t\t\t...(argv.names?.length ? { names: argv.names as string[] } : {}),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (report.status === \"fail\") process.exitCode = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\t\t\t\t\t.command(\n\t\t\t\t\t\t\"update [name]\",\n\t\t\t\t\t\t\"Update installed skills to their latest upstream versions via npx skills update\",\n\t\t\t\t\t\t(yy) =>\n\t\t\t\t\t\t\tyy.positional(\"name\", {\n\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\tdescribe: \"Skill name to update (omit to update all installed skills)\",\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t(argv) => {\n\t\t\t\t\t\t\tconst report = runSkillsUpdate({\n\t\t\t\t\t\t\t\tcontext: { repoRoot: argv.cwd, dryRun: argv.dryRun },\n\t\t\t\t\t\t\t\t...(argv.name ? { name: argv.name as string } : {}),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (report.status === \"fail\") process.exitCode = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\t\t\t\t\t.command(\n\t\t\t\t\t\t\"$0\",\n\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t() => {},\n\t\t\t\t\t\tasync (argv) => {\n\t\t\t\t\t\t\tawait launchMenu(\n\t\t\t\t\t\t\t\tCOMMAND_REGISTRY.filter((e) => e.group === \"skills\"),\n\t\t\t\t\t\t\t\targv,\n\t\t\t\t\t\t\t\t\"skills — choose a subcommand:\",\n\t\t\t\t\t\t\t\t\"Run `holocron skills --help` to see available skills subcommands.\"\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t),\n\t\t\t() => {}\n\t\t)\n\t\t.command(\n\t\t\t\"secret set [name] [value]\",\n\t\t\t\"Set a single secret via the configured `secrets` capability\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.positional(\"name\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Secret name (e.g., NPM_TOKEN)\",\n\t\t\t\t\t})\n\t\t\t\t\t.positional(\"value\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"Secret value (positional). If omitted, sources from --from-stdin, --from-env, or env var matching <name>.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"from-stdin\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdefault: false,\n\t\t\t\t\t\tdescribe: \"Read the secret value from stdin\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"from-env\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Read the secret value from the named env var (otherwise: env var matching <name>)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"scope\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdefault: \"repo\",\n\t\t\t\t\t\tdescribe: 'Scope: \"repo\" (default), \"env=<name>\", or \"org=<name>\"',\n\t\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tconst tokens = tokenContext(argv.token);\n\t\t\t\tif (!tokens) return;\n\t\t\t\tconst [name] = await promptForPositionals(getEntry(\"secret set\"), argv as Record<string, unknown>);\n\t\t\t\tconst scopeArg = argv.scope as string;\n\t\t\t\tconst scope = parseScope(scopeArg);\n\t\t\t\tconst loaded = await loadConfig(argv.cwd);\n\t\t\t\tapplyResolvedConfig(argv, loaded.resolved);\n\t\t\t\tconst report = await runSecretSet({\n\t\t\t\t\tloaded,\n\t\t\t\t\tcontext: {\n\t\t\t\t\t\trepoRoot: argv.cwd,\n\t\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t\t...tokens,\n\t\t\t\t\t\torg: resolveOrg(argv, loaded.resolved),\n\t\t\t\t\t},\n\t\t\t\t\tname: name!,\n\t\t\t\t\t...(argv.value ? { value: argv.value as string } : {}),\n\t\t\t\t\t...(argv.fromStdin ? { fromStdin: true } : {}),\n\t\t\t\t\t...(argv.fromEnv ? { fromEnv: argv.fromEnv as string } : {}),\n\t\t\t\t\tscope,\n\t\t\t\t});\n\t\t\t\tif (report.status === \"fail\") {\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"secrets sync [environmentId]\",\n\t\t\t\"Read a vault environment + fan KEY=VALUEs out to secrets + deployment env vars\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.positional(\"environmentId\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Vault environment id to read (1P Environment id, etc.)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"project-id\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Deployment project id (e.g., Vercel prj_*). Required when deployment is loaded.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"target\", {\n\t\t\t\t\t\ttype: \"array\",\n\t\t\t\t\t\tdefault: [\"production\", \"preview\"] as Array<\"development\" | \"preview\" | \"production\">,\n\t\t\t\t\t\tdescribe: \"Deployment targets to sync to. Defaults to production + preview.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"github-secret\", {\n\t\t\t\t\t\ttype: \"array\",\n\t\t\t\t\t\tdescribe: \"Vault key(s) to push to GH Actions secrets (repeatable). Omit to push every key.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"github-secret-scope\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdefault: \"repo\",\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t'Scope applied to every --github-secret key: \"repo\" (default), \"env=<name>\", or \"org=<name>\".',\n\t\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tconst tokens = tokenContext(argv.token);\n\t\t\t\tif (!tokens) return;\n\t\t\t\tconst githubSecretScope = parseScope(argv.githubSecretScope as string);\n\t\t\t\tconst [environmentId] = await promptForPositionals(\n\t\t\t\t\tgetEntry(\"secrets sync\"),\n\t\t\t\t\targv as Record<string, unknown>\n\t\t\t\t);\n\t\t\t\tconst loaded = await loadConfig(argv.cwd);\n\t\t\t\tapplyResolvedConfig(argv, loaded.resolved);\n\t\t\t\tconst report = await runSecretsSync({\n\t\t\t\t\tloaded,\n\t\t\t\t\tcontext: {\n\t\t\t\t\t\trepoRoot: argv.cwd,\n\t\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t\t...tokens,\n\t\t\t\t\t\torg: resolveOrg(argv, loaded.resolved),\n\t\t\t\t\t},\n\t\t\t\t\tenvironmentId: environmentId!,\n\t\t\t\t\t...(argv.projectId ? { projectId: argv.projectId } : {}),\n\t\t\t\t\t...(argv.githubSecret?.length ? { githubSecretKeys: argv.githubSecret as string[] } : {}),\n\t\t\t\t\tgithubSecretScope,\n\t\t\t\t\ttargets: argv.target as Array<\"development\" | \"preview\" | \"production\">,\n\t\t\t\t});\n\t\t\t\tif (report.summary.fail > 0) {\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"deploy [branch]\",\n\t\t\t\"Trigger a deployment via the configured `deployment` capability\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.positional(\"branch\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Git branch to deploy (omit when using --files)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"project-id\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdemandOption: true,\n\t\t\t\t\t\tdescribe: \"Deployment project id (e.g., Vercel prj_*)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"target\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tchoices: [\"production\", \"staging\"] as const,\n\t\t\t\t\t\tdescribe: \"Named environment to deploy into. Omit for a branch preview.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"files\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"Deploy from a local directory of source files instead of a Git branch — calls deployFunction(), no linked repo required. Conflicts with `branch`.\",\n\t\t\t\t\t})\n\t\t\t\t\t.conflicts(\"files\", \"branch\"),\n\t\t\tasync (argv) => {\n\t\t\t\tconst tokens = tokenContext(argv.token);\n\t\t\t\tif (!tokens) return;\n\t\t\t\tconst loaded = await loadConfig(argv.cwd);\n\t\t\t\tapplyResolvedConfig(argv, loaded.resolved);\n\t\t\t\tconst context = {\n\t\t\t\t\trepoRoot: argv.cwd,\n\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t...tokens,\n\t\t\t\t\torg: resolveOrg(argv, loaded.resolved),\n\t\t\t\t};\n\n\t\t\t\tif (argv.files) {\n\t\t\t\t\tconst report = await runDeployFromFiles({\n\t\t\t\t\t\tloaded,\n\t\t\t\t\t\tcontext,\n\t\t\t\t\t\tprojectId: argv.projectId as string,\n\t\t\t\t\t\tdir: argv.files as string,\n\t\t\t\t\t\t...(argv.target ? { target: argv.target as \"production\" | \"staging\" } : {}),\n\t\t\t\t\t});\n\t\t\t\t\tif (report.status === \"fail\") {\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst [branch] = await promptForPositionals(getEntry(\"deploy\"), argv as Record<string, unknown>);\n\t\t\t\tconst report = await runDeploy({\n\t\t\t\t\tloaded,\n\t\t\t\t\tcontext,\n\t\t\t\t\tprojectId: argv.projectId as string,\n\t\t\t\t\tbranch: branch!,\n\t\t\t\t\t...(argv.target ? { target: argv.target as \"production\" | \"staging\" } : {}),\n\t\t\t\t});\n\t\t\t\tif (report.status === \"fail\") {\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"cleanup-preview [pr]\",\n\t\t\t\"List and delete Cloudflare Pages preview deployments for a GitHub PR\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.positional(\"pr\", {\n\t\t\t\t\t\ttype: \"number\",\n\t\t\t\t\t\tdescribe: \"PR number to clean up\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"project\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdemandOption: true,\n\t\t\t\t\t\tdescribe: \"Cloudflare Pages project name (e.g. theholocron-preview)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"repo\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"GitHub repo as owner/name — defaults to the repo in holocron.config\",\n\t\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tconst tokens = tokenContext(argv.token);\n\t\t\t\tif (!tokens) return;\n\t\t\t\tconst [pr] = await promptForPositionals(getEntry(\"cleanup-preview\"), argv as Record<string, unknown>);\n\t\t\t\tconst loaded = await loadConfig(argv.cwd);\n\t\t\t\tapplyResolvedConfig(argv, loaded.resolved);\n\t\t\t\tconst report = await runCleanupPreview({\n\t\t\t\t\tloaded,\n\t\t\t\t\tcontext: {\n\t\t\t\t\t\trepoRoot: argv.cwd,\n\t\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t\t...tokens,\n\t\t\t\t\t\torg: resolveOrg(argv, loaded.resolved),\n\t\t\t\t\t},\n\t\t\t\t\tprNumber: Number(pr),\n\t\t\t\t\tproject: argv.project as string,\n\t\t\t\t\t...(argv.repo ? { repo: argv.repo as string } : {}),\n\t\t\t\t});\n\t\t\t\tif (report.status === \"fail\") {\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"bump-versions [new-version]\",\n\t\t\t\"Bump all non-private package versions in lockstep (semantic-release prepareCmd)\",\n\t\t\t(y) =>\n\t\t\t\ty.positional(\"new-version\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescribe: \"Version to set (e.g., 4.2.0 or 2.0.0-alpha.1)\",\n\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tconst [newVersion] = await promptForPositionals(\n\t\t\t\t\tgetEntry(\"bump-versions\"),\n\t\t\t\t\targv as Record<string, unknown>\n\t\t\t\t);\n\t\t\t\tconst report = await runNpmBumpVersions({\n\t\t\t\t\tversion: newVersion!,\n\t\t\t\t\tcwd: argv.cwd,\n\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t});\n\t\t\t\tif (report.status === \"fail\") {\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"publish\",\n\t\t\t\"Publish @theholocron/* packages to npm\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.option(\"initial\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdefault: false,\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"One-shot bootstrap publish for trusted-publishing-eligible packages (npm needs the \" +\n\t\t\t\t\t\t\t\"package to exist before Trusted Publishing can be configured for it). Skips the \" +\n\t\t\t\t\t\t\t\"steady-state OIDC path below — use only for a package's very first publish.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"tag\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"npm distribution tag. Defaults to alpha for --initial, latest for a steady-state publish.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"otp\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"One-time password from your authenticator (required if npm needs 2FA for writes)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"sync-trust\", {\n\t\t\t\t\t\ttype: \"array\",\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"Migrate npm Trusted Publisher config to a new workflow filename across every public \" +\n\t\t\t\t\t\t\t\"package: --sync-trust <old-file> <new-file>. See issue #689 — npm requires fresh \" +\n\t\t\t\t\t\t\t\"interactive 2FA per package; re-run after approving the printed authUrl if it stops early.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"repo\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"owner/repo for Trusted Publisher config (--sync-trust). Defaults to theholocron/holocron.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"provenance\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdefault: true,\n\t\t\t\t\t\tdescribe: \"Publish with --provenance (steady-state only). Default on — free under CI/OIDC.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"skip-already-published\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdefault: false,\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"Steady-state only: check `npm view <pkg>@<version>` before publishing each package and \" +\n\t\t\t\t\t\t\t\"skip it if that exact version already exists, instead of one bulk publish. For repos \" +\n\t\t\t\t\t\t\t\"that ship many independently-versioned packages where a release doesn't bump every one.\",\n\t\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tif (argv.syncTrust) {\n\t\t\t\t\tconst [oldFile, newFile] = argv.syncTrust as [string?, string?];\n\t\t\t\t\tif (!oldFile || !newFile) {\n\t\t\t\t\t\tgetLogger().error(\"publish --sync-trust requires exactly two values: <old-file> <new-file>\");\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst report = await runSyncTrust({\n\t\t\t\t\t\tcwd: argv.cwd,\n\t\t\t\t\t\toldFile,\n\t\t\t\t\t\tnewFile,\n\t\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t\t...(argv.repo ? { repo: argv.repo as string } : {}),\n\t\t\t\t\t});\n\t\t\t\t\tif (report.status === \"fail\") {\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (argv.initial) {\n\t\t\t\t\tconst report = await runPublish({\n\t\t\t\t\t\tcwd: argv.cwd,\n\t\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t\t...(argv.tag ? { tag: argv.tag as string } : {}),\n\t\t\t\t\t\t...(argv.otp ? { otp: argv.otp as string } : {}),\n\t\t\t\t\t});\n\t\t\t\t\tif (report.status === \"fail\") {\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst report = await runSteadyPublish({\n\t\t\t\t\tcwd: argv.cwd,\n\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\tprovenance: argv.provenance as boolean,\n\t\t\t\t\tskipAlreadyPublished: argv.skipAlreadyPublished as boolean,\n\t\t\t\t\t...(argv.tag ? { tag: argv.tag as string } : {}),\n\t\t\t\t\t...(argv.otp ? { otp: argv.otp as string } : {}),\n\t\t\t\t});\n\t\t\t\tif (report.status === \"fail\") {\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"sync [steps..]\",\n\t\t\t\"Sync state from config to the provider and local files (labels, properties, teams, topics, keywords, description, homepage, readme, workflows, scripts, wiki)\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.positional(\"steps\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tarray: true,\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"Steps to run: labels, properties, teams, topics, keywords, description, homepage, readme, workflows, scripts, wiki (default: all)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"repo\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: 'Repo coords (\"owner/name\"). Defaults to plugin-specific resolution.',\n\t\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tconst tokens = tokenContext(argv.token);\n\t\t\t\tif (!tokens) return;\n\t\t\t\tconst loaded = await loadConfig(argv.cwd);\n\t\t\t\tapplyResolvedConfig(argv, loaded.resolved);\n\t\t\t\tconst report = await runSync({\n\t\t\t\t\tloaded,\n\t\t\t\t\tcontext: {\n\t\t\t\t\t\trepoRoot: argv.cwd,\n\t\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t\t...(argv.repo ? { repo: argv.repo } : {}),\n\t\t\t\t\t\t...tokens,\n\t\t\t\t\t\torg: resolveOrg(argv, loaded.resolved),\n\t\t\t\t\t},\n\t\t\t\t\t...(argv.steps && argv.steps.length > 0 ? { steps: argv.steps as string[] } : {}),\n\t\t\t\t});\n\t\t\t\tif (report.summary.fail > 0) {\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"run <task> [job] [passthrough..]\",\n\t\t\t\"Run a task locally (test, typecheck, lint, build, audit) — figures out turbo / the tool / the package manager\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.positional(\"task\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdemandOption: true,\n\t\t\t\t\t\tdescribe: \"Task name (test, typecheck, lint, build, audit). See `holocron run --help`.\",\n\t\t\t\t\t})\n\t\t\t\t\t.positional(\"job\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"Sub-job within the task (e.g. `holocron run audit performance`). Omit to run every job. Only `audit` has jobs today.\",\n\t\t\t\t\t})\n\t\t\t\t\t.positional(\"passthrough\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tarray: true,\n\t\t\t\t\t\tdescribe: \"Args forwarded to the tool — put them after `--`.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"required\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdefault: false,\n\t\t\t\t\t\tdescribe: \"Fail (exit 1) if this repo has no such task, instead of skipping.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"filter\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"turbo --filter=<pkg> passthrough (monorepo).\",\n\t\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tconst { logger } = buildCliLogger(argv, { command: \"run\" });\n\t\t\t\t// The task manifest drives `lint`'s linter set; other tasks are\n\t\t\t\t// filesystem-driven and ignore it. Missing / unparseable config → undefined.\n\t\t\t\tconst config = await loadTasksConfig(argv.cwd as string).catch(() => undefined);\n\t\t\t\tconst astromech = createAstromech({ cwd: argv.cwd, logger, config });\n\t\t\t\tconst report = astromech.run(argv.task as string, {\n\t\t\t\t\t...(argv.job !== undefined ? { job: argv.job as string } : {}),\n\t\t\t\t\tpassthrough: [\n\t\t\t\t\t\t...((argv.passthrough as string[] | undefined) ?? []),\n\t\t\t\t\t\t...((argv[\"--\"] as string[] | undefined) ?? []),\n\t\t\t\t\t],\n\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\trequired: argv.required,\n\t\t\t\t\t...(argv.filter ? { filter: argv.filter as string } : {}),\n\t\t\t\t});\n\t\t\t\tif (report.status === \"fail\" || report.status === \"unknown\") process.exitCode = 1;\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"ci\",\n\t\t\t\"Run the merge-gating checks locally, in CI order — 'will CI pass?'\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.option(\"all\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdefault: false,\n\t\t\t\t\t\tdescribe: \"Run every `ci: true` task, not just the required ones.\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"filter\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"turbo --filter=<pkg> passthrough (monorepo).\",\n\t\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tconst { logger } = buildCliLogger(argv, { command: \"ci\" });\n\t\t\t\tconst config = await loadTasksConfig(argv.cwd as string).catch(() => undefined);\n\t\t\t\tconst astromech = createAstromech({ cwd: argv.cwd, logger, config });\n\t\t\t\tconst report = astromech.ci({\n\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\tscope: argv.all ? \"all\" : \"required\",\n\t\t\t\t\t...(argv.filter ? { filter: argv.filter as string } : {}),\n\t\t\t\t});\n\t\t\t\tif (report.status === \"fail\") process.exitCode = 1;\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"lint\",\n\t\t\t\"Lint content locally against the org's shared rules\",\n\t\t\t(y) =>\n\t\t\t\ty.command(\n\t\t\t\t\t\"commit-msg <file>\",\n\t\t\t\t\t\"Lint a commit message file — matches `commitlint --edit`'s own contract, for use from .husky/commit-msg\",\n\t\t\t\t\t(yy) =>\n\t\t\t\t\t\tyy.positional(\"file\", {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tdemandOption: true,\n\t\t\t\t\t\t\tdescribe: \"Path to the commit message file (git's commit-msg hook passes this as $1).\",\n\t\t\t\t\t\t}),\n\t\t\t\t\tasync (argv) => {\n\t\t\t\t\t\tconst result = await lintCommitMsgFile(argv.file as string, argv.cwd as string);\n\t\t\t\t\t\tif (!result.valid) {\n\t\t\t\t\t\t\tfor (const violation of result.violations) {\n\t\t\t\t\t\t\t\tconsole.error(`✖ ${violation.rule}: ${violation.message}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t),\n\t\t\t() => {}\n\t\t)\n\t\t.command(\n\t\t\t\"sync-github\",\n\t\t\t\"Sync workflow templates and composite actions to theholocron/.github\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.option(\"repo\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdefault: \"theholocron/.github\",\n\t\t\t\t\t\tdescribe: \"Target org/repo (default: theholocron/.github)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"branch\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"Push to this branch instead of the default branch (enables PR-based workflow for protected repos)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"pr\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdefault: false,\n\t\t\t\t\t\tdescribe: \"Open a PR after pushing to --branch (no-op without --branch)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"message\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Commit message (default: chore: sync from theholocron/holocron)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"output-dir\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Write generated files to this local directory instead of pushing (for validation)\",\n\t\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tconst outputDir = argv[\"output-dir\"] as string | undefined;\n\t\t\t\tconst parsed = tokenContext(argv.token);\n\t\t\t\tif (!parsed) return;\n\t\t\t\tlet token: string;\n\t\t\t\tif (outputDir) {\n\t\t\t\t\ttoken = \"no-token-needed\";\n\t\t\t\t} else {\n\t\t\t\t\ttry {\n\t\t\t\t\t\ttoken = resolveSyncToken({ cliToken: parsed.cliTokens?.[\"github\"] ?? parsed.cliToken });\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tgetLogger().error(`sync-github: ${err instanceof AuthError ? err.message : String(err)}`);\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst report = await runSyncGithub({\n\t\t\t\t\ttoken,\n\t\t\t\t\trepo: argv.repo,\n\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t...(argv.branch ? { branch: argv.branch } : {}),\n\t\t\t\t\t...(argv.pr ? { createPr: true } : {}),\n\t\t\t\t\t...(argv.message ? { message: argv.message } : {}),\n\t\t\t\t\t...(outputDir ? { outputDir } : {}),\n\t\t\t\t});\n\t\t\t\tif (report.status === \"fail\") {\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"sync-readme\",\n\t\t\t\"Sync the Installation + Usage block in README.md from package.json\",\n\t\t\t(y) =>\n\t\t\t\ty.option(\"dry-run\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdescribe: \"Print what would change without writing\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\tconst loaded = await loadConfig(argv.cwd);\n\t\t\t\tapplyResolvedConfig(argv, loaded.resolved);\n\t\t\t\tconst report = await runSyncReadme({\n\t\t\t\t\tloaded,\n\t\t\t\t\tcontext: { repoRoot: argv.cwd, dryRun: argv.dryRun },\n\t\t\t\t});\n\t\t\t\tif (report.status === \"fail\") process.exitCode = 1;\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"config show\",\n\t\t\t\"Print the resolved holocron config\",\n\t\t\t() => {},\n\t\t\tasync (argv) => {\n\t\t\t\tconst loaded = await loadConfig(argv.cwd);\n\t\t\t\tconsole.log(JSON.stringify(loaded.resolved, null, 2));\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"new [type] [name]\",\n\t\t\t\"Scaffold a new repo from a GitHub template (e.g. cli, react, nextjs, node, monorepo, base)\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.positional(\"type\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"Template type — maps to theholocron/<type>-template \" +\n\t\t\t\t\t\t\t\"(e.g. cli, react, nextjs, node, monorepo, base)\",\n\t\t\t\t\t})\n\t\t\t\t\t.positional(\"name\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"New repo name (kebab-case, e.g. my-tool)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"description\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Short description — replaces <description> placeholders in the template\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"homepage\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Homepage URL — replaces <homepage> placeholders and appears in holocron.config.ts\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"vault\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Vault provider: none, doppler, 1password, infisical\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"deployment\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Deployment provider: none, vercel\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"agent\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"AI agent: claude, none\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"runtime-environment\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Runtime environment: node, browser, universal, none\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"topics\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Comma-separated repo topics (e.g. typescript,nodejs)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"protection\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Branch protection level: strict, balanced, minimal\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"open-source\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdescribe: \"Whether the repo is open source (default: true)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"uses-external-packages\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdescribe: \"Whether the repo calls external APIs or services (default: true)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"skills\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Comma-separated agent skill names (e.g. git-safety,pr-workflow)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"is-template\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdescribe: \"Mark the new repo as a GitHub template repository\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"org\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdefault: \"theholocron\",\n\t\t\t\t\t\tdescribe: \"GitHub org that owns the template and will own the new repo\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"verify\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdefault: true,\n\t\t\t\t\t\tdescribe: \"Run pnpm install + holocron setup after bootstrapping (--no-verify skips)\",\n\t\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst tokens = tokenContext(argv.token);\n\t\t\t\t\tif (!tokens) return;\n\t\t\t\t\tconst adminToken = tokens.cliTokens?.[\"github\"] ?? tokens.cliToken;\n\n\t\t\t\t\tlet type = argv.type as string | undefined;\n\t\t\t\t\tlet name = argv.name as string | undefined;\n\t\t\t\t\tlet description = argv.description as string | undefined;\n\t\t\t\t\tlet homepage = argv.homepage as string | undefined;\n\t\t\t\t\tlet vaultProvider = argv.vault as string | undefined;\n\t\t\t\t\tlet vaultProject: string | undefined;\n\t\t\t\t\tlet vaultConfig: string | undefined;\n\t\t\t\t\tlet deploymentProvider = argv.deployment as string | undefined;\n\t\t\t\t\tlet agent = argv.agent as string | undefined;\n\t\t\t\t\tlet runtimeEnvironment = argv.runtimeEnvironment as string | undefined;\n\t\t\t\t\tlet topics: string[] = parseTopics(argv.topics as string | undefined);\n\t\t\t\t\tlet protection = argv.protection as string | undefined;\n\t\t\t\t\tlet openSource = argv.openSource as boolean | undefined;\n\t\t\t\t\tlet usesExternalPackages = argv.usesExternalPackages as boolean | undefined;\n\t\t\t\t\tlet skills: string[] = parseTopics(argv.skills as string | undefined);\n\t\t\t\t\tconst isTemplate = argv.isTemplate as boolean | undefined;\n\n\t\t\t\t\t// Interactive wizard — skip any field already supplied as a CLI arg\n\t\t\t\t\tif (!type) {\n\t\t\t\t\t\ttype = await select({\n\t\t\t\t\t\t\tmessage: \"Template type:\",\n\t\t\t\t\t\t\tchoices: [\n\t\t\t\t\t\t\t\t{ name: \"node — Node.js library or tool\", value: \"node\" },\n\t\t\t\t\t\t\t\t{ name: \"cli — CLI application (inquirer, chalk, yargs)\", value: \"cli\" },\n\t\t\t\t\t\t\t\t{ name: \"monorepo — Turbo monorepo\", value: \"monorepo\" },\n\t\t\t\t\t\t\t\t{ name: \"react — React component library\", value: \"react\" },\n\t\t\t\t\t\t\t\t{ name: \"nextjs — Next.js application\", value: \"nextjs\" },\n\t\t\t\t\t\t\t\t{ name: \"base — Minimal repo (no package.json)\", value: \"base\" },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!name) {\n\t\t\t\t\t\tname = await input({\n\t\t\t\t\t\t\tmessage: \"Repo name (kebab-case):\",\n\t\t\t\t\t\t\tvalidate: validateRepoName,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tname = name.trim();\n\t\t\t\t\t}\n\n\t\t\t\t\tif (description === undefined) {\n\t\t\t\t\t\tdescription = await input({ message: \"Short description:\" });\n\t\t\t\t\t}\n\n\t\t\t\t\tif (homepage === undefined) {\n\t\t\t\t\t\tconst raw = await input({ message: \"Homepage URL (optional, Enter to skip):\" });\n\t\t\t\t\t\thomepage = raw.trim() || undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!runtimeEnvironment) {\n\t\t\t\t\t\truntimeEnvironment = await select({\n\t\t\t\t\t\t\tmessage: \"Runtime environment:\",\n\t\t\t\t\t\t\tchoices: [\n\t\t\t\t\t\t\t\t{ name: \"node — Node.js process\", value: \"node\" },\n\t\t\t\t\t\t\t\t{ name: \"browser — Browser only\", value: \"browser\" },\n\t\t\t\t\t\t\t\t{ name: \"universal — Node.js + browser\", value: \"universal\" },\n\t\t\t\t\t\t\t\t{ name: \"none — No runtime (docs, config, etc.)\", value: \"none\" },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tdefault: type === \"base\" ? \"none\" : \"node\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!vaultProvider) {\n\t\t\t\t\t\tvaultProvider = await select({\n\t\t\t\t\t\t\tmessage: \"Vault provider:\",\n\t\t\t\t\t\t\tchoices: [\n\t\t\t\t\t\t\t\t{ name: \"None\", value: \"none\" },\n\t\t\t\t\t\t\t\t{ name: \"Doppler\", value: \"doppler\" },\n\t\t\t\t\t\t\t\t{ name: \"1Password\", value: \"1password\" },\n\t\t\t\t\t\t\t\t{ name: \"Infisical\", value: \"infisical\" },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (vaultProvider === \"doppler\") {\n\t\t\t\t\t\tvaultProject = await input({ message: \"Doppler project name:\", default: name });\n\t\t\t\t\t\tvaultConfig = await input({ message: \"Doppler config:\", default: \"dev\" });\n\t\t\t\t\t} else if (vaultProvider === \"1password\" || vaultProvider === \"infisical\") {\n\t\t\t\t\t\tvaultProject = await input({\n\t\t\t\t\t\t\tmessage: `${vaultProvider === \"1password\" ? \"1Password vault\" : \"Infisical project\"} name:`,\n\t\t\t\t\t\t\tdefault: name,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!deploymentProvider) {\n\t\t\t\t\t\tdeploymentProvider = await select({\n\t\t\t\t\t\t\tmessage: \"Deployment provider:\",\n\t\t\t\t\t\t\tchoices: [\n\t\t\t\t\t\t\t\t{ name: \"None\", value: \"none\" },\n\t\t\t\t\t\t\t\t{ name: \"Vercel\", value: \"vercel\" },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!agent) {\n\t\t\t\t\t\tagent = await select({\n\t\t\t\t\t\t\tmessage: \"AI agent:\",\n\t\t\t\t\t\t\tchoices: [\n\t\t\t\t\t\t\t\t{ name: \"Claude\", value: \"claude\" },\n\t\t\t\t\t\t\t\t{ name: \"None\", value: \"none\" },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (topics.length === 0) {\n\t\t\t\t\t\tconst raw = await input({ message: \"Topics (comma-separated, optional):\" });\n\t\t\t\t\t\ttopics = parseTopics(raw);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!protection) {\n\t\t\t\t\t\tprotection = await select({\n\t\t\t\t\t\t\tmessage: \"Branch protection:\",\n\t\t\t\t\t\t\tchoices: [\n\t\t\t\t\t\t\t\t{ name: \"strict — required reviews + passing checks\", value: \"strict\" },\n\t\t\t\t\t\t\t\t{ name: \"balanced — required reviews, flexible checks\", value: \"balanced\" },\n\t\t\t\t\t\t\t\t{ name: \"minimal — branch protection only\", value: \"minimal\" },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (openSource === undefined) {\n\t\t\t\t\t\tconst ans = await select({\n\t\t\t\t\t\t\tmessage: \"Open source?\",\n\t\t\t\t\t\t\tchoices: [\n\t\t\t\t\t\t\t\t{ name: \"Yes\", value: \"yes\" },\n\t\t\t\t\t\t\t\t{ name: \"No\", value: \"no\" },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\t\t\t\t\t\topenSource = ans === \"yes\";\n\t\t\t\t\t}\n\n\t\t\t\t\tif (usesExternalPackages === undefined) {\n\t\t\t\t\t\tconst ans = await select({\n\t\t\t\t\t\t\tmessage: \"Uses external APIs or services?\",\n\t\t\t\t\t\t\tchoices: [\n\t\t\t\t\t\t\t\t{ name: \"Yes\", value: \"yes\" },\n\t\t\t\t\t\t\t\t{ name: \"No\", value: \"no\" },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\t\t\t\t\t\tusesExternalPackages = ans === \"yes\";\n\t\t\t\t\t}\n\n\t\t\t\t\tif (skills.length === 0) {\n\t\t\t\t\t\tconst raw = await input({ message: \"Agent skills (comma-separated, optional):\" });\n\t\t\t\t\t\tskills = parseTopics(raw);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!type) {\n\t\t\t\t\t\tgetLogger().error(\"new: template type is required\");\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (!name) {\n\t\t\t\t\t\tgetLogger().error(\"new: repo name is required\");\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst report = await runNew({\n\t\t\t\t\t\ttype,\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tdescription: description || undefined,\n\t\t\t\t\t\thomepage,\n\t\t\t\t\t\tvaultProvider: (vaultProvider as \"doppler\" | \"1password\" | \"infisical\" | \"none\") ?? \"none\",\n\t\t\t\t\t\tvaultProject,\n\t\t\t\t\t\tvaultConfig,\n\t\t\t\t\t\tdeploymentProvider: (deploymentProvider as \"vercel\" | \"none\") ?? \"none\",\n\t\t\t\t\t\tagent: (agent as \"claude\" | \"none\") ?? \"claude\",\n\t\t\t\t\t\truntimeEnvironment: (runtimeEnvironment as \"node\" | \"browser\" | \"universal\" | \"none\") ?? \"node\",\n\t\t\t\t\t\tprotection: protection ?? \"strict\",\n\t\t\t\t\t\topenSource: openSource ?? true,\n\t\t\t\t\t\tusesExternalPackages: usesExternalPackages ?? true,\n\t\t\t\t\t\ttopics,\n\t\t\t\t\t\tskills,\n\t\t\t\t\t\tisTemplate,\n\t\t\t\t\t\torg: argv.org,\n\t\t\t\t\t\ttoken: adminToken,\n\t\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t\tnoVerify: !argv.verify,\n\t\t\t\t\t\tcwd: argv.cwd,\n\t\t\t\t\t});\n\t\t\t\t\tif (report.status === \"fail\") process.exitCode = 1;\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (err instanceof NewError) {\n\t\t\t\t\t\tgetLogger().error(`new: ${err.message}`);\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthrow err;\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"plugin create [slug] [vendor]\",\n\t\t\t\"Scaffold a new @theholocron/holocron-plugin-<slug> package\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.positional(\"slug\", { type: \"string\", describe: \"Package slug (kebab-case)\" })\n\t\t\t\t\t.positional(\"vendor\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Vendor display name (PascalCase)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"capability\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"Capability key: source|ci|secrets|environments|issues|deployment|storage|auth|vault|dns|tooling|notifications|analytics|errors|logs|wiki|workers\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"token-env\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Holocron env var name (defaults to HOLOCRON_<VENDOR>_TOKEN)\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"vendor-env\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"Vendor-native env var name\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"base-url\", {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tdescribe: \"REST base URL\",\n\t\t\t\t\t})\n\t\t\t\t\t.option(\"verify\", {\n\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\tdefault: true,\n\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\"Run post-scaffold pnpm install + typecheck + lint + test (default true; --no-verify skips)\",\n\t\t\t\t\t}),\n\t\t\tasync (argv) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst [slug, vendor] = await promptForPositionals(\n\t\t\t\t\t\tgetEntry(\"plugin create\"),\n\t\t\t\t\t\targv as Record<string, unknown>\n\t\t\t\t\t);\n\t\t\t\t\tconst { capability, vendorEnv, baseUrl } = await resolvePluginCreateInputs(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcapability: argv.capability as string | undefined,\n\t\t\t\t\t\t\tvendorEnv: argv.vendorEnv as string | undefined,\n\t\t\t\t\t\t\tbaseUrl: argv.baseUrl as string | undefined,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tselectCapability: () =>\n\t\t\t\t\t\t\t\tselect({\n\t\t\t\t\t\t\t\t\tmessage: \"Capability:\",\n\t\t\t\t\t\t\t\t\tchoices: Object.keys(CARDINALITY).map((k) => ({ name: k, value: k })),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tinputVendorEnv: () =>\n\t\t\t\t\t\t\t\tinput({\n\t\t\t\t\t\t\t\t\tmessage: `Vendor-native env var for the ${vendor} token (e.g. MYVENDOR_API_KEY):`,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tinputBaseUrl: () =>\n\t\t\t\t\t\t\t\tinput({\n\t\t\t\t\t\t\t\t\tmessage: `REST base URL for the ${vendor} API (e.g. https://api.myvendor.com):`,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\n\t\t\t\t\tconst report = runPluginCreate({\n\t\t\t\t\t\tslug: slug!,\n\t\t\t\t\t\tvendorName: vendor!,\n\t\t\t\t\t\tcapability,\n\t\t\t\t\t\tvendorEnv,\n\t\t\t\t\t\tbaseUrl,\n\t\t\t\t\t\t...(argv.tokenEnv ? { tokenEnv: argv.tokenEnv as string } : {}),\n\t\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t\t// Yargs: `--no-verify` flips `argv.verify` to false. We pass\n\t\t\t\t\t\t// the inverse to preserve the internal `noVerify` naming.\n\t\t\t\t\t\tnoVerify: !argv.verify,\n\t\t\t\t\t\tcwd: argv.cwd,\n\t\t\t\t\t});\n\t\t\t\t\tif (report.status === \"fail\") process.exitCode = 1;\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (err instanceof PluginCreateError) {\n\t\t\t\t\t\tgetLogger().error(`plugin create: ${err.message}`);\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthrow err;\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\t\t.command(\n\t\t\t\"upgrade\",\n\t\t\t\"Upgrade toolchain version pins across the repo\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.command(\n\t\t\t\t\t\t\"node [to]\",\n\t\t\t\t\t\t\"Scan the repo and update every Node.js version pin to a new major\",\n\t\t\t\t\t\t(yy) =>\n\t\t\t\t\t\t\tyy\n\t\t\t\t\t\t\t\t.positional(\"to\", {\n\t\t\t\t\t\t\t\t\ttype: \"number\",\n\t\t\t\t\t\t\t\t\tdescribe: \"Target Node.js major version (e.g., 22)\",\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.option(\"from\", {\n\t\t\t\t\t\t\t\t\ttype: \"number\",\n\t\t\t\t\t\t\t\t\tdescribe:\n\t\t\t\t\t\t\t\t\t\t\"Current major version to replace. Auto-detected from .nvmrc / engines.node when omitted.\",\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\tasync (argv) => {\n\t\t\t\t\t\t\tconst [to] = await promptForPositionals(\n\t\t\t\t\t\t\t\tgetEntry(\"upgrade node\"),\n\t\t\t\t\t\t\t\targv as Record<string, unknown>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t// Read upgrade.node.extra from holocron.config.json if present.\n\t\t\t\t\t\t\t// We read the raw file directly rather than through loadConfig because\n\t\t\t\t\t\t\t// the upgrade config is not part of the plugin schema.\n\t\t\t\t\t\t\tlet extra: string[] = [];\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst raw = readFileSync(join(argv.cwd, \"holocron.config.json\"), \"utf8\");\n\t\t\t\t\t\t\t\tconst cfg = JSON.parse(raw) as { upgrade?: { node?: { extra?: unknown } } };\n\t\t\t\t\t\t\t\tconst extraRaw = cfg.upgrade?.node?.extra;\n\t\t\t\t\t\t\t\tif (Array.isArray(extraRaw)) {\n\t\t\t\t\t\t\t\t\textra = extraRaw as string[];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t/* no config or no upgrade section — fine */\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst report = await runUpgradeNode({\n\t\t\t\t\t\t\t\tto: Number(to),\n\t\t\t\t\t\t\t\t...(argv.from != null ? { from: argv.from as number } : {}),\n\t\t\t\t\t\t\t\tcwd: argv.cwd,\n\t\t\t\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t\t\t\textra,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (report.status === \"fail\") {\n\t\t\t\t\t\t\t\tif (report.message) getLogger().error(`upgrade node: ${report.message}`);\n\t\t\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\t\t\t\t\t.command(\n\t\t\t\t\t\t\"deps\",\n\t\t\t\t\t\t\"Bump every @theholocron/* pin to latest and migrate holocron.config.ts to the current preset API\",\n\t\t\t\t\t\t(yy) =>\n\t\t\t\t\t\t\tyy.option(\"pins-only\", {\n\t\t\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\t\t\tdefault: false,\n\t\t\t\t\t\t\t\tdescribe: \"Only bump the catalog pins — skip the holocron.config.ts migration\",\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\tasync (argv) => {\n\t\t\t\t\t\t\tconst report = await runUpgradeDeps({\n\t\t\t\t\t\t\t\tcwd: argv.cwd,\n\t\t\t\t\t\t\t\tdryRun: argv.dryRun,\n\t\t\t\t\t\t\t\tpinsOnly: argv.pinsOnly as boolean,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (report.status === \"fail\") {\n\t\t\t\t\t\t\t\tif (report.message) getLogger().error(`upgrade deps: ${report.message}`);\n\t\t\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\t\t\t\t\t.command(\n\t\t\t\t\t\t\"$0\",\n\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t() => {},\n\t\t\t\t\t\tasync (argv) => {\n\t\t\t\t\t\t\tawait launchMenu(\n\t\t\t\t\t\t\t\tCOMMAND_REGISTRY.filter((e) => e.group === \"upgrade\"),\n\t\t\t\t\t\t\t\targv,\n\t\t\t\t\t\t\t\t\"upgrade — choose a subcommand:\",\n\t\t\t\t\t\t\t\t\"Run `holocron upgrade --help` to see available upgrade subcommands.\"\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t),\n\t\t\t() => {}\n\t\t)\n\t\t.command(\n\t\t\t\"auth <subcommand>\",\n\t\t\t\"Manage bootstrap credentials in the OS keyring\",\n\t\t\t(y) =>\n\t\t\t\ty\n\t\t\t\t\t.command(\n\t\t\t\t\t\t\"set [provider] [value]\",\n\t\t\t\t\t\t\"Verify + store a bootstrap token for a provider\",\n\t\t\t\t\t\t(yy) => yy.positional(\"provider\", { type: \"string\" }).positional(\"value\", { type: \"string\" }),\n\t\t\t\t\t\tasync (argv) => {\n\t\t\t\t\t\t\tconst [provider] = await promptForPositionals(\n\t\t\t\t\t\t\t\tgetEntry(\"auth set\"),\n\t\t\t\t\t\t\t\targv as Record<string, unknown>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tconst result = await runAuthSet({\n\t\t\t\t\t\t\t\tprovider: provider!,\n\t\t\t\t\t\t\t\t...(argv.value ? { positional: argv.value as string } : {}),\n\t\t\t\t\t\t\t\t...(argv.org ? { org: argv.org as string } : {}),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (result.status === \"fail\") process.exitCode = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\t\t\t\t\t.command(\n\t\t\t\t\t\t\"unset [provider]\",\n\t\t\t\t\t\t\"Remove a stored bootstrap token\",\n\t\t\t\t\t\t(yy) => yy.positional(\"provider\", { type: \"string\" }),\n\t\t\t\t\t\tasync (argv) => {\n\t\t\t\t\t\t\tconst [provider] = await promptForPositionals(\n\t\t\t\t\t\t\t\tgetEntry(\"auth unset\"),\n\t\t\t\t\t\t\t\targv as Record<string, unknown>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\trunAuthUnset({ provider: provider! });\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\t\t\t\t\t.command(\n\t\t\t\t\t\t\"check [provider]\",\n\t\t\t\t\t\t\"Re-verify a stored bootstrap token\",\n\t\t\t\t\t\t(yy) => yy.positional(\"provider\", { type: \"string\" }),\n\t\t\t\t\t\tasync (argv) => {\n\t\t\t\t\t\t\tconst [provider] = await promptForPositionals(\n\t\t\t\t\t\t\t\tgetEntry(\"auth check\"),\n\t\t\t\t\t\t\t\targv as Record<string, unknown>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tconst result = await runAuthCheck({\n\t\t\t\t\t\t\t\tprovider: provider!,\n\t\t\t\t\t\t\t\t...(argv.org ? { org: argv.org as string } : {}),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (result.status === \"fail\") process.exitCode = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\t\t\t\t\t.command(\n\t\t\t\t\t\t\"list\",\n\t\t\t\t\t\t\"List every provider with a stored bootstrap token\",\n\t\t\t\t\t\t() => {},\n\t\t\t\t\t\tasync () => {\n\t\t\t\t\t\t\tawait runAuthList();\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\t\t\t\t\t.command(\n\t\t\t\t\t\t\"$0\",\n\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t() => {},\n\t\t\t\t\t\tasync (argv) => {\n\t\t\t\t\t\t\tawait launchMenu(\n\t\t\t\t\t\t\t\tCOMMAND_REGISTRY.filter((e) => e.group === \"auth\"),\n\t\t\t\t\t\t\t\targv,\n\t\t\t\t\t\t\t\t\"auth — choose a subcommand:\",\n\t\t\t\t\t\t\t\t\"Run `holocron auth --help` to see available auth subcommands.\"\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t),\n\t\t\t() => {}\n\t\t)\n\t\t.command(\n\t\t\t\"$0\",\n\t\t\tfalse,\n\t\t\t() => {},\n\t\t\tasync (argv) => {\n\t\t\t\tawait launchMenu(\n\t\t\t\t\tCOMMAND_REGISTRY.filter((e) => !e.group),\n\t\t\t\t\targv\n\t\t\t\t);\n\t\t\t}\n\t\t)\n\t\t.strict()\n\t\t.help()\n\t\t.epilogue(\n\t\t\t\"Execution contexts:\\n\" +\n\t\t\t\t` global works from a bare 'npm i -g': ${commandsInContext(\"global\").join(\", \")}\\n` +\n\t\t\t\t` repo-aware needs ./holocron.config in cwd: ${commandsInContext(\"repo-aware\").join(\", \")}\\n` +\n\t\t\t\t` workspace also needs the plugin packages: ${commandsInContext(\"workspace\").join(\", \")}\\n` +\n\t\t\t\t\" https://theholocron.github.io/holocron/execution-contexts\"\n\t\t)\n\t\t.fail((msg, err) => {\n\t\t\t// A user-facing error (a `workspace` command with no resolvable\n\t\t\t// plugins, a missing `holocron.config`) — its message is the whole\n\t\t\t// story. Print that: no usage dump, no stack trace.\n\t\t\tif (err instanceof Error && USER_FACING_ERRORS.has(err.name)) {\n\t\t\t\tcaptureException(err);\n\t\t\t\tgetLogger().error(err.message);\n\t\t\t\terrorReported = true;\n\t\t\t\tprocess.exitCode = 1;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Anything else a handler threw: hand back to the outer catch so\n\t\t\t// telemetry + the generic path own it.\n\t\t\tif (err) throw err;\n\t\t\t// A yargs validation failure (unknown command, missing positional):\n\t\t\t// keep yargs' own message.\n\t\t\tgetLogger().error(msg);\n\t\t\terrorReported = true;\n\t\t\tprocess.exitCode = 1;\n\t\t})\n\t\t.parse();\n} catch (err) {\n\tcaptureException(err);\n\t// User-facing errors carry a self-contained message — print it instead of\n\t// letting a raw stack trace escape (unless `.fail()` already did).\n\tif (!errorReported && err instanceof Error && USER_FACING_ERRORS.has(err.name)) {\n\t\tgetLogger().error(err.message);\n\t}\n\tif (!process.exitCode) process.exitCode = 1;\n}\n\nfinishCommand(!process.exitCode);\nendSession();\n// `--debug` / `--verbose`: surface the correlation id for Axiom lookup. This is\n// user-facing reference output (print semantics); cli.ts has no `print` injection.\nconst rid = getRunId();\nif (printRunId && rid) console.log(`Run ID: ${rid}`);\nconst notify = await updateCheckPromise;\nnotify?.();\nawait flush();\n\n/**\n * Parse `--scope` strings: `repo` | `env=NAME` | `org=NAME`.\n */\nfunction parseScope(\n\ts: string\n): { kind: \"repo\" } | { kind: \"environment\"; name: string } | { kind: \"organization\"; name: string } {\n\tif (s === \"repo\") return { kind: \"repo\" };\n\tif (s.startsWith(\"env=\")) return { kind: \"environment\", name: s.slice(\"env=\".length) };\n\tif (s.startsWith(\"org=\")) return { kind: \"organization\", name: s.slice(\"org=\".length) };\n\tthrow new Error(`invalid --scope \"${s}\" — expected \"repo\", \"env=<name>\", or \"org=<name>\"`);\n}\n"],"mappings":"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"}