@p11-core/cli 0.0.16 → 0.0.17
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 +93 -4
- package/docs/index.md +5 -2
- package/docs/sharing.md +10 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3699,6 +3699,22 @@ Environment:
|
|
|
3699
3699
|
);
|
|
3700
3700
|
});
|
|
3701
3701
|
allowLegacyParserBehavior(commentsCommand);
|
|
3702
|
+
const replyCommand = program2.command("reply").description("Reply to a comment on a read URL or id.").argument("[readUrl|readId]").argument("[commentId]").option("--name [name]", "Reply author name. Defaults to AI Agent.").option("--body [text]", "Plain-text reply body. Newlines are preserved.").option("--body-file [file]", "Read plain-text reply body from a file, or '-' for stdin.").option("--json", "Print the API response as JSON.").option("--version [n]", "Reply on a specific page version.").option("--api-url [url]", "Override the p11 API URL.").action(async (target, commentId, options2) => {
|
|
3703
|
+
await runCliAction(
|
|
3704
|
+
"reply",
|
|
3705
|
+
{
|
|
3706
|
+
has_target: Boolean(target),
|
|
3707
|
+
has_comment_id: Boolean(commentId),
|
|
3708
|
+
json: Boolean(options2.json),
|
|
3709
|
+
body: typeof options2.body === "string",
|
|
3710
|
+
body_file: typeof options2.bodyFile === "string",
|
|
3711
|
+
version: typeof options2.version === "string",
|
|
3712
|
+
api_url_override: typeof options2.apiUrl === "string"
|
|
3713
|
+
},
|
|
3714
|
+
() => reply(target, commentId, normalizeReplyOptions(options2))
|
|
3715
|
+
);
|
|
3716
|
+
});
|
|
3717
|
+
allowLegacyParserBehavior(replyCommand);
|
|
3702
3718
|
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) => {
|
|
3703
3719
|
await runCliAction(
|
|
3704
3720
|
"delete",
|
|
@@ -3791,6 +3807,16 @@ function normalizeCommentsOptions(options) {
|
|
|
3791
3807
|
apiUrl: optionString(options.apiUrl, "--api-url requires a URL.")
|
|
3792
3808
|
};
|
|
3793
3809
|
}
|
|
3810
|
+
function normalizeReplyOptions(options) {
|
|
3811
|
+
return {
|
|
3812
|
+
json: options.json,
|
|
3813
|
+
name: optionString(options.name, "--name requires a value."),
|
|
3814
|
+
body: optionString(options.body, "--body requires reply text."),
|
|
3815
|
+
bodyFile: optionString(options.bodyFile, "--body-file requires a file path or '-'."),
|
|
3816
|
+
version: optionString(options.version, "--version requires a positive integer."),
|
|
3817
|
+
apiUrl: optionString(options.apiUrl, "--api-url requires a URL.")
|
|
3818
|
+
};
|
|
3819
|
+
}
|
|
3794
3820
|
function normalizeDeleteOptions(options) {
|
|
3795
3821
|
return {
|
|
3796
3822
|
json: options.json,
|
|
@@ -3938,6 +3964,57 @@ async function comments(target, options) {
|
|
|
3938
3964
|
printComments(data);
|
|
3939
3965
|
}
|
|
3940
3966
|
}
|
|
3967
|
+
async function reply(target, commentId, options) {
|
|
3968
|
+
if (!target || !commentId) {
|
|
3969
|
+
throw new Error("Usage: p11 reply <readUrl|readId> <commentId> --body TEXT [--name NAME] [--json] [--version N]");
|
|
3970
|
+
}
|
|
3971
|
+
validateCommentId(commentId);
|
|
3972
|
+
const body = await replyBody(options);
|
|
3973
|
+
if (!body.trim()) throw new Error("Reply body is required. Use --body TEXT or --body-file FILE.");
|
|
3974
|
+
const version = options.version === void 0 ? void 0 : parseVersionFlag(String(options.version));
|
|
3975
|
+
const url = replyApiUrlForTarget(target, {
|
|
3976
|
+
apiUrl: options.apiUrl,
|
|
3977
|
+
version
|
|
3978
|
+
});
|
|
3979
|
+
const response = await fetchForOperation("Reply", url, {
|
|
3980
|
+
method: "POST",
|
|
3981
|
+
headers: {
|
|
3982
|
+
"content-type": "application/json"
|
|
3983
|
+
},
|
|
3984
|
+
body: JSON.stringify({
|
|
3985
|
+
name: options.name ?? "AI Agent",
|
|
3986
|
+
body,
|
|
3987
|
+
parentId: commentId
|
|
3988
|
+
})
|
|
3989
|
+
});
|
|
3990
|
+
const text = await response.text();
|
|
3991
|
+
if (!response.ok) {
|
|
3992
|
+
throw new Error(`Reply failed (${response.status}): ${responseErrorMessage(text)}`);
|
|
3993
|
+
}
|
|
3994
|
+
const data = JSON.parse(text);
|
|
3995
|
+
if (options.json) {
|
|
3996
|
+
console.log(JSON.stringify(data, null, 2));
|
|
3997
|
+
return;
|
|
3998
|
+
}
|
|
3999
|
+
console.log(`Replied ${data.comment?.id ?? "comment"}`);
|
|
4000
|
+
if (data.comment?.parentId) console.log(`parentId: ${data.comment.parentId}`);
|
|
4001
|
+
if (data.comment?.createdAt) console.log(`createdAt: ${data.comment.createdAt}`);
|
|
4002
|
+
}
|
|
4003
|
+
async function replyBody(options) {
|
|
4004
|
+
if (options.body !== void 0 && options.bodyFile !== void 0) {
|
|
4005
|
+
throw new Error("Use either --body or --body-file, not both.");
|
|
4006
|
+
}
|
|
4007
|
+
if (options.body !== void 0) return options.body;
|
|
4008
|
+
if (options.bodyFile === "-") return readStdin();
|
|
4009
|
+
if (options.bodyFile !== void 0) return readFile(path.resolve(options.bodyFile), "utf8");
|
|
4010
|
+
return "";
|
|
4011
|
+
}
|
|
4012
|
+
async function readStdin() {
|
|
4013
|
+
let body = "";
|
|
4014
|
+
process.stdin.setEncoding("utf8");
|
|
4015
|
+
for await (const chunk of process.stdin) body += chunk;
|
|
4016
|
+
return body;
|
|
4017
|
+
}
|
|
3941
4018
|
async function deleteDocument(target, options) {
|
|
3942
4019
|
if (!target) {
|
|
3943
4020
|
throw new Error("Usage: p11 delete <editUrl|editId> [--json] [--api-url URL]");
|
|
@@ -4270,10 +4347,10 @@ function printComments(data) {
|
|
|
4270
4347
|
console.log(`[${comment.createdAt}]${target}${resolved} ${comment.name}`);
|
|
4271
4348
|
if (comment.quote) console.log(`> ${comment.quote}`);
|
|
4272
4349
|
console.log(comment.body);
|
|
4273
|
-
for (const
|
|
4274
|
-
const replyResolved =
|
|
4275
|
-
console.log(` [${
|
|
4276
|
-
console.log(` ${
|
|
4350
|
+
for (const reply2 of comment.replies ?? []) {
|
|
4351
|
+
const replyResolved = reply2.resolvedAt ? " [resolved]" : "";
|
|
4352
|
+
console.log(` [${reply2.createdAt}] reply${replyResolved} ${reply2.name}`);
|
|
4353
|
+
console.log(` ${reply2.body}`);
|
|
4277
4354
|
}
|
|
4278
4355
|
console.log("");
|
|
4279
4356
|
}
|
|
@@ -4642,6 +4719,14 @@ function commentsApiUrlForTarget(value, options = {}) {
|
|
|
4642
4719
|
if (version !== void 0) url.searchParams.set("v", String(version));
|
|
4643
4720
|
return url;
|
|
4644
4721
|
}
|
|
4722
|
+
function replyApiUrlForTarget(value, options = {}) {
|
|
4723
|
+
const target = parseAccessTarget(value, ["read"], "a read URL with /r/<readId> or a read id", { parseVersion: true });
|
|
4724
|
+
const apiUrl = normalizeApiUrl(String(options.apiUrl ?? target.apiUrl ?? defaultApiUrl));
|
|
4725
|
+
const url = new URL(`/api/read/${encodeURIComponent(target.id)}/comments`, apiUrl);
|
|
4726
|
+
const version = options.version ?? target.version;
|
|
4727
|
+
if (version !== void 0) url.searchParams.set("v", String(version));
|
|
4728
|
+
return url;
|
|
4729
|
+
}
|
|
4645
4730
|
function deleteApiUrlForTarget(value, options = {}) {
|
|
4646
4731
|
const target = parseEditTarget(value);
|
|
4647
4732
|
const apiUrl = normalizeApiUrl(String(options.apiUrl ?? target.apiUrl ?? defaultApiUrl));
|
|
@@ -4682,6 +4767,9 @@ function validateAccessTarget(target, expected) {
|
|
|
4682
4767
|
const prefix = target.kind === "read" ? "read" : "edit";
|
|
4683
4768
|
if (!new RegExp(`^${prefix}_[A-Za-z0-9_-]{6,80}$`).test(target.id)) throw new Error(`Invalid ${expected}.`);
|
|
4684
4769
|
}
|
|
4770
|
+
function validateCommentId(commentId) {
|
|
4771
|
+
if (!/^cmt_[A-Za-z0-9_-]{8,64}$/.test(commentId)) throw new Error("Invalid comment id.");
|
|
4772
|
+
}
|
|
4685
4773
|
function normalizeApiUrl(value) {
|
|
4686
4774
|
return value.endsWith("/") ? value.slice(0, -1) : value;
|
|
4687
4775
|
}
|
|
@@ -4769,6 +4857,7 @@ export {
|
|
|
4769
4857
|
parseReadId,
|
|
4770
4858
|
publishOutputLines,
|
|
4771
4859
|
readHistoryEntries,
|
|
4860
|
+
replyApiUrlForTarget,
|
|
4772
4861
|
resolveBuildParentDir,
|
|
4773
4862
|
runCli,
|
|
4774
4863
|
validatePageSource
|
package/docs/index.md
CHANGED
|
@@ -11,10 +11,13 @@ p11 share <page.tsx>
|
|
|
11
11
|
p11 share <page.tsx> --edit-url <editUrl>
|
|
12
12
|
p11 history
|
|
13
13
|
p11 comments <readUrl|editUrl|readId|editId>
|
|
14
|
+
p11 reply <readUrl|readId> <commentId> --body "Reply text"
|
|
14
15
|
p11 delete <editUrl|editId>
|
|
15
16
|
```
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
Replies are plain text; newlines are preserved. Markdown and HTML are not rendered.
|
|
19
|
+
|
|
20
|
+
For `share`, `history`, `comments`, `reply`, and `delete`, add `--json` when scripting or when exact structured fields are needed.
|
|
18
21
|
|
|
19
22
|
## Docs Topics
|
|
20
23
|
|
|
@@ -32,4 +35,4 @@ p11 example all
|
|
|
32
35
|
p11 example all --output ./all.tsx
|
|
33
36
|
```
|
|
34
37
|
|
|
35
|
-
Use `p11 share --help`, `p11 comments --help`, `p11 delete --help`, and `p11 history --help` for command-specific flags.
|
|
38
|
+
Use `p11 share --help`, `p11 comments --help`, `p11 reply --help`, `p11 delete --help`, and `p11 history --help` for command-specific flags.
|
package/docs/sharing.md
CHANGED
|
@@ -26,6 +26,16 @@ p11 comments <readUrl|editUrl|readId|editId> --version 1
|
|
|
26
26
|
p11 comments <readUrl|editUrl|readId|editId> --output comments.json
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
+
Reply to a top-level comment:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
p11 reply <readUrl|readId> <commentId> --body "Reply text"
|
|
33
|
+
p11 reply <readUrl|readId> <commentId> --body-file reply.txt
|
|
34
|
+
p11 reply <readUrl|readId> <commentId> --body-file - --json
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Replies are plain text; newlines are preserved. Markdown and HTML are not rendered.
|
|
38
|
+
|
|
29
39
|
Delete a shared document and all of its versions, comments, and replies:
|
|
30
40
|
|
|
31
41
|
```bash
|