@p11-core/cli 0.0.9 → 0.0.11

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/index.js CHANGED
@@ -3466,8 +3466,11 @@ var require_commander = __commonJS({
3466
3466
  });
3467
3467
 
3468
3468
  // src/index.ts
3469
+ import { randomUUID } from "crypto";
3469
3470
  import { realpathSync } from "fs";
3470
3471
  import { chmod, mkdir, mkdtemp, readFile, readdir, rename, rm, stat, writeFile } from "fs/promises";
3472
+ import http from "http";
3473
+ import https from "https";
3471
3474
  import { createRequire } from "module";
3472
3475
  import { homedir, tmpdir } from "os";
3473
3476
  import path from "path";
@@ -3503,11 +3506,16 @@ var nodeRequire = createRequire(import.meta.url);
3503
3506
  var packageJson = nodeRequire("../package.json");
3504
3507
  var builtDefaultApiUrl = "https://p11.rarexlabs.com";
3505
3508
  var defaultApiUrl = process.env.P11_API_URL || builtDefaultApiUrl;
3509
+ var builtPostHogKey = "phc_CftZMyBB3bMZQRj3CmJovHB3kvzwJmQhXSwUBgzUTUi6";
3510
+ var builtPostHogHost = "https://us.i.posthog.com";
3511
+ var builtAppEnv = "production";
3506
3512
  var generate = nodeRequire("@babel/generator").default;
3507
3513
  var traverse = nodeRequire("@babel/traverse").default;
3508
3514
  var updateCheckIntervalMs = 30 * 60 * 1e3;
3509
3515
  var updateCheckTimeoutMs = 800;
3516
+ var telemetryTimeoutMs = 300;
3510
3517
  var P11_HISTORY_FILE = "history.json";
3518
+ var P11_TELEMETRY_FILE = "telemetry.json";
3511
3519
  var P11_HISTORY_DIR_MODE = 448;
3512
3520
  var P11_HISTORY_FILE_MODE = 384;
3513
3521
  var P11_HISTORY_LOCK_STALE_MS = 3e4;
@@ -3521,7 +3529,12 @@ var docsTopics = /* @__PURE__ */ new Map([
3521
3529
  ["components", "docs/components.md"],
3522
3530
  ["sharing", "docs/sharing.md"]
3523
3531
  ]);
3524
- var exampleFiles = /* @__PURE__ */ new Map([["all-components", "examples/all-components.tsx"]]);
3532
+ var exampleFiles = /* @__PURE__ */ new Map([
3533
+ ["minimal", "examples/minimal.tsx"],
3534
+ ["all", "examples/all-components.tsx"],
3535
+ ["all-components", "examples/all-components.tsx"]
3536
+ ]);
3537
+ var publicExampleNames = ["minimal", "all"];
3525
3538
  var allowedDocumentComponents = /* @__PURE__ */ new Set([
3526
3539
  "Document",
3527
3540
  "Page",
@@ -3646,39 +3659,87 @@ function createCliProgram(options = {}) {
3646
3659
  "after",
3647
3660
  `
3648
3661
 
3662
+ Examples:
3663
+ p11 example minimal --output ./page.tsx
3664
+ p11 example all
3665
+ p11 share ./page.tsx
3666
+ p11 docs components
3667
+
3649
3668
  Environment:
3650
3669
  P11_API_URL Defaults to ${builtDefaultApiUrl}
3651
- P11_BUILD_DIR Directory for temporary share build files. Defaults to the OS temp directory.`
3670
+ P11_BUILD_DIR Directory for temporary share build files. Defaults to the OS temp directory.
3671
+ P11_TELEMETRY_DISABLED=1 disables anonymous usage analytics.`
3652
3672
  );
3653
3673
  const shareCommand = program2.command("share").description("Share a review link for a page.").argument("[page.tsx]").option("--json", "Print the API response as JSON.").option("--edit-url [url]", "Share a new version using an edit URL or edit id.").option("--api-url [url]", "Override the p11 API URL.").option("--build-dir [dir]", "Directory for temporary build files.").action(async (input, options2) => {
3654
- await publish(input, normalizePublishOptions(options2));
3674
+ await runCliAction(
3675
+ "share",
3676
+ {
3677
+ has_input: Boolean(input),
3678
+ json: Boolean(options2.json),
3679
+ edit_url: typeof options2.editUrl === "string",
3680
+ api_url_override: typeof options2.apiUrl === "string",
3681
+ build_dir_override: typeof options2.buildDir === "string"
3682
+ },
3683
+ () => publish(input, normalizePublishOptions(options2))
3684
+ );
3655
3685
  });
3656
3686
  allowLegacyParserBehavior(shareCommand);
3657
3687
  const commentsCommand = program2.command("comments").description("Fetch exported comments for a read/edit URL or id.").argument("[readUrl|editUrl|readId|editId]").option("--json", "Print comments as JSON.").option("--output [file]", "Write comments JSON to a file.").option("--version [n]", "Fetch comments for a specific page version.").option("--api-url [url]", "Override the p11 API URL.").action(async (target, options2) => {
3658
- await comments(target, normalizeCommentsOptions(options2));
3688
+ await runCliAction(
3689
+ "comments",
3690
+ {
3691
+ has_target: Boolean(target),
3692
+ json: Boolean(options2.json),
3693
+ output: typeof options2.output === "string",
3694
+ version: typeof options2.version === "string",
3695
+ api_url_override: typeof options2.apiUrl === "string"
3696
+ },
3697
+ () => comments(target, normalizeCommentsOptions(options2))
3698
+ );
3659
3699
  });
3660
3700
  allowLegacyParserBehavior(commentsCommand);
3661
3701
  const deleteCommand = program2.command("delete").description("Delete a document and all of its versions and comments.").argument("[editUrl|editId]").option("--json", "Print the API response as JSON.").option("--api-url [url]", "Override the p11 API URL.").action(async (target, options2) => {
3662
- await deleteDocument(target, normalizeDeleteOptions(options2));
3702
+ await runCliAction(
3703
+ "delete",
3704
+ {
3705
+ has_target: Boolean(target),
3706
+ json: Boolean(options2.json),
3707
+ api_url_override: typeof options2.apiUrl === "string"
3708
+ },
3709
+ () => deleteDocument(target, normalizeDeleteOptions(options2))
3710
+ );
3663
3711
  });
3664
3712
  allowLegacyParserBehavior(deleteCommand);
3665
3713
  program2.command("version").description("Print the p11 CLI version.").action(async () => {
3666
- await warnBeforeAction({ force: true });
3667
- console.log(packageJson.version);
3714
+ await runCliAction("version", {}, async () => {
3715
+ await warnBeforeAction({ force: true });
3716
+ console.log(packageJson.version);
3717
+ });
3668
3718
  });
3669
3719
  program2.command("history").description("List saved read/edit links.").option("--json", "Print saved history as JSON.").action(async (options2) => {
3670
- await history(normalizeHistoryOptions(options2));
3720
+ await runCliAction("history", { json: Boolean(options2.json) }, () => history(normalizeHistoryOptions(options2)));
3671
3721
  });
3672
3722
  const docsCommand = program2.command("docs").description("Print p11 authoring docs.").argument("[topic]", "Docs topic: components or sharing.").action(async (topic) => {
3673
- await docs(topic);
3723
+ await runCliAction("docs", { has_topic: Boolean(topic), known_topic: isKnownDocsTopic(topic) }, () => docs(topic));
3674
3724
  });
3675
3725
  allowLegacyParserBehavior(docsCommand);
3676
- const exampleCommand = program2.command("example").description("Print or write a p11 example document.").argument("[name]", "Example name: all-components.").option("--output [file]", "Write the example to a file.").action(async (name, options2) => {
3677
- await example(name, normalizeExampleOptions(options2));
3726
+ const exampleCommand = program2.command("example").description("Print or write a p11 example document.").argument("[name]", "Example name: minimal or all.").option("--output [file]", "Write the example to a file.").action(async (name, options2) => {
3727
+ await runCliAction(
3728
+ "example",
3729
+ {
3730
+ has_example: Boolean(name),
3731
+ known_example: isKnownExampleName(name),
3732
+ output: typeof options2.output === "string"
3733
+ },
3734
+ () => example(name, normalizeExampleOptions(options2))
3735
+ );
3678
3736
  });
3679
3737
  allowLegacyParserBehavior(exampleCommand);
3680
3738
  return program2;
3681
3739
  }
3740
+ var __testing = {
3741
+ captureCliTelemetry: captureCliTelemetryNow
3742
+ };
3682
3743
  function isKnownTopLevelCommand(program2, command) {
3683
3744
  return command === "--help" || command === "-h" || isVersionFlag(command) || command === "help" || program2.commands.some((subcommand) => subcommand.name() === command);
3684
3745
  }
@@ -3688,6 +3749,31 @@ function isVersionFlag(command) {
3688
3749
  function allowLegacyParserBehavior(command) {
3689
3750
  return command.allowUnknownOption().allowExcessArguments();
3690
3751
  }
3752
+ function isKnownDocsTopic(topic) {
3753
+ return docsTopics.has(topic ?? "index");
3754
+ }
3755
+ function isKnownExampleName(name) {
3756
+ return name === void 0 || exampleFiles.has(name);
3757
+ }
3758
+ async function runCliAction(command, properties, action) {
3759
+ const startedAt = Date.now();
3760
+ try {
3761
+ await action();
3762
+ captureCliTelemetry("p11_cli_command_succeeded", {
3763
+ command,
3764
+ duration_ms: Date.now() - startedAt,
3765
+ ...properties
3766
+ });
3767
+ } catch (error) {
3768
+ await captureCliTelemetryNow("p11_cli_command_failed", {
3769
+ command,
3770
+ duration_ms: Date.now() - startedAt,
3771
+ error_name: error instanceof Error ? error.name : "Error",
3772
+ ...properties
3773
+ });
3774
+ throw error;
3775
+ }
3776
+ }
3691
3777
  function normalizePublishOptions(options) {
3692
3778
  return {
3693
3779
  json: options.json,
@@ -3749,7 +3835,7 @@ async function publish(input, options) {
3749
3835
  const url = editTarget ? new URL(`/api/edit/${encodeURIComponent(editTarget.editId)}/page`, apiUrl) : new URL("/api/pages", apiUrl);
3750
3836
  const uploadBody = new ArrayBuffer(zipBytes.byteLength);
3751
3837
  new Uint8Array(uploadBody).set(zipBytes);
3752
- const response = await fetch(url, {
3838
+ const response = await fetchForOperation("Share", url, {
3753
3839
  method: "POST",
3754
3840
  headers: {
3755
3841
  "content-type": "application/zip"
@@ -3770,19 +3856,26 @@ async function publish(input, options) {
3770
3856
  if (options.json) {
3771
3857
  console.log(JSON.stringify(data, null, 2));
3772
3858
  } else {
3773
- console.log(data.readUrl ?? data.url);
3774
- if (data.editUrl) console.log(`editUrl: ${data.editUrl}`);
3775
- if (data.docId) console.log(`docId: ${data.docId}`);
3776
- if (data.readId) console.log(`readId: ${data.readId}`);
3777
- if (data.editId) console.log(`editId: ${data.editId}`);
3778
- if (data.version) console.log(`version: ${data.version}`);
3779
- if (data.latestVersion) console.log(`latestVersion: ${data.latestVersion}`);
3780
- if (data.createdAt) console.log(`createdAt: ${data.createdAt}`);
3859
+ for (const line of publishOutputLines(data)) console.log(line);
3781
3860
  }
3782
3861
  } finally {
3783
3862
  if (cleanupDir) await rm(cleanupDir, { recursive: true, force: true });
3784
3863
  }
3785
3864
  }
3865
+ function publishOutputLines(data) {
3866
+ const lines = [];
3867
+ const readUrl = data.readUrl ?? data.url;
3868
+ if (readUrl) lines.push(`readUrl: ${readUrl}`);
3869
+ if (data.editUrl) lines.push(`editUrl: ${data.editUrl}`);
3870
+ if (readUrl && data.editUrl) lines.push("Note: share readUrl for comments; keep editUrl private for updates and deletion.");
3871
+ if (data.docId) lines.push(`docId: ${data.docId}`);
3872
+ if (data.readId) lines.push(`readId: ${data.readId}`);
3873
+ if (data.editId) lines.push(`editId: ${data.editId}`);
3874
+ if (data.version) lines.push(`version: ${data.version}`);
3875
+ if (data.latestVersion) lines.push(`latestVersion: ${data.latestVersion}`);
3876
+ if (data.createdAt) lines.push(`createdAt: ${data.createdAt}`);
3877
+ return lines;
3878
+ }
3786
3879
  async function history(options) {
3787
3880
  const entries = await readHistoryEntries();
3788
3881
  if (options.json) {
@@ -3802,14 +3895,15 @@ async function docs(topic) {
3802
3895
  async function example(name, options) {
3803
3896
  if (!name) {
3804
3897
  console.log("Available examples:");
3805
- for (const exampleName of exampleFiles.keys()) console.log(` ${exampleName}`);
3898
+ for (const exampleName of publicExampleNames) console.log(` ${exampleName}`);
3806
3899
  console.log("");
3807
- console.log("Usage: p11 example all-components [--output FILE]");
3900
+ console.log("Usage: p11 example minimal [--output FILE]");
3901
+ console.log(" p11 example all [--output FILE]");
3808
3902
  return;
3809
3903
  }
3810
3904
  const relativePath = exampleFiles.get(name);
3811
3905
  if (!relativePath) {
3812
- throw new Error(`Unknown example: ${name}. Available examples: ${Array.from(exampleFiles.keys()).join(", ")}`);
3906
+ throw new Error(`Unknown example: ${name}. Available examples: ${publicExampleNames.join(", ")}`);
3813
3907
  }
3814
3908
  const contents = await readCliAsset(relativePath);
3815
3909
  if (options.output) {
@@ -3827,7 +3921,7 @@ async function comments(target, options) {
3827
3921
  apiUrl: options.apiUrl,
3828
3922
  version
3829
3923
  });
3830
- const response = await fetch(url);
3924
+ const response = await fetchForOperation("Fetch comments", url);
3831
3925
  const text = await response.text();
3832
3926
  if (!response.ok) {
3833
3927
  throw new Error(`Fetch comments failed (${response.status}): ${text}`);
@@ -3850,7 +3944,7 @@ async function deleteDocument(target, options) {
3850
3944
  const url = deleteApiUrlForTarget(target, {
3851
3945
  apiUrl: options.apiUrl
3852
3946
  });
3853
- const response = await fetch(url, {
3947
+ const response = await fetchForOperation("Delete", url, {
3854
3948
  method: "DELETE"
3855
3949
  });
3856
3950
  const text = await response.text();
@@ -4018,6 +4112,130 @@ function delay(ms) {
4018
4112
  function historyFilePath() {
4019
4113
  return path.join(homedir(), ".p11", P11_HISTORY_FILE);
4020
4114
  }
4115
+ function captureCliTelemetry(event, properties = {}) {
4116
+ scheduleTelemetry(() => captureCliTelemetryNow(event, properties, { keepAlive: false }));
4117
+ }
4118
+ async function captureCliTelemetryNow(event, properties = {}, options = {}) {
4119
+ const key = postHogKey();
4120
+ if (!key) return;
4121
+ try {
4122
+ const host = postHogHost();
4123
+ const { anonymousId, isNew } = await telemetryIdentity();
4124
+ const baseProperties = cliTelemetryBaseProperties();
4125
+ const events = [];
4126
+ if (isNew && event !== "p11_cli_activated") {
4127
+ events.push(sendPostHogEvent(host, key, "p11_cli_activated", anonymousId, baseProperties, options));
4128
+ }
4129
+ events.push(sendPostHogEvent(host, key, event, anonymousId, { ...baseProperties, ...properties }, options));
4130
+ await Promise.all(events);
4131
+ } catch {
4132
+ }
4133
+ }
4134
+ function scheduleTelemetry(task) {
4135
+ const run = () => {
4136
+ task().catch(() => {
4137
+ });
4138
+ };
4139
+ if (typeof setImmediate === "function") {
4140
+ setImmediate(run);
4141
+ return;
4142
+ }
4143
+ setTimeout(run, 0);
4144
+ }
4145
+ async function sendPostHogEvent(host, key, event, distinctId, properties, options = {}) {
4146
+ const payload = JSON.stringify({
4147
+ api_key: key,
4148
+ event,
4149
+ distinct_id: distinctId,
4150
+ properties: compactObject(properties)
4151
+ });
4152
+ const endpoint = new URL("/capture/", host);
4153
+ const client = endpoint.protocol === "http:" ? http : https;
4154
+ await new Promise((resolve, reject) => {
4155
+ const request = client.request(
4156
+ endpoint,
4157
+ {
4158
+ method: "POST",
4159
+ headers: {
4160
+ "content-type": "application/json",
4161
+ "content-length": Buffer.byteLength(payload)
4162
+ }
4163
+ },
4164
+ (response) => {
4165
+ response.resume();
4166
+ response.on("end", resolve);
4167
+ }
4168
+ );
4169
+ const timeout = setTimeout(() => {
4170
+ request.destroy(new Error("Telemetry request timed out."));
4171
+ }, telemetryTimeoutMs);
4172
+ if (options.keepAlive === false) timeout.unref?.();
4173
+ request.on("socket", (socket) => {
4174
+ if (options.keepAlive === false) socket.unref();
4175
+ });
4176
+ request.on("error", reject);
4177
+ request.on("close", () => clearTimeout(timeout));
4178
+ request.end(payload);
4179
+ });
4180
+ }
4181
+ function cliTelemetryBaseProperties() {
4182
+ return {
4183
+ product: "p11",
4184
+ surface: "cli",
4185
+ app_env: analyticsEnv(),
4186
+ cli_version: packageJson.version,
4187
+ node_version: process.versions.node,
4188
+ platform: process.platform,
4189
+ arch: process.arch
4190
+ };
4191
+ }
4192
+ function postHogKey() {
4193
+ if (isTruthyEnv(process.env.P11_TELEMETRY_DISABLED) || isTruthyEnv(process.env.DO_NOT_TRACK)) return "";
4194
+ return (process.env.P11_POSTHOG_KEY || builtPostHogKey || "").trim();
4195
+ }
4196
+ function postHogHost() {
4197
+ const rawHost = (process.env.P11_POSTHOG_HOST || builtPostHogHost || "https://us.i.posthog.com").trim();
4198
+ try {
4199
+ return new URL(rawHost.endsWith("/") ? rawHost : `${rawHost}/`);
4200
+ } catch {
4201
+ return new URL("https://us.i.posthog.com/");
4202
+ }
4203
+ }
4204
+ function isTruthyEnv(value) {
4205
+ return value === "1" || value === "true" || value === "yes";
4206
+ }
4207
+ function analyticsEnv() {
4208
+ return (process.env.APP_ENV || builtAppEnv || "production").trim() || "production";
4209
+ }
4210
+ async function telemetryIdentity() {
4211
+ const filePath = telemetryFilePath();
4212
+ const raw = await readFile(filePath, "utf8").catch(() => null);
4213
+ if (raw) {
4214
+ const parsed = JSON.parse(raw);
4215
+ if (typeof parsed.anonymousId === "string" && /^anon_[A-Za-z0-9-]{12,80}$/.test(parsed.anonymousId)) {
4216
+ return {
4217
+ anonymousId: parsed.anonymousId,
4218
+ isNew: false
4219
+ };
4220
+ }
4221
+ }
4222
+ const data = {
4223
+ anonymousId: `anon_${randomUUID()}`,
4224
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
4225
+ };
4226
+ const telemetryDir = path.dirname(filePath);
4227
+ await ensurePrivateHistoryDir(telemetryDir);
4228
+ await writeFile(filePath, `${JSON.stringify(data, null, 2)}
4229
+ `, { mode: P11_HISTORY_FILE_MODE });
4230
+ await chmod(filePath, P11_HISTORY_FILE_MODE);
4231
+ return {
4232
+ anonymousId: data.anonymousId,
4233
+ isNew: true
4234
+ };
4235
+ }
4236
+ function telemetryFilePath() {
4237
+ return path.join(homedir(), ".p11", P11_TELEMETRY_FILE);
4238
+ }
4021
4239
  function commentsExportJson(data) {
4022
4240
  return JSON.stringify(commentExportData(data), null, 2);
4023
4241
  }
@@ -4067,9 +4285,34 @@ function responseErrorMessage(text) {
4067
4285
  }
4068
4286
  return text;
4069
4287
  }
4288
+ async function fetchForOperation(operation, url, init) {
4289
+ try {
4290
+ return await fetch(url, init);
4291
+ } catch (error) {
4292
+ throw new Error(formatNetworkError(operation, url, error));
4293
+ }
4294
+ }
4295
+ function formatNetworkError(operation, url, error) {
4296
+ return `${operation} request failed before receiving a response: ${fetchFailureDetails(error)}. API URL: ${url.origin}. ${networkErrorHint()}`;
4297
+ }
4298
+ function fetchFailureDetails(error) {
4299
+ const message = errorMessage(error);
4300
+ const cause = errorCause(error);
4301
+ if (!cause) return message;
4302
+ const causeCode = errorCode(cause);
4303
+ const causeMessage = errorMessage(cause);
4304
+ const causeDetails = causeCode && !causeMessage.includes(causeCode) ? `${causeCode} ${causeMessage}` : causeMessage;
4305
+ return `${message} (cause: ${causeDetails})`;
4306
+ }
4307
+ function networkErrorHint() {
4308
+ return "If running in an agent sandbox, retry with network access outside the sandbox or with escalated network permissions.";
4309
+ }
4070
4310
  function errorMessage(error) {
4071
4311
  return error instanceof Error ? error.message : String(error);
4072
4312
  }
4313
+ function errorCause(error) {
4314
+ return typeof error === "object" && error !== null && "cause" in error ? error.cause : null;
4315
+ }
4073
4316
  async function readCliAsset(relativePath) {
4074
4317
  return readFile(path.join(cliPackageRoot, relativePath), "utf8");
4075
4318
  }
@@ -4500,6 +4743,7 @@ function parseUrlVersion(value) {
4500
4743
  }
4501
4744
  }
4502
4745
  export {
4746
+ __testing,
4503
4747
  addSourceLineAttributes,
4504
4748
  appendPublishHistory,
4505
4749
  buildPageModule,
@@ -4507,10 +4751,12 @@ export {
4507
4751
  commentsExportJson,
4508
4752
  createCliProgram,
4509
4753
  deleteApiUrlForTarget,
4754
+ formatNetworkError,
4510
4755
  isNewerVersion,
4511
4756
  parseCommentsTarget,
4512
4757
  parseEditId,
4513
4758
  parseReadId,
4759
+ publishOutputLines,
4514
4760
  readHistoryEntries,
4515
4761
  resolveBuildParentDir,
4516
4762
  validatePageSource
package/docs/index.md CHANGED
@@ -5,6 +5,8 @@ p11 shares reviewable, public-but-unlisted document pages from React files.
5
5
  ## Common Commands
6
6
 
7
7
  ```bash
8
+ p11 example minimal --output ./page.tsx
9
+ p11 example all
8
10
  p11 share <page.tsx>
9
11
  p11 share <page.tsx> --edit-url <editUrl>
10
12
  p11 history
@@ -25,8 +27,9 @@ p11 docs sharing
25
27
 
26
28
  ```bash
27
29
  p11 example
28
- p11 example all-components
29
- p11 example all-components --output ./all-components.tsx
30
+ p11 example minimal --output ./page.tsx
31
+ p11 example all
32
+ p11 example all --output ./all.tsx
30
33
  ```
31
34
 
32
35
  Use `p11 share --help`, `p11 comments --help`, `p11 delete --help`, and `p11 history --help` for command-specific flags.
@@ -271,7 +271,7 @@ export default function All() {
271
271
  <CodeBlock language="json">
272
272
  {code`
273
273
  {
274
- "docId": "all-components",
274
+ "docId": "all",
275
275
  "version": 2,
276
276
  "comments": true,
277
277
  "languages": ["typescript", "javascript", "python", "rust", "html", "css", "json", "yaml", "bash"]
@@ -285,7 +285,7 @@ export default function All() {
285
285
  <CodeBlock language="yaml">
286
286
  {code`
287
287
  document:
288
- id: all-components
288
+ id: all
289
289
  version: 2
290
290
  comments: true
291
291
  retentionDays: 7
@@ -307,7 +307,7 @@ export default function All() {
307
307
  <Heading>14. Bash</Heading>
308
308
  <CodeBlock language="bash">
309
309
  {code`
310
- p11 share ./all-components.tsx
310
+ p11 share ./all.tsx
311
311
  p11 comments <readUrl> --version 1
312
312
  `}
313
313
  </CodeBlock>
@@ -0,0 +1,21 @@
1
+ import { Document, Heading, Page, Section, Text } from "@p11-core/components";
2
+
3
+ // For the full component set, run:
4
+ // p11 docs components
5
+ // p11 example all
6
+
7
+ export default function Minimal() {
8
+ return (
9
+ <Document mode="page">
10
+ <Page>
11
+ <Section>
12
+ <Heading level={1}>Review Brief</Heading>
13
+ <Text>
14
+ This is a minimal p11 document. Replace this text with the content
15
+ you want reviewers to read and comment on.
16
+ </Text>
17
+ </Section>
18
+ </Page>
19
+ </Document>
20
+ );
21
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@p11-core/cli",
3
- "version": "0.0.9",
3
+ "version": "0.0.11",
4
4
  "license": "UNLICENSED",
5
5
  "type": "module",
6
6
  "bin": {