@theholocron/holocron-plugin-fern 5.0.0-alpha.41 → 5.0.0-alpha.411

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/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ <!-- alex disable host-hostess -->
2
+
1
3
  <!-- editorconfig-checker-disable-file -->
2
4
 
3
5
  # `@theholocron/holocron-plugin-fern`
@@ -42,7 +44,7 @@ pnpm add -D @theholocron/holocron-plugin-fern
42
44
  | `domain` | No | Base domain (`"wiki.theholocron.dev"`) or full path (`"wiki.theholocron.dev/myrepo"`). When a base domain is given, the repo name is appended automatically as a basepath. |
43
45
  | `fernOrg` | No | Fern workspace slug. Defaults to `config.org`. Set this when the Fern workspace name differs from the GitHub org (e.g. workspace `"holocron"`, org `"theholocron"`). |
44
46
 
45
- ## What `holocron setup` does
47
+ ## What `holocron repo setup` does
46
48
 
47
49
  1. **Writes `fern/fern.config.json`** — Fern workspace org name and pinned
48
50
  CLI version. Always overwritten.
@@ -79,11 +81,11 @@ DNS: add one CNAME record — `wiki.theholocron.dev` →
79
81
  Password protection is configured in the **Fern Dashboard**
80
82
  (`dashboard.buildwithfern.com`) — it is not configurable via `docs.yml` or
81
83
  any CLI flag. Configure access control manually in the dashboard after
82
- running `holocron setup`.
84
+ running `holocron repo setup`.
83
85
 
84
86
  ## CI secrets
85
87
 
86
- Add `HOLOCRON_FERN_TOKEN` to your repo's GitHub Secrets. The `wiki.yml` thin caller
88
+ Add `HOLOCRON_FERN_TOKEN` to your repo's GitHub Secrets. The `publish-wiki` thin caller
87
89
  passes it to the Fern CLI during `fern generate --docs`.
88
90
 
89
91
  | Secret | Purpose |
package/dist/index.d.mts CHANGED
@@ -1,10 +1,15 @@
1
- import { AuthError, DnsRecordRequest, ResolveTokenInput, Wiki, WikiProvisionOpts, WikiProxyConfig } from "@theholocron/cli";
2
- //#region src/capabilities/wiki.d.ts
3
- declare const FERN_VERSION = "5.114.1";
4
- interface FernWikiOptions {
1
+ import { AuthError, DnsRecordRequest, PluginToken, ResolveTokenInput, Wiki, WikiProvisionOpts, WikiProxyConfig } from "@theholocron/cli";
2
+ /** Resolves the Fern token from `--token`, `HOLOCRON_FERN_TOKEN`, `FERN_TOKEN` or the keyring entry for `fern`, and throws `AuthError` when none is set. */
3
+ export declare const resolveToken: import("@theholocron/cli").TokenResolver;
4
+ /** Every token this plugin takes, for `holocron doctor tokens`. */
5
+ export declare const tokens: PluginToken[];
6
+ /** The Fern CLI version written into `fern/fern.config.json`. */
7
+ export declare const FERN_VERSION = "5.114.1";
8
+ /** Options for the Fern `wiki` capability. */
9
+ interface FernWikiOptions extends ResolveTokenInput {
5
10
  /** Absolute path to the working repo root. Injected by the loader from RuntimeContext. */
6
11
  repoRoot?: string;
7
- /** Active org name (e.g. "theholocron"). Injected by the loader from RuntimeContext. */
12
+ /** Active org name (e.g. "acme"). Injected by the loader from RuntimeContext. */
8
13
  org?: string;
9
14
  /**
10
15
  * "owner/name" repo coordinate. Injected by the loader from RuntimeContext.
@@ -12,15 +17,15 @@ interface FernWikiOptions {
12
17
  */
13
18
  repo?: string;
14
19
  /**
15
- * Base domain for the Fern docs site (e.g. "wiki.theholocron.dev").
20
+ * Base domain for the Fern docs site (e.g. "wiki.example.dev").
16
21
  *
17
22
  * When provided without a path, the repo name is appended automatically:
18
- * domain "wiki.theholocron.dev" + repo "owner/holocron"
19
- * → custom-domain: wiki.theholocron.dev/holocron
23
+ * domain "wiki.example.dev" + repo "owner/holocron"
24
+ * → custom-domain: wiki.example.dev/holocron
20
25
  * → multi-source: true
21
26
  *
22
27
  * You can also supply the full path explicitly:
23
- * domain "wiki.theholocron.dev/holocron"
28
+ * domain "wiki.example.dev/holocron"
24
29
  *
25
30
  * Note: password protection is configured in the Fern Dashboard
26
31
  * (https://dashboard.buildwithfern.com) — it is not configurable via docs.yml.
@@ -30,42 +35,68 @@ interface FernWikiOptions {
30
35
  * Fern workspace org slug. Defaults to `org` (the GitHub org name).
31
36
  * Set this explicitly when the Fern workspace name differs from the
32
37
  * GitHub org — e.g. the workspace was registered as "holocron" while
33
- * the GitHub org is "theholocron".
38
+ * the GitHub org is "acme".
34
39
  */
35
40
  fernOrg?: string;
36
41
  /**
37
42
  * One-line description shown on the global product switcher card.
38
43
  * Falls back to the top-level `description` field in `holocron.config.ts`
39
- * when omitted. Only used by `holocron sync --steps wiki`.
44
+ * when omitted. Only used by `holocron repo sync --steps wiki`.
40
45
  */
41
46
  subtitle?: string;
42
47
  /**
43
48
  * Font Awesome icon class for the product switcher card (e.g. `"fa-duotone fa-gear"`).
44
- * Only used by `holocron sync --steps wiki`.
49
+ * Only used by `holocron repo sync --steps wiki`.
45
50
  */
46
51
  icon?: string;
47
52
  }
48
- declare class FernWiki implements Wiki {
53
+ /** `wiki` capability for Fern: writes the Fern config and docs scaffold for a repo. */
54
+ export declare class FernWiki implements Wiki {
49
55
  private readonly opts;
56
+ /** Capability key; always `"wiki"`. */
50
57
  readonly key: "wiki";
58
+ /** Provider name; always `"fern"`. */
51
59
  readonly providerName = "fern";
52
60
  constructor(opts: FernWikiOptions);
53
61
  provision(callOpts?: WikiProvisionOpts): Promise<string>;
54
62
  proxyConfig(): WikiProxyConfig | null;
63
+ /**
64
+ * Confirms `HOLOCRON_FERN_TOKEN`/`FERN_TOKEN` resolves, or a Fern token
65
+ * is stored in the keyring — not a live check. Fern exposes no
66
+ * lightweight endpoint to verify a token actually works (the only
67
+ * token-consuming operation is a full `fern generate`, see
68
+ * holocron#1079); this only confirms one is configured, the same way
69
+ * CI's `fern generate --docs` step would find it.
70
+ *
71
+ * Deliberately ignores `cliToken` (`--token`): CI's step only ever sees
72
+ * the env var from a GitHub Actions secret, never a CLI flag — and a
73
+ * bare `--token <value>` meant for some OTHER provider is forwarded to
74
+ * every loaded plugin as a fallback (see AGENTS.md), so honoring it
75
+ * here would report "configured" even when no Fern-specific credential
76
+ * exists anywhere CI would actually look.
77
+ *
78
+ * Only `AuthError` (the specific "no token found" signal) is treated as
79
+ * `ok: false` — any other error (e.g. a real keyring failure) is a
80
+ * genuine problem and must surface as a failure, not get misreported as
81
+ * a missing token.
82
+ */
83
+ whoami(): Promise<{
84
+ ok: boolean;
85
+ }>;
55
86
  dnsRecord(): DnsRecordRequest | null;
56
87
  }
57
- //#endregion
58
- //#region src/auth.d.ts
59
- declare const resolveToken: (input?: ResolveTokenInput) => string;
60
- //#endregion
61
- //#region src/index.d.ts
62
- type FernPluginOptions = FernWikiOptions;
63
- declare function wiki(opts: FernPluginOptions): Wiki;
64
- declare function createPlugin(options?: FernPluginOptions): {
88
+ /** Options for the Fern plugin; the same as the `wiki` capability's. */
89
+ export type FernPluginOptions = FernWikiOptions;
90
+ /** Builds the `wiki` capability from the plugin options. */
91
+ export declare function wiki(opts: FernPluginOptions): Wiki;
92
+ /** Creates the Fern plugin: its `connection` probe and the `wiki` capability. */
93
+ export declare function createPlugin(options?: FernPluginOptions): {
65
94
  name: string;
95
+ probes: {
96
+ connection: import("@theholocron/cli").Probe;
97
+ };
66
98
  capabilities: {
67
99
  wiki: () => Wiki;
68
100
  };
69
101
  };
70
- //#endregion
71
- export { AuthError, FERN_VERSION, FernPluginOptions, FernWiki, type FernWikiOptions, type ResolveTokenInput, createPlugin, resolveToken, wiki };
102
+ export { AuthError, type FernWikiOptions, type ResolveTokenInput };
package/dist/index.mjs CHANGED
@@ -1,11 +1,26 @@
1
+ import { AuthError, connectionProbe, createResolveToken } from "@theholocron/cli";
1
2
  import { mkdir, readFile, writeFile } from "node:fs/promises";
2
3
  import { join } from "node:path";
3
- import { AuthError, createResolveToken } from "@theholocron/cli";
4
- //#region src/capabilities/wiki.ts
4
+ import { stringifyJson } from "@theholocron/json-utils";
5
+ // src/auth.ts
6
+ /** Resolves the Fern token from `--token`, `HOLOCRON_FERN_TOKEN`, `FERN_TOKEN` or the keyring entry for `fern`, and throws `AuthError` when none is set. */
7
+ const resolveToken = createResolveToken({
8
+ envName: "HOLOCRON_FERN_TOKEN",
9
+ vendorEnvName: "FERN_TOKEN",
10
+ keyringService: "fern",
11
+ errorMessage: "no Fern token found. Set HOLOCRON_FERN_TOKEN / FERN_TOKEN, or run: holocron auth set fern <token>"
12
+ });
13
+ /** Every token this plugin takes, for `holocron doctor tokens`. */
14
+ const tokens = [resolveToken.token];
15
+ // src/capabilities/wiki.ts
16
+ /** The Fern CLI version written into `fern/fern.config.json`. */
5
17
  const FERN_VERSION = "5.114.1";
18
+ /** `wiki` capability for Fern: writes the Fern config and docs scaffold for a repo. */
6
19
  var FernWiki = class {
7
20
  opts;
21
+ /** Capability key; always `"wiki"`. */
8
22
  key = "wiki";
23
+ /** Provider name; always `"fern"`. */
9
24
  providerName = "fern";
10
25
  constructor(opts) {
11
26
  this.opts = opts;
@@ -33,6 +48,38 @@ var FernWiki = class {
33
48
  headers: { "X-Fern-Host": this.opts.domain.split("/")[0] }
34
49
  };
35
50
  }
51
+ /**
52
+ * Confirms `HOLOCRON_FERN_TOKEN`/`FERN_TOKEN` resolves, or a Fern token
53
+ * is stored in the keyring — not a live check. Fern exposes no
54
+ * lightweight endpoint to verify a token actually works (the only
55
+ * token-consuming operation is a full `fern generate`, see
56
+ * holocron#1079); this only confirms one is configured, the same way
57
+ * CI's `fern generate --docs` step would find it.
58
+ *
59
+ * Deliberately ignores `cliToken` (`--token`): CI's step only ever sees
60
+ * the env var from a GitHub Actions secret, never a CLI flag — and a
61
+ * bare `--token <value>` meant for some OTHER provider is forwarded to
62
+ * every loaded plugin as a fallback (see AGENTS.md), so honoring it
63
+ * here would report "configured" even when no Fern-specific credential
64
+ * exists anywhere CI would actually look.
65
+ *
66
+ * Only `AuthError` (the specific "no token found" signal) is treated as
67
+ * `ok: false` — any other error (e.g. a real keyring failure) is a
68
+ * genuine problem and must surface as a failure, not get misreported as
69
+ * a missing token.
70
+ */
71
+ async whoami() {
72
+ try {
73
+ resolveToken({
74
+ ...this.opts,
75
+ cliToken: void 0
76
+ });
77
+ return { ok: true };
78
+ } catch (err) {
79
+ if (err instanceof AuthError) return { ok: false };
80
+ throw err;
81
+ }
82
+ }
36
83
  dnsRecord() {
37
84
  const { org, domain, fernOrg } = this.opts;
38
85
  if (!domain) return null;
@@ -52,10 +99,10 @@ async function writeFernConfig({ repoRoot, fernOrg }) {
52
99
  const fernDir = join(repoRoot, "fern");
53
100
  await mkdir(fernDir, { recursive: true });
54
101
  const org = fernOrg ?? "holocron";
55
- const content = JSON.stringify({
102
+ const content = stringifyJson({
56
103
  organization: org,
57
104
  version: FERN_VERSION
58
- }, null, 2) + "\n";
105
+ });
59
106
  await writeFile(join(fernDir, "fern.config.json"), content, "utf8");
60
107
  return `fern.config.json: org=${org}, version=${FERN_VERSION}`;
61
108
  }
@@ -130,24 +177,24 @@ function updateInstancesBlock(content, instanceUrl, customDomain, multiSource, r
130
177
  if (match[0] === newBlock) return content;
131
178
  return content.replace(blockRe, newBlock);
132
179
  }
133
- //#endregion
134
- //#region src/auth.ts
135
- const resolveToken = createResolveToken({
136
- envName: "HOLOCRON_FERN_TOKEN",
137
- vendorEnvName: "FERN_TOKEN",
138
- keyringService: "fern",
139
- errorMessage: "no Fern token found. Set HOLOCRON_FERN_TOKEN / FERN_TOKEN, or run: holocron auth set fern <token>"
140
- });
141
- //#endregion
142
- //#region src/index.ts
180
+ // src/index.ts
181
+ /** Builds the `wiki` capability from the plugin options. */
143
182
  function wiki(opts) {
144
183
  return new FernWiki(opts);
145
184
  }
185
+ /** Creates the Fern plugin: its `connection` probe and the `wiki` capability. */
146
186
  function createPlugin(options = {}) {
147
187
  return {
148
188
  name: "@theholocron/holocron-plugin-fern",
189
+ probes: { connection: connectionProbe({
190
+ provider: "Fern",
191
+ token: () => resolveToken(options),
192
+ verify: async () => ({
193
+ ok: true,
194
+ subject: "a token is set (Fern cannot check it from here)"
195
+ })
196
+ }) },
149
197
  capabilities: { wiki: () => wiki(options) }
150
198
  };
151
199
  }
152
- //#endregion
153
- export { AuthError, FERN_VERSION, FernWiki, createPlugin, resolveToken, wiki };
200
+ export { AuthError, FERN_VERSION, FernWiki, createPlugin, resolveToken, tokens, wiki };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theholocron/holocron-plugin-fern",
3
- "version": "5.0.0-alpha.41",
3
+ "version": "5.0.0-alpha.411",
4
4
  "description": "Holocron plugin for Fern. Implements the wiki capability for engineering knowledge publishing.",
5
5
  "keywords": [
6
6
  "fern",
@@ -8,12 +8,12 @@
8
8
  "plugin",
9
9
  "wiki"
10
10
  ],
11
- "homepage": "https://github.com/theholocron/holocron/tree/main/packages/holocron-plugin-fern#readme",
11
+ "homepage": "https://docs.theholocron.dev/holocron/plugins/fern/",
12
12
  "bugs": "https://github.com/theholocron/holocron/issues",
13
13
  "repository": {
14
14
  "type": "git",
15
15
  "url": "git+https://github.com/theholocron/holocron.git",
16
- "directory": "packages/holocron-plugin-fern"
16
+ "directory": "plugins/holocron-plugin-fern"
17
17
  },
18
18
  "license": "MIT",
19
19
  "author": "Newton Koumantzelis",
@@ -29,25 +29,28 @@
29
29
  "files": [
30
30
  "dist"
31
31
  ],
32
+ "dependencies": {
33
+ "@theholocron/json-utils": "^1.17.0-alpha.4"
34
+ },
32
35
  "devDependencies": {
33
- "@theholocron/eslint-config": "^8.0.0",
34
- "@theholocron/tsconfig": "^8.0.0",
35
- "@theholocron/tsdown-config": "^8.0.0",
36
- "@theholocron/vitest-config": "^8.0.0",
37
36
  "@types/node": "^26",
38
- "@vitest/coverage-v8": "^4.1.11",
39
- "@vitest/eslint-plugin": "^1.6.27",
40
- "eslint": "^10.8.1",
41
- "eslint-plugin-n": "^18.3.0",
42
- "globals": "^17.11.0",
43
- "tsdown": "^0.22.14",
44
- "tsx": "4.23.12",
37
+ "@vitest/coverage-v8": "^5.1.0",
38
+ "@vitest/eslint-plugin": "^1.6.28",
39
+ "eslint": "^10.14.0",
40
+ "eslint-plugin-n": "^18.5.0",
41
+ "globals": "^17.14.0",
42
+ "tsdown": "^0.23.5",
43
+ "tsx": "4.23.15",
45
44
  "typescript": "^5.9.3",
46
- "vitest": "^4.1.11",
47
- "@theholocron/cli": "5.0.0-alpha.41"
45
+ "vitest": "^5.1.0",
46
+ "@theholocron/tsconfig": "^8.9.0-alpha.16",
47
+ "@theholocron/eslint-config": "^8.9.0-alpha.16",
48
+ "@theholocron/tsdown-config": "^8.9.0-alpha.16",
49
+ "@theholocron/vitest-config": "^8.9.0-alpha.16",
50
+ "@theholocron/cli": "5.0.0-alpha.411"
48
51
  },
49
52
  "peerDependencies": {
50
- "@theholocron/cli": "5.0.0-alpha.41"
53
+ "@theholocron/cli": "5.0.0-alpha.411"
51
54
  },
52
55
  "engines": {
53
56
  "node": ">=22"
@@ -56,10 +59,10 @@
56
59
  "access": "public"
57
60
  },
58
61
  "scripts": {
59
- "delivery.build": "tsdown",
60
- "sourceQuality.staticAnalysis": "holocron run sourceQuality.staticAnalysis --",
62
+ "build": "tsdown",
63
+ "lint:code": "eslint .",
64
+ "test:unit": "vitest run --coverage",
61
65
  "test:watch": "vitest",
62
- "verification.typeSafety": "holocron run verification.typeSafety --",
63
- "verification.unitTests": "holocron run verification.unitTests --"
66
+ "typecheck": "tsc --noEmit"
64
67
  }
65
68
  }