@theholocron/cli 3.43.0 → 3.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,7 +12,7 @@ import { ProviderApiError } from "@theholocron/http-client";
12
12
  * See `.notes/tech-architecture.spec.md` for the design narrative
13
13
  * (status: proposed, issue: #74).
14
14
  */
15
- type CapabilityKey = "source" | "ci" | "secrets" | "environments" | "issues" | "deployment" | "storage" | "auth" | "vault" | "dns" | "tooling" | "notifications" | "analytics" | "observability";
15
+ type CapabilityKey = "source" | "ci" | "secrets" | "environments" | "issues" | "deployment" | "storage" | "auth" | "vault" | "dns" | "tooling" | "notifications" | "analytics" | "observability" | "wiki";
16
16
  type Cardinality = "single" | "many";
17
17
  declare const CARDINALITY: {
18
18
  readonly source: "single";
@@ -29,6 +29,7 @@ declare const CARDINALITY: {
29
29
  readonly notifications: "many";
30
30
  readonly analytics: "many";
31
31
  readonly observability: "many";
32
+ readonly wiki: "single";
32
33
  };
33
34
  /**
34
35
  * No capabilities are strictly required — repos without secrets (e.g. org
@@ -625,6 +626,41 @@ interface Observability extends ProviderIdentity {
625
626
  alreadyExists: boolean;
626
627
  }>;
627
628
  }
629
+ interface WikiProvisionOpts {
630
+ /** Project display name used in the wiki title (e.g. "Holocron"). */
631
+ name?: string;
632
+ }
633
+ /**
634
+ * DNS record that `setup` should create for a wiki custom domain.
635
+ * Returned by `Wiki.dnsRecord()` when a custom domain is configured.
636
+ */
637
+ interface WikiDnsRecord {
638
+ /** Zone apex passed as the first argument to `dns.upsertRecord`. */
639
+ zone: string;
640
+ /** Full hostname for the CNAME (e.g. "wiki.theholocron.dev"). */
641
+ cname: string;
642
+ /** CNAME target (e.g. "holocron.docs.buildwithfern.com"). */
643
+ target: string;
644
+ }
645
+ /**
646
+ * Engineering wiki provider.
647
+ *
648
+ * A swappable provider for publishing the `docs/decisions/` and
649
+ * `docs/engineering/` surfaces as a browsable, access-controlled site.
650
+ * Local-only providers (fern, mintlify) write config files; remote
651
+ * providers (github) make API calls.
652
+ */
653
+ interface Wiki extends ProviderIdentity {
654
+ readonly key: "wiki";
655
+ /** Provision the wiki — write config files or call the provider API. */
656
+ provision(opts?: WikiProvisionOpts): Promise<string>;
657
+ /**
658
+ * DNS record needed for the custom domain, when one is configured.
659
+ * Returns null when no custom domain is set.
660
+ * Called by `setup` to provision the CNAME via the `dns` capability.
661
+ */
662
+ dnsRecord?(): WikiDnsRecord | null;
663
+ }
628
664
  interface CapabilityImpls {
629
665
  source: Source;
630
666
  ci: Ci;
@@ -640,10 +676,11 @@ interface CapabilityImpls {
640
676
  notifications: Notifications;
641
677
  analytics: Analytics;
642
678
  observability: Observability;
679
+ wiki: Wiki;
643
680
  }
644
681
  type CardinalityFor<K extends CapabilityKey> = (typeof CARDINALITY)[K];
645
682
  /** Resolved runtime shape: single → one impl; many → array. */
646
683
  type ResolvedCapability<K extends CapabilityKey> = CardinalityFor<K> extends "many" ? CapabilityImpls[K][] : CapabilityImpls[K];
647
684
  declare function isMulti<K extends CapabilityKey>(key: K): CardinalityFor<K> extends "many" ? true : false;
648
685
  //#endregion
649
- export { Analytics, Auth, AuthDescription, AuthEvent, AuthEventType, AuthIdentity, AuthUser, CARDINALITY, CapabilityImpls, CapabilityKey, Cardinality, CardinalityFor, Ci, CiRun, CiRunFilter, CiRunStatus, ConnectionStringOptions, CreateAuthUserInput, Deployment, DeploymentProject, DeploymentProjectSettings, DeploymentRecord, DeploymentTarget, DeploymentTrigger, Dns, DnsRecord, DnsRecordType, EnsureResult, Environment, EnvironmentReviewer, Environments, Issue, IssueSearchFilter, Issues, LabelDef, LifecycleResult, LifecycleSlot, NormalizedAuthUser, Notifications, Observability, PagesConfig, ParseWebhookInput, ProviderApiError, ProviderIdentity, PullRequest, REQUIRED_CAPABILITIES, RepoRef, RepoSettings, ResolvedCapability, Ruleset, SecretScope, Secrets, Source, StatusCategory, Storage, StorageBranch, TeamEntry, TeamPermission, Tooling, ToolingDoctorReport, TrackerDoctorReport, TrackerUser, Vault, WebhookDashboardInfo, WebhookVerificationError, isMulti };
686
+ export { Analytics, Auth, AuthDescription, AuthEvent, AuthEventType, AuthIdentity, AuthUser, CARDINALITY, CapabilityImpls, CapabilityKey, Cardinality, CardinalityFor, Ci, CiRun, CiRunFilter, CiRunStatus, ConnectionStringOptions, CreateAuthUserInput, Deployment, DeploymentProject, DeploymentProjectSettings, DeploymentRecord, DeploymentTarget, DeploymentTrigger, Dns, DnsRecord, DnsRecordType, EnsureResult, Environment, EnvironmentReviewer, Environments, Issue, IssueSearchFilter, Issues, LabelDef, LifecycleResult, LifecycleSlot, NormalizedAuthUser, Notifications, Observability, PagesConfig, ParseWebhookInput, ProviderApiError, ProviderIdentity, PullRequest, REQUIRED_CAPABILITIES, RepoRef, RepoSettings, ResolvedCapability, Ruleset, SecretScope, Secrets, Source, StatusCategory, Storage, StorageBranch, TeamEntry, TeamPermission, Tooling, ToolingDoctorReport, TrackerDoctorReport, TrackerUser, Vault, WebhookDashboardInfo, WebhookVerificationError, Wiki, WikiDnsRecord, WikiProvisionOpts, isMulti };
@@ -14,7 +14,8 @@ const CARDINALITY = {
14
14
  tooling: "many",
15
15
  notifications: "many",
16
16
  analytics: "many",
17
- observability: "many"
17
+ observability: "many",
18
+ wiki: "single"
18
19
  };
19
20
  /**
20
21
  * No capabilities are strictly required — repos without secrets (e.g. org
package/dist/cli.mjs CHANGED
@@ -137,7 +137,8 @@ const CARDINALITY = {
137
137
  tooling: "many",
138
138
  notifications: "many",
139
139
  analytics: "many",
140
- observability: "many"
140
+ observability: "many",
141
+ wiki: "single"
141
142
  };
142
143
  /**
143
144
  * No capabilities are strictly required — repos without secrets (e.g. org
@@ -3280,6 +3281,9 @@ var test_default$1 = "name: Test\n\non: # yamllint disable-line rule:truthy\n p
3280
3281
  //#region src/commands/workflows/typecheck.yml
3281
3282
  var typecheck_default$1 = "name: Typecheck\n\non: # yamllint disable-line rule:truthy\n push:\n branches: [main, alpha]\n pull_request:\n\nconcurrency:\n group: typecheck-${{ github.ref }}\n cancel-in-progress: true\n\npermissions:\n contents: read\n\njobs:\n typecheck:\n name: Typecheck\n uses: theholocron/.github/.github/workflows/typecheck.yml@main\n secrets: inherit\n";
3282
3283
  //#endregion
3284
+ //#region src/commands/workflows/wiki.yml
3285
+ var wiki_default$1 = "name: Wiki\n\non: # yamllint disable-line rule:truthy\n push:\n branches: [main]\n pull_request:\n branches: [main]\n\nconcurrency:\n group: ${{ github.event_name == 'pull_request' && format('wiki-preview-{0}', github.event.pull_request.number) || 'wiki' }}\n cancel-in-progress: ${{ github.event_name == 'pull_request' }}\n\npermissions:\n contents: read\n\njobs:\n publish:\n name: Publish\n if: ${{ github.event_name != 'pull_request' }}\n uses: theholocron/.github/.github/workflows/wiki.yml@main\n secrets: inherit\n\n preview:\n name: Preview\n if: ${{ github.event_name == 'pull_request' }}\n uses: theholocron/.github/.github/workflows/wiki.yml@main\n with:\n preview: true\n preview-id: pr-${{ github.event.pull_request.number }}\n secrets: inherit\n";
3286
+ //#endregion
3283
3287
  //#region src/commands/setup-workflows.ts
3284
3288
  /**
3285
3289
  * Header prepended to every auto-generated workflow thin caller.
@@ -3321,7 +3325,8 @@ const WORKFLOW_TEMPLATES = {
3321
3325
  dependencies: dependencies_default$1,
3322
3326
  bookkeeping: bookkeeping_default$1,
3323
3327
  audit: audit_default$1,
3324
- deploy: deploy_default$1
3328
+ deploy: deploy_default$1,
3329
+ wiki: wiki_default$1
3325
3330
  };
3326
3331
  const KNOWN_WORKFLOWS = new Set(Object.keys(WORKFLOW_TEMPLATES));
3327
3332
  /**
@@ -4254,6 +4259,27 @@ async function runSetup(input) {
4254
4259
  print(formatStep(steps[steps.length - 1]));
4255
4260
  }
4256
4261
  }
4262
+ if (loader.has("wiki")) {
4263
+ const wiki = loader.get("wiki");
4264
+ print(style.step("wiki"));
4265
+ steps.push(await runStep("wiki", "provision wiki config", dryRun, async () => {
4266
+ return await wiki.provision({ name: config.name });
4267
+ }));
4268
+ print(formatStep(steps[steps.length - 1]));
4269
+ const wikiDns = wiki.dnsRecord?.();
4270
+ if (wikiDns && loader.has("dns")) {
4271
+ const dns = loader.get("dns");
4272
+ steps.push(await runStep("dns", `upsertRecord ${wikiDns.cname}`, dryRun, async () => {
4273
+ await dns.upsertRecord(wikiDns.zone, {
4274
+ type: "CNAME",
4275
+ name: wikiDns.cname,
4276
+ content: wikiDns.target,
4277
+ ttl: 1
4278
+ });
4279
+ }));
4280
+ print(formatStep(steps[steps.length - 1]));
4281
+ }
4282
+ }
4257
4283
  if (loader.has("deployment")) {
4258
4284
  const deploy = loader.get("deployment");
4259
4285
  print(style.step("deployment"));
@@ -5358,6 +5384,9 @@ var test_default = "name: Test\n\non: # yamllint disable-line rule:truthy\n wor
5358
5384
  //#region src/templates/workflows/typecheck.yml
5359
5385
  var typecheck_default = "name: Typecheck\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n secrets:\n TURBO_TOKEN:\n required: false\n\njobs:\n typecheck:\n name: tsc --noEmit\n permissions:\n contents: read\n runs-on: ubuntu-latest\n timeout-minutes: 10\n env:\n TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}\n TURBO_TEAM: ${{ vars.TURBO_TEAM }}\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - run: pnpm typecheck\n name: Type check\n\n\n conclusion:\n name: Conclusion\n runs-on: ubuntu-latest\n if: always()\n needs: [typecheck]\n steps:\n - name: Check job statuses\n run: |\n if [[ \"$RESULTS\" == *\"failure\"* ]] || [[ \"$RESULTS\" == *\"cancelled\"* ]]; then\n exit 1\n fi\n env:\n RESULTS: ${{ join(needs.*.result, ',') }}\n";
5360
5386
  //#endregion
5387
+ //#region src/templates/workflows/wiki.yml
5388
+ var wiki_default = "name: Wiki\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n inputs:\n fern-version:\n description: >\n Fern CLI version to install. Pin this to avoid breaking changes when\n Fern updates their config schema.\n type: string\n required: false\n default: \"5.35.4\"\n preview:\n description: >\n When true, publishes a preview instead of production.\n Requires preview-id to be set.\n type: boolean\n required: false\n default: false\n preview-id:\n description: >\n Stable ID for the preview URL. The preview is accessible at\n {fern-org}-preview-{id}.docs.buildwithfern.com. Use the PR number\n (e.g. \"pr-123\") so the same URL is reused on every push to\n the branch.\n type: string\n required: false\n default: \"\"\n fern-org:\n description: >\n Fern workspace org slug (e.g. \"holocron\"). When set, a GitHub\n deployment is created after a successful preview so the URL appears\n in the PR sidebar widget — the same pattern as Cloudflare Pages previews.\n type: string\n required: false\n default: \"\"\n base-path:\n description: >\n Basepath appended to the preview URL (e.g. \"holocron\" when using\n multi-source routing with wiki.theholocron.dev/holocron).\n Omit for single-instance Fern sites.\n type: string\n required: false\n default: \"\"\n secrets:\n HOLOCRON_FERN_TOKEN:\n required: false\n FERN_TOKEN:\n required: false\n\njobs:\n publish:\n name: ${{ inputs.preview && 'Preview' || 'Publish' }} to Fern\n runs-on: ubuntu-latest\n timeout-minutes: 10\n permissions:\n contents: read\n deployments: write\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n\n - name: Install Fern CLI\n run: npm install -g \"fern-api@$FERN_VERSION\"\n env:\n FERN_VERSION: ${{ inputs.fern-version }}\n\n - name: Publish docs\n if: ${{ !inputs.preview }}\n run: fern generate --docs\n env:\n FERN_TOKEN: ${{ secrets.HOLOCRON_FERN_TOKEN || secrets.FERN_TOKEN }}\n\n - name: Preview docs\n if: ${{ inputs.preview && inputs.preview-id != '' }}\n run: fern generate --docs --preview --id \"$PREVIEW_ID\"\n env:\n FERN_TOKEN: ${{ secrets.HOLOCRON_FERN_TOKEN || secrets.FERN_TOKEN }}\n PREVIEW_ID: ${{ inputs.preview-id }}\n\n - name: Report preview URL\n if: ${{ inputs.preview && inputs.preview-id != '' && inputs.fern-org != '' }}\n env:\n GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n FERN_ORG: ${{ inputs.fern-org }}\n PREVIEW_ID: ${{ inputs.preview-id }}\n BASE_PATH: ${{ inputs.base-path }}\n run: |\n PREVIEW_URL=\"https://${FERN_ORG}-preview-${PREVIEW_ID}.docs.buildwithfern.com${BASE_PATH:+/${BASE_PATH}}\"\n PAYLOAD=$(printf '{\"ref\":\"%s\",\"environment\":\"fern (Preview)\",\"description\":\"Fern Docs\",\"production_environment\":false,\"auto_merge\":false,\"required_contexts\":[]}' \\\n \"$GITHUB_HEAD_REF\")\n DEPLOY_ID=$(echo \"$PAYLOAD\" | gh api \"repos/${GITHUB_REPOSITORY}/deployments\" \\\n --method POST --input - | jq -r '.id')\n gh api \"repos/${GITHUB_REPOSITORY}/deployments/${DEPLOY_ID}/statuses\" \\\n --method POST --field state=success --field environment_url=\"$PREVIEW_URL\"\n";
5389
+ //#endregion
5361
5390
  //#region src/templates/index.ts
5362
5391
  /**
5363
5392
  * All reusable workflow and composite action content bundled as string
@@ -5392,7 +5421,8 @@ const REUSABLE_WORKFLOWS = {
5392
5421
  "sync-github": sync_github_default,
5393
5422
  sync: sync_default,
5394
5423
  test: test_default,
5395
- typecheck: typecheck_default
5424
+ typecheck: typecheck_default,
5425
+ wiki: wiki_default
5396
5426
  };
5397
5427
  const WORKFLOW_TEMPLATE_PROPERTIES = { bookkeeping: JSON.stringify({
5398
5428
  name: "Bookkeeping",