bikeshed-now 0.4.0 → 0.5.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.
- package/README.md +32 -11
- package/package.json +1 -1
- package/src/client.mjs +1 -1
- package/src/index.mjs +75 -3
package/README.md
CHANGED
|
@@ -3,24 +3,26 @@
|
|
|
3
3
|
Publish a document to a [Bikeshed](https://bikeshed.now) deployment, then read
|
|
4
4
|
the comments people left on it — each one with the exact sentence it is about.
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
It talks to [bikeshed.now](https://bikeshed.now) over HTTPS, with a personal
|
|
7
|
+
access token that carries exactly your own permissions. Bikeshed is also
|
|
8
|
+
self-hostable: point the client at your own deployment and everything below
|
|
9
|
+
works the same, with your address in place of `https://bikeshed.now`.
|
|
9
10
|
|
|
10
11
|
```bash
|
|
11
12
|
npm i -g bikeshed-now
|
|
12
13
|
bikeshed login # asks for the deployment and a token
|
|
13
14
|
```
|
|
14
15
|
|
|
15
|
-
Create a token
|
|
16
|
-
It is shown once. `BIKESHED_ORIGIN` and `BIKESHED_TOKEN` work
|
|
17
|
-
`login` where an interactive command cannot run — a CI job, or an
|
|
16
|
+
Create a token at [bikeshed.now/account](https://bikeshed.now/account) — choose
|
|
17
|
+
**Command line**. It is shown once. `BIKESHED_ORIGIN` and `BIKESHED_TOKEN` work
|
|
18
|
+
instead of `login` where an interactive command cannot run — a CI job, or an
|
|
19
|
+
agent.
|
|
18
20
|
|
|
19
21
|
## The loop
|
|
20
22
|
|
|
21
23
|
```bash
|
|
22
24
|
bikeshed publish proposal.md --title "Storage migration"
|
|
23
|
-
# published storage-migration v1 — https
|
|
25
|
+
# published storage-migration v1 — https://bikeshed.now/d/storage-migration
|
|
24
26
|
|
|
25
27
|
# Somebody highlights a sentence and says what is wrong with it.
|
|
26
28
|
bikeshed comments storage-migration
|
|
@@ -42,7 +44,7 @@ The address comes from the title. To choose it, pass `--id`:
|
|
|
42
44
|
|
|
43
45
|
```bash
|
|
44
46
|
bikeshed publish platform.md --id 01-platform
|
|
45
|
-
# published 01-platform v1 — https
|
|
47
|
+
# published 01-platform v1 — https://bikeshed.now/d/01-platform
|
|
46
48
|
```
|
|
47
49
|
|
|
48
50
|
If the id is taken, the document is still published, at the id plus a few
|
|
@@ -53,12 +55,30 @@ unlisted document you are not a member of needs the link, because its key is in
|
|
|
53
55
|
it; without the key the document answers as an id that does not exist.
|
|
54
56
|
|
|
55
57
|
```bash
|
|
56
|
-
bikeshed comments 'https
|
|
58
|
+
bikeshed comments 'https://bikeshed.now/d/build-estimate?k=…'
|
|
57
59
|
```
|
|
58
60
|
|
|
59
61
|
`bikeshed --help` lists the rest — listing documents, folders, and installing the
|
|
60
62
|
agent skills a deployment serves.
|
|
61
63
|
|
|
64
|
+
## Forking
|
|
65
|
+
|
|
66
|
+
To revise a document you can read but do not own, fork it. You get your own
|
|
67
|
+
private copy, at the version you name or the current one, and it remembers what
|
|
68
|
+
it was forked from.
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
bikeshed fork 'https://bikeshed.now/d/build-estimate?k=…'
|
|
72
|
+
# forked build-estimate into build-estimate-x7k2p9 — https://bikeshed.now/d/build-estimate-x7k2p9
|
|
73
|
+
bikeshed lineage build-estimate-x7k2p9
|
|
74
|
+
# forked from build-estimate v3 Build estimate (changed since)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
`lineage` shows each original you can open, nearest first, and whether the
|
|
78
|
+
nearest has changed since you forked it. On a document you own it also counts
|
|
79
|
+
its forks. The author of what you fork sees that it was forked — a count, never
|
|
80
|
+
who.
|
|
81
|
+
|
|
62
82
|
## Sharing is not automated
|
|
63
83
|
|
|
64
84
|
There is no command that shares a document, changes who can read it, or sets an
|
|
@@ -66,8 +86,9 @@ expiry. Those are decisions a person makes in the interface, deliberately.
|
|
|
66
86
|
|
|
67
87
|
## For agents
|
|
68
88
|
|
|
69
|
-
A deployment serves its own instructions at
|
|
70
|
-
|
|
89
|
+
A deployment serves its own instructions at
|
|
90
|
+
[`https://bikeshed.now/llms.txt`](https://bikeshed.now/llms.txt), and the skills
|
|
91
|
+
behind them at `/skills/index.json`. `bikeshed skills install <dir>`
|
|
71
92
|
writes them where your harness reads skills from.
|
|
72
93
|
|
|
73
94
|
Everything done with a token is stamped with the channel it came through, so a
|
package/package.json
CHANGED
package/src/client.mjs
CHANGED
package/src/index.mjs
CHANGED
|
@@ -39,6 +39,8 @@ const USAGE = `bikeshed — publish and revise documents
|
|
|
39
39
|
bikeshed list documents you can read
|
|
40
40
|
bikeshed publish <file> create a new document
|
|
41
41
|
bikeshed update <id> <file> publish a new version
|
|
42
|
+
bikeshed fork <id> your own copy, which remembers its original
|
|
43
|
+
bikeshed lineage <id> what it was forked from; for its owner, its forks
|
|
42
44
|
bikeshed get <id> print a document's source
|
|
43
45
|
bikeshed comments <id> unresolved feedback, with its anchored text
|
|
44
46
|
bikeshed reply <id> <thread> <text> reply in a thread
|
|
@@ -72,9 +74,10 @@ What you can publish
|
|
|
72
74
|
|
|
73
75
|
Options
|
|
74
76
|
--json machine-readable output
|
|
75
|
-
--title <text> title for publish
|
|
77
|
+
--title <text> title for publish or fork (fork default: the original's)
|
|
76
78
|
--id <id> with publish: the address, /d/<id> (default: from the title)
|
|
77
|
-
--folder <id> destination folder for publish
|
|
79
|
+
--folder <id> destination folder for publish or fork
|
|
80
|
+
--version <v> with fork: the version to copy (default: current)
|
|
78
81
|
--parent <id> parent folder for mkdir
|
|
79
82
|
--limit <n> with list: rows per page (default 20, max 50)
|
|
80
83
|
--cursor <id> with list: the page after the one that printed it
|
|
@@ -188,7 +191,8 @@ async function list(flags) {
|
|
|
188
191
|
}
|
|
189
192
|
for (const doc of result.documents) {
|
|
190
193
|
const marker = doc.visibility === "private" ? " " : doc.visibility === "public" ? "◉" : "◐";
|
|
191
|
-
|
|
194
|
+
// ⑂ marks a fork; where it came from is `bikeshed lineage`'s to say.
|
|
195
|
+
console.log(`${marker} ${doc.id.padEnd(34)} ${doc.version.padEnd(5)} ${doc.title}${doc.forked ? " ⑂" : ""}`);
|
|
192
196
|
}
|
|
193
197
|
if (result.nextCursor) console.log(`\n… more: --cursor ${result.nextCursor}`);
|
|
194
198
|
});
|
|
@@ -343,6 +347,71 @@ async function folders(flags) {
|
|
|
343
347
|
});
|
|
344
348
|
}
|
|
345
349
|
|
|
350
|
+
/**
|
|
351
|
+
* Your own copy of a document you can read. The original's author sees that it
|
|
352
|
+
* was forked — a count, never who — and the fork records where it came from,
|
|
353
|
+
* which only people who can open the original are shown (SPEC §21).
|
|
354
|
+
*/
|
|
355
|
+
async function fork(flags, [ref]) {
|
|
356
|
+
if (!ref) fail("usage: bikeshed fork <id> [--version <v>] [--folder <id>] [--title <text>]");
|
|
357
|
+
const { origin, token } = resolveAuth(flags);
|
|
358
|
+
const args = docArgs(ref);
|
|
359
|
+
if (typeof flags.version === "string") args.version = flags.version;
|
|
360
|
+
if (typeof flags.folder === "string") args.folder = flags.folder;
|
|
361
|
+
if (typeof flags.title === "string") args.title = flags.title;
|
|
362
|
+
const result = await callTool(origin, token, "fork_document", args);
|
|
363
|
+
out(flags.json, { ...result, url: result.url ?? `${origin}/d/${result.docId}` }, () =>
|
|
364
|
+
console.log(`forked ${args.id} into ${result.docId} — ${result.url ?? `${origin}/d/${result.docId}`}`),
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Where a document came from, nearest first, as far as you can open, and — for
|
|
370
|
+
* its owner — what has been forked from it. The deployment decides what you may
|
|
371
|
+
* see; this only prints it (SPEC §21).
|
|
372
|
+
*/
|
|
373
|
+
async function lineage(flags, [ref]) {
|
|
374
|
+
if (!ref) fail("usage: bikeshed lineage <id>");
|
|
375
|
+
const { origin, token } = resolveAuth(flags);
|
|
376
|
+
const result = await callTool(origin, token, "get_lineage", docArgs(ref));
|
|
377
|
+
out(flags.json, result, () => console.log(describeLineage(result)));
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/** The human form of a get_lineage result. */
|
|
381
|
+
function describeLineage(result) {
|
|
382
|
+
const lines = [];
|
|
383
|
+
if (result.forked) {
|
|
384
|
+
if (result.forkedFrom.length === 0) {
|
|
385
|
+
lines.push("forked from a document you can't open");
|
|
386
|
+
}
|
|
387
|
+
result.forkedFrom.forEach((a, i) => {
|
|
388
|
+
const changed = a.changedSince ? " (changed since)" : "";
|
|
389
|
+
lines.push(`${i === 0 ? "forked from" : " which was"} ${a.id} ${a.version} ${a.title}${changed}`);
|
|
390
|
+
});
|
|
391
|
+
if (result.forkedFrom.length > 0 && result.moreYouCannotOpen) {
|
|
392
|
+
lines.push(" which was forked from a document you can't open");
|
|
393
|
+
}
|
|
394
|
+
} else if (!result.forks) {
|
|
395
|
+
lines.push(`${result.id} is not a fork.`);
|
|
396
|
+
}
|
|
397
|
+
if (result.forks) {
|
|
398
|
+
const { total, youCannotOpen, listed } = result.forks;
|
|
399
|
+
if (lines.length) lines.push("");
|
|
400
|
+
if (total === 0) {
|
|
401
|
+
lines.push("Nobody has forked it yet.");
|
|
402
|
+
} else {
|
|
403
|
+
const times = total === 1 ? "once" : `${total} times`;
|
|
404
|
+
lines.push(youCannotOpen ? `forked ${times}; ${youCannotOpen} you can't open` : `forked ${times}`);
|
|
405
|
+
for (const f of listed) {
|
|
406
|
+
const when = f.forkedAt ? f.forkedAt.slice(0, 10) : "";
|
|
407
|
+
const owner = f.owner ? ` ${f.owner}` : "";
|
|
408
|
+
lines.push(` ${f.id.padEnd(34)} ${f.visibility.padEnd(8)} ${when.padEnd(10)} ${f.title}${owner}`);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
return lines.join("\n");
|
|
413
|
+
}
|
|
414
|
+
|
|
346
415
|
async function mkdir(flags, rest) {
|
|
347
416
|
const name = rest.join(" ");
|
|
348
417
|
if (!name) fail("usage: bikeshed mkdir <name> [--parent <id>]");
|
|
@@ -454,6 +523,8 @@ const COMMANDS = {
|
|
|
454
523
|
list,
|
|
455
524
|
publish,
|
|
456
525
|
update,
|
|
526
|
+
fork,
|
|
527
|
+
lineage,
|
|
457
528
|
get,
|
|
458
529
|
comments,
|
|
459
530
|
reply,
|
|
@@ -480,6 +551,7 @@ async function main() {
|
|
|
480
551
|
title: { type: "string" },
|
|
481
552
|
id: { type: "string" },
|
|
482
553
|
folder: { type: "string" },
|
|
554
|
+
version: { type: "string" },
|
|
483
555
|
parent: { type: "string" },
|
|
484
556
|
origin: { type: "string" },
|
|
485
557
|
token: { type: "string" },
|