@popoverinstall/cli 0.4.1 → 0.6.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/CHANGELOG.md +158 -0
- package/dist/aardvark.d.ts +30 -0
- package/dist/aardvark.d.ts.map +1 -0
- package/dist/aardvark.js +97 -0
- package/dist/aardvark.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +140 -52
- package/dist/index.js.map +1 -1
- package/dist/login.d.ts +8 -1
- package/dist/login.d.ts.map +1 -1
- package/dist/login.js +51 -23
- package/dist/login.js.map +1 -1
- package/dist/next-steps.d.ts +18 -0
- package/dist/next-steps.d.ts.map +1 -0
- package/dist/next-steps.js +73 -0
- package/dist/next-steps.js.map +1 -0
- package/dist/scene.d.ts +43 -0
- package/dist/scene.d.ts.map +1 -0
- package/dist/scene.js +276 -0
- package/dist/scene.js.map +1 -0
- package/dist/snapshot.d.ts +2 -0
- package/dist/snapshot.d.ts.map +1 -0
- package/dist/snapshot.js +828 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/terminal.d.ts +58 -0
- package/dist/terminal.d.ts.map +1 -0
- package/dist/terminal.js +139 -0
- package/dist/terminal.js.map +1 -0
- package/dist/theme.d.ts +123 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +257 -0
- package/dist/theme.js.map +1 -0
- package/dist/welcome.d.ts +23 -0
- package/dist/welcome.d.ts.map +1 -0
- package/dist/welcome.js +128 -0
- package/dist/welcome.js.map +1 -0
- package/package.json +5 -4
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/README.md +11 -1
- package/plugin/commands/fork.md +118 -0
- package/plugin/commands/team.md +44 -20
- package/plugin/hooks/hooks.json +6 -0
- package/plugin/mcp/index.mjs +69 -0
- package/plugin/scripts/deliver-messages.mjs +76 -0
package/dist/login.d.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
export interface LoginOptions {
|
|
2
|
+
/**
|
|
3
|
+
* Continue an existing trunk rather than opening one. Set when `popover welcome` has
|
|
4
|
+
* already drawn the frame this login is happening inside.
|
|
5
|
+
*/
|
|
6
|
+
framed?: boolean;
|
|
7
|
+
}
|
|
1
8
|
/**
|
|
2
9
|
* Device authorization flow.
|
|
3
10
|
*
|
|
@@ -6,5 +13,5 @@
|
|
|
6
13
|
* long-lived credential is in transit. The separate device code authenticates polling
|
|
7
14
|
* and is discarded once claimed.
|
|
8
15
|
*/
|
|
9
|
-
export declare function login(apiUrl: string): Promise<number>;
|
|
16
|
+
export declare function login(apiUrl: string, opts?: LoginOptions): Promise<number>;
|
|
10
17
|
//# sourceMappingURL=login.d.ts.map
|
package/dist/login.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../src/login.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../src/login.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,wBAAsB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiIpF"}
|
package/dist/login.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { createHash, randomBytes } from "node:crypto";
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import { saveCredentials } from "@popoverinstall/shared";
|
|
4
|
-
import {
|
|
4
|
+
import { openBrowser } from "./ui.js";
|
|
5
5
|
import { askDaemon } from "./ipc-client.js";
|
|
6
|
+
import { nextSteps } from "./next-steps.js";
|
|
7
|
+
import { box, line, spinner, step, stepFail, style, trunk } from "./theme.js";
|
|
6
8
|
const sha256 = (v) => createHash("sha256").update(v, "utf8").digest("hex");
|
|
7
9
|
const secret = () => randomBytes(32).toString("base64url");
|
|
8
10
|
/**
|
|
@@ -13,9 +15,11 @@ const secret = () => randomBytes(32).toString("base64url");
|
|
|
13
15
|
* long-lived credential is in transit. The separate device code authenticates polling
|
|
14
16
|
* and is discarded once claimed.
|
|
15
17
|
*/
|
|
16
|
-
export async function login(apiUrl) {
|
|
18
|
+
export async function login(apiUrl, opts = {}) {
|
|
17
19
|
const deviceToken = secret();
|
|
18
20
|
const deviceCode = secret();
|
|
21
|
+
if (!opts.framed)
|
|
22
|
+
console.log("");
|
|
19
23
|
let start;
|
|
20
24
|
try {
|
|
21
25
|
const res = await fetch(`${apiUrl}/api/device/start`, {
|
|
@@ -29,34 +33,38 @@ export async function login(apiUrl) {
|
|
|
29
33
|
}),
|
|
30
34
|
});
|
|
31
35
|
if (!res.ok) {
|
|
32
|
-
|
|
36
|
+
stepFail(`Could not start login (${res.status}). Is ${apiUrl} reachable?`);
|
|
33
37
|
return 1;
|
|
34
38
|
}
|
|
35
39
|
start = (await res.json());
|
|
36
40
|
}
|
|
37
41
|
catch (err) {
|
|
38
|
-
|
|
42
|
+
stepFail(`Could not reach ${apiUrl}: ${err instanceof Error ? err.message : String(err)}`);
|
|
39
43
|
return 1;
|
|
40
44
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
box({
|
|
46
|
+
title: "Confirm this code in your browser",
|
|
47
|
+
lines: ["", style.bold(style.cyan(start.user_code)), "", style.dim(start.verify_url)],
|
|
48
|
+
minWidth: 36,
|
|
49
|
+
});
|
|
50
|
+
trunk();
|
|
51
|
+
step("Opening your browser…");
|
|
48
52
|
await openBrowser(start.verify_url_complete);
|
|
53
|
+
trunk();
|
|
49
54
|
const intervalMs = (start.poll_interval_seconds ?? 2) * 1000;
|
|
50
55
|
const deadline = Date.parse(start.expires_at);
|
|
51
|
-
|
|
56
|
+
// The spinner is the liveness signal the row of dots used to be. It also carries the
|
|
57
|
+
// deadline: a code that quietly expires while someone is hunting for their password is
|
|
58
|
+
// the one failure in this flow that looks like a hang.
|
|
59
|
+
const spin = spinner("Waiting for you to approve…");
|
|
52
60
|
for (;;) {
|
|
53
61
|
if (Date.now() > deadline) {
|
|
54
|
-
|
|
55
|
-
|
|
62
|
+
spin.clear();
|
|
63
|
+
stepFail("That code expired. Run `popover login` again.");
|
|
56
64
|
return 1;
|
|
57
65
|
}
|
|
58
66
|
await sleep(intervalMs);
|
|
59
|
-
|
|
67
|
+
spin.update(`Waiting for you to approve… ${style.dim(`${remaining(deadline)} left`)}`);
|
|
60
68
|
let status;
|
|
61
69
|
try {
|
|
62
70
|
const res = await fetch(`${apiUrl}/api/device/poll`, {
|
|
@@ -71,21 +79,32 @@ export async function login(apiUrl) {
|
|
|
71
79
|
}
|
|
72
80
|
if (status.status === "pending")
|
|
73
81
|
continue;
|
|
74
|
-
console.log("");
|
|
75
82
|
if (status.status === "denied") {
|
|
76
|
-
|
|
83
|
+
spin.clear();
|
|
84
|
+
stepFail("Login denied. Nothing was connected.");
|
|
85
|
+
return 1;
|
|
86
|
+
}
|
|
87
|
+
// The server expires codes on its own schedule, so this arrives slightly before the local
|
|
88
|
+
// deadline check above would have fired. Same situation, so it gets the same sentence
|
|
89
|
+
// rather than the generic one, which rendered as "Login expired.".
|
|
90
|
+
if (status.status === "expired") {
|
|
91
|
+
spin.clear();
|
|
92
|
+
stepFail("That code expired. Run `popover login` again.");
|
|
77
93
|
return 1;
|
|
78
94
|
}
|
|
79
95
|
if (status.status !== "approved" || !status.machine_id) {
|
|
80
|
-
|
|
96
|
+
spin.clear();
|
|
97
|
+
stepFail(`Login ${status.status}. Run \`popover login\` again.`);
|
|
81
98
|
return 1;
|
|
82
99
|
}
|
|
100
|
+
spin.update("Connecting this machine…");
|
|
83
101
|
// Immediately exercise the token so a broken backend config surfaces now, at a
|
|
84
102
|
// prompt, rather than later inside a detached daemon.
|
|
85
103
|
const session = await exchange(apiUrl, deviceToken);
|
|
86
104
|
if (!session) {
|
|
87
|
-
|
|
88
|
-
|
|
105
|
+
spin.clear();
|
|
106
|
+
stepFail("Connected, but the machine could not obtain an access token.");
|
|
107
|
+
line(style.dim("Check SUPABASE_JWT_SECRET on the server, then run `popover doctor`."));
|
|
89
108
|
return 1;
|
|
90
109
|
}
|
|
91
110
|
saveCredentials({
|
|
@@ -100,12 +119,21 @@ export async function login(apiUrl) {
|
|
|
100
119
|
// `popover login` the next time they open /team. Best effort: no daemon is fine, the
|
|
101
120
|
// next start reads the file anyway.
|
|
102
121
|
await askDaemon({ t: "ping", id: "login" }, 5_000);
|
|
103
|
-
|
|
104
|
-
dim("Your Claude Code sessions will appear to your team while they are running.");
|
|
105
|
-
|
|
122
|
+
spin.stop(style.bold("This machine is connected."));
|
|
123
|
+
line(style.dim("Your Claude Code sessions will appear to your team while they are running."));
|
|
124
|
+
// Connecting a machine is the same milestone however it was reached, so a bare
|
|
125
|
+
// `popover login` gets the same send-off. When welcome() is driving it prints this itself,
|
|
126
|
+
// once, after this returns.
|
|
127
|
+
if (!opts.framed)
|
|
128
|
+
nextSteps();
|
|
106
129
|
return 0;
|
|
107
130
|
}
|
|
108
131
|
}
|
|
132
|
+
/** Time left on the code, as mm:ss — the shape a countdown is read in. */
|
|
133
|
+
function remaining(deadline) {
|
|
134
|
+
const seconds = Math.max(0, Math.round((deadline - Date.now()) / 1000));
|
|
135
|
+
return `${Math.floor(seconds / 60)}:${String(seconds % 60).padStart(2, "0")}`;
|
|
136
|
+
}
|
|
109
137
|
async function exchange(apiUrl, deviceToken) {
|
|
110
138
|
try {
|
|
111
139
|
const res = await fetch(`${apiUrl}/api/device/session`, {
|
package/dist/login.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../src/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../src/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What to do now that the machine is connected.
|
|
3
|
+
*
|
|
4
|
+
* Its own module because both entry points end here: `popover welcome`, which the installer
|
|
5
|
+
* hands off to, and a bare `popover login` run later. Connecting a machine is the same milestone
|
|
6
|
+
* either way, so it gets the same send-off — and login.ts cannot import this from welcome.ts,
|
|
7
|
+
* which imports login.ts.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* The product name as people see it. The installers print it too — they are separate templates
|
|
11
|
+
* in apps/web/src/lib/install-script*.ts, so that string is paired with this one rather than
|
|
12
|
+
* shared.
|
|
13
|
+
*/
|
|
14
|
+
export declare const BRAND = "Popover";
|
|
15
|
+
export declare const TAGLINE = "The first multiplayer coding experience.";
|
|
16
|
+
export declare const TAGLINE_SECONDARY = "Let your team's AI agents communicate and collaborate with each other.";
|
|
17
|
+
export declare function nextSteps(): void;
|
|
18
|
+
//# sourceMappingURL=next-steps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"next-steps.d.ts","sourceRoot":"","sources":["../src/next-steps.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH;;;;GAIG;AACH,eAAO,MAAM,KAAK,YAAY,CAAC;AAC/B,eAAO,MAAM,OAAO,6CAA6C,CAAC;AAClE,eAAO,MAAM,iBAAiB,2EAC4C,CAAC;AAoB3E,wBAAgB,SAAS,IAAI,IAAI,CAoChC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What to do now that the machine is connected.
|
|
3
|
+
*
|
|
4
|
+
* Its own module because both entry points end here: `popover welcome`, which the installer
|
|
5
|
+
* hands off to, and a bare `popover login` run later. Connecting a machine is the same milestone
|
|
6
|
+
* either way, so it gets the same send-off — and login.ts cannot import this from welcome.ts,
|
|
7
|
+
* which imports login.ts.
|
|
8
|
+
*/
|
|
9
|
+
import { badge, box, glyph, line, step, style, trunk, wrap } from "./theme.js";
|
|
10
|
+
/**
|
|
11
|
+
* The product name as people see it. The installers print it too — they are separate templates
|
|
12
|
+
* in apps/web/src/lib/install-script*.ts, so that string is paired with this one rather than
|
|
13
|
+
* shared.
|
|
14
|
+
*/
|
|
15
|
+
export const BRAND = "Popover";
|
|
16
|
+
export const TAGLINE = "The first multiplayer coding experience.";
|
|
17
|
+
export const TAGLINE_SECONDARY = "Let your team's AI agents communicate and collaborate with each other.";
|
|
18
|
+
/**
|
|
19
|
+
* Things the agent can genuinely do, phrased the way someone would actually type them.
|
|
20
|
+
*
|
|
21
|
+
* Checked against what the plugin actually exposes — two tools, `team_list` and `team_ask` —
|
|
22
|
+
* rather than invented to sound capable. Suggesting anything else here would be the CLI
|
|
23
|
+
* teaching people a command that fails: the agent can see which teammates are active in this
|
|
24
|
+
* repo, and it can put one question to a teammate's agent, which a read-only copy answers.
|
|
25
|
+
* That is the whole surface.
|
|
26
|
+
*
|
|
27
|
+
* One per tool, then one that uses both — which is the pattern worth teaching, since asking
|
|
28
|
+
* without listing first means guessing at a handle.
|
|
29
|
+
*/
|
|
30
|
+
const ASK_EXAMPLES = [
|
|
31
|
+
`Ask ${BRAND} who on my team is working in this repo right now.`,
|
|
32
|
+
`Ask ${BRAND} to ask G1 why they ruled out Redis for the roster cache.`,
|
|
33
|
+
`Ask ${BRAND} who knows this service, then ask their agent how retries work.`,
|
|
34
|
+
];
|
|
35
|
+
export function nextSteps() {
|
|
36
|
+
// Wrapped to the window, like the welcome box, and before styling — `wrap` counts
|
|
37
|
+
// characters, so escape codes would be measured as content.
|
|
38
|
+
const room = Math.max(28, (process.stdout.columns ?? 80) - 8);
|
|
39
|
+
trunk();
|
|
40
|
+
box({
|
|
41
|
+
title: badge(`${BRAND} is ready to be toasted!`),
|
|
42
|
+
lines: [
|
|
43
|
+
"",
|
|
44
|
+
...wrap(`${BRAND} can now communicate with your team's agents.`, room).map(style.bold),
|
|
45
|
+
...wrap("These commands make it excruciatingly easy to get started.", room).map(style.dim),
|
|
46
|
+
"",
|
|
47
|
+
],
|
|
48
|
+
minWidth: 36,
|
|
49
|
+
});
|
|
50
|
+
trunk();
|
|
51
|
+
step("Pick a starting point");
|
|
52
|
+
bullet(`${style.bold("/popover:team")} ${style.dim("run it in any Claude Code session")}`);
|
|
53
|
+
bullet(`${style.bold("popover doctor")} ${style.dim("if something looks wrong")}`);
|
|
54
|
+
trunk();
|
|
55
|
+
step("Ask your coding agent");
|
|
56
|
+
for (const example of ASK_EXAMPLES) {
|
|
57
|
+
// Continuation lines are indented, so a wrapped quote still reads as one quote.
|
|
58
|
+
const [first, ...rest] = wrap(`"${example}"`, room);
|
|
59
|
+
line(style.dim(first ?? ""));
|
|
60
|
+
for (const more of rest)
|
|
61
|
+
line(style.dim(` ${more}`));
|
|
62
|
+
}
|
|
63
|
+
trunk();
|
|
64
|
+
line(style.dim("Restart Claude Code for the plugin to load."));
|
|
65
|
+
trunk();
|
|
66
|
+
line(style.amber("Happy popping!"));
|
|
67
|
+
console.log("");
|
|
68
|
+
}
|
|
69
|
+
/** A bulleted line hanging off the trunk. */
|
|
70
|
+
function bullet(text) {
|
|
71
|
+
console.log(`${style.dim(glyph.trunk)} ${style.dim(glyph.dot)} ${text}`);
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=next-steps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"next-steps.js","sourceRoot":"","sources":["../src/next-steps.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAE/E;;;;GAIG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,SAAS,CAAC;AAC/B,MAAM,CAAC,MAAM,OAAO,GAAG,0CAA0C,CAAC;AAClE,MAAM,CAAC,MAAM,iBAAiB,GAC5B,wEAAwE,CAAC;AAE3E;;;;;;;;;;;GAWG;AACH,MAAM,YAAY,GAAG;IACnB,OAAO,KAAK,oDAAoD;IAChE,OAAO,KAAK,2DAA2D;IACvE,OAAO,KAAK,iEAAiE;CAC9E,CAAC;AAEF,MAAM,UAAU,SAAS;IACvB,kFAAkF;IAClF,4DAA4D;IAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAE9D,KAAK,EAAE,CAAC;IACR,GAAG,CAAC;QACF,KAAK,EAAE,KAAK,CAAC,GAAG,KAAK,0BAA0B,CAAC;QAChD,KAAK,EAAE;YACL,EAAE;YACF,GAAG,IAAI,CAAC,GAAG,KAAK,+CAA+C,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;YACtF,GAAG,IAAI,CAAC,4DAA4D,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;YAC1F,EAAE;SACH;QACD,QAAQ,EAAE,EAAE;KACb,CAAC,CAAC;IAEH,KAAK,EAAE,CAAC;IACR,IAAI,CAAC,uBAAuB,CAAC,CAAC;IAC9B,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,mCAAmC,CAAC,EAAE,CAAC,CAAC;IAC7F,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,0BAA0B,CAAC,EAAE,CAAC,CAAC;IAEpF,KAAK,EAAE,CAAC;IACR,IAAI,CAAC,uBAAuB,CAAC,CAAC;IAC9B,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;QACnC,gFAAgF;QAChF,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,OAAO,GAAG,EAAE,IAAI,CAAC,CAAC;QACpD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;QAC7B,KAAK,MAAM,IAAI,IAAI,IAAI;YAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,KAAK,EAAE,CAAC;IACR,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC,CAAC;IAC/D,KAAK,EAAE,CAAC;IACR,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC;AAED,6CAA6C;AAC7C,SAAS,MAAM,CAAC,IAAY;IAC1B,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;AAC5E,CAAC"}
|
package/dist/scene.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The welcome scene: the aardvark standing in some grass, under a sky.
|
|
3
|
+
*
|
|
4
|
+
* Same half-block bitmap trick as the aardvark itself — two stacked pixels per terminal cell
|
|
5
|
+
* via U+2580, foreground painting the top pixel and background the bottom — but over one
|
|
6
|
+
* shared canvas with a palette, so the moon, the clouds and the grass can each have their own
|
|
7
|
+
* colour while still sharing cells with whatever they overlap.
|
|
8
|
+
*
|
|
9
|
+
* The sky follows the clock: a crescent moon and stars at night, a sun during the day. Beyond
|
|
10
|
+
* being a nice touch, it means the scene someone sees at 2am is not pretending it is midday.
|
|
11
|
+
*
|
|
12
|
+
* Stars are the one exception to the bitmap: they are `*` glyphs rather than blocks, because a
|
|
13
|
+
* star drawn as a half-block is a rectangle. Any cell containing one is rendered as the glyph
|
|
14
|
+
* instead of as pixels.
|
|
15
|
+
*/
|
|
16
|
+
/** Total columns the scene needs, trunk and indent included. */
|
|
17
|
+
export declare const SCENE_COLUMNS: number;
|
|
18
|
+
export interface SceneOptions {
|
|
19
|
+
/** Columns available. A scene wider than the window is worse than no scene. */
|
|
20
|
+
columns?: number;
|
|
21
|
+
/** Overridden by the tests and by `--night` / `--day`; otherwise read off the clock. */
|
|
22
|
+
night?: boolean;
|
|
23
|
+
indent?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Whether half blocks are safe to emit. Defaults to what the terminal announced.
|
|
26
|
+
*
|
|
27
|
+
* An override for the same reason `night` is one: the ambient value is environmental, and a
|
|
28
|
+
* test that reads it asserts against whatever terminal happens to run it — passing on a
|
|
29
|
+
* developer's Windows Terminal and failing on a bare CI runner, where no
|
|
30
|
+
* `WT_SESSION`/`TERM_PROGRAM` means ASCII and the scene is empty by design.
|
|
31
|
+
*/
|
|
32
|
+
unicode?: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The scene as terminal rows, each prefixed with the trunk so it hangs off the same vertical
|
|
36
|
+
* line as the rest of the flow.
|
|
37
|
+
*
|
|
38
|
+
* Returns an empty array when the terminal has not told us it speaks UTF-8 — half blocks come
|
|
39
|
+
* out as replacement characters there — and null when the window is too narrow, which is the
|
|
40
|
+
* caller's cue to fall back to the aardvark on its own.
|
|
41
|
+
*/
|
|
42
|
+
export declare function sceneLines(opts?: SceneOptions): string[] | null;
|
|
43
|
+
//# sourceMappingURL=scene.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scene.d.ts","sourceRoot":"","sources":["../src/scene.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AASH,gEAAgE;AAChE,eAAO,MAAM,aAAa,QAAY,CAAC;AAsPvC,MAAM,WAAW,YAAY;IAC3B,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wFAAwF;IACxF,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,IAAI,GAAE,YAAiB,GAAG,MAAM,EAAE,GAAG,IAAI,CAqBnE"}
|
package/dist/scene.js
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The welcome scene: the aardvark standing in some grass, under a sky.
|
|
3
|
+
*
|
|
4
|
+
* Same half-block bitmap trick as the aardvark itself — two stacked pixels per terminal cell
|
|
5
|
+
* via U+2580, foreground painting the top pixel and background the bottom — but over one
|
|
6
|
+
* shared canvas with a palette, so the moon, the clouds and the grass can each have their own
|
|
7
|
+
* colour while still sharing cells with whatever they overlap.
|
|
8
|
+
*
|
|
9
|
+
* The sky follows the clock: a crescent moon and stars at night, a sun during the day. Beyond
|
|
10
|
+
* being a nice touch, it means the scene someone sees at 2am is not pretending it is midday.
|
|
11
|
+
*
|
|
12
|
+
* Stars are the one exception to the bitmap: they are `*` glyphs rather than blocks, because a
|
|
13
|
+
* star drawn as a half-block is a rectangle. Any cell containing one is rendered as the glyph
|
|
14
|
+
* instead of as pixels.
|
|
15
|
+
*/
|
|
16
|
+
import { AARDVARK_SPRITE } from "./aardvark.js";
|
|
17
|
+
import { AMBER_INK, AMBER_WASH, colorEnabled, glyph, style, unicodeEnabled } from "./theme.js";
|
|
18
|
+
const WIDTH = 64;
|
|
19
|
+
/** Two pixel rows per terminal row, so this must stay even. */
|
|
20
|
+
const HEIGHT = 20;
|
|
21
|
+
/** Total columns the scene needs, trunk and indent included. */
|
|
22
|
+
export const SCENE_COLUMNS = WIDTH + 3;
|
|
23
|
+
// ------------------------------------------------------------------ sky art
|
|
24
|
+
/**
|
|
25
|
+
* The moon, at cell resolution and in two tones.
|
|
26
|
+
*
|
|
27
|
+
* Coverage per cell is supersampled against a crescent — a disc of radius 7 with a radius-5 disc
|
|
28
|
+
* bitten out of it, offset 2.5 — then quantised: mostly covered becomes a solid block, partly
|
|
29
|
+
* covered becomes stipple. That is what produces the soft two-tone edge and the detached tips at
|
|
30
|
+
* the horns, rather than them being drawn in.
|
|
31
|
+
*
|
|
32
|
+
* Cell resolution rather than pixels because a cell is roughly twice as tall as it is wide, so a
|
|
33
|
+
* round moon needs twice as many columns as rows — 14 by 7 — and because the stipple is a
|
|
34
|
+
* character, which cannot be half a cell tall.
|
|
35
|
+
*
|
|
36
|
+
* Mirrored from the reference so it opens back towards the aardvark.
|
|
37
|
+
*/
|
|
38
|
+
// prettier-ignore
|
|
39
|
+
const MOON = [
|
|
40
|
+
"...dMMMMMMd...",
|
|
41
|
+
"..d...ddMMMMM.",
|
|
42
|
+
".........MMMMM",
|
|
43
|
+
".........dMMMM",
|
|
44
|
+
".........MMMMM",
|
|
45
|
+
"..d...ddMMMMM.",
|
|
46
|
+
"...dMMMMMMd...",
|
|
47
|
+
];
|
|
48
|
+
/**
|
|
49
|
+
* Disc and eight rays, on the moon's footprint so the sky does not reflow at dawn.
|
|
50
|
+
*
|
|
51
|
+
* Drawn by hand. Generating the rays as an arc cut into spokes produced confetti — at this
|
|
52
|
+
* size every ray has to be placed, not derived.
|
|
53
|
+
*/
|
|
54
|
+
// prettier-ignore
|
|
55
|
+
const SUN = [
|
|
56
|
+
"......ss......",
|
|
57
|
+
"......ss......",
|
|
58
|
+
"..s........s..",
|
|
59
|
+
".....ssss.....",
|
|
60
|
+
"....ssssss....",
|
|
61
|
+
"...ssssssss...",
|
|
62
|
+
"ss.ssssssss.ss",
|
|
63
|
+
"ss.ssssssss.ss",
|
|
64
|
+
"...ssssssss...",
|
|
65
|
+
"....ssssss....",
|
|
66
|
+
".....ssss.....",
|
|
67
|
+
"..s........s..",
|
|
68
|
+
"......ss......",
|
|
69
|
+
"......ss......",
|
|
70
|
+
];
|
|
71
|
+
/*
|
|
72
|
+
* Clouds are stippled rather than solid, and drawn at cell resolution rather than in pixels.
|
|
73
|
+
*
|
|
74
|
+
* A cloud is the one thing here made of a character instead of blocks: U+2591 LIGHT SHADE, whose
|
|
75
|
+
* dot grid is the texture in the reference. That means a cloud cannot be half a cell tall, so its
|
|
76
|
+
* art is one row per terminal row and `stampCells` writes it to both pixel rows of each — which
|
|
77
|
+
* is also why the silhouettes are stepped mesas rather than curves. It is the shape the medium
|
|
78
|
+
* wants.
|
|
79
|
+
*/
|
|
80
|
+
// prettier-ignore
|
|
81
|
+
const CLOUD_BIG = [
|
|
82
|
+
"......cccc....",
|
|
83
|
+
"..ccc.ccccccc.",
|
|
84
|
+
"cccccccccccccc",
|
|
85
|
+
];
|
|
86
|
+
// prettier-ignore
|
|
87
|
+
const CLOUD_SMALL = [
|
|
88
|
+
"...cccc...",
|
|
89
|
+
"cccccccccc",
|
|
90
|
+
];
|
|
91
|
+
/**
|
|
92
|
+
* Where the stars go. Placed by hand to sit in the gaps rather than on top of anything, and all
|
|
93
|
+
* above the skyline — a star down at grass height reads as a dropped asterisk.
|
|
94
|
+
*/
|
|
95
|
+
const STARS = [
|
|
96
|
+
[36, 0],
|
|
97
|
+
[42, 1],
|
|
98
|
+
[47, 0],
|
|
99
|
+
[49, 5],
|
|
100
|
+
[63, 6],
|
|
101
|
+
[35, 7],
|
|
102
|
+
[41, 8],
|
|
103
|
+
[48, 9],
|
|
104
|
+
];
|
|
105
|
+
/**
|
|
106
|
+
* Strand heights in pixels, cycled across the ground.
|
|
107
|
+
*
|
|
108
|
+
* Paired with uneven gaps below. Heights alone are not enough — strands on a fixed 2px pitch
|
|
109
|
+
* read as a picket fence however much their tops vary.
|
|
110
|
+
*/
|
|
111
|
+
const GRASS_HEIGHTS = [3, 5, 2, 4, 3, 2, 5, 3, 4, 2, 3, 5, 2, 4, 3, 2, 4, 3, 5, 2];
|
|
112
|
+
/** Columns to skip before the next strand. */
|
|
113
|
+
const GRASS_GAPS = [2, 3, 2, 2, 3, 2, 4, 2];
|
|
114
|
+
/** Grass starts clear of the aardvark's hind legs and runs to the edge. */
|
|
115
|
+
const GRASS_FROM = 35;
|
|
116
|
+
// ------------------------------------------------------------------ palette
|
|
117
|
+
const RESET = "\x1b[0m";
|
|
118
|
+
/** Moonlight: the solid blocks and the stippled edge share it. */
|
|
119
|
+
const MOONLIGHT = "\x1b[37m";
|
|
120
|
+
/** Foreground codes per palette key. The aardvark keeps the terminal's own dark red. */
|
|
121
|
+
const INK = {
|
|
122
|
+
"1": "\x1b[31m", // aardvark body
|
|
123
|
+
"4": "\x1b[97m", // its eye
|
|
124
|
+
s: AMBER_INK, // the sun, in the same amber as the rest of the flow
|
|
125
|
+
c: "\x1b[90m", // cloud
|
|
126
|
+
g: "\x1b[32m", // grass
|
|
127
|
+
};
|
|
128
|
+
/** Background codes, for the lower pixel of a cell. */
|
|
129
|
+
const WASH = {
|
|
130
|
+
"1": "\x1b[41m",
|
|
131
|
+
"4": "\x1b[107m",
|
|
132
|
+
s: AMBER_WASH,
|
|
133
|
+
c: "\x1b[100m",
|
|
134
|
+
g: "\x1b[42m",
|
|
135
|
+
};
|
|
136
|
+
const UPPER = "▀";
|
|
137
|
+
const LOWER = "▄";
|
|
138
|
+
const FULL = "█";
|
|
139
|
+
const STAR = "*";
|
|
140
|
+
/** U+2591 LIGHT SHADE. Its dot grid is the cloud texture from the reference. */
|
|
141
|
+
const SHADE = "░";
|
|
142
|
+
// ------------------------------------------------------------------ compose
|
|
143
|
+
function stamp(canvas, art, ox, oy) {
|
|
144
|
+
art.forEach((row, y) => [...row].forEach((ch, x) => {
|
|
145
|
+
if (ch === ".")
|
|
146
|
+
return;
|
|
147
|
+
const cy = oy + y;
|
|
148
|
+
const cx = ox + x;
|
|
149
|
+
if (cy < 0 || cy >= HEIGHT || cx < 0 || cx >= WIDTH)
|
|
150
|
+
return;
|
|
151
|
+
canvas[cy][cx] = ch;
|
|
152
|
+
}));
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Stamp art whose rows are terminal rows rather than pixel rows, by writing each to both pixels
|
|
156
|
+
* of its cell. For anything drawn as a character, where half a cell is not a thing.
|
|
157
|
+
*/
|
|
158
|
+
function stampCells(canvas, art, ox, oy) {
|
|
159
|
+
art.forEach((row, y) => {
|
|
160
|
+
[...row].forEach((ch, x) => {
|
|
161
|
+
if (ch === ".")
|
|
162
|
+
return;
|
|
163
|
+
const cx = ox + x;
|
|
164
|
+
if (cx < 0 || cx >= WIDTH)
|
|
165
|
+
return;
|
|
166
|
+
for (const cy of [oy + y * 2, oy + y * 2 + 1]) {
|
|
167
|
+
if (cy >= 0 && cy < HEIGHT)
|
|
168
|
+
canvas[cy][cx] = ch;
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Build the canvas. Back to front, so the aardvark and the grass sit over the sky rather than
|
|
175
|
+
* being punched through by it.
|
|
176
|
+
*/
|
|
177
|
+
function compose(night) {
|
|
178
|
+
const canvas = Array.from({ length: HEIGHT }, () => Array(WIDTH).fill("."));
|
|
179
|
+
// Top right corner. Both are 14 wide, so the sun's disc and the moon's limb land in the same
|
|
180
|
+
// place — the sky does not shift at dawn.
|
|
181
|
+
if (night)
|
|
182
|
+
stampCells(canvas, MOON, WIDTH - 14, 0);
|
|
183
|
+
else
|
|
184
|
+
stamp(canvas, SUN, WIDTH - 14, 0);
|
|
185
|
+
// Cell rows 1-3 and 5-6, kept clear of the moon so neither sits on the other.
|
|
186
|
+
stampCells(canvas, CLOUD_BIG, 34, 2);
|
|
187
|
+
stampCells(canvas, CLOUD_SMALL, 38, 10);
|
|
188
|
+
// Stars only at night, and only where nothing else already is.
|
|
189
|
+
if (night) {
|
|
190
|
+
for (const [x, y] of STARS) {
|
|
191
|
+
if (canvas[y]?.[x] === ".")
|
|
192
|
+
canvas[y][x] = "*";
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/*
|
|
196
|
+
* A continuous ground line with strands rising out of it. Strands alone, however uneven, read
|
|
197
|
+
* as a picket fence — it is the unbroken base that turns them into grass growing on something.
|
|
198
|
+
* The line sits on the aardvark's own footing: the sprite's legs end on this row too.
|
|
199
|
+
*/
|
|
200
|
+
for (let x = GRASS_FROM; x < WIDTH; x += 1)
|
|
201
|
+
canvas[HEIGHT - 1][x] = "g";
|
|
202
|
+
for (let x = GRASS_FROM, i = 0; x < WIDTH; i += 1) {
|
|
203
|
+
const height = GRASS_HEIGHTS[i % GRASS_HEIGHTS.length];
|
|
204
|
+
for (let y = HEIGHT - height; y < HEIGHT; y += 1)
|
|
205
|
+
canvas[y][x] = "g";
|
|
206
|
+
x += GRASS_GAPS[i % GRASS_GAPS.length];
|
|
207
|
+
}
|
|
208
|
+
stamp(canvas, AARDVARK_SPRITE, 0, 0);
|
|
209
|
+
return canvas;
|
|
210
|
+
}
|
|
211
|
+
/** The sun is up between six in the morning and six at night. Close enough for a sky. */
|
|
212
|
+
function isNight(at = new Date()) {
|
|
213
|
+
const hour = at.getHours();
|
|
214
|
+
return hour < 6 || hour >= 18;
|
|
215
|
+
}
|
|
216
|
+
// ------------------------------------------------------------------ render
|
|
217
|
+
function paint(top, bottom) {
|
|
218
|
+
if (top === "*" || bottom === "*") {
|
|
219
|
+
// A star is a glyph, not a pixel pair. Rendered dim so it reads as distant.
|
|
220
|
+
return colorEnabled ? `${INK.c}${STAR}${RESET}` : STAR;
|
|
221
|
+
}
|
|
222
|
+
/*
|
|
223
|
+
* Everything drawn as a character rather than as a pixel pair is resolved first: clouds and the
|
|
224
|
+
* moon's stipple. All are stamped at cell resolution, so there is never half of one to draw.
|
|
225
|
+
*/
|
|
226
|
+
if (top === "c" || bottom === "c") {
|
|
227
|
+
return colorEnabled ? `${INK.c}${SHADE}${RESET}` : SHADE;
|
|
228
|
+
}
|
|
229
|
+
if (top === "M" || bottom === "M") {
|
|
230
|
+
return colorEnabled ? `${MOONLIGHT}${FULL}${RESET}` : FULL;
|
|
231
|
+
}
|
|
232
|
+
if (top === "d" || bottom === "d") {
|
|
233
|
+
// The stipple reads dimmer than the solid on its own — a quarter of the cell is lit — so it
|
|
234
|
+
// needs no separate colour to sit behind the edge.
|
|
235
|
+
return colorEnabled ? `${MOONLIGHT}${SHADE}${RESET}` : SHADE;
|
|
236
|
+
}
|
|
237
|
+
if (top === "." && bottom === ".")
|
|
238
|
+
return " ";
|
|
239
|
+
if (!colorEnabled) {
|
|
240
|
+
// Nothing to tell the layers apart with, so fall back to shape alone.
|
|
241
|
+
return top === "." ? LOWER : bottom === "." ? UPPER : FULL;
|
|
242
|
+
}
|
|
243
|
+
if (bottom === ".")
|
|
244
|
+
return `${INK[top] ?? ""}${UPPER}${RESET}`;
|
|
245
|
+
if (top === ".")
|
|
246
|
+
return `${INK[bottom] ?? ""}${LOWER}${RESET}`;
|
|
247
|
+
return `${INK[top] ?? ""}${WASH[bottom] ?? ""}${UPPER}${RESET}`;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* The scene as terminal rows, each prefixed with the trunk so it hangs off the same vertical
|
|
251
|
+
* line as the rest of the flow.
|
|
252
|
+
*
|
|
253
|
+
* Returns an empty array when the terminal has not told us it speaks UTF-8 — half blocks come
|
|
254
|
+
* out as replacement characters there — and null when the window is too narrow, which is the
|
|
255
|
+
* caller's cue to fall back to the aardvark on its own.
|
|
256
|
+
*/
|
|
257
|
+
export function sceneLines(opts = {}) {
|
|
258
|
+
if (!(opts.unicode ?? unicodeEnabled))
|
|
259
|
+
return [];
|
|
260
|
+
const columns = opts.columns ?? process.stdout.columns ?? 80;
|
|
261
|
+
if (columns < SCENE_COLUMNS)
|
|
262
|
+
return null;
|
|
263
|
+
const indent = opts.indent ?? 2;
|
|
264
|
+
const canvas = compose(opts.night ?? isNight());
|
|
265
|
+
const rows = [];
|
|
266
|
+
for (let y = 0; y < HEIGHT; y += 2) {
|
|
267
|
+
const top = canvas[y];
|
|
268
|
+
const bottom = canvas[y + 1];
|
|
269
|
+
let out = "";
|
|
270
|
+
for (let x = 0; x < WIDTH; x += 1)
|
|
271
|
+
out += paint(top[x], bottom[x]);
|
|
272
|
+
rows.push(`${style.dim(glyph.trunk)}${" ".repeat(indent)}${out.replace(/\s+$/, "")}`);
|
|
273
|
+
}
|
|
274
|
+
return rows;
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=scene.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scene.js","sourceRoot":"","sources":["../src/scene.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"AA+DA,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAoBjE"}
|